Mybatis-Plus: Generic CRUD, Set generation policy for Mybatis-Plus Id, @TableField (inconsistent attribute and field names, field does not exist, field ignored)

This section takes on the previous section

You can get a wide variety of form operations by inheriting BaseMapper, which we'll cover in more detail next.

BaseMapper.java source

/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.core.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Mapper After inheriting the interface, there is no need to write a mapper.xml file, you can get CRUD function
 * <p>This Mapper supports id generics </p>
 *
 * @author hubin
 * @since 2016-01-23
 */
public interface BaseMapper<T> extends Mapper<T> {

    /**
     * Insert a record
     *
     * @param entity Entity Object
     */
    int insert(T entity);

    /**
     * Delete by ID
     *
     * @param id Primary Key ID
     */
    int deleteById(Serializable id);

    /**
     * Delete records according to columnMap criteria
     *
     * @param columnMap Table field map object
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * Delete records according to entity criteria
     *
     * @param wrapper Entity object encapsulation operation class (null can be used)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

    /**
     * Delete (batch delete based on ID)
     *
     * @param idList Primary Key ID List (cannot be null and empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * Modify according to ID
     *
     * @param entity Entity Object
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * Update records according to where Entity criteria
     *
     * @param entity        Entity object (set condition value, null)
     * @param updateWrapper Entity object encapsulation operation class (null, where entity is used to generate where statements)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * Query by ID
     *
     * @param id Primary Key ID
     */
    T selectById(Serializable id);

    /**
     * Queries (batch queries based on ID)
     *
     * @param idList Primary Key ID List (cannot be null and empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * Query (according to columnMap criteria)
     *
     * @param columnMap Table field map object
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * Query a record based on entity criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * Query total records based on Wrapper criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * Query all records according to entity criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * Query all records based on Wrapper criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * Query all records based on Wrapper criteria
     * <p>Note: Only return the value of the first field </p>
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * Query all records (and page over) according to entity criteria
     *
     * @param page         Paging query criteria (RowBounds.DEFAULT can be used)
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * Query all records (and page over) according to Wrapper criteria
     *
     * @param page         Paging Query Criteria
     * @param queryWrapper Entity Object Encapsulation Action Class
     */
    <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

1 Insert operation

1.1 Method Definition

    /**
     * Insert a record
     *
     * @param entity Entity Object
     */
    int insert(T entity);

1.2 Writing test cases

TestUserMapper.java

package com.tian.springbootmybatis_plus;

import mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import pojo.User;

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestUserMapper {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        User user = new User();
        user.setAge(301);
        user.setUserName("caocao1");
        user.setName("Cao Cao 1");
        user.setPassword("123456");
        int result = this.userMapper.insert(user); //Number of rows affected by result database
        System.out.println("result => " + result);

        //Gets the id value from the growth, which is backfilled into the user object in Mybatis-Plus
        System.out.println("id => " + user.getId());
    }
}

Run result:

As you can see, the data has already been written to the database, but the value of id is incorrect. We expect the database to grow by itself. In fact, MP generated the value of id to be written to the database.

1.3 Set the generation policy for Mybatis-Plus Id

MP supported id policy:

IdType.java

/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.baomidou.mybatisplus.annotation;

import lombok.Getter;

/**
 * Generate ID Type Enumeration Class
 *
 * @author hubin
 * @since 2015-11-10
 */
@Getter
public enum IdType {
    /**
     * Database ID Self-Increasing
     */
    AUTO(0),
    /**
     * This type is not set as the primary key type (follow global in annotation, global approximately equal to INPUT)
     */
    NONE(1),
    /**
     * User Input ID
     * <p>This type can be populated by registering an auto-fill plugin yourself </p>
     */
    INPUT(2),

    /* The following three types are automatically populated only if the insert object ID is empty. */
    /**
     * Assign ID (primary key type is number or string),
     * Default implementation class {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator} (Snowflake algorithm)
     *
     * @since 3.3.0
     */
    ASSIGN_ID(3),
    /**
     * Assign UUID (primary key type is string)
     * Default implementation class {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-"))
     */
    ASSIGN_UUID(4),
	/* The following three types are automatically populated only if the insert object ID is empty. */ 
	/*** Global Unique ID (idWorker) */
    @Deprecated
    ID_WORKER(3),
    /*** String Globally Unique ID (string representation of idWorker) */
    @Deprecated
    ID_WORKER_STR(3),
	/*** Global Unique ID (UUID) */
    @Deprecated
    UUID(4);

    private final int key;

