MyBatis-Plus学习笔记总结

一:MyBatis-Plus简介

定义:MyBatis-Plus是MyBatis框架的增强型工具,旨在简化,提高效率
官网:  MyBatis-Plus
特性:  1.无侵入,只做增强不做改变
           2.内置通用Mapper,少量配置即可实现单表CRUD操作
           3.支持Lambda,编写查询条件无需担心字段写错
           4.支持主键自动生成
           5.内置分页插件

二:MyBatis-Plus入门案例(SpringBoot整合MyBatis-Plus)

        1.创建新模块,选择Spring初始化,并配置相关信息
        2.选择当前模块需要的依赖(只需要MySQL Driver)
        3.在pom.xml文件中添加MyBatyis-Plus起步依赖和Druid数据库连接池依赖
<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>
        4.创建数据库和数据表以及数据
create database if not exists mybatisplus_db character set utf8;
use mybatisplus_db;
CREATE TABLE user (
            id bigint(20) primary key auto_increment,
            name varchar(32) not null,
            password  varchar(32) not null,
            age int(3) not null ,
            tel varchar(32) not null
);
insert into user values(null,'tom','123456',12,'12345678910');
insert into user values(null,'jack','123456',8,'12345678910');
insert into user values(null,'jerry','123456',15,'12345678910');
insert into user values(null,'tom','123456',9,'12345678910');
insert into user values(null,'snake','123456',28,'12345678910');
insert into user values(null,'张益达','123456',22,'12345678910');
insert into user values(null,'张大炮','123456',16,'12345678910');
        5.创建实体类
public class User {
    private Long id;
    private String name;
    private String password;
    private Integer age;
    private String tel;
    //自行添加getter、setter、toString()等方法
}
        6.在application,yml中配置数据库连接信息
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC
    username: root
    password: root
       7.定义数据层接口,这个接口继承BaseMapper
@Mapper
public interface UserDao extends BaseMapper<User> {
}
        8.在service类中或者测试类注入数据层接口,测试查询所有的功能
@SpringBootTest
public class Mybatisplus01QuickstartApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testGetAll() {
        List<User> userList = userDao.selectList(null);
        System.out.println(userList);
    }
}

三:基于MyBatis-Plus实现CRUD和分页功能, 完成标准数据层开发

        MyBatis-Plus提供了许多接口来完成增删改查操作        

        下面我们来对比一下之前我们用MyBatis自己编写的接口和MyBatis-Plus提供的接口

         这个小节案例和入门案例的操作步骤一致,不同点就在于测试类的编写,所以这里仅展现测试类中的代码

        1.基于MyBatis-Plus完成标准数据层开发,实现CRUD功能
@SpringBootTest
class Mybatisplus01QuickstartApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testSave() {
        User user = new User();
        user.setName("张三");
        user.setPassword("123456789");
        user.setAge(15);
        user.setTel("177777888888");
        userDao.insert(user);
    }

    @Test
    void testDelete(){
        userDao.deleteById(1691295532225380353L);
    }

    @Test
    void testUpdate(){
        User user = new User();
        user.setId(1L);
        user.setName("Tom888");
        user.setPassword("dom222");
        userDao.updateById(user);
    }

    @Test
    void testGetById(){
        User user = userDao.selectById(2L);
        System.out.println(user);
    }

    @Test
    void testGetAll(){
        List<User> users = userDao.selectList(null);
        System.out.println(users);
    }
}
        2.基于MyBatis-Plus完成标准数据层开发,实现分页功能

            -1-设置分页拦截器

@Configuration
public class MybatisPlusConfig {
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //1 创建MybatisPlusInterceptor拦截器对象
        MybatisPlusInterceptor mpInterceptor=new MybatisPlusInterceptor();
        //2 添加分页拦截器
        mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mpInterceptor;
    }
}

            -2-在测试类中创建IPage分页对象,设置分页参数,执行分页查询

