Mbatis Plus

2023-02-05 09:46:25

在Mybatis框架上做增强的工具

在原有的mybatis中导入mybatisplus坐标

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

连接池坐标

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.16</version>
</dependency>

主要的修改在dao层

以前的mybatis需要写数据库操作语句,现在就只要继承一个BaseMapper

@Mapper
public interface UserDao extends BaseMapper<User> {
}

mybatisplus主要做单表CRUD,多表的CRUD还是需要自己写

Lombok

一款插件,可以快速构建实体类的构造方法

导入坐标

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>

还需要安装Lombok插件

@Data
public class User {
    private Long id;
    private String name;
    private String password;
    private Integer age;
    private String tel;
}

查询所有

@SpringBootTest
class MybatisplusLombokDemoApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void selectAll(){
        userDao.selectList(null);
      //使用查询list,参数设置为null
    }

}

Mybatis分页查询

先定义一个分页拦截器

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
      //创建MybatisPlusInterceptor的拦截器
        MybatisPlusInterceptor myInterceptor = new MybatisPlusInterceptor();
      //将分页拦截器加入MybatisPlus的拦截器
        myInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return myInterceptor;
    }
}

执行分页查询

    @Test
    void page(){
      //创建IPage分页对象,参数传递当前页码和需要查询多少条数据
        IPage<User> page = new Page<>(1,5);
      //执行分页查询
        userDao.selectPage(page,null);
        System.out.println("每页个数"+page.getSize());
        System.out.println("当前页码"+page.getCurrent());
        System.out.println("总页数"+page.getPages());
        System.out.println("总条数"+page.getTotal());
        System.out.println("当前页的数据"+page.getRecords());

    }

开启MybatisPlus日志

在yml文件中开启

# 开启mp的日志(输出到控制台)
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

关闭spring日志打印

在resource下创建一个logback.xml文件,文件名固定

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
</configuration>

关闭SpringBoot的启动标志

在yml文件中关闭

spring:
  main:
    banner-mode: off # 关闭SpringBoot启动图标(banner)

关闭MybatisPlus启动图标

在yml文件中关闭

# mybatis-plus日志控制台输出
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    banner: off # 关闭mybatisplus启动图标

DQL编程控制

三种条件查询的方法

方法一:按条件查询

//QueryWrapper可以用来添加条件
QueryWrapper<User> qw = new QueryWrapper<>();
//查询年龄小于12的数据
qw.lt("age",12);
System.out.println(userDao.selectList(qw));

方法二:lambda格式按条件查询

QueryWrapper<User> qw = new QueryWrapper<>();
//可以添加lambda格式
qw.lambda().gt(User::getAge,12);
System.out.println(userDao.selectList(qw));

方法三:lambda格式按条件查询

//LambdaQueryWrapper可以之间省略后面的.lambda(),直接使用lambda格式
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.lt(User::getAge,12);
System.out.println(userDao.selectList(lqw));

条件组合

//并且关系(and)
lqw.gt(User::getAge,12).lt(User::getAge,30);
//或者关系(or)
lqw.lt(User::getAge,12).or().gt(User::getAge,30);

对null值的处理

方法的第一个参数可以传递一个boolean值,用来控制条件是否使用,如果为true则使用,false则不使用

Integer minAge=10;
Integer maxAge=null;
lqw.gt(minAge!=null,User::getAge, minAge);
lqw.lt(maxAge!=null,User::getAge, maxAge);

commons-lang包可以对字符串进行操作

导入坐标

<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
StringUtils.isNotBlank(name)//用来判断字符串不为空也不为空字符串

映射投影

/*lqw.select(User::getId, User::getName, User::getAge);*/
//或者
QueryWrapper<User> lqw = new QueryWrapper<User>();
lqw.select("id", "name", "age", "tel");
//只查询这几个字段的数据
QueryWrapper<User> lqw = new QueryWrapper<User>();
//查询个数,和tel的数据
lqw.select("count(*) as count, tel");
//通过tel分组
lqw.groupBy("tel");
//通过键值对的形式展示
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);