    IdType(int key) {
        this.key = key;
    }
}

Modify the User object to specify that the id type is self-growing

First delete the original data, then we set the ID self-growth to 6, next to the data above:

Then rerun the program:

1.4 @TableField

In MyBtais-Plus, you can specify some properties of a field by using the @TableField annotation. There are two common problems to solve:

  1. Inconsistent attribute and field names in the object (non-hump, if hump naming, Mybatis-Plus will automatically help you with the conversion, eg:userName can automatically map user_name)
  2. There are no problems with attribute fields in the table.
  3. Some fields do not join the query (such as password).

Effect:

2. Update operation

In Mybatis-Plus, there are two updates, one based on id and the other based on condition.

2.1 Update based on id

Method Definition:

    /**
     * Modify according to ID
     *
     * @param entity Entity Object
     */
    int updateById(@Param(Constants.ENTITY) T entity);

Test:

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestUserMapper {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(6L); // Primary key
        user.setAge(21); // Updated Fields

        // Update fields that are not null based on id update
        this.userMapper.updateById(user);
    }
}

Run result:

2.2 Update on condition

Note that QueryWrapper and UpdateWrapper are interchangeable most of the time.

Method Definition:

    /**
     * Update records according to where Entity criteria
     *
     * @param entity        Entity object (set condition value, null)
     * @param updateWrapper Entity object encapsulation operation class (null, where entity is used to generate where statements)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

Wrapper can be understood as a query condition.

2.2.1 QueryWrapper usage

    @Test
    public void testUpdate() {
        User user = new User();
        user.setAge(2022); //Updated Fields
        user.setPassword("8888888");

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", "zhangsan"); //Match user_name = zhangsan's user data

        //Update on condition
        int result = this.userMapper.update(user, wrapper);
        System.out.println("result => " + result);
    }

Run result:

2.2.2 UpdateWrapper Usage

UpdateWrapper prefers chain calls.

    @Test
    public void testUpdate2() {

        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.set("age", 21).set("password", "999999") //Updated Fields
                .eq("user_name", "zhangsan"); //Updated Conditions

        //Update on condition
        int result = this.userMapper.update(null, wrapper);
        System.out.println("result => " + result);
    }

Run result:

3. Delete operation

3.1 deleteById

Method Definition:

    /**
     * Delete by ID
     *
     * @param id Primary Key ID
     */
    int deleteById(Serializable id);

Specific examples:

    @Test
    public void testDeleteById() {
        // Delete data with id 1
        int result = this.userMapper.deleteById(1L);
        System.out.println("result => " + result);
    }

Run result:

3.2 deleteByMap

Method Definition:

    /**
     * Delete records according to columnMap criteria
     *
     * @param columnMap Table field map object
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

Specific examples:

    @Test
    public void testDeleteByMap() {
        Map<String, Object> map = new HashMap<>();
        // Delete condition is user_name is Lisi and password is 123 456
        map.put("user_name", "lisi");
        map.put("password", "123456");

        // Delete data based on map, and the relationship between multiple conditions is an and
        int result = this.userMapper.deleteByMap(map);
        System.out.println("result => " + result);
    }

Run result:

3.3 delete

Method Definition:

    /**
     * Delete records according to entity criteria
     *
     * @param wrapper Entity object encapsulation operation class (null can be used)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

Test:

Delete the user whose username is caocao1 and password is 123 456.

    @Test
    public void testDelete() {
        //Usage 1: Note that QueryWrapper can be replaced here with updateWrapper
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.eq("user_name", "caocao1")
//                .eq("password", "123456");

        //Usage 2:
        User user = new User();
        user.setPassword("123456");
        user.setUserName("caocao1");

        QueryWrapper<User> wrapper = new QueryWrapper<>(user);
        // Delete according to packing condition
        int result = this.userMapper.delete(wrapper);
        System.out.println("result => " + result);
    }

Run result:

3.4 deleteBatchIds

Method Definition:

    /**
     * Delete (batch delete based on ID)
     *
     * @param idList Primary Key ID List (cannot be null and empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

Test:

    @Test
    public void testDeleteBatchIds() {
        // Delete data in batches based on id
        int result = this.userMapper.deleteBatchIds(Arrays.asList(3L, 4L));
        System.out.println("result => " + result);
    }

Run result:

4. Query operation

Mybatis-Plus provides a variety of query operations, including id-based queries, batch queries, queries for individual data, query lists, paging queries, and so on.

4.1 selectById

Method Definition:

    /**
     * Query by ID
     *
     * @param id Primary Key ID
     */
    T selectById(Serializable id);