@SpringBootTest
class Mybatisplus01QuickstartApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testGetByPage(){
        // 创建IPage分页对象,设置分页参数
        IPage<User> page = new Page<>(2, 3);
        //2 执行分页查询
        userDao.selectPage(page,null);//queryWrapper为空即不设置查询条件
        //3 获取分页结果
        System.out.println("当前页码值: "+ page.getCurrent());
        System.out.println("每页显示数: "+page.getSize());
        System.out.println("总共的页数: "+page.getPages());
        System.out.println("总共的数据条数: "+page.getTotal());
        System.out.println("当前页的数据为: "+page.getRecords());
    }


}

四:基于MyBatis-Plus完成复杂条件查询(DQL编程控制)

       基于MyBatis-Plus将复杂的SQL查询条件进行了封装(Wrapper<T>),使用编程的形式完成查询条件的组合

        常见的MyBatis-Plus查询接口有:

         0.条件查询案例环境准备 
create database if not exists mybatisplus_db character set utf8;
use mybatisplus_db;
CREATE TABLE tbl_user (
            id bigint(20) primary key auto_increment,
            name varchar(32) not null,
            pwd  varchar(32) not null,
            age int(3) not null ,
            tel varchar(32) not null
);
insert into user values(null,'tom','123456',12,'12345678910');
insert into user values(null,'jack','123456',8,'12345678910');
insert into user values(null,'jerry','123456',15,'12345678910');
insert into user values(null,'tom','123456',9,'12345678910');
insert into user values(null,'snake','123456',28,'12345678910');
insert into user values(null,'张益达','123456',22,'12345678910');
insert into user values(null,'张大炮','123456',16,'12345678910');
@Data
@TableName("tbl_user") //在模型类上方,使用@TableName注解,通过value属性,设置当前类对应的数据库表名称。
public class User {
    private Long id;
    private String name;
    @TableField(value="pwd",select = false)//使用@TableField属性注解,通过value属性,设置当前属性对应的数据库表中的字段关系;通过select属性:设置该属性是否参与查询
    private String password;
    private Integer age;
    private String tel;
}
@Mapper
public interface UserDao extends BaseMapper<User> {

}

         注:Lombok工具的使用

             Lombok,一个Java类库,提供了一组注解,简化POJO实体类开发,常用注解是@Data,这个注解为当前实体类在编译期设置对应的get/set方法,无参/无参构造方法,toString方法,hashCode方法,equals方法等,也就是在实体类上加了这个注解就不用手动生成get/set等方法了

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency>
         1.条件查询中常见的条件构建方式
             -1-常规条件构建格式
//方式一:常规格式

        QueryWrapperr<User> qw = new QueryWrapperr<User>();
        qw.lt("age",18); //条件为年龄小于18

        //List<User> userlist = userDao.selectList(qw);
        //System.out.println(userlist);
                -2-lamda格式条件构建格式 
//方式二:lambda格式(QueryWrapper.lambda())

        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.lambda().lt(User::getAge,10);//条件为年龄小于10

        //List<User> users = userDao.selectList(qw);
        //System.out.println(users);
                 -3-lambda格式条件构建格式  (推荐使用)
//方式三:lambda格式(LambdaQueryWrapper), 更推荐的方式

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.lt(User::getAge, 10);//条件为年龄小于10

        //List<User> userList = userDao.selectList(lqw);
        //System.out.println(userList);
          2.常见的单条件查询

               -1- eq匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//等同于=
