Mybatis-Plus from entry to master

Mybatis-plus

Quick start

First import the package

    <dependencies>
<!--        数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
<!--        工具包  可以帮助生成get set 之类的-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

<!--        mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

If the import mybatis-plus is version 3.0.7 or higher, it needs to be imported

<!--        3.0.7版本移除 对 mybatis-plus-generator 包的依赖,自己按需引入,尽在还需要导入模板依赖,-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

Import data into the database

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]');

Configuration profile

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/mybatis-plus?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver

So the preparation work is complete

Upload code

Create an object corresponding to a table in the database

import lombok.Data;

@Data
public class User {

    private Long id;
    private String name;
    private Integer age;
    private String email;

}

Mapper file

We only need to inherit from BaseMappe. In BaseMappe, he helped us realize most of CRUD, so we don’t need to write anymore.

Here you can see that we only inherited BaseMappe and nothing else is written

@Repository
public interface UserMapper extends BaseMapper<User> {

}

Start class

@SpringBootApplication
@MapperScan("com.bbaa.mapper")
public class MybatisPiusDemo01Application {

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

}

test

@SpringBootTest
class MybatisPiusDemo01ApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    void contextLoads() {
    }

    @Test
    public void test1(){
		//UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

}

result

User(id=1, name=Jone, age=18, [email protected])
User(id=2, name=Jack, age=20, [email protected])
User(id=3, name=Tom, age=28, [email protected])
User(id=4, name=Sandy, age=21, [email protected])
User(id=5, name=Billie, age=24, [email protected])

Configuration log

The configuration log only needs to be added to the configuration file.

#配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
Creating a new SqlSession
SqlSession [[email protected]] was not registered for synchronization because synchronization is not active
JDBC Connection [[email protected] wrapping [email protected]] will not be managed by Spring
==>  Preparing: SELECT id,name,age,email FROM user 
==> Parameters: 
<==    Columns: id, name, age, email
<==        Row: 1, Jone, 18, [email protected]
<==        Row: 2, Jack, 20, [email protected]
<==        Row: 3, Tom, 28, [email protected]
<==        Row: 4, Sandy, 21, [email protected]
<==        Row: 5, Billie, 24, [email protected]
<==      Total: 5

Closing non transactional SqlSession [[email protected]]
User(id=1, name=Jone, age=18, [email protected])
User(id=2, name=Jack, age=20, [email protected])
User(id=3, name=Tom, age=28, [email protected])
User(id=4, name=Sandy, age=21, [email protected])
User(id=5, name=Billie, age=24, [email protected])

CRUD extension

select query

Query a single piece of data based on id

	public void testOptimisticLocker(){
        //因为id是long类型的  所以数字后面加上了L
        User user = userMapper.selectById(1L);
    	System.out.println(user);
    }
User(id=1, name=Jone, age=18, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)

Query multiple data

@Test
    public void testselect(){
        //selectBatchIds需要传入的是list集合
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        users.forEach(System.out::println);
    }
User(id=1, name=Jone, age=18, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=2, name=Jack, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=3, name=Tom, age=28, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)

Conditional query map

//条件查询  map
    @Test
    public void selectByMap(){
        HashMap<String ,Object> map = new HashMap<>();
        //放入自定义条件  比如:我要查询 年龄为20用户的信息
        map.put("age",20);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }
User(id=2, name=Jack, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=4, name=Sandy, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=7, name=ww, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)

Pagination

Common operations for paging in the page object are

Total, previous page, next page, sorting etc...

 //分页
    @Test
    public void testpage(){
        //参数一:第几页
        // 参数二:每页显示的条数
        Page<User> userPage = new Page<>(1,5);
        //参数一:页查询条件(可以为 RowBounds.DEFAULT)
        //参数二:实体对象封装操作类(可以为 null)
        Page<User> userPage1 = userMapper.selectPage(userPage, null);
        //打赢
        userPage1.getRecords().forEach(System.out::println);
    }
