Mybatis-Plus 总结,代码生成器

Mybatis-Plus 总结

狂神课程笔记

快速入门 https://baomidou.com/guide/#%E7%89%B9%E6%80%A7

简介

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

使用第三方组件:

入门

1、导入对应的依赖

2、研究依赖如何配置

3、代码如何编写

4、提高扩展技术的能力

导入依赖

<!--mybatis-plus 是自己开发的,非官方的!-->
	<dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.1.tmp</version>
    </dependency>
<!--lombok-->
	 <dependency>
         <groupId>org.projectlombok</groupId>
         <artifactId>lombok</artifactId>
         <version>1.18.10</version>
         <scope>provided</scope>
     </dependency>

编写pojo文件

编写mapper接口

@Repository 配置注解

继承BaseMapper<类型> 类 添加泛型。

@Repository
public interface UserMapper extends BaseMapper<User> {
}

@MapperScan(“mapper包名”)在主程序开启扫描,后期再MybatisPlusConfig配置类中开启

@MapperScan("com.lt.mapper")

配置日志

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

实体中的属性类型用基础类型的包装类

插入

插入测试 输出未设置的id

image-20201202110359129

未设置主键id,执行insert方法却自动生成id

主键生成策略

img

分布式系统唯一id生成

默认生成会执行 雪花算法 生成

SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的。

这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。
https://blog.csdn.net/lq18050010830/article/details/89845790

如果插入时未设置主键生成策略,则默认ID_WORKER

public enum IdType {
    //数据库ID自增
    AUTO(0),
    
	//该类型为未设置主键类型
    NONE(1),
    
    //用户输入ID
    //该类型可以通过自己注册自动填充插件进行填充
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */

	//全局唯一ID (idWorker)
    ID_WORKER(3),
    
	//全局唯一ID (UUID)
    UUID(4),

	// 字符串全局唯一ID (idWorker 的字符串表示)
    ID_WORKER_STR(5);

自增策略 数据库id也要设置自增,否则会报错

@TableId(type = IdType.AUTO)
private Long id;

修改 通过条件自动拼接动态sql 根据id修改传入参数的是user类型

public void update(){
    User user = new User();
    //通过条件自动拼接动态sql
    user.setId(5L);
    user.setAge(12);
    //根据id修改传入参数的是user类型
    int result = userMapper.updateById(user);
    System.out.println(result);
}

自动填充

1.数据库级别的填充

自动填充时间 默认当前时间戳 勾选更新 低版本不支持 5.7以上[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-llXgLrvT-1607397832345)(…/笔记图片/image-20201202135009868.png)]

在表中新增字段 create_time 、update_time(默认CURRENT_TIMESIAMP)

Mybatis-Plus 自带驼峰标识

但是如果我们不设置mybstis plus 默认的驼峰式编码,mybatis-plus 则会默认把驼峰式编码userCode(数据库是userCode)装换成 user_code, 这种下划线格式的字段,这时你会发现你的代码会出错,它会提示你user_code字段不存在

appliction.yml 里设置 关闭驼峰式编码

mybatis-plus:
  configuration:
    # 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN(下划线命名) 到经典 Java 属性名 aColumn(驼峰命名) 的类似映射
    map-underscore-to-camel-case: false

填充 创建时间和修改时间

2.代码级别的填充

在属性上添加填充注解

//自动填充字段 插入当前时间
@TableField(fill = FieldFill.INSERT)  //fill 填充
private Date createTime;
//插入修改的当前时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

创建处理器 handler 定义类 MyMetaObjectHandler 实现MetaObjectHandler接口

@Slf4j      // 导入日志
@Component  //一定不要忘记把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insertFill");
        //设置要插入字段的名,值和方法
        this.setFieldValByName("createTime",new Date(),metaObject);  //低版本使用
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    //更新的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start updateFill");
        //设置要更新字段的名,值和方法
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

版本不同使用方法也不同

this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本3.3.0(推荐)
// 或者
this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)

乐观锁

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

字段上加上@Version注解

@Version
private Integer version;

