mybatisPlus

打印 上一主题 下一主题

主题 928|帖子 928|积分 2784

mybatisPlus

mybatisplus
基础: mybatis  spring  springmvc
为什么要学习mybatisplus  ?

可以解决大量时间 所有的CRUD 代码它都可以自动化完成
简介
简化 jdbc 操作
简化 mybatis
快速入门

网站:快速开始 | MyBatis-Plus (baomidou.com)
使用第三方依赖

  • 导入对应的依赖
  • 研究依赖如何配置
  • 代码如何编写
  • 提高扩展技术能力
步骤

  • 创建数据库 mybatis_plus
  • 现有一张 User 表,其表结构如下:
    idnameageemail1Jone18test1@baomidou.com2Jack20test2@baomidou.com3Tom28test3@baomidou.com4Sandy21test4@baomidou.com5Billie24test5@baomidou.com
​                其对应的数据库 Schema 脚本如下:
  1. DROP TABLE IF EXISTS user;
  2. CREATE TABLE user
  3. (
  4.     id BIGINT(20) NOT NULL COMMENT '主键ID',
  5.     name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
  6.     age INT(11) NULL DEFAULT NULL COMMENT '年龄',
  7.     email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
  8.     PRIMARY KEY (id)
  9. );
复制代码
​                其对应的数据库 Data 脚本如下:
  1. DELETE FROM user;
  2. INSERT INTO user (id, name, age, email) VALUES
  3. (1, 'Jone', 18, 'test1@baomidou.com'),
  4. (2, 'Jack', 20, 'test2@baomidou.com'),
  5. (3, 'Tom', 28, 'test3@baomidou.com'),
  6. (4, 'Sandy', 21, 'test4@baomidou.com'),
  7. (5, 'Billie', 24, 'test5@baomidou.com');
复制代码

  • 编写项目 ,初始化项目
    1.    
    2. <dependency>
    3.     <groupId>com.mysql</groupId>
    4.     <artifactId>mysql-connector-j</artifactId>
    5. </dependency>
    6. <dependency>
    7.     <groupId>org.projectlombok</groupId>
    8.     <artifactId>lombok</artifactId>
    9. </dependency>
    10. <dependency>
    11.     <groupId>com.baomidou</groupId>
    12.     <artifactId>mybatis-plus-boot-starter</artifactId>
    13.     <version>3.0.5</version>
    14. </dependency>
    复制代码
    说明
    ​        使用mybatisplus 可以节省我们大量的代码,尽量不要同时导入 mybatis 和 mybatis-plus!
    ​        版本差异
  • 链接数据库
    1. spring.couchbase.username=root
    2. spring.datasource.password=123456
    3. spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf8
    4. # mysql8 serverTimezone=GMT%2B8
    5. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    复制代码
    pojo-dao(链接mybatis,配置mapper.xml文件)-service-controller


  • mapper 接口
    1. package com.lmq.mapper;
    2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    3. import com.lmq.pojo.User;
    4. import org.springframework.stereotype.Repository;
    5. /**
    6. * @author 羡鱼
    7. * @version 1.0
    8. * @date 2023/7/20 20:23
    9. */
    10. @Repository  // 持久层
    11. public interface UserMapper extends BaseMapper<User> {
    12.     // 所有CRUD操作都已经编写完成了
    13.     // 你不需要配置一大堆文件了
    14. }
    复制代码
    注意: 我们需要在主启动类上去扫描我们的mapper包下的所有接口 @MapperScan("com.lmq.mapper")
    测试类
    1. package com.lmq;
    2. import com.lmq.mapper.UserMapper;
    3. import com.lmq.pojo.User;
    4. import org.junit.jupiter.api.Test;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.boot.test.context.SpringBootTest;
    7. import java.util.List;
    8. @SpringBootTest
    9. class MybatisPlusApplicationTests {
    10.         @Autowired
    11.         private UserMapper userMapper;
    12.         @Test
    13.         void contextLoads() {
    14.                 // 参数是一个Wrapper,条件构造器,这里我们先不用null
    15.                 // 查询全部用户
    16.                 List<User> users = userMapper.selectList(null);
    17.                 users.forEach(System.out::println);
    18.         }
    19. }
    复制代码
    1、sql是谁帮我写的? MyBatis-plus 写好了
    2、方法哪里来的? MyBatis-plus 都写好了
配置日志

我们所以的sql现在是不可见的,我们希望知道是怎么执行的
  1. #配置日志
  2. mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
复制代码

CRUD扩展

