MyBatisPlus

目录

简介

标准CRUD使用

DQL编程控制

条件查询

查询投影

查询条件

映射匹配兼容性

DML编程控制

ID生成策略

多记录操作

逻辑删除

乐观锁

代码生成器


简介

MybatisPlus( 简称 MP) 是基于 MyBatis 框架基础上开发的增强型工具,旨在简化开发、提供效
率,官网为https://mp.baomidou.com/ ,特性有很多:
  • 无侵入:只做增强不做改变,不会对现有工程产生影响
  • 强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作
  • 支持 Lambda:编写查询条件无需担心字段写错
  • 支持主键自动生成
  • 内置分页插件
  • ……

标准CRUD使用

MybatisPlus提供了内置的方法使用,具体可以看DAO接口继承的BaseMapper

  1. 新增   
    //int:返回值,新增成功后返回1,没有新增成功返回的是0
    int insert (T t)

  2. 删除
    //int:返回值类型,数据删除成功返回1,未删除数据返回0
    int deleteById (Serializable id)

  3. 修改
    //修改的时候,只修改实体对象中有值的字段
    int updateById(T t);

  4. 根据id查询
    //Serializable:参数类型,主键ID的值
    T selectById (Serializable id)

  5. 查询所有
    //Wrapper:用来构建条件查询的条件,目前我们没有可直接传为Null
    List<T> selectList(Wrapper<T> queryWrapper)

  6. Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发,常见注解如下:
    @Setter: 为模型类的属性提供 setter 方法
    @Getter: 为模型类的属性提供 getter 方法
    @ToString: 为模型类的属性提供 toString 方法
    @EqualsAndHashCode: 为模型类的属性提供 equals hashcode 方法
    @Data: 是个组合注解,包含上面的注解的功能
    @NoArgsConstructor: 提供一个无参构造函数
    @AllArgsConstructor: 提供一个包含所有参数的构造函数
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <!--<version>1.18.12</version>-->
    </dependency>

  7. 分页查询(需要配合分页拦截器使用),IPage是一个接口,我们需要找到它的实现类来构建它,具体的实现类,可以进入到IPage类中按ctrl+h,会找到其有一个实现类为Page
    //IPage用来构建分页查询条件,Wrapper用来构建条件查询的条件
    IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper)
    //可参考官网文档
    @Configuration
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            //1 创建MybatisPlusInterceptor拦截器对象
            MybatisPlusInterceptor mpInterceptor=new MybatisPlusInterceptor();
            //2 添加分页拦截器
            mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            return mpInterceptor;
        }
    }

DQL编程控制

MyBatisPlus 将书写复杂的 SQL 查询条件进行了封装,使用编程的形式完成查询条件的组合

条件查询

在进行查询的时候,我们的入口是在 Wrapper这个类上,因为它是一个接口,所以我们需要去找它对应的实现类,关于实现类也有很多,说明我们有多种构建查询条件对象的方式
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(User::getAge, 10).or().gt(User::getAge, 30);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

相当于
SELECT id,name,password,age,tel FROM user WHERE (age < ? OR age > ?)

条件null判定

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(null!=uq.getAge2(),User::getAge, uq.getAge2());
lqw.gt(null!=uq.getAge(),User::getAge, uq.getAge());
List<User> userList = userDao.selectList(lqw);

//condition为boolean类型,返回true,则添加条件,返回false则不添加条件

 

查询投影

查询指定字段

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.select(User::getId,User::getName,User::getAge);
List<User> userList = userDao.selectList(lqw);
或
QueryWrapper<User> lqw = new QueryWrapper<User>();
lqw.select("id","name","age","tel");
List<User> userList = userDao.selectList(lqw);

查询条件

查询条件有很多,包括>,=,<,like,null,in,group,order

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.eq(User::getName, "Jerry").eq(User::getPassword, "jerry");//等值查询
lqw.between(User::getAge, 10, 30);//范围查询
lqw.likeLeft(User::getName, "J");//模糊查询%J
lqw.like(User::getName, "J");//模糊查询%J%
lqw.likeRight(User::getName, "J");//模糊查询J%
lqw.orderBy(true,false, User::getId);//是否排序:是,是否升序:否,排序字段

User loginUser = userDao.selectOne(lqw);

映射匹配兼容性

问题:属性名与表名不一致?模型类中多了一个数据库表不存在的字段?敏感数据不想被查出来?表的名称和模型类的名称不一致?如下注解一一解决