User(id=1, name=Jone, age=18, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=2, name=Jack, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=3, name=Tom, age=28, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=4, name=Sandy, age=20, [email protected]u.com, createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)
User(id=5, name=Billie, age=24, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1)

insert

  @Test
    public void insert(){
        //创建user
        User user = new User();
        user.setName("zs");
        user.setAge(20);
        user.setEmail("[email protected]");
		//添加
        int insert = userMapper.insert(user);
		//打印
        System.out.println(insert);
        System.out.println(user);

    }
JDBC Connection [[email protected] wrapping [email protected]] will not be managed by Spring
    
==>  Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? ) 
==> Parameters: 1401036342073540610(Long), zs(String), 20(Integer), [email protected](String)
<==    Updates: 1
    
Closing non transactional SqlSession [[email protected]]
    
1
    
User(id=1401036342073540610, name=zs, age=20, [email protected])

It can be seen from the code that we did not add the id, but there is an id 1401036342073540610 in the console output, and the id also exists in the user

This shows that userMapper.insert(user) not only helps us create a globally unique id but also gives the value of id to the user object

Primary key generation strategy

Unique id generation strategy for distributed systems: https://www.cnblogs.com/haoxinyue/p/5208136.html

Snow algorithm:

Snowflake is Twitter's open source distributed ID generation algorithm, and the result is a long ID. The core idea is: use 41bit as the number of milliseconds, 10bit as the machine ID (5 bits are the data center, 5 bits of the machine ID), and 12bit as the serial number within milliseconds (meaning that each node can generate every millisecond 4096 IDs), and 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 4.19 million (2^22*1000).

The snowflake algorithm has a stand-alone version and a distributed version in engineering implementation. The stand-alone version is as follows, and the distributed version can refer to the Meituan leaf algorithm: https://github.com/Meituan-Dianping/Leaf

@Data
public class User {

    //对应数据库中的组件 (uuid,自增id,雪花算法,redis,zookeeper)
    //如果是用的自增 数据库中的id也必须设置为自增
    @TableId(type = IdType.ID_WORKER)
    private Long id;
    private String name;
    private Integer age;
    private String email;
}


public enum IdType {
   /**
     * 数据库ID自增
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
     */
    NONE(1),
    /**
     * 用户输入ID
     * <p>该类型可以通过自己注册自动填充插件进行填充</p>
     */
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 分配ID (主键类型为number或string),
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
     *
     * @since 3.3.0
     */
    ASSIGN_ID(3),
    /**
     * 分配UUID (主键类型为 string)
     * 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
     */
    ASSIGN_UUID(4),
    /**
     * @deprecated 3.3.0 please use {@link #ASSIGN_ID}
     */
    @Deprecated
    ID_WORKER(3),
    /**
     * @deprecated 3.3.0 please use {@link #ASSIGN_ID}
     */
    @Deprecated
    ID_WORKER_STR(3),
    /**
     * @deprecated 3.3.0 please use {@link #ASSIGN_UUID}
     */
    @Deprecated
    UUID(4);

    private final int key;

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

Update (modify updata)

    @Test
    public void updata(){
        User user = new User();
        user.setId(6L);//因为是long类型的 所以结尾要加上 L
        user.setName("ls");
        user.setAge(30);
        user.setEmail("[email protected]");
		//修改
        //int updateById(@Param("et") T entity);
        //传入的参数是一个对象  而不是id
        int i = userMapper.updateById(user);
		//打印
        System.out.println(i);
        System.out.println(user);

    }

before fixing

Insert picture description here

After modification

Insert picture description here

result

JDBC Connection [[email protected] wrapping [email protected]] will not be managed by Spring

==>  Preparing: UPDATE user SET name=?, age=?, email=? WHERE id=? 
==> Parameters: ls(String), 30(Integer), [email protected](String), 6(Long)
<==    Updates: 1
    
Closing non transactional SqlSession [[email protected]]
//受影响的行数   
1
//user
User(id=6, name=ls, age=30, [email protected])

It can be seen in the console that we have modified the user information with id 6

Auto fill (e.g. time)

We first create two fields in the database create_time creation time, update_time modification time

Insert picture description here

Add two attributes to the user class

