Introduction to MyBatis-plus

MyBatis-plus

1. Overview of MyBatis-plus

1. What is MyBatis?

MyBatis-plus can help us save a lot of time, and all additions, deletions, modifications, and query codes can be done automatically.

Official website URL: MyBatis official website

2. Characteristics

  • No intrusion : only enhancement and no change, the introduction of it will not affect the existing project, as smooth as silk
  • Low loss : the basic CURD will be automatically injected when it is started, the performance is basically lossless, and the object-oriented operation is directly performed
  • Powerful CRUD operations : Built-in general Mapper and general Service, most of the CRUD operations on a single table can be realized with only a small amount of configuration, and there is a powerful condition constructor to meet various usage needs
  • Support Lambda form call : through Lambda expressions, it is convenient to write various query conditions, no need to worry about field typos
  • Supports automatic primary key generation : supports up to 4 primary key strategies (including a distributed unique ID generator - Sequence), which can be freely configured to perfectly solve the primary key problem
  • Support ActiveRecord mode : support ActiveRecord form call, the entity class only needs to inherit the Model class to perform powerful CRUD operations
  • Support custom global general operations : support global general method injection ( Write once, use anywhere )
  • Built-in code generator : use code or Maven plug-in to quickly generate Mapper, Model, Service, Controller layer code, support template engine, and more custom configurations are waiting for you to use (automatically generate code)
  • Built-in paging plug-in : Based on MyBatis physical paging, developers don't need to care about specific operations. After configuring the plug-in, writing paging is equivalent to ordinary List query
  • The paging plug-in supports multiple databases : supports MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, Postgre, SQLServer and other databases
  • Built-in performance analysis plug-in : It can output SQL statements and their execution time. It is recommended to enable this function during development and testing, which can quickly find out slow queries
  • Built-in global interception plug-in : Provides intelligent analysis and blocking of delete and update operations on the entire table, and can also customize interception rules to prevent misoperations

2. Quick start

1. Quick start

Quick start address: MyBatis-plus

Use third-party components

  1. Import the corresponding dependencies
  2. Study how dependencies are configured
  3. how the code is written
  4. Improve technical scalability
  • Create database mybatis-plus and User tables and add corresponding data
CREATE DATABASE MyBatis_plus;
USE MyBatis_plus;

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);


INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

In actual development, version (optimistic lock), deleted (logical deletion), gmt_create, gmt_modified are essential

  • Initialize the project

Initialize with SpringBoot

  • Import related dependencies
  <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <!--实体类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>

        <!--mybatis-plus自己开发,并非官方的-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

mybatis-plus can save a lot of code, try not to import mybatis and mybatis-plus at the same time

  • Connect to the database
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/MyBatis_plus?userSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456

After using mybatis-plus: POJO -> mapper interface -> use

  • POJO
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private Long id;
    private String name;
    private Integer age;
    private String email;

}

  • Mapper interface
@Repository
public interface UserMapper extends BaseMapper<User> {
    
    
    //mybatis-plus需要在此基础上继承BaseMapper
    //所有的增删改查操作全部编写完成

}

You need to inherit BaseMapper, inherit all its addition, deletion, modification and query methods, and you can complete the method expansion according to your own needs.

At the same time, it should be noted that we need to add @MapperScan ("full path of the package") to the main startup class to scan all mapper interfaces under the corresponding package

@MapperScan("com.example.dao")
@SpringBootApplication
public class MybatisPlusApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(MybatisPlusApplication.class, args);
    }

}
  • use
class MybatisPlusApplicationTests {
    
    
    @Autowired
    private UserMapper userMapper;
    //继承了BaseMapper父类所有的增删改查方法,
    // 我们也可以编写自己的扩展方法

    @Test
    void contextLoads() {
    
    

        //查询全部用户,参数是一个wrapper,是一个条件构造器,可以设置为null
        List<User> users = userMapper.selectList(null);
        users.forEach(user -> {
    
    
            System.out.println(user);
        });

    }

It should be noted userMapper.selectList(wrapper参数)that the parameters in it represent conditional constructors, and can be set to null when not needed

2. Configuration log

Now all SQL is invisible, and only by looking at the log can we know how the SQL is executed.

Here, because other logs such as LOG4J need to add new dependencies, the standard output log of the system is used here

# 配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

The standard output log is as follows:

3. Add, delete, modify, check and expand

(1) Insert

