【MyBatisPlus通俗易懂202003狂神说】Java注解整合mp,雪花算法,CRUD,自动填充,乐观锁,分页,理逻辑删除,性能分析,条件查询,代码生成器

原文:

原视频:https://www.bilibili.com/video/BV17E411N7KN?vd_source=b63e9afd510deaf9d2a1b680368b9935
官网:https://www.kuangstudy.com/

1. MP入门

  • 2022 02 14 最新 稳定版 3.5.1
  • 2022 05 左右更新为 3.5.2
  • 本次教程时最新:3.3.1.tmp
  • 教程用了:3.0.5

地址:https://mp.baomidou.com/guide/quick-start.html#初始化工程

基于MyBatis提供了很多第三方插件,这些插件通常可以完成数据操作方法的封装、数据库逆向工程工作(根据数据表生成实体类、生成映射文件)

  • myBatis-plus
  • tkMapper
  • JPA

父类

教程boot为:2.2.5,最新稳定版为:2.7.2也可以

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.5.RELEASEversion>
        <relativePath/>
    parent> 

	<properties>
        <java.version>1.8java.version>
    properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
            <scope>testscope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintagegroupId>
                    <artifactId>junit-vintage-engineartifactId>
                exclusion>
            exclusions>
        dependency> web 和 lombok记得引用
    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>

数据库准备

创建数据库:

  • 数据库字符集:UTF-8

  • 数据库排序规则:utf8_general_ci

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]'),
(5, 'Billie', 24, '[email protected]');

-- 真实开发中,version(乐观锁)、deleted(逻辑删除)、gmt_create、gmt_modified

引入pom


<dependency>
	<groupId>mysqlgroupId>
	<artifactId>mysql-connector-javaartifactId>
dependency>


<dependency>
	<groupId>org.projectlombokgroupId>
	<artifactId>lombokartifactId>
dependency>


<dependency>
	<groupId>com.baomidougroupId>
	<artifactId>mybatis-plus-boot-starterartifactId>
	<version>3.0.5version>
dependency>

配置数据库

# 数据库连接配置
spring.datasource.username=root
spring.datasource.password=123456

spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# mysql 8,增加了 cj,并且还要:增加时区的配置。高版本 兼容低版本

#以前为:com.mysql.jdbc.Driver//注意后面不能带空格
useSSL=false #mac 安全连接,可能会报错
&useUnicode=true
&characterEncoding=utf-8
&serverTimezone=GMT%2B8 #时区配置,mysql8 必须配置
select version(); 
5.7.25-log

Model Mapper 和 扫描

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
  }
@Repository // 代表持久层。或者加入 @Mapper,不写也行,
public interface UserMapper extends BaseMapper<User> {
    // 所有的CRUD操作都已经编写完成了
}
@MapperScan("com.kuang.mapper")
@SpringBootApplication
public class MybatisPlusApplication {
}

测试

@SpringBootTest
class Tests {

    // 继承了BaseMapper,所有的方法都来自己父类
    @Autowired
    private UserMapper userMapper;

    @Test
    void contextLoads() {
    // 参数是一个 Wrapper ,条件构造器,这里我们先不用 null
    // 查询全部用户
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

}

日志

# 配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
Creating a new SqlSession
JDBC Connection [HikariProxyConnection@521641809 wrapping com.mysql.cj.jdbc.ConnectionImpl@b428830] 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: 5, Billie, 24, [email protected]
<==      Total: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@33751d49]
  • 默认 HikariProxy Connection 数据源

2. CRUD

雪花算法

    // 测试插入
    @Test
    public void testInsert(){
        User user = new User();
        user.setName("狂神说Java");
        user.setAge(3);
        user.setEmail("[email protected]");
        int result = userMapper.insert(user); // 帮我们自动生成id
        System.out.println(result); // 受影响的行数
        System.out.println(user); // 发现,id会自动回填
    }
User(id=1554345100354527233, name=狂神说Java, age=3, [email protected])

默认 ID_WORKER 全局唯一id
分布式系统唯一id生成:https://www.cnblogs.com/haoxinyue/p/5208136.html
雪花算法:
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。