    private Data createTime;
    private Data updateTime;

How to realize automatic insertion and update time?

    /**
     * 插入时填充字段
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /**
     * 更新时填充字段
     */
    @TableField(fill = FieldFill.UPDATE)
    private LocalDateTime updateTime;

Write a processor to process this annotation

There is a tutorial on the official website: https://mp.baomidou.com/guide/auto-fill-metainfo.html

@Slf4j//日志
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    //插入时候的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("插入时候的填充策略");
        //这里LocalDateTime 是要和属性的类型对应
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); 
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());

    }
    //更新时候的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("更新时候的填充策略");
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 
    }
}

@TableField

    /**
     * 字段自动填充策略
     */
    FieldFill fill() default FieldFill.DEFAULT;


//FieldFill类
public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入时填充字段
     */
    INSERT,
    /**
     * 更新时填充字段
     */
    UPDATE,
    /**
     * 插入和更新时填充字段
     */
    INSERT_UPDATE
}

Optimistic lock

Optimistic lock: it will always think that there will be no problems, no matter what to do, it will not be locked, if there is a problem, it will update the value test again

Pessimistic lock: Contrary to optimistic lock, you must lock everything before operating it

For example

有A B两个人同时在修改系统
当前这个系统的版本 version = 1.0 版本
A 在修改系统以后需要在版本改为1.1
updata user set name = 'zs',version = version + 0.1 where id = 10 and version = 1.0
B也在修改系统 
updata user set name = 'zs',version = version + 0.1 where id = 10 and version = 1.0
这个时候 A先完成 把系统升级为version = 1.1版本了 B修改就失败了 B只有重新去获取当前版本的值来查询修改

Actual combat

Now add the version field to the database

Insert picture description here

Add fields to entity classes

    //版本号
    @Version//乐观锁
    private Double version;

Test the success of optimistic locking

//测试乐观锁成功的情况
    @Test
    public void testOptimisticLocker(){
        //查询用户信息
        User user = userMapper.selectById(6L);
        //修改用户信息
        user.setName("zs");
        user.setAge(40);
        //执行修改操作
        userMapper.updateById(user);
    }

result


==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id=? 
==> Parameters: 6(Long)
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 6, ls, 30, [email protected], 2021-06-05 13:46:12, 2021-06-05 13:46:12, 1.00
<==      Total: 1

    //在这里WHERE id=? AND version=?  可以看出判断了版本号是否是1.0版本
==>  Preparing: UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=? 
    
==> Parameters: zs(String), 40(Integer), [email protected](String), 2021-06-05T13:46:12(LocalDateTime), 2021-06-05T13:46:12(LocalDateTime), 1.0(Double), 6(Long), 1(Integer)
    
<==    Updates: 1

Test optimistic lock failure

    //测试乐观锁失败的情况
    @Test
    public void testOptimisticLocker2(){
        //查询用户信息
        User user = userMapper.selectById(6L);
        User user2 = userMapper.selectById(6L);

        //A:修改用户信息
        user.setName("zs");
        user.setAge(40);

        //B:修改用户信息
        user2.setName("kk");
        user2.setAge(30);

        //执行修改操作
        userMapper.updateById(user2);
        //如果没有乐观锁的情况下  下面的这一条数据会把上面的数据给覆盖
        userMapper.updateById(user);
    }

result

//user的
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id=? 
==> Parameters: 6(Long)
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 6, zs, 40, [email protected], 2021-06-05 13:46:12, 2021-06-05 13:46:12, 1
<==      Total: 1