  //插入测试
    @Test
    public void testInsert(){
    
    
        User user = new User();
        user.setName("Mike");
        user.setAge(18);
        user.setEmail("[email protected]");
        int affectRow = userMapper.insert(user); //帮助我们自动生成id
        System.out.println(affectRow);
        System.out.println(user);
    }

Final Results:

mybatis-plus will help us automatically generate id

The default value for database insertion is our global unique id

(2) Primary key generation strategy

Distributed system unique id generation: https://www.cnblogs.com/haoxinyue/p/5208136.html

snowflake algorithm

Snowflake is Twitter's open-source distributed ID generation algorithm, and the result is a long-type ID. Its core idea is: use 41bit as the number of milliseconds, 10bit as the ID of the machine (5 bits for the data center, 5 bits for the machine ID), and 12bit as the serial number within milliseconds (meaning that each node can generate 4096 IDs), there is a sign bit at the end, which is always 0. The specific implementation code can be found at https://github.com/twitter/snowflake. The TPS supported by the snowflake algorithm can reach about 4.19 million (2^22*1000). Almost guaranteed to be globally unique.

 @TableId(type = IdType.ID_WORKER)
public enum IdType {
    
    
    AUTO(0), //数据库id自增
    NONE(1),//未设置主键
    INPUT(2),//手动输入
    ID_WORKER(3),//全局唯一id
    UUID(4),//全局唯一id uuid
    ID_WORKER_STR(5);//ID-WORKER字符串表示

    private int key;

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

    public int getKey() {
    
    
        return this.key;
    }
}

  1. Default ID WORKER

globally unique ID

  1. primary key auto increment
   @TableId(type = IdType.AUTO)

Configure the primary key auto-increment strategy:

  • Add annotations to entity classes@TableId(type = IdType.AUTO)
  • Database fields must be self-incrementing

Test insert operation

//设置@TableId(type = IdType.AUTO)
@Test
    public void testInsert(){
    
    
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        user.setEmail("[email protected]");
        int affectRow = userMapper.insert(user); 
        System.out.println(affectRow);
        System.out.println(user);
    }

The result is as follows:

  1. manual input
 @TableId(type = IdType.INPUT)
 @Test
    public void testInsert(){
    
    
        User user = new User();
        user.setName("李四");
        user.setAge(18);
        user.setEmail("[email protected]");
        int affectRow = userMapper.insert(user); //帮助我们自动生成id
        System.out.println(affectRow);
        System.out.println(user);
    }

Set the id change to manual input, and set the id of the corresponding insertion object to null

Therefore, once you enter it manually, you must configure the corresponding id yourself

(3) Update operation

  //测试更新操作
    @Test
    public void testUpdate(){
    
    
        User user = new User();
        user.setAge(25);
        user.setId(6L);
        user.setEmail("[email protected]");
        int i = userMapper.updateById(user);
    }

Use to updateById(User t)complete the change of the record with id 6, the changed content mainly includes age and email

The result is as follows:

The result is that mybatis-plus automatically stitches dynamic SQL

(4) Automatic filling

Creation time, modification time, and these operations are generally done automatically, and manual updates are not expected.

All database tables should contain the following two fields: gmt_create, gtm_modified (almost all tables must be configured and need to be updated automatically)

  1. Database level autofill - deprecated

Add fields gmt_create and gtm_modified to the table

ALTER TABLE User ADD create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'创建时间';

ALTER TABLE User ADD update_time  datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_STAMP COMMENT '更新时间'

Test the insert method again and synchronize the entity class

 private Date createTime;
 private Date updateTime;
  @Test
    public void testUpdate(){
    
    
        User user = new User();
        user.setAge(17);
        user.setId(6L);
        user.setEmail("[email protected]");
        int i = userMapper.updateById(user);
    }

Results updated with update time