其核心思想是:

  • 使用41bit作为毫秒数,
  • 10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),
  • 12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),
  • 最后还有一个符号位,永远是0。
  • 可以保证几乎全球唯一!
public enum IdType {
	AUTO(0), // 数据库id自增
	NONE(1), // 未设置主键
	INPUT(2), // 手动输入
	ID_WORKER(3), // 默认的全局唯一id。默认
	UUID(4), // 全局唯一id uuid
	ID_WORKER_STR(5); //ID_WORKER 字符串表示法
}
    // 对应数据库中的主键 (uuid、自增id、雪花算法、redis、zookeeper!)
    @TableId(type = IdType.AUTO) //主键自增
    private Long id;

2、数据库字段一定要是自增!

  • 我的测试 结果每次 自增2个

    1554345100354527233
    1554345100354527235
    1554345100354527237
    

更新

    // 测试更新
    @Test
    public void testUpdate(){
        User user = new User();
        // 通过条件自动拼接动态sql
        user.setId(1240620674645544965L);
        user.setName("关注公众号:狂神说");
        user.setAge(20);
        // 注意:updateById 但是参数是一个 对象!
        int i = userMapper.updateById(user);
        System.out.println(i);
    }

数据库级别

在表中新增字段 create_time, update_time 。datetime 类型。

  • 默认为: CURRENT_TIMESTAMP 。current_timestamp

  • update_time 自动更新

private Date createTime;
private Date updateTime;

代码级别

    // 字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
编写处理器
		//获取到需要被填充的字段的值
		Object fieldValue = getFieldValByName("name", metaObject);
		if(fieldValue == null) {
            //为 null的 时候,才做操作
		}
@Slf4j
@Component // 一定不要忘记把处理器加到IOC容器中!
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill.....");
        // 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("start update fill.....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}
  • 测试 更新 和 插入 即可。
==>  Preparing: INSERT INTO user ( name, age, email, create_time, update_time ) VALUES ( ?, ?, ?, ?, ? ) 
==> Parameters: 我的测试(String), 3(Integer), 24736743@qq.com(String), 2022-08-02 15:44:09.008(Timestamp), 2022-08-02 15:44:09.008(Timestamp)
<==    Updates: 1


==>  Preparing: UPDATE user SET name=?, age=?, update_time=? WHERE id=? 
==> Parameters: 关注公众号:狂神说(String), 20(Integer), 2022-08-02 15:47:24.833(Timestamp), 1554359625145405457(Long)
<==    Updates: 1

JUC 中,原子引用。

乐观锁

乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,
再次更新值测试
悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
我们这里主要讲解 乐观锁机制!

乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败
乐观锁:1、先查询,获得版本号 version = 1
-- A
update user set name = "kuangshen", version = version + 1
where id = 2 and version = 1
-- B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
update user set name = "kuangshen", version = version + 1
where id = 2 and version = 1

1、给数据库中增加version字段!

2、我们实体类加对应的字段

@Version //乐观锁Version注解
private Integer version;

通用的配置

// 扫描我们的 mapper 文件夹
@MapperScan("com.kuang.mapper")
@EnableTransactionManagement //默认是打开的
@Configuration // 配置类
public class MyBatisPlusConfig {

    // 注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}
==>  Preparing: UPDATE user SET name=?, age=?, email=?, update_time=?, version=? WHERE id=? AND version=? 
==> Parameters: 关注公众号:狂神1111说(String), 20(Integer), [email protected](String), 2022-08-02 16:28:34.372(Timestamp), 2(Integer), 1554359625145405457(Long), 1(Integer)
<==    Updates: 1

原来是1,更新后 为2

optimistic
英
/ˌɒptɪˈmɪstɪk/
adj.
乐观的,乐观主义的;(估计)过于乐观的,高估的
    // 测试乐观锁失败!多线程下
    @Test
    public void testOptimisticLocker2(){

        // 线程 1
        User user = userMapper.selectById(1L);
        user.setName("kuangshen111");
        user.setEmail("[email protected]");

        // 模拟另外一个线程执行了插队操作
        User user2 = userMapper.selectById(1L);
        user2.setName("kuangshen222");
        user2.setEmail("[email protected]");
        userMapper.updateById(user2);

        // 自旋锁来多次尝试提交!
        userMapper.updateById(user); // 如果没有乐观锁就会覆盖插队线程的值!
    }
  • 第二次 更新为 0条
==>  Preparing: UPDATE user SET name=?, age=?, email=?, update_time=?, version=? WHERE id=? AND version=? 
==> Parameters: kuangshen111(String), 18(Integer), 24736743@qq.com(String), 2022-08-02 16:35:46.473(Timestamp), 2(Integer), 1(Long), 1(Integer)
<==    Updates: 0

查询

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