lqw.eq(User::getName, "Jerry").eq(User::getPassword, "jerry");
User loginUser = userDao.selectOne(lqw);
System.out.println(loginUser);

               -2- lt匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.lt(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

               -3- le匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.le(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

               -4- gt匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.gt(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

               -5- ge匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
lqw.ge(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

               -6- between匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//范围查询 lt le gt ge eq between
lqw.between(User::getAge, 10, 30);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

               -7- like匹配

LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//模糊匹配 like
lqw.likeLeft(User::getName, "J");
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
          3.多条件查询

              -1-两个条件同时满足(并且关系)

//并且关系
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//并且关系:10到30岁之间
lqw.lt(User::getAge, 30).gt(User::getAge, 10);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);

              -2-两个条件满足其一(或者关系)

//或者关系
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//或者关系:小于10岁或者大于30岁
lqw.lt(User::getAge, 10).or().gt(User::getAge, 30);
List<User> userList = userDao.selectList(lqw);
System.out.println(userList);
          4.条件查询中追加对于空值的处理(实现动态查询)
                -1-使用if条件语句
@Test
    //使用if条件语句进行空值的处理
    void testConditionNotNull1() {
        Integer minAge = 10;
        Integer maxAge = null;
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        if (minAge != null) {
            lqw.gt(User::getAge, minAge);
        }
        if (maxAge != null) {
            lqw.lt(User::getAge, maxAge);
        }
        List<User> users = userDao.selectList(lqw);
        users.forEach(System.out::println);
    }
                -2-使用条件参数控制
 @Test
        //使用条件参数控制进行空值的处理(不使用链式编程)
    void testConditionNotNull2() {
        Integer minAge = null;
        Integer maxAge = 20;
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.gt(minAge != null, User::getAge, minAge);
        lqw.lt(maxAge != null, User::getAge, maxAge);
        List<User> users = userDao.selectList(lqw);
        users.forEach(System.out::println);
    }
@Test
        //使用条件参数控制进行空值的处理(使用链式编程)
    void testConditionNotNull3() {
        Integer minAge = null;
        Integer maxAge = 20;
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.gt(minAge != null, User::getAge, minAge)
                .lt(maxAge != null, User::getAge, maxAge);
        List<User> users = userDao.selectList(lqw);
        users.forEach(System.out::println);
    }
          5.查询投影

            -1-查询模型类中部分属性

 @Test
    void testSelectCast1() {
        //查询部分属性而不是模型类中所有的属性
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.select(User::getId, User::getName, User::getAge);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

            -2-查询模型类中未定义的属性

@Test
    void testSelectCast2() {
        //查询模型类中没有的属性
        QueryWrapper<User> qw = new QueryWrapper<User>();
        //qw.select("count(*) as count,tel");
        qw.select("count(*) as count","tel");
        qw.groupBy("tel");
        List<Map<String, Object>> userList = userDao.selectMaps(qw);
        System.out.println(userList);
    }

六:DML控制

      1.id生成策略控制

         -1-常见id生成策略

         -2-模型类中添加id生成策略的方式

               正如上图所示: 将@TableId注解定义在模型类中用于表示主键的属性上方,type属性设置主键属性的生成策略,值参照IdType枚举值

         -3-在application.yml文件中全局配置id生成策略的方式

mybatis-plus:
  global-config:
    db-config:
      id-type: assign_id
      table-prefix: tbl_  # 将这个id生成策略应用到所有以tbl_开头的表中
       2.批量删除
@Test
    void testBatchDelete() {
        ArrayList<Long> list = new ArrayList<>();
        list.add(6L);
        list.add(5L);
        userDao.deleteBatchIds(list);
    }
       3.批量查询
@Test
    void testBatchSelect(){
        ArrayList<Long> list = new ArrayList<>();
        list.add(1L);
        list.add(2L);
        list.add(3L);
        userDao.selectBatchIds(list);
    }
        4.逻辑删除

             --定义

                删除数据时并不是真的删除数据,而是将新增一个逻辑删除标记字段,删除时设置该字段为不可用字段,数据保留在数据库中

              --步骤

                    -1-添加逻辑删除标记字段

                      -2-实体类中添加对应字段,并在该字段上添加@TableLogic设定当前字段为逻辑删除标记字段 

@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;
    @TableLogic(value="0",delval = "1")
    private Integer deleted; //逻辑删除字段,标记当前记录是否被删除,未删除为0,删除为1
   }

                        -3- 在application.yml文件中配置逻辑删除字段名及字段值

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

                       -4- 编写测试代码

 @Test
    void testUpdate(){
        User user = new User();
        user.setId(1L);
        user.setName("Tom888");
        user.setPassword("dom222");
        user.setDeleted(1);
        userDao.updateById(user);
    }

七:实体类与表映射相关问题

      1.实体类属性和表字段名称不一致问题解决方案

          在模型类属性上添加@TableField注解,通过value属性,设置两者之间的对应关系

@Data
public class User {
    private Long id;
    private String name;
    @TableField(value="pwd")//使用@TableField属性注解,通过value属性,设置当前属性对应的数据库表中的字段关系;
    private String password;
    private Integer age;
    private String tel;
 }
      2.实体类中添加了数据库中中未定义的属性

        在模型类属性上,添加@TableField注解,通过exist属性,设置该属性为false即可(默认为true)

@Data
public class User {
    private Long id;
    private String name;
    @TableField(value="pwd")//使用@TableField属性注解,通过value属性,设置当前属性对应的数据库表中的字段关系;
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist = false) //使用@TableField注解,通过exist属性,设置属性在数据库表字段中是否存在,默认为true
    private Integer online;
}
      3.在模型类中设置对应表的映射关系

        在模型类上添加注解@TableName,通过value属性,设置当前类对应的数据表名称

@Data
@TableName("tbl_user") //在模型类上方,使用@TableName注解,通过value属性,设置当前类对应的数据库表名称。
public class User {
    private Long id;
    private String name;
    @TableField(value="pwd")//使用@TableField属性注解,通过value属性,设置当前属性对应的数据库表中的字段关系;
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist = false) //使用@TableField注解,通过exist属性,设置属性在数据库表字段中是否存在,默认为true
    private Integer online;
}
      4.在模型类中设置字段是否参与查询

        在模型类属性上方,使用@TableField注解,通过select属性的值设置是否参与查询,true为参与查询,false为不参与查询

@Data
@TableName("tbl_user") //在模型类上方,使用@TableName注解,通过value属性,设置当前类对应的数据库表名称。
public class User {
    private Long id;
    private String name;
    @TableField(value="pwd",select = false)//使用@TableField属性注解,通过value属性,设置当前属性对应的数据库表中的字段关系;通过select属性:设置该属性是否参与查询
    private String password;
    private Integer age;
    private String tel;
   /@TableField(exist = false) //使用@TableField注解,通过exist属性,设置属性在数据库表字段中是否存在,默认为true
    private Integer online;
}

八:日志控制

     1.开启MyBatisPlus日志
# 开启mp的日志(输出到控制台)
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      2.取消Spring初始化日志打印

          在resources下新建一个logback.xml文件,名称固定,内容如下:

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

</configuration>
      3.取消SpringBoot启动banner
spring:
  main:
    banner-mode: off # 关闭SpringBoot启动图标(banner)
      4.取消MyBatis-plus启动banner
# mybatis-plus日志控制台输出
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    banner: off # 关闭mybatisplus启动图标

九:配置文件

在springboot项目配置文件中可以配置如下内容

mybatis-plus:
  type-aliases-package: com.**.entity
  mapper-locations: classpath:/**/xml/*.xml
  configuration:
   log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
     map-underscore-to-camel-case: true
    call-setters-on-nulls: true
  global-config:
     id-type: auto
     field-strategy: NOT_EMPTY
     db-type: MYSQL
     logic-not-delete-value: 0
     logic-delete-value: 1
    table-prefix: t_
mybatis-plus:
  # 包扫描路径(当前项目的实体类所在位置。别名包扫描路径,通过该属性可以给包中的类注册别名,多个路径用逗号分割)
  type-aliases-package: com.**.entity
  # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  mapper-locations: classpath:/**/xml/*.xml
  configuration:
   log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
     map-underscore-to-camel-case: true
    # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
    # 允许在resultType="map"时映射null值
    # call-setters-on-nulls: true
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用(包括执行结果)
    # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
   global-config:
  #  db-config:
  #   # 主键类型 AUTO:"数据库ID自增"
  #   # INPUT:"用户输入ID",
  #   # ID_WORKER:"全局唯一ID (数字类型唯一ID)",
  #   # UUID:"全局唯一ID UUID";
  #   id-type: auto
  #   # 字段策略 IGNORED:"忽略判断"  NOT_NULL:"非 NULL 判断")  NOT_EMPTY:"非空判断"
  #   field-strategy: NOT_EMPTY
  #   # 数据库类型
  #   db-type: MYSQL
  #   # 逻辑删除配置
  #   # 删除前
  #   logic-not-delete-value: 0
  #   # 删除后
  #   logic-delete-value: 1
  #   # 数据库表名的前缀
  #   table-prefix: t_

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值