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.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.1</version>
    </dependency>
    
  • 可以安装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_
    
  • 实体类,使用注解 描述对应关系

    • 全局配置 局部配置

    • 标记表名

    • 标记字段名

    • 设置主键

      • 主键自增(由数据库自增)
      • 主键默认值
      @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;
      }
      
  • Dao层

    /**
     * 在MybatisPlus中dao接口无需定义任何的抽象方法,继承BaseMapper<实体类型>的父接口就可以了
     */
    @Mapper
    public interface UserDao extends BaseMapper<User> {
    }
    
  • 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);
        }
    }
    

CRUD的实现

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

    • 接口上使用 @Mapper注解

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

      @SpringBootApplication
      //@MapperScan(basePackages = "com.dx.dao")  //接口上使用@Mapper就可以了
      public class Springboot12MybatisPlusApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(Springboot12MybatisPlusApplication.class, args);
          }
      }
      
  • 增删改查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);
            }
        }
    }
    
Service层的CRUD
  • 传统的需要依赖注入

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

  • /**
     * 在MybatisPlus中提供一个IService<实体类类型>的父接口
     * 在service接口也可扩展自己的方法
     */
    public interface EmpService extends IService<Emp> {
        //扩展方法
        void test();
    }
    
    /**
     * 在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();
        }
    }
    
  • 测试Demo 自动注入

    @SpringBootTest
    public class ServiceTests {
        @Autowired
        private EmpService empService;
        //......
    }
    
  • 新增数据

    @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);
    }
    
  • 更新数据

    @Test
    void testUpdate(){
        Emp emp = new Emp();
        emp.setEmpno(7946);
        emp.setEname("wangwu");
        emp.setJob("aaaaaaa");
        empService.updateById(emp);
    }
    
  • 删除数据

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

    @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);
    }
    

条件构造器查询

  • 条件构造器

    • 用于写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);
      }
      

扩展

逻辑删除

  • 物理删除:使用delete

    delete from tbl_emp where empno=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;
      
    • 配置逻辑删除标志

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

分页插件

  • 配置类配置分页插件

    @Configuration
    public class MybatisPlusConfig {
    
        /**
         * 分页插件配置
         */
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    }
    
  • 测试

    /**
     * 分页查询
     */
    @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());
    }
    

非表字段注解

  • 实体类的非表字段标注
    /**
     * @TableField(exist=false) :表示该属性不为数据库表字段
     */
    @TableField(exist = false)
    private String str;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值