    // 测试批量查询!
    @Test
    public void testSelectByBatchId(){
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        users.forEach(System.out::println);
    }
    
    // 按条件查询之一使用map操作
    @Test
    public void testSelectByBatchIds(){
        HashMap<String, Object> map = new HashMap<>();
        // 自定义要查询
        map.put("name","狂神说Java");
        map.put("age",3);

        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
        
    }
==>  Preparing: SELECT id,name,age,email,create_time,update_time,version FROM user WHERE id IN ( ? ) 
==> Parameters: 1(Integer)

分页配置

1、原始的 limit 进行分页
2、pageHelper 第三方插件
3、MP 其实也内置了分页插件!

@Configuration // 配置类
public class MyBatisPlusConfig {

    // 分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return  new PaginationInterceptor();
    }
}

pagination
n.
标记页数;页码
    // 测试分页查询
    @Test
    public void testPage(){
        //  参数一:当前页
        //  参数二:页面大小
        //  使用了分页插件之后,所有的分页操作也变得简单的!
        Page<User> page = new Page<>(2,5);
        userMapper.selectPage(page,null);

        //直接获取 数据
        page.getRecords().forEach(System.out::println);
        System.out.println(page.getTotal());

    }
==>  Preparing: SELECT COUNT(1) FROM user  -- 先做总数的查询

SELECT id,name,age,email,create_time,update_time,version FROM user LIMIT 0,5 
-- 第一页,是 0,5。
-- 第二页:LIMIT 5,5  数据是从 第六个 开始查出来的

删除

  	// 测试删除
    @Test
    public void testDeleteById(){
        userMapper.deleteById(1L);
    }

    // 通过id批量删除
    @Test
    public void testDeleteBatchId(){
        userMapper.deleteBatchIds(Arrays.asList(124L,12402L));
    }

    // 通过map删除
    @Test
    public void testDeleteMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","狂神说Java");
        userMapper.deleteByMap(map);
    }

逻辑删除

1、在数据表中增加一个 deleted 字段

2、实体类中增加属性

    @TableLogic //逻辑删除
    private Integer deleted;
@Configuration // 配置类
public class MyBatisPlusConfig {
	// 逻辑删除组件!
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
}

Logic
逻辑,(做某事的)道理;推理方法,逻辑学;(事实或事件的)规律,相互联系;(计算机或电器的)逻辑操作
# 配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
        userMapper.deleteById(1L);
==>  Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0 
==> Parameters: 1(Long)
<==    Updates: 1

性能分析插件

druid
作用:性能分析拦截器,用于输出每条 SQL 语句及其执行时间
MP也提供性能分析插件,如果超过这个时间就停止运行

  • 比如:超过1秒的SQL,找出来
    /**
     * SQL执行效率插件
     */
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启,保证我们的效率
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor p = new PerformanceInterceptor();
        p.setMaxTime(100); //ms 设置sql执行的最大时间,如果超过了则不执行
        p.setFormat(true);
        return p;
    }
performance
n.
表演,演出;工作情况,表现;(投资的)业绩;执行,履行;麻烦,苦差事(a performance);艺术上的表现,演技;(汽车的)性能;(语言学)语言表现,言语行为
adj.
性能卓越的,高性能的
# 设置开发环境
spring.profiles.active=dev
 Time43 ms - ID:com.kuang.mapper.UserMapper.selectBatchIds
Execute SQLSELECT
        id,
        name,
        age,
        email,
        create_time,
        update_time,
        version,
        deleted 
    FROM
        user 
    WHERE
        id IN (
            1 
        ) 
        AND deleted=0

