A. Instructions

Mybatis – Plus website: mp.baomidou.com/

Mybatis-Plus is a Mybatis framework enhancement plug-in, according to the official description,MP only do enhancement do not change, the introduction of it will not affect the existing project, as smooth as silk. And with simple configuration, CRUD operations can be performed quickly, saving a lot of time. Code generation, paging, performance analysis and other functions are available, the latest version has been updated to 3.1.1,3.X series support lambda syntax, let me write conditional construction when a lot of less “magic value “, from the code structure is more concise.

Ii. Project environment

MyBatis-Plus version: 3.2.0

SpringBoot version: 2.2.7

JDK version: 1.8

Maven has the following dependencies:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <! -- mybatisPlus Core library -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        <! Ali database connection pool -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
</dependencies>
Copy the code

The configuration is as follows:

# config port
server:
  port: 8081
spring:
  # configure data source
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mp_student? useUnicode=true&characterEncoding=utf-8
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
# Mybatis -plus related configuration
mybatis-plus:
  # XML scan, multiple directories separated by commas or semicolons (to tell Mapper where the corresponding XML file is)
  mapper-locations: classpath:mapper/*.xml
  The following configurations have default values
  global-config:
    db-config:
      # primary key type AUTO:" database ID increment "INPUT:" user INPUT ID",ID_WORKER:" globally unique ID (number type unique ID)", UUID:" globally unique ID UUID";
      id-type: auto
      # field policy IGNORED:" ignore judgment "NOT_NULL:" non-null judgment ") NOT_EMPTY:" Non-null judgment"
      field-strategy: NOT_EMPTY
      # database type
      db-type: MYSQL
  configuration:
    Enable automatic camel name mapping: a similar mapping from database column names to Java attribute camel names
    map-underscore-to-camel-case: true
    True: null is returned if the map is null. False: hidden if the map is null
    call-setters-on-nulls: true
    This configuration prints out the executed SQL for use during development or testing
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Copy the code

Table structure:

CREATE TABLE `user_info` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(32) DEFAULT NULL COMMENT 'name',
  `age` int(11) DEFAULT NULL COMMENT 'age',
  `skill` varchar(32) DEFAULT NULL COMMENT 'skills',
  `evaluate` varchar(64) DEFAULT NULL COMMENT 'evaluation',
  `fraction` bigint(11) DEFAULT NULL COMMENT 'scores'.PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COMMENT='Student Information Form';
CREATE TABLE `dept_info` (
  `dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'department ID',
  `dept_name` varchar(64) NOT NULL COMMENT 'Department Name',
  `create_id` varchar(20) DEFAULT NULL COMMENT 'creator ID',
  `create_time` timestamp NULL DEFAULT NULL COMMENT 'Creation time',
  `update_id` varchar(20) DEFAULT NULL COMMENT 'Updater ID',
  `update_time` timestamp NULL DEFAULT NULL COMMENT 'Update Time',
  `deleted` tinyint(1) DEFAULT '0' COMMENT 'Logical delete 0: normal 1: delete'.PRIMARY KEY (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4;
Copy the code

Table data:

INSERT INTO `user_info` VALUES (1.'Ming'.20.'drawing'.'The student has some talent in painting'.89);
INSERT INTO `user_info` VALUES (2.'xiao LAN'.19.'games'.'Recently, the student's score was lowered due to the game'.64);
INSERT INTO `user_info` VALUES (3.'his'.18.'English'.'The student recently won the second prize in the English competition'.90);
INSERT INTO `user_info` VALUES (4.'rhubarb'.20.'sports'.'The student recently suffered a foot injury due to participating in a basketball match'.76);
INSERT INTO `user_info` VALUES (5.'the great'.17.'painting'.'The student won the third prize in the art competition'.77);
INSERT INTO `user_info` VALUES (7.'little dragon'.18.'JAVA'.'The student is a coder fixing a BUG'.59);
INSERT INTO `user_info` VALUES (9.'Sans'.18.'sleep'.'Sans is a little fat man with a big skeleton and a short body who likes to sleep. '.60);
INSERT INTO `user_info` VALUES (10.'papyrus'.18.'JAVA'.'Papyrus is a loud, flamboyant, confident, charismatic skinny skeleton. '.58);
INSERT INTO `user_info` VALUES (11.'Delete data 1'.3.'Paint a portrait'.NULL.61);
INSERT INTO `user_info` VALUES (12.'Delete data 2'.3.NULL.NULL.61);
INSERT INTO `user_info` VALUES (13.'Delete data 3'.3.NULL.NULL.61);
INSERT INTO `user_info` VALUES (14.'Delete data 4'.5.'delete'.NULL.10);
INSERT INTO `user_info` VALUES (15.'Delete data 5'.6.'delete'.NULL.10);
Copy the code

Write the base class

Add annotations to scan the DAO on the startup class

@SpringBootApplication
@MapperScan(basePackages = {"com.mp.demo.dao"}) / / scanning DAO
public class DemoApplication {
    public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}Copy the code

Write the Config configuration class

/ * * *@DescriptionMybatisPlus configuration class *@Author Sans
 * @CreateTime2019/5/26 and * /
@Configuration
public class MybatisPlusConfig {
    /** ** paging plug-in */
    @Bean
    public PaginationInterceptor paginationInterceptor(a) {
        return newPaginationInterceptor(); }}Copy the code