  1. Code-level autocompletion
  • Delete the default action at the database level
  • Add annotations (@TableField) to entity class field properties
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
    
    ElementType.FIELD})
public @interface TableField {
    
    
    String value() default "";

    String el() default "";

    boolean exist() default true;

    String condition() default "";

    String update() default "";

    FieldStrategy strategy() default FieldStrategy.DEFAULT;

    FieldFill fill() default FieldFill.DEFAULT;

    boolean select() default true;
}

  /**为以下两个属性设置相应的注解*/
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;

Creating a field needs to be updated when inserting, and updating a field needs to perform corresponding update operations when inserting and updating.

  • Write processor processing annotations

The meta object handler interface needs to be implemented: com.baomidou.mybatisplus.core.handlers.MetaObjectHandler

@Slf4j
@Component /**需要将相应的组件添加至IOC容器中*/
public class MyMetaObjectHandler implements MetaObjectHandler {
    
    
    /**插入时候的填充策略*/
    @Override
    public void insertFill(MetaObject metaObject) {
    
    
        log.info("insert start.......");
        //setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        //创建时间插入的时候填充
        this.setFieldValByName("createTime",new Date(),metaObject);
        //更新时间插入的时候填充
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }

    /**更新时候的填充策略*/
    @Override
    public void updateFill(MetaObject metaObject) {
    
    
        log.info("update start......");
        //更新时间在更新的时候填充
        this.setFieldValByName("updateTime",new Date(),metaObject);

    }
}

  • insert test
 //插入测试
    @Test
    public void testInsert(){
    
    
        User user = new User();
        user.setName("小明");
        user.setAge(16);
        user.setEmail("[email protected]");
        int affectRow = userMapper.insert(user); //帮助我们自动生成id
        System.out.println(affectRow);
        System.out.println(user);
    }

    //测试更新操作
    @Test
    public void testUpdate(){
    
    
        User user = new User();
        user.setAge(19);
        user.setId(1502634608783667204L);
        user.setEmail("[email protected]");
        int i = userMapper.updateById(user);
    }

The result is that both time points have changed when inserting data, but when updating, the creation time remains unchanged and the update time changes.

(5) Optimistic lock

Optimistic lock: very optimistic, always think that there will be no problems, no matter what you do, it will not be locked, if there is a problem, update the test again (version new version)

Pessimistic lock: very pessimistic, it always thinks there will be a problem, no matter what it does, it will lock it first, and then perform the corresponding operation

optimistic locking mechanism

Optimistic lock implementation:

  • When fetching records, get the current version
  • When updating, bring this version
  • When performing an update, set version = newVersion where version = oldVersion
  • If the version is incorrect, the update will fail
UPDATE user SET name=‘xxx’,version=oldversion+1 WHERE id=2 AND version=oldversion;

If version=oldversion is not established in the condition, the insertion operation cannot be completed, and safe communication between threads can be guaranteed.

Implementation of Optimistic Locking

  1. Add a version field to the database
ALTER TABLE user ADD version int DEFAULT 1 COMMENT '乐观锁';

At this time, the version of all rows in the table is 1

  1. Entity classes add corresponding fields and add version annotations
  /**添加乐观锁字段*/
    @Version
    private Integer version;
  1. Register optimistic lock components (create config folder and create classes)
/**扫描对应的mapper文件夹*/
@MapperScan("com.example.dao")
@EnableTransactionManagement/**自动管理事务*/
@Configuration /**表示这是一个配置类*/
public class MyBatisPlusConfig {
    
    

  //注册乐观锁插件
  @Bean
  public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    
    
      return new OptimisticLockerInterceptor();
  }
}

  1. test
  • Optimistic locking under single thread
  //测试乐观锁成功
    @Test
    public void testOptimisticLock(){
    
    
        //查出id为1的用户
        User user = userMapper.selectById(1L);
        //修改用户信息
        user.setName("李白");
        user.setEmail("[email protected]");
        //执行更新操作
        int i = userMapper.updateById(user);


    }

At this time, it can be executed successfully under single thread.

  • Simulate optimistic locking under multithreading