超出会报错

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException:  The SQL execution time is too large, please optimize ! 
persistence
n.
继续存在,维持;坚持不懈,执意

3. 条件查询

between eq like

  • 新版没有 EntityWrapper
		//老版本的 MP 条件查询
		//当前为 第一页,每页显示2条
		List<Employee> emps =employeeMapper.selectPage(new Page<Employee>(1, 2),
					new EntityWrapper<Employee>()
					.between("age", 18, 50)
					.eq("gender", 1)
					.eq("last_name", "Tom")
				);
		System.out.println(emps);

		// 查询tbl_employee表中, 性别为女并且名字中带有"老师" 或者  邮箱中带有"a"
		List<Employee> emps = employeeMapper.selectList(
				new EntityWrapper<Employee>()
				.eq("gender", 0)
				.like("last_name", "老师")
				//.or()    // SQL: (gender = ? AND last_name LIKE ? OR email LIKE ?)    
				.orNew()   // SQL: (gender = ? AND last_name LIKE ?) OR (email LIKE ?) 
				.like("email", "a")
				);
		System.out.println(emps);

		//依然可以用
        QueryWrapper<User> eq = Condition.create(new User())
                .notLike("name","e")
                .likeRight("email","t");

isNotNull > eq between

@Test
    void contextLoads() {
        // 查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .isNotNull("name")
                .isNotNull("email")
                .ge("age",12);
        userMapper.selectList(wrapper).forEach(System.out::println); // 和我们刚才学习的map对比一下
    }

    @Test
    void test2(){
        // 查询名字狂神说
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name","狂神说");
        User user = userMapper.selectOne(wrapper); // 查询一个数据,出现多个结果使用List 或者 Map
        System.out.println(user);
    }

    @Test
    void test3(){
        // 查询年龄在 20 ~ 30 岁之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age",20,30); // 区间
        Integer count = userMapper.selectCount(wrapper);// 查询结果数
        System.out.println(count);
    }


模糊查询

notLike,like右边是%

    // 模糊查询
    @Test
    void test4(){
        // 查询年龄在 20 ~ 30 岁之间的用户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        // 左和右  t%
        wrapper.notLike("name","e")
                .likeRight("email","t");

        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }
Execute SQLSELECT
		*
    FROM
        user 
    WHERE
        deleted=0 
        AND name NOT LIKE '%e%' 
        AND email LIKE 't%'

insql 倒叙

    // 模糊查询
    @Test
    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);
    }
    SELECT
		*
    FROM
        user 
    WHERE
        deleted=0 
        AND id IN (
            select
                id 
            from
                user 
            where
                id<3
        )
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        // 通过id进行排序
        wrapper.orderByAsc("id");

        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);

4. 代码生成器

旧代码

	@Test
	public void  testGenerator() {
        
		//1. 全局配置
		GlobalConfig config = new GlobalConfig();
		config.setActiveRecord(true) // 是否支持AR模式
			  .setAuthor("weiyunhui") // 作者
			  .setOutputDir("D:\\workspace_mp\\mp03\\src\\main\\java") // 生成路径
			  .setFileOverride(true)  // 文件覆盖
			  .setIdType(IdType.AUTO) // 主键策略
			  .setServiceName("%sService")  // 设置生成的service接口的名字的首字母是否为I
			  					   // IEmployeeService
 			  .setBaseResultMap(true)
 			  .setBaseColumnList(true);
		
		//2. 数据源配置
		DataSourceConfig  dsConfig  = new DataSourceConfig();
		dsConfig.setDbType(DbType.MYSQL)  // 设置数据库类型
				.setDriverName("com.mysql.jdbc.Driver")
				.setUrl("jdbc:mysql://localhost:3306/mp")
				.setUsername("root")
				.setPassword("1234");
		 
		//3. 策略配置
		StrategyConfig stConfig = new StrategyConfig();
		stConfig.setCapitalMode(true) //全局大写命名
				.setDbColumnUnderline(true)  // 指定表名 字段名是否使用下划线
				.setNaming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
				.setTablePrefix("tbl_")
				.setInclude("tbl_employee");  // 生成的表
		
		//4. 包名策略配置 
		PackageConfig pkConfig = new PackageConfig();
		pkConfig.setParent("com.atguigu.mp")
				.setMapper("mapper")
				.setService("service")
				.setController("controller")
				.setEntity("beans")
				.setXml("mapper");
		
		//5. 整合配置
		AutoGenerator  ag = new AutoGenerator();
		
		ag.setGlobalConfig(config)
		  .setDataSource(dsConfig)
		  .setStrategy(stConfig)
		  .setPackageInfo(pkConfig);
		
		//6. 执行
		ag.execute();
}
logic 
n.
逻辑,(做某事的)道理;推理方法,逻辑学;(事实或事件的)规律,相互联系;(计算机或电器的)逻辑操作