Write the Entity class

/ * * *@DescriptionStudent information Entity class *@Author Sans
 * @CreateTime2019/5/26 all * /
@Data
@TableName("user_info")// the value in @tablename corresponds to the TableName
public class UserInfoEntity {

    /** * primary key *@TableId* AUTO: database ID increment * INPUT: user INPUT ID * ID_WORKER: globally unique ID, primary key of type Long * ID_WORKER_STR: String Globally unique ID * UUID: indicates a globally unique ID. Primary key of the UUID type * NONE: indicates that the primary key type is not set */
    @TableId(type = IdType.AUTO)
    private Long id;
    /** * name */
    private String name;
    /** * age */
    private Integer age;
    /** * skills */
    private String skill;
    /** * evaluation */
    private String evaluate;
    /** * score */
    private Long fraction;
}
Copy the code

Write the Dao class

/ * * *@DescriptionUser information DAO *@Author Sans
 * @CreateTime2019/6/8 16:24 * /
public interface UserInfoDao extends BaseMapper<UserInfoEntity> {}Copy the code

Write the Service class

/ * * *@DescriptionUser business interface *@Author Sans
 * @CreateTime7 all 2019/6/8 * /
public interface UserInfoService extends IService<UserInfoEntity> {}Copy the code

Write ServiceImpl class

/ * * *@DescriptionUser business implementation *@Author Sans
 * @CreateTime7 all 2019/6/8 * /
@Service
@Transactional
public class UserInfoSerivceImpl extends ServiceImpl<UserInfoDao.UserInfoEntity> implements UserInfoService {}Copy the code

Basic demonstration of MyBatis-Plus

Here we see, we didn’t write any method in the service and official MyBatis – Plus encapsulates many basic CRUD methods, can directly use a lot of time saving, MP method is detailed in IService, common ServiceImpl, BaseMapper source code, write in Servic Transaction binding is already available in eImpl, so here we demonstrate some common methods.

