MyBatisPlus笔记

火影  金牌会员 | 2022-10-11 20:48:32 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 850|帖子 850|积分 2550

MyBatisPlus

快速入门

1.创建数据库mybatisplus

2.创建user表并插入数据
  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. );
  10. INSERT INTO user (id, name, age, email) VALUES
  11. (1, 'Jone', 18, 'test1@baomidou.com'),
  12. (2, 'Jack', 20, 'test2@baomidou.com'),
  13. (3, 'Tom', 28, 'test3@baomidou.com'),
  14. (4, 'Sandy', 21, 'test4@baomidou.com'),
  15. (5, 'Billie', 24, 'test5@baomidou.com');
  16. -- 真实开发中一般还需要version(乐观锁)、deleted(逻辑删除)、gmt_create、gmt_modified
复制代码
3.初始化SpringBoot项目

4.导入依赖

尽量不要同时导入mybatis和mybatisplus的依赖
  1. <dependency>
  2.     <groupId>mysql</groupId>
  3.     <artifactId>mysql-connector-java</artifactId>
  4. </dependency>
  5. <dependency>
  6.     <groupId>org.projectlombok</groupId>
  7.     <artifactId>lombok</artifactId>
  8. </dependency>
  9. <dependency>
  10.     <groupId>com.baomidou</groupId>
  11.     <artifactId>mybatis-plus-boot-starter</artifactId>
  12.     <version>3.0.5</version>
  13. </dependency>
复制代码
5.连接数据库

application.properties
  1. # mysql 5 驱动不同 com.mysql.jdbc.Driver
  2. # mysql 8 驱动不同com.mysql.cj.jdbc.Driver、需要增加时区的配置serverTimezone=GMT%2B8
  3. spring.datasource.username=root
  4. spring.datasource.password=123456
  5. spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  6. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
复制代码
6.传统方式pojo-dao(连接mybatis,配置mapper.xml文件)-service-controller
6.使用MyBatisPlus


  • pojo
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class User {
  5.     private Long id;
  6.     private String name;
  7.     private Integer age;
  8.     private String email;
  9. }
复制代码

  • mapper接口
  1. @Repository//持久层
  2. public interface UserMapper extends BaseMapper<User> {
  3. }
复制代码

  • 测试类
首先在主类中配置mapper扫描@MapperScan("com.xust.mapper")
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.     @Autowired
  4.     private UserMapper userMapper;
  5.     @Test
  6.     void contextLoads() {
  7.         //参数是一个Wrapper,条件构造器,这里先不用
  8.         List<User> users=userMapper.selectList(null);
  9.         users.forEach(System.out::println);
  10.     }
  11. }
复制代码
配置日志

在开发中使用,通过日志查看sql如何执行
applicatiohn.properties
  1. mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
复制代码
CRUD扩展

插入
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.         // 测试插入
  4.     @Test
  5.     public void testInsert() {
  6.         User user = new User();
  7.         user.setName("xust");
  8.         user.setAge(3);
  9.         user.setEmail("24736743@qq.com");
  10.         int result = userMapper.insert(user); // 帮我们自动生成id
  11.         System.out.println(result); // 受影响的行数
  12.         System.out.println(user); // 发现,id会自动回填
  13.     }
  14. }
复制代码
更新
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.     @Autowired
  4.     private UserMapper userMapper;
  5.     //测试更新
  6.     @Test
  7.     public void testUpdate(){
  8.         User user = new User();
  9.         user.setId(1L);
  10.         user.setName("xxx");
  11.         userMapper.updateById(user);
  12.     }
  13. }
复制代码
自动填充

创建时间、修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新
我这里使用的是SQLyog
数据库级别操作


代码级别操作

1.首先恢复清除数据库中默认值和更新效果
2.实体类字段属性上需要增加注解
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class User {
  5.     @TableId(type = IdType.INPUT)      //一旦手动输入id后就需要自己配置id了
  6.     private Long id;
  7.     private String name;
  8.     private Integer age;
  9.     private String email;
  10.     @TableField(fill= FieldFill.INSERT)     //插入时自动填充
  11.     private Date createTime;
  12.     @TableField(fill= FieldFill.INSERT_UPDATE)      //插入和更新时自动填充
  13.     private Date updateTime;
  14. }