//多线程下测试乐观锁
    @Test
    public void testOptimisticLocker(){
    
    
        //线程1
        User user = userMapper.selectById(1L);
        user.setName("李白");
        user.setEmail("[email protected]");

        //线程2执行插队操作

        User user1 = userMapper.selectById(1L);
        //修改用户信息
        user1.setName("李白1");
        user1.setEmail("[email protected]");
        //执行更新操作
        int i1 = userMapper.updateById(user1);


        //如果没有乐观锁就会覆盖插队线程的值
        //要想实现原先的操作,需要使用自旋锁尝试提交
        int i = userMapper.updateById(user);

    }

If thread 2 jumps in the queue and submits the modification, then thread 1 will no longer be able to complete the operation on the database because the value of version has changed.

If the thread that wants to be queued is executed successfully, a spin lock can be set to complete the corresponding repeated submission operation.

(6) Query operation

 //测试查询
    @Test
    public void testQuery(){
    
    
        User user = userMapper.selectById(1);
        System.out.println(user);

    }

    //查询多个用户(批量查询)
    @Test
    public void testBatchUser(){
    
    
        //此处需要传递的参数为一个Collection类型
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3, 4));
        //users.forEach(user -> {
    
    
        //    System.out.println(user);
        //});
        users.forEach(System.out::println);
    }

    //测试条件查询,使用Map
    @Test
    public void testQueryBy(){
    
    
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","李白");
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }

}

Both basic query and conditional query mybatis-plus can complete the operation

(7) Pagination query

Pagination is used a lot on websites. You can use limit paging, pagehelper paging, mybatis-plus paging

Use mybatis-plus to implement pagination

  1. Configure the interceptor component
 //注册分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor(){
    
    
      PaginationInterceptor paginationInterceptor=new PaginationInterceptor();
      设置请求的页面大于最大页后操作,true调回到首页,false继续请求,默认false
      //  paginationInterceptor.setOverflow(false);
      //  //设置最大单页限制数量,默认500条 -1不受限制
      //  paginationInterceptor.setLimit(500);
      //  //开启count的join优化,只针对部分的left join
      //  paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;

    }
}
  1. Just use the page object directly
//方法的API参数
IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
  //测试分页查询
    @Test
    public void testLimitPage(){
    
    
        //由于需要page对象,所以需要创建page,参数表示第一页,查询三个数据(1.当前页,2.页面大小)
        Page<User> page = new Page<>(1,3);
        //由于方法参数需要Ipage对象,wrapper:表示高级查询
        userMapper.selectPage(page,null);
        page.getRecords().forEach(System.out::println);
    }

The result is as follows:

First of all, before the paging query, the total number of pages will be queried. In the above example, the total number is 6, and the query data in the table with a total of 6 is essentially still using the Limit to realize the paging query.

After using the pagination plug-in, all paging operations become simple.

(8) Delete operation

  1. Delete the corresponding data according to the id
  //测试删除数据
    @Test
    public void testDelete(){
    
    
        //通过id来删除用户
        int i = userMapper.deleteById(1502634608783667204L);
        if (i>0){
    
    
            System.out.println("删除成功!");
        }else {
    
    
            System.out.println("删除失败!");
        }
    }
  1. Batch delete related data
  //测试批量删除
    @Test
    public void testBatchDelete(){
    
    
        int i = userMapper
                .deleteBatchIds(Arrays.asList(1502634608783667205L,1502634608783667206L,1502634608783667207L));

        if (i>0){
    
    
            System.out.println("删除成功!");
        }else {
    
    
            System.out.println("删除失败!");
        }
    }

Successfully implemented bulk deletion of related content

  1. Delete data through map
  //测试通过Map删除
    @Test
    public void testDeleteByMap(){
    
    
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","小华");
        int i = userMapper.deleteByMap(map);
        if (i>0){
    
    
            System.out.println("删除成功!");
        }else {
    
    
            System.out.println("删除失败!");
        }
    }

(9) Logical deletion

Often encountered in the work is tombstone

  • Physical deletion: directly removed from the database
  • Logical deletion: It has not been removed in the database, and it is invalidated by variables, such as changing the original delete from 0 to 1 to make it invalid