@Data
@TableName("tbl_user")
public class User {
    private Long id;
    private String name;
    @TableField(value = "pwd",select = false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist = false)
    private Integer online;
}

DML编程控制

ID生成策略

不同的业务采用的 ID生成方式是不一样的,其中auto是使用数据库ID自增,input需要手动设置id,assign_id不需要手动设置id,会根据雪花算法自动生成 一个64位 Long类型的数据;assign_uuid则自动生成 一个32位 String 类型的数据
@Data
@TableName("tbl_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;

}
  • NONE: 不设置id生成策略,MP不自动生成,约等于INPUT,所以这两种方式都需要用户手动设置,但是手动设置第一个问题是容易出现相同的ID造成主键冲突,为了保证主键不冲突就需要做很多判定,实现起来比较复杂
  • AUTO:数据库ID自增,这种策略适合在数据库服务器只有1台的情况下使用,不可作为分布式ID使用
  • ASSIGN_UUID:可以在分布式的情况下使用,而且能够保证唯一,但是生成的主键是32位的字符 串,长度过长占用空间而且还不能排序,查询性能也慢
  • ASSIGN_ID:可以在分布式的情况下使用,生成的是Long类型的数字,可以排序性能也高,但是生成的策略和服务器时间有关,如果修改了系统时间就有可能导致出现重复主键
综上所述,每一种主键策略都有自己的优缺点,根据自己项目业务的实际情况来选择使用才是最明
智的选择。
//让所有的模型类都可以使用该主键ID策略
mybatis-plus:
  global-config:
    db-config:
      id-type: assign_id
//设置所有属性名加上前缀,构成表名
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_

多记录操作

//根据id批量删除
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends
Serializable> idList);

//根据id集合批量查询
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends
Serializable> idList);
相当于select * from tb where id in(?,?,?)

逻辑删除

逻辑删除 : 为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库
中,执行的是update操作,相当于
UPDATE tbl_user SET deleted =1 where id = ? AND deleted =0
方式一:模型类的属性上添加@TableLogic注解
@TableLogic(value="0",delval="1")
//value为正常数据的值,delval为删除数据的值
private Integer deleted;

方式二:在配置文件中添加全局配置
mybatis-plus:
  global-config:
    db-config:
      # 逻辑删除字段名
      logic-delete-field: deleted
      # 逻辑删除字面值:未删除为0
      logic-not-delete-value: 0
      # 逻辑删除字面值:删除为1
      logic-delete-value: 1

乐观锁

官方文档https://mp.baomidou.com/guide/interceptor-optimisticlocker.html#optimisticlockerinnerinterceptor

原理:更新前分别先查询version的值,更新的时候同步将version+1更新回到数据库表中

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor() {
    //1.定义Mp拦截器
    MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
    //2.添加乐观锁拦截器
    mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return mpInterceptor;
    }
}

代码生成器

代码自动生成,需导入依赖mybatis-plus-generator及以下内容

  • 模板: MyBatisPlus提供,可以自己提供,但是麻烦,不建议
  • 数据库相关配置:读取数据库获取表和字段信息
  • 开发者自定义配置:手工配置,比如ID生成策略

代码生成类可以参考官方文档https://mp.baomidou.com/guide/generator.html

运行成功后,会在当前项目中生成很多代码,代码包含 controller , service mapper entity
package com.itheima;

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;

public class CodeGenerator {
    public static void main(String[] args) {
        //1.获取代码生成器的对象
        AutoGenerator autoGenerator = new AutoGenerator();

        //设置数据库相关配置
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);

        //设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatisplus_04_generator/src/main/java");    //设置代码生成位置
        globalConfig.setOpen(false);    //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("黑马程序员");    //设置作者
        globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);

        //设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo.setParent("com.aaa");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setEntity("domain");    //设置实体类包名
        packageInfo.setMapper("dao");   //设置数据层包名
        autoGenerator.setPackageInfo(packageInfo);

        //策略设置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tbl_user");  //设置当前参与生成的表名,参数为可变参数
        strategyConfig.setTablePrefix("tbl_");  //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名  例如: User = tbl_user - tbl_
        strategyConfig.setRestControllerStyle(true);    //设置是否启用Rest风格
        strategyConfig.setVersionFieldName("version");  //设置乐观锁字段名
        strategyConfig.setLogicDeleteFieldName("deleted");  //设置逻辑删除字段名
        strategyConfig.setEntityLombokModel(true);  //设置是否启用lombok
        autoGenerator.setStrategy(strategyConfig);
        //2.执行生成操作
        autoGenerator.execute();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值