/ * * *@Description UserInfoController
 * @Author Sans
 * @CreateTime2019/6/8 16:27 * /
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {

    @Autowired
    private UserInfoService userInfoService;

    /** * Get user information based on ID *@Author Sans
     * @CreateTime2019/6/8 o *@ParamUserId userId *@ReturnUserInfoEntity User entity */
    @RequestMapping("/getInfo")
    public UserInfoEntity getInfo(String userId){
        UserInfoEntity userInfoEntity = userInfoService.getById(userId);
        return userInfoEntity;
    }
    /** * query all information *@Author Sans
     * @CreateTime2019/6/8 now *@ParamUserId userId *@ReturnList<UserInfoEntity> Set of user entities */
    @RequestMapping("/getList")
    public List<UserInfoEntity> getList(a){
        List<UserInfoEntity> userInfoEntityList = userInfoService.list();
        return userInfoEntityList;
    }
    /** ** ** ** ** ** ** ** **@Author Sans
     * @CreateTime2019/6/8 scatter *@ReturnIPage<UserInfoEntity> paging data */
    @RequestMapping("/getInfoListPage")
    public IPage<UserInfoEntity> getInfoListPage(a){
        // Paging plug-ins need to be configured in the Config configuration class
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(5); / / the current page
        page.setSize(1);    // Number of entries per page
        page = userInfoService.page(page);
        return page;
    }
    /** * Query user information set * based on the specified field@Author Sans
     * @CreateTime2019/6/8 desired *@ReturnCollection<UserInfoEntity> Collection of user entities */
    @RequestMapping("/getListMap")
    public Collection<UserInfoEntity> getListMap(a){
        Map<String,Object> map = new HashMap<>();
        //kay is the field name and value is the field value
        map.put("age".20);
        Collection<UserInfoEntity> userInfoEntityList = userInfoService.listByMap(map);
        return userInfoEntityList;
    }
    /** * Add user information *@Author Sans
     * @CreateTime 2019/6/8 16:40
     */
    @RequestMapping("/saveInfo")
    public void saveInfo(a){
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setName("Small dragon");
        userInfoEntity.setSkill("JAVA");
        userInfoEntity.setAge(18);
        userInfoEntity.setFraction(59L);
        userInfoEntity.setEvaluate("The student is a coder fixing a BUG.");
        userInfoService.save(userInfoEntity);
    }
    /** * Add user information in batches *@Author Sans
     * @CreateTime2019/6/8 * / calm
    @RequestMapping("/saveInfoList")
    public void saveInfoList(a){
        // Create an object
        UserInfoEntity sans = new UserInfoEntity();
        sans.setName("Sans");
        sans.setSkill("Sleep");
        sans.setAge(18);
        sans.setFraction(60L);
        sans.setEvaluate("Sans is a sleeping, short, fat little skeleton with a huge skeleton.");
        UserInfoEntity papyrus = new UserInfoEntity();
        papyrus.setName("papyrus");
        papyrus.setSkill("JAVA");
        papyrus.setAge(18);
        papyrus.setFraction(58L);
        papyrus.setEvaluate("Papyrus is a loud, flamboyant, confident, charismatic skinny skeleton.");
        // Batch save
        List<UserInfoEntity> list =new ArrayList<>();
        list.add(sans);
        list.add(papyrus);
        userInfoService.saveBatch(list);
    }
    /** * Update user information *@Author Sans
     * @CreateTime2019/6/8 yet * /
    @RequestMapping("/updateInfo")
    public void updateInfo(a){
        If the value of other fields is null, this field will not be updated. Refer to the YML configuration file
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setId(1L);
        userInfoEntity.setAge(19);
        userInfoService.updateById(userInfoEntity);
    }
    /** * Add or update user information *@Author Sans
     * @CreateTime2019/6/8 thus * / were
    @RequestMapping("/saveOrUpdateInfo")
    public void saveOrUpdate(a){
        // If the ID is null in the incoming entity class userInfoEntity, it will be added.
        // The entity class ID value exists, if the database ID exists, it will be updated, if not, it will be added
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setId(1L);
        userInfoEntity.setAge(20);
        userInfoService.saveOrUpdate(userInfoEntity);
    }
    /** * Delete user information based on ID *@Author Sans
     * @CreateTime2019/6/8 hast judged * /
    @RequestMapping("/deleteInfo")
    public void deleteInfo(String userId){
        userInfoService.removeById(userId);
    }
    /** * Delete user information in batches based on ID *@Author Sans
     * @CreateTime 2019/6/8 16:55
     */
    @RequestMapping("/deleteInfoList")
    public void deleteInfoList(a){
        List<String> userIdlist = new ArrayList<>();
        userIdlist.add("12");
        userIdlist.add("13");
        userInfoService.removeByIds(userIdlist);
    }
    /** * Deletes user information * based on the specified field@Author Sans
     * @CreateTime2019/6/8 16:57 * /
    @RequestMapping("/deleteInfoMap")
    public void deleteInfoMap(a){
        //kay is the field name and value is the field value
        Map<String,Object> map = new HashMap<>();
        map.put("skill"."Delete");
        map.put("fraction".10L); userInfoService.removeByMap(map); }}Copy the code

MyBatis-Plus QueryWrapper conditional constructor

When query conditions are complex, we can use MP’s conditional constructor, as described below in the QueryWrapper conditional parameter description

A query Method statement
setSqlSelect Set the SELECT query field
where WHERE statement, concatenation + WHERE condition
and AND statement, concatenate + AND field = value
or OR statement, concatenation + OR field = value
eq Equal to =
allEq Map based content is equal to =
ne Is not the same as < >
gt More than >
ge The value is greater than or equal to >=
lt < <
le Less than or equal to <=
like Fuzzy query LIKE
notLike Fuzzy query NOT LIKE
in IN the query
notIn NOT IN the query
isNull A NULL value query
isNotNull IS NOT NULL
groupBy GROUP BY GROUP
having HAVING keywords
orderBy Sort ORDER BY
orderByAsc ASC sort ORDER BY
orderByDesc DESC sort ORDER BY
exists EXISTS condition statement
notExists NOT EXISTS Conditional statement
between BETWEEN conditional statement
notBetween NOT BETWEEN conditional statement
addFilter Free concatenation SQL
last Splice at the end, e.g. : last(“LIMIT 1”)
Here are some common examples
“` java
/ * *
  • @Description UserInfoPlusController
  • @Author Sans
  • @CreateTime 2019/6/9 14:52

*/ @RestController @RequestMapping(“/userInfoPlus”) public class UserInfoPlusController {

@Autowired private UserInfoService userInfoService; /** * MP extension demo * @author Sans * @createTime 2019/6/8 16:37 * @return Map<String,Object> Returns data */ @requestMapping ("/getInfoListPlus") public Map<String,Object> getInfoListPage(){// Initialize class Map<String,Object> result = new HashMap<>(); Select * from student where age = 18; SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age = 18 QueryWrapper<UserInfoEntity> queryWrapper1 = new QueryWrapper<>(); queryWrapper1.lambda().eq(UserInfoEntity::getAge,18); List<UserInfoEntity> userInfoEntityList1 = userInfoService.list(queryWrapper1); result.put("studentAge18",userInfoEntityList1); Select * from student where age > 5 and age < 18; SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age > 5 AND age <= 18 QueryWrapper<UserInfoEntity> queryWrapper2 = new QueryWrapper<>(); queryWrapper2.lambda().gt(UserInfoEntity::getAge,5); queryWrapper2.lambda().le(UserInfoEntity::getAge,18); List<UserInfoEntity> userInfoEntityList2 = userInfoService.list(queryWrapper2); result.put("studentAge5",userInfoEntityList2); // Fuzzy query skill field with "draw" data, and descending order by age // equivalent SQL: SELECT id, name, age, skill, evaluate, fraction FROM user_info WHERE skill LIKE '% % painting' ORDER BY age DESC QueryWrapper<UserInfoEntity> queryWrapper3 = new QueryWrapper<>(); QueryWrapper3. Lambda (.) like (UserInfoEntity: : getSkill, "painting"); queryWrapper3.lambda().orderByDesc(UserInfoEntity::getAge); List<UserInfoEntity> userInfoEntityList3 = userInfoService.list(queryWrapper3); result.put("studentAgeSkill",userInfoEntityList3); // select * from students whose names are younger or older than 18; SELECT id, name, age, skill, evaluate, fraction FROM user_info WHERE the name LIKE 'little % %' OR the age 18 QueryWrapper > < UserInfoEntity >  queryWrapper4 = new QueryWrapper<>(); QueryWrapper4. Lambda (.) like (UserInfoEntity: : getName, "small"); queryWrapper4.lambda().or().gt(UserInfoEntity::getAge,18); List<UserInfoEntity> userInfoEntityList4 = userInfoService.list(queryWrapper4); result.put("studentOr",userInfoEntityList4); SQL > select * from student where evaluation is not NULL; SELECT id, name, age, skill, evaluate, fraction FROM user_info WHERE the evaluate IS NOT NULL LIMIT 0, 5 IPage < UserInfoEntity > page = new Page<>(); page.setCurrent(1); page.setSize(5); QueryWrapper<UserInfoEntity> queryWrapper5 = new QueryWrapper<>(); queryWrapper5.lambda().isNotNull(UserInfoEntity::getEvaluate); page = userInfoService.page(page,queryWrapper5); result.put("studentPage",page); return result; }Copy the code

}

The introduction of Mybatis-Plus will not affect the existing Mybatis architecture of the project. And Mybatis-Plus supports all Mybatis native features, which is also one of the reasons I like to use it, because some business is complex, we may have to write some more complex SQL statements, we give a simple example to demonstrate the custom SQL. Scores (example: query is greater than the set points of students for the dynamic input, and there are pages) written Mapper. The XML file ` ` ` XML < Mapper namespace = "com. Mp. Demo. Dao. UserInfoDao" > <! -- Sans 2019/6/9 14:35 --> <select id="selectUserInfoByGtFraction" resultType="com.mp.demo.entity.UserInfoEntity" parameterType="long"> SELECT * FROM user_info WHERE fraction > #{fraction} </select> </mapper>Copy the code

Add methods to DAO

    /** * select * from students whose score is greater than this@Author Sans
     * @CreateTime14:28 2019/6/9 *@ParamPage page parameter *@ParamFraction score *@ReturnIPage<UserInfoEntity> paging data */
    IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction);
Copy the code

Add methods to service

    /** * select * from students whose score is greater than this@Author Sans
     * @CreateTime 2019/6/9 14:27
     * @ParamPage page parameter *@ParamFraction score *@ReturnIPage<UserInfoEntity> paging data */
    IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page,Long fraction);
Copy the code

Add methods in serviceImpl

    /** * select * from students whose score is greater than this@Author Sans
     * @CreateTime 2019/6/9 14:27
     * @ParamPage page parameter *@ParamFraction score *@ReturnIPage<UserInfoEntity> paging data */
    @Override
    public IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction) {
        return this.baseMapper.selectUserInfoByGtFraction(page,fraction);
    }
Copy the code

Test in Controller

    /** * MP custom SQL *@Author Sans
     * @CreateTimeHe 2019/6/9 *@ReturnIPage<UserInfoEntity> paging data */
    @RequestMapping("/getInfoListSQL")
    public IPage<UserInfoEntity> getInfoListSQL(a){
        // Select * from student whose score is greater than 60
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(5);
        page = userInfoService.selectUserInfoByGtFraction(page,60L);
        return page;
    }
Copy the code

Automatic fill and logical delete

The MybaitS-Plus extension features such as auto-fill, logical deletion and optimistic locking, which can be used to reduce the amount of code and improve readability at development time.

  1. Entity test cases
/** * Department information entity class *@Author Sans
 * @CreateTime2020/8/15 20:03 * /
@Data
@TableName("dept_info")
public class DeptInfoEntity {
    /**
     * ID主键
     */
    @TableId(type = IdType.AUTO)
    private Long deptId;
    /** * Department name */
    private String deptName;
    INSERT_UPDATE Inserts and updates the fill field * FieldFill.UPDATE Updates the fill field * FieldFill.DEFAULT */ is not processed by default
    /** * creator ID */
    @TableField(fill = FieldFill.INSERT)
    private String createId;
    /** * create time */
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    /** * update ID */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateId;
    /** * update time */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    /** * logical delete * TableLogic is a logical delete annotation. If yML is configured with a global logical delete field, this annotation can be omitted
    @TableLogic
    private Integer deleted;
}
Copy the code
  1. Autofill configuration
/** * MP automatically fills Handler *@Author Sans
 * @CreateTime2020/8/15 21:49 * /
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    /** * Insert operation populates field method */
    @Override
    public void insertFill(MetaObject metaObject) {
        /** * Fill operator/update * The DEMO is just an example, the actual project here can be determined by the business ** for example, from Shrio securityutils.getSubject ().getPrincipal() to get the current user information fill */
        this.strictInsertFill(metaObject, "createId", String.class,"ADMIN");
        this.strictInsertFill(metaObject, "updateId", String.class, "ADMIN");
        // Fill time
        Date date = new Date();
        this.strictInsertFill(metaObject, "createTime", Date.class, date);
        this.strictInsertFill(metaObject, "updateTime", Date.class, date);
    }
    /** * Update operation populates field method */
    @Override
    public void updateFill(MetaObject metaObject) {
        Date date = new Date();
        this.strictUpdateFill(metaObject, "updateId", String.class, "ADMIN");
        this.strictUpdateFill(metaObject, "updateTime", Date.class, date); }}Copy the code

Seven. Project source code

Project source: gitee.com/liselotte/s…

Personally, I really like using MyBatis Plus. It saves time and the code is clean and it gives me the feeling of transitionfrom SSM to SpringBoot at that time

Yeah, it smells good

Thank you for reading this article. If you like it, please click “like”. If there are shortcomings in this article, please give your valuable opinions.