//user2的
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id=? 
==> Parameters: 6(Long)
<==    Columns: id, name, age, email, create_time, update_time, version
<==        Row: 6, zs, 40, [email protected], 2021-06-05 13:46:12, 2021-06-05 13:46:12, 1
<==      Total: 1

//编译时  user2的
==>  Preparing: UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=? 
==> Parameters: kk(String), 30(Integer), [email protected](String), 2021-06-05T13:46:12(LocalDateTime), 2021-06-05T13:46:12(LocalDateTime), 2(Integer), 6(Long), 1(Integer)
<==    Updates: 1

//编译时  user的 
==>  Preparing: UPDATE user SET name=?, age=?, email=?, create_time=?, update_time=?, version=? WHERE id=? AND version=? 
==> Parameters: zs(String), 40(Integer), [email protected](String), 2021-06-05T13:46:12(LocalDateTime), 2021-06-05T13:46:12(LocalDateTime), 2(Integer), 6(Long), 1(Integer)
    //影响的行数 0 说明添加失败
<==    Updates: 0

Delete operation

Insert picture description here

Delete a single piece of data according to id

//删除
    //删除单条数据 根据id
    //条件查询  map
    @Test
    public void deleteById(){
        int i = userMapper.deleteById(6L);
        System.out.println(i);
    }
==>  Preparing: DELETE FROM user WHERE id=? 
==> Parameters: 6(Long)
<==    Updates: 1
Closing non transactional SqlSession [[email protected]]
1

Other operations are actually the same as those in select

Tombstone

Physical deletion: directly delete the data in the database

Logical deletion: No data is removed from the database, but the user no longer queries to invalidate the data through a variable delete = 0 -> delete = 1

On some websites, administrators can view the deleted data. These are logical deletions.

Tombstone can prevent the loss of data similar to the recycle bin

We now add a field in a database deletes Be careful not to delete the field name as a keyword to be wrong

Insert picture description here
Insert picture description here

Add the deletes attribute to the user object

    @TableLogic//逻辑删除
    private Integer deletes;

Add tombstone configuration in the configuration file

mybatis-plus:
    #逻辑删除
  global-config:
    db-config:
      logic-delete-field: flag  # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置@TableLogic)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

test

   //逻辑删除
    @Test
    public void testdelete(){
        int i = userMapper.deleteById(9L);
        System.out.println(i);
    }
==>  Preparing: UPDATE user SET deletes=1 WHERE id=? AND deletes=0 //这里加上了一个条件 deletes=0 代表这条数据是没有被删除过的
==> Parameters: 9(Long)
<==    Updates: 1
//受影响的行数
1

Here we can see that the update method is actually called

Insert picture description here

The data in the database is not deleted but delete is modified to 1

Let's check again to see if it can still be queried

		User user = userMapper.selectById(9L);
        System.out.println(user);
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version,deletes FROM user WHERE id=? AND deletes=0 
==> Parameters: 9(Long)
<==      Total: 0  //0条数据

It can be seen that it has not been queried because deletes=0 is added to the judgment condition

Performance analysis plugin

This can help us test the running time of sql

The performance analysis plug-in was officially deleted after version 3.3.2

Interested friends can view it on Baidu

Wrapper condition constructor

caveat:

Does not support and does not support Wrapper transmission in RPC calls

  1. wrapper is heavy
  2. The transmission wrapper can be analogous to your controller using map to receive values ​​(the development is cool, and the crematorium is maintained)
  3. The correct RPC call posture is to write a DTO for transmission, and the callee then performs the corresponding operation according to the DTO
  4. Refuse to accept any issues or even pr related to RPC transmission Wrapper errors

The parent class of QueryWrapper (LambdaQueryWrapper) and UpdateWrapper (LambdaUpdateWrapper) is
used to generate SQL where conditions , and the entity attribute is also used to generate SQL where conditions