复制代码
3.编写处理器来处理这个注解
  1. @Slf4j
  2. @Component  //将处理器加入到IOC容器中
  3. public class MyMetaObjectHandler implements MetaObjectHandler {
  4.     //插入时的填充策略
  5.     @Override
  6.     public void insertFill(MetaObject metaObject) {
  7.         log.info("start insert fill...........");
  8.         this.setFieldValByName("createTime",new Date(),metaObject);
  9.         this.setFieldValByName("updateTime",new Date(),metaObject);
  10.     }
  11.     //更新时的填充策略
  12.     @Override
  13.     public void updateFill(MetaObject metaObject) {
  14.         log.info("start update fill...........");
  15.         this.setFieldValByName("updateTime",new Date(),metaObject);
  16.     }
  17. }
复制代码
乐观锁

意图:

当更新一条数据时,希望这条数据没有被其他人更新。


  • 乐观锁:它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新值测试
  • 悲观锁:它总是认为总是出现问题,无论干什么都会上锁!再去操作
乐观锁实现方式:


  • 取出记录时,获取当前version
  • 更新时带上version
  • 执行更新时,set version=newVersion where version=oldVersion
  • 如果version不对,就更新失败
  1. 乐观锁:1、先查询,获得版本号 version = 1
  2. -- A
  3. update user set name = "kuangshen", version = version + 1
  4. where id = 2 and version = 1
  5. -- B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
  6. update user set name = "kuangshen", version = version + 1
  7. where id = 2 and version = 1
复制代码
测试

1. 数据库添加version字段


2.实体类加对应字段
  1. @Version //乐观锁Version注解
  2. private Integer version;
复制代码
3.注册组件
  1. @EnableTransactionManagement
  2. @Configuration // 配置类
  3. public class MyBatisPlusConfig { // 注册乐观锁插件
  4.     @Bean
  5.     public OptimisticLockerInterceptor optimisticLockerInterceptor() {
  6.         return new OptimisticLockerInterceptor();
  7.     }
  8. }
复制代码
4.测试
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.     @Autowired
  4.     private UserMapper userMapper;
  5.     //测试乐观锁成功
  6.     @Test
  7.     public void testOptimisticLocker(){
  8.         //查询用户信息
  9.         User user = userMapper.selectById(1L);
  10.         //修改用户信息
  11.         user.setName("yyy");
  12.         user.setEmail("111@qq.com");
  13.         //执行更新操作
  14.         userMapper.updateById(user);
  15.     }
  16.     //测试乐观锁失败
  17.     @Test
  18.     public void testOptimisticLocker2(){
  19.         //A
  20.         User user = userMapper.selectById(1L);
  21.         user.setName("yyy1");
  22.         user.setEmail("123@qq.com");
  23.         //B,模拟另外一个线程执行了插队操作
  24.         User user2 = userMapper.selectById(1L);
  25.         user2.setName("yyy2");
  26.         user2.setEmail("222@qq.com");
  27.         //B执行更新
  28.         userMapper.updateById(user2);
  29.         //A执行更新,如果没有乐观锁就会更新
  30.         userMapper.updateById(user);
  31.     }
  32. }
复制代码
查询操作
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.     @Autowired
  4.     private UserMapper userMapper;
  5.     // 测试查询
  6.     @Test
  7.     public void testSelectById() {
  8.         User user = userMapper.selectById(1L);
  9.         System.out.println(user);
  10.     }
  11.     // 测试批量查询!
  12.     @Test
  13.     public void testSelectByBatchId() {
  14.         List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
  15.         users.forEach(System.out::println);
  16.     }
  17.     // 按条件查询之使用map操作
  18.     @Test
  19.     public void testSelectByBatchIds() {
  20.         HashMap<String, Object> map = new HashMap<>();
  21.         // 自定义要查询
  22.         map.put("name", "ccc");
  23.         map.put("age", 3);
  24.         List<User> users = userMapper.selectByMap(map);
  25.         users.forEach(System.out::println);
  26.     }
  27. }
复制代码
分页查询

1.配置拦截器组件

MyBatisPlusConfig.java
  1. @Bean
  2. public PaginationInterceptor paginationInterceptor() {
  3.     return new PaginationInterceptor();
  4. }