insert
  1.         @Test
  2.         public void testInsert(){
  3.                 User user = new User();
  4.                 user.setName("lmq");
  5.                 user.setAge(21);
  6.                 user.setEmail("1435456124@qq.com");
  7.                 int result = userMapper.insert(user); // 帮我们自动生成id
  8.                 System.out.println(result); //受影响的行数
  9.                 System.out.println(user); // 发现id会自动回填
  10.         }
复制代码

数据库插入的id的默认值为:全局的唯一id
主键生成策略

默认ID_WORKER  全局唯一ID
雪花算法:

snowflake 是 Twitter 开源的分布式id生成算法,结果是个long型的id.核心思想是:使6用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在毫秒可以产生4096个ID),最后hiatus有一个符号位,永远是0,可以保证全球唯一
主键自增
我们需要配置主键自增

  • 实体类字段上@TableId(type= Idtype.AUTO)
  • 数据库字段也要是自增
其他源码解释
  1. public enum IdType {
  2.     AUTO(0),  // 数据库自增
  3.     NONE(1),  // 未设置主键
  4.     INPUT(2),  // 手动输入
  5.     ID_WORKER(3),  // 默认 雪花算法 id
  6.     UUID(4),         //
  7.     ID_WORKER_STR(5);  //字符串截取
  8.     private int key;
  9.     private IdType(int key) {
  10.         this.key = key;
  11.     }
  12.     public int getKey() {
  13.         return this.key;
  14.     }
  15. }
复制代码
更新操作

自动填充

方式一 :数据库级别   (工作中不允许你修改数据库)

  • 表中加入字段 create_time update_time    默认值为CURRENT_TIMESTAMP

方式二:代码级别

  • 删除数据库的默认值
  • 实体类字段属性上需要增加注解
    1. // 字段添加填充内容
    2. @TableField(fill = FieldFill.INSERT)
    3. private Date createTime;
    4. @TableField(fill = FieldFill.INSERT_UPDATE)
    5. private Date updateTime;
    复制代码
  • 编写处理器来处理这个注解
    1. package com.lmq.handler;
    2. import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    3. import lombok.extern.slf4j.Slf4j;
    4. import org.apache.ibatis.reflection.MetaObject;
    5. import org.springframework.stereotype.Component;
    6. import java.util.Date;
    7. /**
    8. * @author 羡鱼
    9. * @version 1.0
    10. * @date 2023/7/21 17:49
    11. */
    12. @Slf4j
    13. @Component  // 不要忘记把处理器加入到我们的ioc容器中
    14. public class MyMetaObjectHandler implements MetaObjectHandler {
    15.     // 插入时候的填充策略
    16.     @Override
    17.     public void insertFill(MetaObject metaObject) {
    18.         log.info("start insert fill 插入填充");
    19.         // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
    20.         this.setFieldValByName("createTime",new Date(),metaObject);
    21.         this.setFieldValByName("updateTime",new Date(),metaObject);
    22.     }
    23.     // 插入时候的填充策略
    24.     @Override
    25.     public void updateFill(MetaObject metaObject) {
    26.         this.setFieldValByName("updateTime",new Date(),metaObject);
    27.     }
    28. }
    复制代码


乐观锁 : 顾名思义 十分乐观 它认为不会出问题,无论干什么都不去上锁
悲观锁: 顾名思义十分悲观 他认为都会出问题 无论什么都去上锁
  1. `version` `new version`
复制代码
乐观锁实现方式

  • 取出记录时,获取当前的version
  • 更新时,带上这个version
  • 执行时 set version = newVersion where version = oldVersion
  • 如果version不对,更新失败
  1.      乐观锁 1 先查询
  2.      
  3.      -- A
  4.      update User set name = "lmq",version = version+1
  5.      where id = 2 and version = 1
  6.      -- B  线程抢线完成 这个时候 version = 2 会导致 A修改失败!
  7.      update User set name = "lmq",version = version+1
  8.      where id = 2 and version = 1
复制代码
测试一下MP中的乐观锁插件

  • 给数据库添加version字段
  • 我们实体类加对应的字段
    1. // 乐观锁的version注解
    2. @Version
    3. private Integer version;
    复制代码
  • 注册组件
    1. // Spring Boot 方式
    2. @Configuration
    3. @MapperScan("按需修改")
    4. public class MybatisPlusConfig {
    5.     /**
    6.      * 旧版
    7.      */
    8.     @Bean
    9.     public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    10.         return new OptimisticLockerInterceptor();
    11.     }
    12.     /**
    13.      * 新版
    14.      */
    15.     @Bean
    16.     public MybatisPlusInterceptor mybatisPlusInterceptor() {
    17.         MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
    18.         mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    19.         return mybatisPlusInterceptor;
    20.     }
    21. }
    复制代码
  • 测试
    1. @Test
    2. public void test2OptimisticLocker(){
    3.     // 线程1
    4.     User user = userMapper.selectById(1l);
    5.     user.setName("lmq");
    6.     user.setEmail("1435456124@qq.com");
    7.     // 模拟线程插队操作
    8.     User user2 = userMapper.selectById(1l);
    9.     user2.setName("lmq222");
    10.     user2.setEmail("LLL1435456124@qq.com");
    11.     userMapper.updateById(user2);
    12.     //自旋锁来多次尝试提交
    13.     userMapper.updateById(user);  // 如果没有乐观锁就会插队
    14. }
    复制代码