For example, website administrators can view deleted records, which is done to prevent data loss, similar to the recycle bin.

  1. Add a deleted field to the data table
ALTER TABLE user ADD deleted int DEFAULT 0 COMMENT '逻辑删除';
  1. Add attribute to entity class
 /**添加逻辑删除属性与逻辑删除注解*/
    @TableLogic//逻辑删除注解
    private Integer deleted;

  1. Configure related tombstones (register tombstone components)
    //注册逻辑删除组件
  @Bean
  public ISqlInjector sqlInjector(){
    
    
    return new LogicSqlInjector();
  }
  1. Configure tombstone
# 配置逻辑删除(没有删除的值为0,删除的设置为1)
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
  1. Test delete user
  @Test
    public void testDelete(){
    
    
        //通过id来删除用户
        int i = userMapper.deleteById(1502634608783667209L);

        if (i>0){
    
    
            System.out.println("删除成功!");
        }else {
    
    
            System.out.println("删除失败!");
        }
    }

The result is as follows

The record is still in the database, and the value of deleted has changed.

After logical deletion, query the user again, and the logically deleted fields will be automatically filtered

Fourth, the performance analysis plug-in

In normal development, you will encounter some slow SQL. mybatis-plus also provides a performance analysis plug-in, which will stop running if it exceeds this time.

Function: performance analysis plug-in, used to output each SQL statement and its execution time.

The use of performance analysis plug-ins:

  1. configure plugin
 //SQL的执行效率插件
  @Bean
  @Profile({
    
    "dev","test"})// 只是在测试和开发环境下使用,提高效率。
  public PerformanceInterceptor performanceInterceptor(){
    
    
    //获取性能分析拦截器对象
    PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    //可以设置sql执行的最大时间,如果超过了则不执行。ms
    performanceInterceptor.setMaxTime(1);
    //开启格式化支持true
    performanceInterceptor.setFormat(true);

    return performanceInterceptor;
  }

Among them, you can set the maximum time for sql execution and whether to enable formatting support

  1. Configure sql execution environment

Set it up as a test environment or a development environment.

# 设置开发环境
spring.profiles.active=dev
  1. test query
    @Test
    void contextLoads() {
    
    

        //查询全部用户,参数是一个wrapper,是一个条件构造器,可以设置为null
        List<User> users = userMapper.selectList(null);
        users.forEach(user -> {
    
    
            System.out.println(user);
        });

    }

The result is as follows:

The sql has been formatted accordingly

Due to the timeout, the corresponding query operation cannot be executed smoothly, and the timeout (originally set to 1ms)

Using the performance analysis plugin, we can improve efficiency

5. Condition constructor

wrapper: very important, conditional constructor

When we write some complex sql, we can use wrapper to replace it.

  1. Test 1: Query users whose age is greater than 12 and whose name and email address are not empty

usage isNotNulland gemethod

   @Test
    void contextLoads() {
    
    
        //查询name不为空的用户(复杂查询)并且邮箱不为空的用户,年龄大于12岁的
        //由于查询需要使用到warpper
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //可以使用链式编程
        wrapper.isNotNull("name")
                .isNotNull("email")
                .ge("age",12);
        //查询参数为wrapper
        List<User> users =
                userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }
  1. Test 2: Test eqMethod
  @Test
    void test2(){
    
    
        //需要查询名字为小煌的
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //查询条件名字为小煌的
        wrapper.eq("name","Jack");
        //查询一个用户使用selectOne,出现多个结果使用map或者list
        System.out.println(userMapper.selectOne(wrapper));


    }
  1. Test 3: Query users in a certain range

Using between()the method, where it selectCountrepresents the number of results for the query

   @Test
    public void test3(){
    
    
        //查询年龄在20-30之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age",20,30);
        //selectCount表示查询结果数
        Integer integer = userMapper.selectCount(wrapper);
        System.out.println("年龄在20-30之间的有:"+integer);
    }
  1. Test Four: Using notLikeandlikeRight