复制代码
2.直接使用Page对象
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.     @Autowired
  4.     private UserMapper userMapper;
  5.     //测试分页查询
  6.     @Test
  7.     public void testPage(){
  8.         //参数一:当前页
  9.         //参数二:显示条数
  10.         Page<User> page=new Page<>(1,3);
  11.         userMapper.selectPage(page,null);
  12.         //打印当前页
  13.         page.getRecords().forEach(System.out::println);
  14.         //打印总数
  15.         System.out.println(page.getTotal());
  16.     }
  17. }
复制代码
删除操作

根据id删除
  1. @SpringBootTest
  2. class MybatisPlusApplicationTests {
  3.     @Autowired
  4.     private UserMapper userMapper;
  5.     //测试删除
  6.     @Test
  7.     public void testDeleteById() {
  8.         userMapper.deleteById(1579436224978829314L);
  9.     }
  10.     //批量删除
  11.     @Test
  12.     public void testDeleteBatchId() {
  13.         userMapper.deleteBatchIds(Arrays.asList(1579459015811768322L, 1579459015811768324L));
  14.     }
  15.     //条件删除map操作
  16.     @Test
  17.     public void testDeleteMap() {
  18.         HashMap<String, Object> map = new HashMap<>();
  19.         map.put("name", "ccc");
  20.         userMapper.deleteByMap(map);
  21.     }
  22. }
复制代码
逻辑删除

物理删除:从数据库中直接移除
逻辑删除:在数据库中没有直接移除,通过一个变量使其失效
1.在数据库表中增加一个deleted字段,为0表示没删


2.实体类中增加属性
  1. @TableLogic //逻辑删除
  2. private Integer deleted;
复制代码
3.配置

MyBatisPlusConfig.java
  1. // 逻辑删除组件!
  2. @Bean
  3. public ISqlInjector sqlInjector() {
  4.     return new LogicSqlInjector();
  5. }
复制代码
application.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
复制代码
4.测试

执行之前的删除操作,实际上进行的是update操作
性能分析插件

平时开发时会遇到一些慢SQL
作用:性能分析拦截器,用于输出每条 SQL 语句及其执行时间
在测试和开发环境下使用
1.设置开发环境

application.properties
  1. spring.profiles.active=dev
复制代码
2.导入插件

MyBatisPlusConfig.java
  1. @Bean
  2. @Profile({"dev","test"})    //设置在dev、test环境开启,保证效率
  3. public PerformanceInterceptor performanceInterceptor(){
  4.     PerformanceInterceptor performanceInterceptor=new PerformanceInterceptor();
  5.     performanceInterceptor.setMaxTime(100);    //设置SQL执行的最大时间,超过则不执行
  6.     performanceInterceptor.setFormat(true); //是否开启格式化,让SQL查看起来更方便
  7.     return performanceInterceptor;
  8. }
复制代码
条件构造器(Wrapper)

比较重要,写复杂的SQL可以用它来代替
[code]@SpringBootTestpublic class WrapperTest {    @Autowired    private UserMapper userMapper;    @Test    void contextLoads() {        //查询name不为空,email不为空,且年龄大于等于12的        QueryWrapper wrapper=new QueryWrapper();        wrapper.isNotNull("name")                .isNotNull("email")                .ge("age",12);        userMapper.selectList(wrapper);    }    @Test    void test2() {        //查询name为Tom的        QueryWrapper wrapper=new QueryWrapper();        wrapper.eq("name","Tom");        User user = userMapper.selectOne(wrapper);        System.out.println(user);    }    @Test    void test3() {        //查询年龄20~30的人        QueryWrapper wrapper=new QueryWrapper();        wrapper.between("age",20,30);        Integer count= userMapper.selectCount(wrapper);//查询结果数        System.out.println(count);    }    //模糊查询    @Test    void test4() {        //name中不包含o,且email以t开头        QueryWrapper wrapper=new QueryWrapper();        wrapper.notLike("name","o")                .likeRight("email","t");    //相当于t%        List maps= userMapper.selectMaps(wrapper);        maps.forEach(System.out::println);    }    @Test    void test5() {        QueryWrapper wrapper=new QueryWrapper();        //id在子查询中查出来        wrapper.inSql("id","select id from user where id

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

火影

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

标签云

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