• MyBatis-Plus(详解)


    在这里插入图片描述

    🍁博客主页:👉不会压弯的小飞侠
    ✨欢迎关注:👉点赞👍收藏⭐留言✒
    ✨系列专栏:👉MyBatis-Plus专栏
    ✨如果觉得博主的文章还不错的话,请三连支持一下博主。
    🔥欢迎大佬指正,一起 学习!一起加油!
    在这里插入图片描述

    在这里插入图片描述


    🍁MyBatisPlus简介

    • MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率。

    • 开发方式

      • 基于MyBatis使用MyBatisPlus
      • 基于Spring使用MyBatisPlus
      • 基于SpringBoot使用MyBatisPlus

    🍁MyBatisPlus快速入门案例

    • 本案例采用SpringBoot整合MyBatis开发
    • 创建SpringBoot工程
    1. 创建过程在这就不过多描述,详细过程在Springboot专栏里👉点击直接查看
    2. 勾选配置使用的技

    在这里插入图片描述

    1. 手动添加MP依赖:
            <dependency>
    			<groupId>com.baomidou</groupId>
    			<artifactId>mybatis-plus-boot-starter</artifactId>
    			<version>3.4.1</version>
    		</dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ⭐⭐⭐注意:阿里云版本可以直接勾选MyBatisPlus

    1. 设置dataSource相关属性(JDBC参数)
    spring:
      datasource:
        driver-class-name=com: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC
        username: root
        password: root
        type: com.alibaba.druid.pool.DruidDataSource
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用Druid数据源,需要导入坐标:

    	<dependency>
    			<groupId>com.alibaba</groupId>
    			<artifactId>druid</artifactId>
    			<version>1.2.11</version>
    		</dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 创建实体类(User)
    package com.jkj.domain;
    import lombok.Data;
    @Data
    public class User {
        private Long id;
        private String name;
        private String password;
        private Integer age;
        private String tel;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 创建表结构

    在这里插入图片描述

    1. 定义数据接口继承BaseMapper
    package com.jkj.dao;
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.jkj.domain.User;
    import org.apache.ibatis.annotations.Mapper;
    @Mapper
    public interface UserDao extends BaseMapper<User> {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 创建测试类
    @SpringBootTest
    class Mybatisplus01ApplicationTests {
    
    	@Autowired
    	private UserDao userDao;
    	@Test
    	void findAll(){
    		
    		List<User> users = userDao.selectList(null);
    		System.out.println(users);
           }
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 测试

    在这里插入图片描述

    🍁标准数据层开发

    🔥MP接口

    • 新增:int insert(T t)
    • 删除:int deleteById(Serializable id)
    • 修改:int updateById(T t)
    • id查询:T selectById(Serializable id)
    • 查询全部:List selectList()
    • 分页查询:IPage selectPage( IPage page)
    • 条件查询:Page selectPage(Wrapper querywrapper)

    🔥 id查询

       @Test
        void findById(){
            User user = userDao.selectById(3L);
            System.out.println(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    测试:
    在这里插入图片描述

    🔥修改

    @Test
        void updateById(){
            User user=new User();
            user.setId(2L);
            user.setName("老二");
            user.setTel("212121");
           userDao.updateById(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    测试:
    在这里插入图片描述

    🔥删除

       @Test
        void deleteById(){
            userDao.deleteById(4L);
        }
    
    • 1
    • 2
    • 3
    • 4

    测试:
    在这里插入图片描述

    🔥保存

       @Test
        void save(){
            User user=new User();
            user.setId(4L);
            user.setName("老四");
            user.setPassword("444");
            user.setAge(67);
            user.setTel("555222");
            userDao.insert(user);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    测试:
    在这里插入图片描述

    🔥分页

    1. 设置分页拦截器作为Spring管理的bean
    package com.jkj.config;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MpConfig {
       @Bean
       //设置分页拦截器
        public MybatisPlusInterceptor pageInterceptor(){
           //定义MP拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            //添加具体的拦截器
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 执行分页查询
      @Test
        void selectPage(){
            IPage page = new Page(1, 2);
            userDao.selectPage(page,null);
            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());
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试:
    在这里插入图片描述

    🔥开启日志

    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 1
    • 2
    • 3

    🍁DQL控制

    • MyBatisPlus将书写复杂的sQL查询条件进行了封装,使用编程的形式完成查询条件的组合。
      • selectOneWrapper):T
      • selectCountWrapper): Integer
      • selectListWrapper): List
      • selectMapsWrapper): List >
      • selectObjsWrapper): List
      • selectPage(IPage,Wrapper): IPage
      • selectMapsPage(IPage,Wrapper): lPage>

    🔥条件查询

    🔥方式一按条件查询

    		QueryWrapper qw = new QueryWrapper();
    		qw.lt("age",20);
    		List<User> users = userDao.selectList(qw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4

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

    		QueryWrapper<User> qw = new QueryWrapper<User>();
    		qw.lambda().lt(User::getAge,20);
    		List<User> users = userDao.selectList(qw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4

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

    		LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    		lqw.lt(User::getAge,20);
    		List<User> users = userDao.selectList(lqw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4

    测试:
    在这里插入图片描述

    🔥并且and

    • 年龄大于20小于35
    		LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    		lqw.lt(User::getAge,35).gt(User::getAge,20);
    		List<User> users = userDao.selectList(lqw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4

    测试:
    在这里插入图片描述

    🔥或者or

    • 小于20大于35
    		LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    		lqw.lt(User::getAge,20).or().gt(User::getAge,35);
    		List<User> users = userDao.selectList(lqw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4

    测试:
    在这里插入图片描述

    🔥条件查询—null值处理

    • if语句控制条件追加
            LambdaQuerywrapper<User> lqw = new LambdaQuerywrapper<User>();
            if(null != userQuery.getAge()(
                      lqwn .ge(User::getAge,userQuery.getAge());
                       }
            if(null != userQuery.getAge2()){
                       lqw .lt(User::getAge,userQuery.getAge2());
                       }
            List<User> userList = userDao.selectList(lqw);
            System.out.print1n(userList);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 条件参数控制
            LambdaQuerywrapper<User> lqw = new LambdaQuerywrapper<User>();
            lqw.ge(null != userQuery.getAge(),User::getAge,userQuery.getAge());
            lqw.1t(null != userQuery.getAge2( ),User::getAge,userQuery.getAge2());
            List<User> userList = userDao.selectList( 1qw ) ;
            System.out.println(userList);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 条件参数控制(链式编程)
            LambdaQuerywrapper<User> lqw = new LambdaQuerywrapper<User>();
            lqw.ge(null != userQuery.getAge(),User::getAge,userQuery.getAge())
            .1t(null != userQuery.getAge2( ),user::getAge,userQuery.getAge2());
            List<User> userList = userDao.selectList( 1qw ) ;
            System.out.println(userList);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    🔥查询投影

    • 查询结果包含模型类中部分属性
            //查询投影(方式一)
    		LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    		lqw.select(User::getId,User::getName,User::getAge);
    		List<User> users = userDao.selectList(lqw);
    		System.out.println(users);
    
    		//查询投影(方式二)
    		QueryWrapper qw = new QueryWrapper();
    		qw.select("id","name","age");
    		List<User> users = userDao.selectList(qw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    测试:
    在这里插入图片描述

    🔥 分组统计

    		QueryWrapper qw = new QueryWrapper();
    		qw.select("count(*) as count","tel");
    		qw.groupBy("tel");
    		List<Map<String,Object>> list = userDao.selectMaps(qw);
    		System.out.println(list);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    测试:
    在这里插入图片描述

    🔥 查询条件

    • 查询条件
      • 范围匹配(> = between )
      • 模糊匹配( like)
      • 空判定(null)
      • 包含性匹配 ( in )
      • 分组( group)
      • 排序( order)
    • 模拟用户登录
            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    		lqw.eq(User::getName,"老二").eq(User::getPassword,"222");
    		User user = userDao.selectOne(lqw);
    		System.out.println(user);
    
    • 1
    • 2
    • 3
    • 4

    测试:
    在这里插入图片描述

    🔥 范围查询

            LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
    		lqw.between(User::getAge,10,35);
    		List<User> users = userDao.selectList(lqw);
    		System.out.println(users);
    
    • 1
    • 2
    • 3
    • 4

    测试:
    在这里插入图片描述

    🔥 字段映射与表明映射

    • 当实体类属性和字段不一致时
      • @TableField
      • 属性注解
      • 设置当前属性对应的数据库表中的字段关系
      • value (默认〕:设置数据库表字段名称
    @TableField(value = "psw")
        private String password;
    
    • 1
    • 2
    • 编码中添加了数据库中未定义的属性
    • exist:设置属性在数据表字段中是否存在,默认是true
    @TableField(exist = false)
        private String address;
    
    • 1
    • 2
    • 查询字段的权限
    • select: 设置属性是否参与查询
     @TableField(value = "psw",select = false)
        private String password;
    
    • 1
    • 2
    • 表名与实体类名不一致
    • @TableName
    • 类注解
    • 设置当前类对应数据库表关系
    @TableName("xfx_user")
    public class User {
    }
    
    • 1
    • 2
    • 3
    • 在配置中解决表名与实体类名不一致的问题
    mybatis-plus:
      global-config:
        db-config:
          id-type: auto
          table-prefix: xfx
    
    • 1
    • 2
    • 3
    • 4
    • 5

    🍁DML控制

    🔥id生成策越

    • 名称:@TableId
    • 类型:属性注解
    • 位置:模型类中用于表示主键的属性定义上方
    • 作用:设置当前类中主键属性的生成策略
    • 相关属性
      • value:设置数据库主键名称
      • type:设置主键属性的生成策略,值参照IdType枚举值
      • AUTO(0):使用数据库id自增策略控制id生成
      • NONE(1):不设置id生成策略
      • INPUT(2):用户手工输入id
      • ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符串型)
      • ASSIGN_UUID(4):以UUID生成算法作为id生成策略
     @TableId(type = IdType.AUTO)
        private Integer id;
    
    • 1
    • 2

    测试:

        @Test
    	void save(){
    		User user=new User();
    		user.setName("老八");
    		user.setAge(88);
    		user.setPassword("888");
    		user.setTel("6888867");
    		userDao.insert(user);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    🔥多数据操作(删除)

        @Test
    	void all(){
    		List<Integer> list = new ArrayList<>();
    		list.add(7);
    		list.add(8);
    		list.add(9);
    		list.add(10);
    		userDao.deleteBatchIds(list);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    删除前:
    在这里插入图片描述
    删除后:
    在这里插入图片描述

    🔥多数据操作(查询)

    测试:

    @Test
    	void all(){
    		List<Integer> list = new ArrayList<>();
    		list.add(1);
    		list.add(3);
    		list.add(5);
    		list.add(6);
    		userDao.selectBatchIds(list);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    🔥逻辑删除

    • 数据表中添加删除标记字段

    在这里插入图片描述

    • 实体类添加对应的字段,并设定字段为逻辑删除标记字段
        @TableLogic(value = "0",delval = "1")
        private Integer deleted;
    
    • 1
    • 2
    • 或者配置逻辑删除字面值
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      global-config:
        db-config:
          id-type: auto
          table-prefix: xfx
          logic-delete-field: deleted
          logic-not-delete-value: 0
          logic-delete-value: 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 测试
    	@Test
    	void contextLoads() {
    		userDao.deleteById(5);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 执行sql语句

    在这里插入图片描述

    • 测试结果
      在这里插入图片描述

    🔥乐观锁

    乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁,只有到数据提交的时候才通过一种机制来验证数据是否存在冲突。乐观锁是通过在表中增加一个版本(version)或时间戳(timestamp)来实现,版本最为常用。乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行 +1 操作,否则就执行失败。

    • 数据表中添加锁

    在这里插入图片描述

    • 实体类添加对应的字段,并设定字段为逻辑删除标记字段
       @Version
       private Integer version;
    
    • 1
    • 2
    • 配置乐观锁拦截器机制对应的动态SQL语句拼装
    @Configuration
    public class MpConfig {
       @Bean
       //设置分页拦截器
        public MybatisPlusInterceptor pageInterceptor(){
           //定义MP拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            //添加具体的拦截器
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            //乐观锁拦截器
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 使用乐观锁机制在修改前必须获取到对应数据的version方可正常运行
    	@Test
    	void contextLoads() {
    		User user = userDao.selectById(1);
    		user.setName("老大");
    		userDao.updateById(user);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    • 执行修改前先执行查询语句
    SELECT id,name,age,tel,deleted,version FROM xfx_user WHERE id=? 
    
    • 1
    • 执行修改时使用version字段作为乐观锁检查依据。
     UPDATE xfx_user SET name=?, age=?, tel=?, version=? WHERE id=? AND version=?
    
    • 1
  • 相关阅读:
    全功能知识付费源码系统微信小程序+H5+PC端一站通行,自定义你的小程序
    亚马逊、eBay、wish、Lazada、shoppe和mercari如何降低测评成本提高测评效率?
    QT day3
    【Java】helloworld
    原子性(juc编程)
    渗透测试-apt攻击与防御系列-利用WinRAR跨目录获取Net-NTLM Hash和DLL劫持
    String字符串,FastJson常用操作方法
    在滴滴和字节跳动划水4年,过于真实了...
    JS实现瀑布流页面布局
    仿游戏热血江湖游戏类31
  • 原文地址:https://blog.csdn.net/qq_43514330/article/details/125897239