Test:

    @Test
    public void testSelectById() {
        // Query users with id 5
        User user = this.userMapper.selectById(5L);
        System.out.println(user);
    }

4.2 selectBatchIds

Method Definition:

    /**
     * Queries (batch queries based on ID)
     *
     * @param idList Primary Key ID List (cannot be null and empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

Example:

First, we insert a few more pieces of data into the database. The previous data is almost erased, which is too miserable.

-- Insert Test Data
INSERT INTO `tb_user` ( `id`, `user_name`, `password`, `name`, `age`, `email` )
VALUES
	( '1', 'zhangsan', '123456', 'Zhang San', '18', 'test1@itcast.cn' );
INSERT INTO `tb_user` ( `id`, `user_name`, `password`, `name`, `age`, `email` )
VALUES
	( '2', 'lisi', '123456', 'Li Si', '20', 'test2@itcast.cn' );
INSERT INTO `tb_user` ( `id`, `user_name`, `password`, `name`, `age`, `email` )
VALUES
	( '3', 'wangwu', '123456', 'King Five', '28', 'test3@itcast.cn' );
INSERT INTO `tb_user` ( `id`, `user_name`, `password`, `name`, `age`, `email` )
VALUES
	( '4', 'zhaoliu', '123456', 'Zhao Six', '21', 'test4@itcast.cn' );

Write the test code below:

    @Test
    public void testSelectBatchIds() {
        // Bulk query data id based on id is 1,2,3,4
        List<User> users = this.userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L, 4L));
        for (User user : users) {
            System.out.println(user);
        }
    }

Run result:

4.3 selectOne

Method Definition:

    /**
     * Query a record based on entity criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Example:

    @Test
    public void testSelectOne() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //query criteria
        wrapper.eq("password", "123456");
        // Exceptions are thrown when more than one piece of data is queried
        User user = this.userMapper.selectOne(wrapper);
        System.out.println(user);
    }

Run result:

Let's change the criteria and locate only one data.

    @Test
    public void testSelectOne() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //query criteria
        wrapper.eq("password", "123456").eq("id", 1);
        // Exceptions are thrown when more than one piece of data is queried
        User user = this.userMapper.selectOne(wrapper);
        System.out.println(user);
    }

4.4 selectCount

Method Definition:

    /**
     * Query total records based on Wrapper criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Example: Query the number of users older than 20

    @Test
    public void testSelectCount() {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        // gt is a bigger operation
        wrapper.gt("age", 20); // Conditions: Users older than 20 years

        // Query the number of data bars based on criteria
        Integer count = this.userMapper.selectCount(wrapper);
        System.out.println("count is : " + count);
    }

Run result:

4.5 selectList

Method Definition:

    /**
     * Query all records according to entity criteria
     *
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Case 1: Query the user whose email field contains itcase

    @Test
    public void testSelectList() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Set Query Criteria The condition set here is that the email field contains the value itcase
        wrapper.like("email", "itcast");

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }

Run result:

Case 2: Query users older than 23

    @Test
    public void testSelectList() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Set Query Conditions Set here the condition is that the age is older than 23
        wrapper.gt("age", 23);

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }

Run result:

4.6 selectPage

Method Definition:

    /**
     * Query all records (and page over) according to entity criteria
     *
     * @param page         Paging query criteria (RowBounds.DEFAULT can be used)
     * @param queryWrapper Entity object encapsulation operation class (null can be used)
     */
    <E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Configure Paging Plugins:

MybatisPlusConfig.java

package com.tian.springbootmybatisplus;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.tian.mapper") //Because this is a configuration class, we put the package scan for the boot class here
public class MybatisPlusConfig {
    @Bean //Configure Paging Plugins
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

Write a test case: Query the first page for three pieces of data (email contains itcase data)

    // Test Paging Query
    @Test
    public void testSelectPage() {

        Page<User> page = new Page<>(1, 3); //Query the first page for 3 pieces of data

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Set Query Conditions
        wrapper.like("email", "itcast");

        IPage<User> iPage = this.userMapper.selectPage(page, wrapper);
        System.out.println("Total number of data bars: " + iPage.getTotal());
        System.out.println("Total pages of data: " + iPage.getPages());
        System.out.println("Current number of pages: " + iPage.getCurrent());

        // Print out the data you get
        List<User> records = iPage.getRecords();
        for (User record : records) {
            System.out.println(record);
        }
    }

Run result:

Tags: Java mybatis-plus intellij-idea CRUD

Posted by RIRedinPA on Tue, 15 Mar 2022 03:03:21 +1030