Test 1: Query people whose name is not null and whose age is greater than or equal to 20 years old

    @Test
    public void test(){
        //设置条件查询 查询一般使用QueryWrapper对象
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //isNotNull("name")---sql语句里面--->name is not null
        wrapper.isNotNull("name")//name不为null
                //ge("age", 18)---sql语句里面--->age >= 18
                .ge("age",20);//age大于或者等于20岁
        userMapper.selectList(wrapper).forEach(System.out::println);
    }
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version,deletes FROM user WHERE deletes=0 AND (name IS NOT NULL AND age >= ?) 
==> Parameters: 20(Integer)
    
User(id=2, name=Jack, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1, deletes=0)
User(id=3, name=Tom, age=28, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1, deletes=0)
User(id=4, name=Sandy, age=20, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1, deletes=0)
User(id=5, name=Billie, age=24, [email protected], createTime=2021-06-05T13:46:12, updateTime=2021-06-05T13:46:12, version=1, deletes=0)
User(id=10, name=ww, age=23, [email protected], createTime=2021-06-06T10:24:07, updateTime=2021-06-06T10:24:07, version=1, deletes=0)

Test 2: Query the person whose name is ww

    @Test
    public void test2(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //eq:eq("name", "老王")---sql语句里面--->name = '老王'
        wrapper.eq("name","ww");//姓名为ww
        userMapper.selectList(wrapper).forEach(System.out::println);
    }

Test 3: Interpolate those whose age is id>4


    @Test
    public void test3(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //字段 IN ( sql语句 )
        //例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
        //例: inSql("id", "select id from table where id > 4")--->id in (select id from table where id > 4)
       
        wrapper.inSql("id","select id from user where id >4");//重点
        userMapper.selectList(wrapper).forEach(System.out::println);

    }

Code generator

Import package

<!--        3.0.3 版本移除 需自己引入,添加 模板引擎 依赖-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

<!--        添加 代码生成器 依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>

Configured code

package com.jiang;

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 org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;

@SpringBootTest
public class DMcode {

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        //获取到用户当前的目录
        String projectPath = System.getProperty("user.dir");
        //生成的地址
        gc.setOutputDir(projectPath + "/src/main/java");
        //生成作者信息
        gc.setAuthor("jiang");
        //是否打开文件夹
        gc.setOpen(false);
        //是否覆盖之前生成的文件
        gc.setFileOverride(false);
        //默认的初始算法  id
        gc.setIdType(IdType.ID_WORKER);
        //配置日期的类型
//        gc.setDateType(DateType.ONLY_DATE);
        // gc.setSwagger2(true); 是否配置swagger文档

        //全局配置放在代码生成器中
        mpg.setGlobalConfig(gc);

        //设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        //数据库类型 mysql
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        //模块名
        pc.setModuleName("plus");
        //在哪个包下面生成模块
        pc.setParent("com.jiang.demo");
        //实体类的名字
        pc.setEntity("pojo");
        //mapper类
        pc.setMapper("mapper");
        //设置为servic层的名称
        pc.setService("service");
        //设置controller层名称
        pc.setController("controller");
        mpg.setPackageInfo(pc);


        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //设置映射的表名
        strategy.setInclude("user");
        //设置包命名的规则  下划线转驼峰命名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //数据库字段命名的规则  下划线转驼峰命名
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //自动生成lombok  链式编程
        strategy.setEntityLombokModel(true);
        //设置逻辑删除
        strategy.setLogicDeleteFieldName("deletes");
        //设置自动填充字段
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updatetime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> list = new ArrayList<>();
        list.add(createTime);
        list.add(updatetime);
        strategy.setTableFillList(list);
        //乐观锁
        strategy.setVersionFieldName("version");
        //设置驼峰命名
        strategy.setRestControllerStyle(true);
        //localhost:8080/hello_id_2
        strategy.setControllerMappingHyphenStyle(true);
        mpg.setStrategy(strategy);

        //执行
        mpg.execute();


    }
}