说明:

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity
  • 仅支持 updateById(id)update(entity, wrapper) 方法
  • update(entity, wrapper) 方法下, wrapper 不能复用!!!

查询

//查询全部
List<User> users = userMapper.selectList(null);
//根据id查询
@Test
public void select01(){
    User user = userMapper.selectById(2L);
    System.out.println(user);
}
//批量查询
@Test
public void select02(){
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1,2,3));
    for (User user:users) {
        System.out.println(user);
    }
}
//条件查询  map 方法之一
@Test
public void select03(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","L");
    List<User> user = userMapper.selectByMap(map);
    System.out.println(user);
}

分页

1、原始的limit进行分页

2、pageHelper 第三方插件

3、Mybatis-Plus中也内置了分页插件!

1.注册插件

@Bean
public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
    return paginationInterceptor;
}

2.测试

public void page(){
    //从0开始,查询三个
    Page<User> page = new Page<>(0,3);
    userMapper.selectPage(page,null);
    //输出查询结果
    page.getRecords().forEach(System.out::println);
    //数据总条数
    page.getTotal();
}

逻辑删除

相当于回收站,删除了只是改变数据中的delete字段(从0到1),并没有直接删除数据。

logic 逻辑

1.注册 Bean(3.1.1开始不再需要这一步):

@Configuration
public class MyBatisPlusConfiguration {

    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }
}

2.配置

#逻辑删除设置
#默认为0,删除为1
#全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
mybatis-plus.global-config.db-config.logic-delete-field=flag  
mybatis-plus.global-config.db-config.logic-delete-value=1    
mybatis-plus.global-config.db-config.logic-not-delete-value=0

3.全局逻辑删除: 3.3.0开始支持

如果公司代码比较规范,比如统一了全局都是flag为逻辑删除字段。

使用此配置则不需要在实体类上添加 @TableLogic。

但如果实体类上有 @TableLogic 则以实体上的为准,忽略全局。 即先查找注解再查找全局,都没有则此表没有逻辑删除。

@TableLogic
private Integer deleted; //flag就不用加注解

性能优化 (新版已无)

我们在平时的开发中,会遇到一些慢sql。测试!druid…

作用:性能分析拦截器,用于输出每条SQL语句及执行时间

MP也提供性能分析插件,如果超过这和时间就会停止运行

插件配置

  @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(100);// ms 设置sql执行的最大时间,如果超过就停止
        performanceInterceptor.setFormat(true);
        return new PerformanceInterceptor();

条件查询

wrapper 包装

//条件查询
@Test
public void select04(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper
            //条件不能为空
            .isNull("name")
            .isNotNull("email")
            //年龄大于十二
            .ge("age",12);
    userMapper.selectList(wrapper).forEach(System.out::println);
}
//单个查询
@Test
public void select05(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //查询姓名为L的用户
    wrapper.eq("name","L");
    User user = userMapper.selectOne(wrapper);
    System.out.println(user);
}
//查询在什么到什么之间的总个数
@Test
public void select06(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //查询年龄在20到30之间的总个数
    wrapper.between("age",20,30);
    Integer integer = userMapper.selectCount(wrapper);
    System.out.println(integer);
}
//模糊查询
@Test
public void select07(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    //名字里边包含 a 的,email里不包含2的
    wrapper
            .like("name","a")
            .notLike("email",2);
    userMapper.selectMaps(wrapper).forEach(System.out::println);
}

代码生成器

dao、pojo、conrtroller、service自动生成

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、 Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

依赖

<!--mybatis-plus 是自己开发的,非官方的!-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
    <scope>provided</scope>
</dependency>
<!-- 模板引擎 -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>
<!--swagger-->
<!-- swagger -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

代码

package com.util;

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("LT");
        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://localhost: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("admin");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        //3、包的配置
        PackageConfig pc = new PackageConfig();
//        pc.setModuleName("blog");
        pc.setParent("com.lt");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);

        //4、策略配置
        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("deleted");
        // 自动填充配置
        TableFill gmtCreate = new TableFill("create_time", FieldFill.INSERT);
        TableFill gmtModified = new TableFill("modified_time", 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();
        //执行
    }
}

版权声明:本文为qq_48457516原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。