查询操作
  1.     // 查询测试
  2.     @Test
  3.     public void testSelectById() {   //单个
  4.         User user = userMapper.selectById(1L);
  5.         System.out.println(user);
  6.     }
  7.     @Test
  8.     public void testSelectByBatchId() {  // 批量查询
  9.         List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
  10.         users.forEach(System.out::println);
  11.     }
  12.     @Test
  13.     public void testSelectByBatchIds() {  //条件查询
  14.         HashMap<String, Object> map = new HashMap<>();
  15.         map.put("name", "lmq");
  16.         List<User> users = userMapper.selectByMap(map);
  17.         users.forEach(System.out::println);
  18.     }
复制代码
分页查询

网站使用十分多

  • 原始的limit进行分页
  • pageHelper 第三方的插件
  • MP内置了分页插件
如何使用

  • 导入插件
    1.     @Bean
    2.     public PaginationInterceptor paginationInterceptor() {
    3.         return new PaginationInterceptor();
    4.     }
    复制代码
  • 直接使用Page对象
    1.     //测试分页查询
    2.     @Test
    3.     public void testPage(){
    4.         // 参数一 当前页   参数二 页面大小  所有的分页变简单了
    5.         Page<User> page = new Page<>(2,5);
    6.         userMapper.selectPage(page,null);
    7.         page.getRecords().forEach(System.out::println);
    8.         System.out.println(page.getTotal());
    9.     }
    复制代码
删除操作
  1.     //测试删除
  2.     @Test
  3.     public void testDeleteById() {  // 单个id
  4.         userMapper.deleteById(1682330740093681666L);
  5.     }
  6.     @Test
  7.     public void testDeleteBatchIds() {  // 多个id
  8.         userMapper.deleteBatchIds(Arrays.asList(1L, 2L));
  9.     }
  10.     @Test
  11.     public void testDeleteByMap() {  // 通过map删除
  12.         HashMap<String, Object> map = new HashMap<>();
  13.         map.put("name", "lmq");
  14.         userMapper.deleteByMap(map);
  15.     }
  16. }
复制代码
逻辑删除

物理删除 : 从数据库中直接移除
逻辑删除: 在数据库中没有删除,而是通过一个变量来让他失效! deleted =0=>deleted =1
管理员可以看见删除记录! 防止数据丢失,类似回收站

  • 在数据库中加入deleted 字段
  • pojo 实体类中增加属性
    1.     // 逻辑删除
    2.     @TableLogic
    3.     private Integer deleted;
    复制代码
  • 配置bean
    1.     @Bean
    2.     public ISqlInjector sqlInjector() {
    3.         return new LogicSqlInjector();
    4.     }
    复制代码
  • 配置properties
    1. # 配置逻辑删除
    2. mybatis-plus.global-config.db-config.logic-delete-value=1
    3. mybatis-plus.global-config.db-config.logic-not-delete-value=0
    复制代码
性能分析插件

开发中经常遇到慢sql    测试! druid..
MP也提供性能分析插件 超过时间就停止运行

  • 导入插件
    1. @Bean
    2. @Profile({"dev", "test"}) //保证效率    设置环境
    3. public PerformanceInterceptor performanceInterceptor() {
    4.     PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    5.     performanceInterceptor.setMaxTime(100); //sql执行的最大时间  如果超过就不仔细了
    6.     performanceInterceptor.setFormat(true);
    7.     return performanceInterceptor;
    8. }
    复制代码
    1. #设置开发环境
    2. spring.profiles.active=dev
    复制代码
  • 测试使用
  1. Time:78 ms - ID:com.lmq.mapper.UserMapper.insert
  2. Execute SQL:
  3.     INSERT
  4.     INTO
  5.         user
  6.         ( id, name, age, email, create_time, update_time )
  7.     VALUES
  8.         ( 1682397170604474369, 'lmq', 21, '1435456124@qq.com', '2023-07-21 22:28:37.558', '2023-07-21 22:28:37.559' )
复制代码
条件构造器

十分重要Wrapper

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王海鱼

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表