可能需要引入的

3.0.7版本移除 对 mybatis-plus-generator 包的依赖,自己按需引入,还需要导入模板依赖,

<dependency>
	<groupId>org.apache.velocitygroupId>
	<artifactId>velocity-engine-coreartifactId>
	<version>2.0version>
dependency>
现在官网已经3.3.1了,最新为3.5.2



<dependency>
    <groupId>com.spring4allgroupId>
    <artifactId>spring-boot-starter-swaggerartifactId>
    <version>1.5.1.RELEASEversion>
dependency>

<dependency>
    <groupId>org.freemarkergroupId>
    <artifactId>freemarkerartifactId>
    <version>2.3.30version>
dependency>

<dependency>
    <groupId>com.ibeetlgroupId>
    <artifactId>beetlartifactId>
    <version>3.3.2.RELEASEversion>
dependency>
Beetl是一款6倍于Freemarker的超高性能的java模板引擎

新代码

import com.baomidou.mybatisplus.annotation.DbType;
annotation.FieldFill;
annotation.IdType;
core.conditions.Condition;
core.conditions.query.QueryWrapper;
generator.AutoGenerator;

generator.config.DataSourceConfig;

GlobalConfig;
PackageConfig;
StrategyConfig;
po.TableFill;
rules.DateType;
rules.NamingStrategy;

public static void main(String[] args) {
        // 需要构建一个 代码自动生成器 对象
        AutoGenerator mpg = new AutoGenerator();
    
        // 配置策略
        // 1、全局配置
        GlobalConfig gc = new GlobalConfig();
    
    	//项目的主目录:D:\MyFile\project\testStudy\mybatis_plus
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("狂神说");
        gc.setOpen(false);
        gc.setFileOverride(false); // 是否覆盖
        gc.setServiceName("%sService"); // 去Service的I前缀
        gc.setIdType(IdType.ID_WORKER);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);
        
        //2、设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://192.168.2.219:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);
        
        //3、包的配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("blog");
        pc.setParent("com.kuang");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);
        
        //4、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("blog_tags", "course"); // 设置要映射的表名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true); // 自动lombok;
        strategy.setLogicDeleteFieldName("deleted");
        
        // 自动填充配置
        TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
        TableFill gmtModified = new TableFill("gmt_modified",
                FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(gmtCreate);
        tableFills.add(gmtModified);
        strategy.setTableFillList(tableFills);
    
        // 乐观锁
        strategy.setVersionFieldName("version");
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true); //localhost:8080 / hello_id_2
        mpg.setStrategy(strategy);
        mpg.execute(); //执行
    }

生成的代码

@RestController
@RequestMapping("/blog/user")
public class UserController {
}

public interface UserService extends IService<User> {
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}
public interface UserMapper extends BaseMapper<User> {
}

<mapper namespace="com.kuang.blog.mapper.UserMapper">
</mapper>
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="User对象", description="")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "姓名")
    private String name;

    @ApiModelProperty(value = "逻辑删除")
    @TableLogic
    private Integer deleted;

    @ApiModelProperty(value = "乐观锁")
    @Version
    private Integer version;

    @ApiModelProperty(value = "创建时间")
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @ApiModelProperty(value = "修改时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

你可能感兴趣的:(mybatis-plus,java,spring,boot,mybatisplus)