Among them, notLike refers to the meaning of not including, and likeRight refers to the condition that the wildcard is on the right. That is, all users whose mailboxes start with t

  @Test
    public void test4(){
    
    
        //使用模糊查询,查询名字中
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //左与右:其实代表的是%是在左边还是右边
        //查询名字中不包含e字母的
            wrapper.notLike("name","e")
                    //表示查询email中以t开头的
            .likeRight("email","t");
        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);

    }

Test Results

  1. Test Five: Subquery inSql()Method
   @Test
    public void test5(){
    
    
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //id在子查询中查出来
        wrapper.inSql("id","SELECT id FROM user WHERE id<3");

        List<Object> objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }

result:

  1. Test Six: Sorting

Use orderByDescto sort in descending order, and pass in the id

 @Test
    public void test6(){
    
    
        //测试通过id进行排序
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //通过id进行降序排序
        wrapper.orderByDesc("id");

        List<User> users = userMapper.selectList(wrapper);

    }

The result is as follows: sorted in descending order according to id

6. Automatic Code Generator

AutoGenerator is the code generator of MyBatis-Plus. Through AutoGenerator, the code of each module such as Entity, Mapper, Mapper XML, Service, and Controller can be quickly generated, which greatly improves the development efficiency.

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;

//代码自动生成器
public class AutoCode {
    
    
    public static void main(String[] args) {
    
    
        //构建一个代码自动生成器对象
        AutoGenerator mpg=new AutoGenerator();

        //执行之前需要配置一些策略
        //1.全局配置
        GlobalConfig gc = new GlobalConfig();
        //获取当前系统目录
        String projectPath = System.getProperty("user.dir");
        //设置代码输出的目录
        gc.setOutputDir(projectPath+"/src/main/java");
        //设置作者
        gc.setAuthor("Lambda");
        //是否打开资源管理器
        gc.setOpen(false);
        //是否覆盖原来生成的
        gc.setFileOverride(false);
        //去掉service的I前缀
        gc.setServiceName("%sService");
        //设置id生成策略
        gc.setIdType(IdType.ID_WORKER);
        //设置日期类型
        gc.setDateType(DateType.ONLY_DATE);
        //设置swagger
        gc.setSwagger2(true);

        mpg.setGlobalConfig(gc);

        //2. 设置数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/MyBatis_plus?userSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8");
        dataSourceConfig.setUsername("root");
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setPassword("xielibin20001011");
        //设置数据库的类型
        dataSourceConfig.setDbType(DbType.MYSQL);
        mpg.setDataSource(dataSourceConfig);

        //3.配置一系列的要生成的包
        PackageConfig packageConfig = new PackageConfig();
        //设置模块名
        packageConfig.setModuleName("blog");
        //设置包路径,生成com.example.blog这个模块
        packageConfig.setParent("com.example");
        //设置具体的包名
        packageConfig.setEntity("entity");
        packageConfig.setMapper("mapper");
        packageConfig.setService("service");
        packageConfig.setController("controller");
        mpg.setPackageInfo(packageConfig);

        //4.策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        //设置需要映射的表名
        strategyConfig.setInclude("user");
        //设置下划线转驼峰命名
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        //设置列名格式
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        //设置自身的父类实体,没有就不设置
        strategyConfig.setSuperEntityClass("父类实体,没有就不设置");
        //设置启动Lombok
        strategyConfig.setEntityLombokModel(true);
        //设置restful风格
        strategyConfig.setRestControllerStyle(true);
        //设置逻辑删除的名字
        strategyConfig.setLogicDeleteFieldName("deleted");

        //设置自动填充策略
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        //将上述的策略填充仅tableFills中
        tableFills.add(createTime);
        tableFills.add(updateTime);
        strategyConfig.setTableFillList(tableFills);

        //设置乐观锁
        strategyConfig.setVersionFieldName("version");

        //设置url的下划线命名
        strategyConfig.setControllerMappingHyphenStyle(true);

        //将策略设置进mpg生成器对象
        mpg.setStrategy(strategyConfig);
        //执行代码构造
        mpg.execute();

    }

}

When you need to generate different codes, strategyConfig.setInclude("user");you only need to change the table name accordingly.

insert image description here

Guess you like

Origin blog.csdn.net/qq_50824019/article/details/130503295