条件查询

between,查询范围内的数据

//第一个参数是对应的列,第二个是大于的参数,第三个是小于的参数
//(10<User::getAge<30)
lqw.between(User::getAge, 10, 30);
List<User> userList = userDao.selectList(lqw);

模糊查询

lqw.like(Student::getName,"德"); -> // %德%
lqw.likeRight(Student::getName,"马"); -> // 马% Riget表示百分号在字段右边
lqw.likeLeft(Student::getName,"马"); -> //  %马 Left表示百分号在字段左边

and嵌套

 qw.and(i->i.eq("char_length(name)",2).likeRight("name","马"));//姓马并且字符串长度为2

字段映射与表名映射

//当实体类和表列名不对应可以使用@TableField的value设置对应的数据库表中的字段关系
@TableField(value = "pwd")
private String password;
//当属性名在数据库表中不存在,可以使用@TableField的exist进行注释
@TableField(exist = false)
private Integer online;
//开通通过@TableField的select设置该属性是否参与查询
@TableField(value = "pwd",select = false)
private String password;
//当实体类名和数据库表名不对应时可以使用@TableName("表名")进行设置
@TableName("tbl_user")
public class User {
}

id生成策略控制

//@TableId(type = ***)设置id生成的策略
@TableId(type = IdType.AUTO)
private Long id;

IdType.AUTO:使用数据库id自增策略控制id生成
IdType.NONE:不设置id生成策略
IdType.INPUT:用户手动输入id
IdType.ASSIGN_ID:雪花算法生成id(可兼容数字类型和字符串类型)
IdType.ASSIGN_UUID:以UUID算法作为id的生成策略

id生成策略全局配置

mybatis-plus:
  global-config:
    db-config:
      id-type: assign_id #设置id生成策略
      table-prefix: tbl_ #设置所有映射表明前加上tbl_ -> tbl_user

多记录操作

userDao.deleteBatchIds(list);//删除集合中所有id数据
userDao.selectBatchIds(list);//查询集合中所有id数据

逻辑删除

为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中

1.数据库中添加逻辑删除对应字段

deleted

2.创建实体类,实体类中添加对应字段,设置当前字段为逻辑删除标记字段

@Data
public class UserLog extends User{//使用继承获取父类的属性,并且添加子类特有属性
    //逻辑删除字段,标记当前记录是否被删除
    @TableLogic
    private Integer deleted;   
}

3.在配置中配置逻辑删除字面值

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      # 逻辑删除字段名
      logic-delete-field: deleted
      # 逻辑删除字面值:未删除为0
      logic-not-delete-value: 0
      # 逻辑删除字面值:删除为1
      logic-delete-value: 1

乐观锁(不常用)

在我们从数据库获得数据时也会获得一个乐观锁对应的数值,如果当两个用户同时获取到同一个乐观锁数值,当其中一位用户执行完操作,乐观锁的数值就会进行更改,当第二位用户在操作完后发现乐观锁的数值不对应,那么第二个用户的操作就会失败

只有当操作完成,乐观锁的数据才会更改

1.在数据库表中添加乐观锁对应字段

version

2.创建实体类,实体类中添加对应字段,设置当前字段为乐观锁标记字段

@Data
public class User extends User{
  //标记当前字段为乐观锁
    @Version
    private Integer version;
}

3.在MybatisPlus拦截器中加入乐观锁拦截器

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor() {
        //1.定义Mp拦截器
        MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();

        //2.添加乐观锁拦截器
        mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        
        return mpInterceptor;
    }
}

4.使用乐观锁我们需要先查询对应的所有数据

User user = userDao.selectById(3L);  //version=3
User user2 = userDao.selectById(3L);//version=3
user2.setName("Jock aaa");
userDao.updateById(user2);  //version=>4
user.setName("Jock bbb");
userDao.updateById(user);//verion=3?条件还成立吗?
  • 作者:Trouble=Maker
  • 原文链接:https://blog.csdn.net/weixin_52226593/article/details/123145878
    更新时间:2023-02-05 09:46:25