• MyBatisPlus知识点总结-DX的笔记


    Mybatis Plus

    • 官网:daomidou.com 苞米豆
    • 去官网看指南,就是课件了

    简介

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

    特性

    • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
    • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
    • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
    • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
    • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
    • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
    • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
    • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
    • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
    • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
    • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

    项目搭建

    • 创建项目后,引入依赖

      <dependency>
          <groupId>com.baomidougroupId>
          <artifactId>mybatis-plus-boot-starterartifactId>
          <version>3.5.1version>
      dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 可以安装MybatisX插件

    • 配置文件 配置数据源

      # DataSource Config
      spring:
        datasource:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/student
          username: root
          password: 111111
      
      mybatis-plus:
        mapper-locations: mapper/*.xml
        configuration:
          log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
          #在mybatis-plus中下划线转驼峰默认是开启的
          map-underscore-to-camel-case: true
        #全局配置
        global-config:
          #数据库相关配置
          db-config:
            #主键生成策略的全局配置
            id-type: assign_id
            #表的前缀
      #      table-prefix: tbl_
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    • 实体类,使用注解 描述对应关系

      • 全局配置 局部配置

      • 标记表名

      • 标记字段名

      • 设置主键

        • 主键自增(由数据库自增)
        • 主键默认值
        @Data
        @Accessors(chain = true)
        //@TableName("tbl_user")
        public class User {
            /**
             * 实体属性与表中主键字段对应
             * type配置项,设置主键生成策略
             * type = IdType.AUTO 数据库主键自增
             * type = IdType.ASSIGN_ID 默认值,表示当前主键值,由MybatisPlus生成,采用雪花算法(主键类型为varchar,bigint)
             * type = IdType.ASSIGN_UUID 表示当前主键值,由MybatisPlus生成,采用UUID
             */
            // @TableId(value = "id",type = IdType.AUTO)
            // @TableId(value = "id",type = IdType.ASSIGN_ID)
            // @TableId(value = "id",type = IdType.ASSIGN_UUID)
            private String id;
            //实体属性与表非主键字段对应
            @TableField("name")
            private String userName;
            private Integer age;
            private String email;
            //非表中字段
            @TableField(exist = false)
            private String genderName;
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
    • Dao层

      /**
       * 在MybatisPlus中dao接口无需定义任何的抽象方法,继承BaseMapper<实体类型>的父接口就可以了
       */
      @Mapper
      public interface UserDao extends BaseMapper<User> {
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • Mapper层,可以省略,不用写

    • 测试

      @SpringBootTest
      class Springboot12MybatisPlusApplicationTests {
      
          @Autowired
          UserDao userDao;
      
          @Test
          void testUserList() {
              List<User> userList = userDao.selectList(null);
              for (User user : userList) {
                  System.out.println(user);
              }
          }
      
          @Test
          void testUserInsert(){
              int result = userDao.insert(new User().setUserName("ccc").setAge(23).setEmail("ccc@qq.com"));
              System.out.println(result);
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20

    CRUD的实现

    Dao层的CRUD
    • 自动获取empDao的两种方式

      • 接口上使用 @Mapper注解

        @Mapper
        public interface EmpDao extends BaseMapper<Emp> {
            // void test();
        }
        
        • 1
        • 2
        • 3
        • 4
      • 配置类上使用 @MapperScan,这个插件会报错,但是不影响使用

        @SpringBootApplication
        //@MapperScan(basePackages = "com.dx.dao")  //接口上使用@Mapper就可以了
        public class Springboot12MybatisPlusApplication {
        
            public static void main(String[] args) {
                SpringApplication.run(Springboot12MybatisPlusApplication.class, args);
            }
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
    • 增删改查Demo

      @SpringBootTest
      public class MapperTests {
      
          @Autowired
          EmpDao empDao;
      
          @Test
          void test(){
              System.out.println(empDao);
          }
      
          @Test
          void testInsert(){
              Emp emp = new Emp();
              emp.setEname("张三");
              emp.setJob("职员");
              emp.setHiredate(new Date());
              emp.setSal(5600.0);
              emp.setDeptno(10);
      
              int result = empDao.insert(emp);
              //MybatisPlus自动开启主键返回功能
              System.out.println("主键值:" + emp.getEmpno());
              System.out.println(result);
          }
      
          @Test
          void testUpdate(){
              //根据实体对象中的成员变量的值来判断哪些列是需要更新的(属性值为null,则不更新)
              Emp emp = new Emp();
              emp.setEmpno(7945);
              emp.setEname("李四");
              emp.setJob("经理");
              empDao.updateById(emp);
          }
      
          @Test
          void testDelete(){
              // empDao.deleteById(1);
              // empDao.deleteBatchIds(Arrays.asList(1,2,3,4));
              Map<String, Object> map = new HashMap<>();
              map.put("deptno", 100);
              empDao.deleteByMap(map);
          }
      
          @Test
          void testSelectSingle(){
              Emp emp = empDao.selectById(7945);
              System.out.println(emp);
          }
      
          @Test
          void testSelectList(){
              List<Emp> emplist = empDao.selectList(null);
              for (Emp emp : emplist) {
                  System.out.println(emp);
              }
          }
      
          @Test
          void testSelectByMap(){
              Map<String, Object> map = new HashMap<>();
              map.put("job", "SALESMAN");
              map.put("deptno", 10);
              List<Emp> empList = empDao.selectByMap(map);
              for (Emp emp : empList) {
                  System.out.println(emp);
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
    Service层的CRUD
    • 传统的需要依赖注入

    • 现在继承接口直接用提供的属性就可以

    • /**
       * 在MybatisPlus中提供一个IService<实体类类型>的父接口
       * 在service接口也可扩展自己的方法
       */
      public interface EmpService extends IService<Emp> {
          //扩展方法
          void test();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      /**
       * 在MybatisPlus的Service实现类中需要继承一个父类ServiceImpl<持久层接口类型, 实体类类型>
       */
      @Service
      public class EmpServiceImpl extends ServiceImpl<EmpDao, Emp> implements EmpService {
      
          // @Autowired
          // private EmpDao empDao;
      
          @Override
          public void test() {
              //在Service层中调用dao
              // empDao.selectList(null);
              // this.baseMapper.selectList(null);
              // this.baseMapper.test();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    • 测试Demo 自动注入

      @SpringBootTest
      public class ServiceTests {
          @Autowired
          private EmpService empService;
          //......
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 新增数据

      @Test
      void testSave(){
          Emp emp = new Emp();
          emp.setEname("zhangsan");
          emp.setJob("zhiyuan");
          emp.setHiredate(new Date());
          emp.setSal(5600.0);
          emp.setDeptno(10);
          boolean result = empService.save(emp);
          System.out.println(result);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 更新数据

      @Test
      void testUpdate(){
          Emp emp = new Emp();
          emp.setEmpno(7946);
          emp.setEname("wangwu");
          emp.setJob("aaaaaaa");
          empService.updateById(emp);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • 删除数据

      @Test
      void testRemove(){
          empService.removeById(7499);
      }
      
      • 1
      • 2
      • 3
      • 4
    • 查询数据

      @Test
      void testGet(){
          Emp emp = empService.getById(7946);
          System.out.println(emp);
      }
      
      @Test
      void testList(){
          List<Emp> empList = empService.list();
          for (Emp emp : empList) {
              System.out.println(emp);
          }
      }
      
      @Test
      void testCount(){
          long total = empService.count();
          System.out.println(total);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19

    条件构造器查询

    • 条件构造器

      • 用于写where后面的条件

      • 条件:大于 小于 between like …

      • 使用条件查询器

        /**
         * 条件查询中使用的条件构造器
         */
        @Test
        void testWrapper(){
            Integer deptno = 10;
            Double sal = 1500.0;
            String ename = "S";
            QueryWrapper<Emp> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("empno", "ename", "job");
            /**
             * eq(查询字段名, 字段值)
             * eq(条件, 查询字段名, 字段值)
             */
            queryWrapper.eq(deptno!=null, "deptno", deptno);
            queryWrapper.ge(sal!=null, "sal", sal);
            queryWrapper.like(StringUtils.hasLength(ename), "ename", ename);
            queryWrapper.orderBy(true, false, "sal");
            empService.list(queryWrapper);
        }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20

    扩展

    逻辑删除

    • 物理删除:使用delete

      delete from tbl_emp where empno=1;
      
      • 1
    • 逻辑删除:更改表中设计的删除标志的字段,使用updata

      • -- 1.需要在表中设计一个字段(删除标志) 0表示数据正常 1数据删除
        -- 2.查询时必须携带删除标志字段的条件
        select * from tbl_emp where del_flag=0; 
        -- 3.删除时仅需更新删除标志字段的值为1即可
        update tbl_emp set del_flag=1 where empno=7369;
        
        • 1
        • 2
        • 3
        • 4
        • 5
      • 配置逻辑删除标志

        /**
         * @TableLogic 注解是逻辑删除,实体类加上这个注解再执行删除方法的时候会变成修改
         */
        @TableLogic
        private String delFlag;
        
        • 1
        • 2
        • 3
        • 4
        • 5

    分页插件

    • 配置类配置分页插件

      @Configuration
      public class MybatisPlusConfig {
      
          /**
           * 分页插件配置
           */
          @Bean
          public MybatisPlusInterceptor mybatisPlusInterceptor(){
              MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
              interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
              return interceptor;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • 测试

      /**
       * 分页查询
       */
      @Test
      void testPage(){
          /**
           * page(分页设置对象, 分页时条件查询器)
           */
          Page<Emp> page = new Page<>(1, 5);
          IPage<Emp> iPage = empService.page(page);
          //当前页列表数据
          List<Emp> empList = iPage.getRecords();
          for (Emp emp : empList) {
              System.out.println(emp);
          }
          System.out.println("当前页码:" + iPage.getCurrent());
          System.out.println("每页条数:" + iPage.getSize());
          System.out.println("总记录数:" + iPage.getTotal());
          System.out.println("总页数:" + iPage.getPages());
          System.out.println("是否存在上一页:" + ((Page<Emp>)iPage).hasPrevious());
          System.out.println("是否存在下一页:" + ((Page<Emp>)iPage).hasNext());
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

    非表字段注解

    • 实体类的非表字段标注
      /**
       * @TableField(exist=false) :表示该属性不为数据库表字段
       */
      @TableField(exist = false)
      private String str;
      
      • 1
      • 2
      • 3
      • 4
      • 5
  • 相关阅读:
    gdb调试
    LeetCode 2525. 根据规则将箱子分类:优雅解法?
    程序员如何成长
    Linux系统下配置LEMP
    基于SSM的图书商城网站设计与实现
    这个 MySQL 问题困扰了我一个月,现在终于把他解决了
    day02 mybatis
    骁龙咣咣咣三脚,再次改写格局
    J9数字论:以太坊合并后的概念科普
    链表——双链表
  • 原文地址:https://blog.csdn.net/qq_43528471/article/details/126591891