# mybatisPlus **Repository Path**: ppNut/mybatisPlus ## Basic Information - **Project Name**: mybatisPlus - **Description**: 跟着狂神学习mybatisPlus - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2020-04-11 - **Last Updated**: 2022-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 1. # mybatisPlus学习 本文使用springBoot来整合mybatisPlus进行使用 ## 1.快速开始(第一个hello world) 1.1 创建一个user表 ```sql DROP TABLE IF EXISTS user; CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com'); ``` 1.2 导入依赖 ```xml org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.projectlombok lombok 1.18.10 provided mysql mysql-connector-java org.projectlombok lombok com.baomidou mybatis-plus-boot-starter 3.0.5 ``` 1.3 在application.properties中配置对应的数据库连接 ```properties spring.datasource.username=StudyDatabase spring.datasource.password=root spring.datasource.url=jdbc:mysql://localhost:3306/StudyDatabase?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` 1.4 编写pojo类(user) ```java @Data @AllArgsConstructor @NoArgsConstructor public class User { private Long id; private String name; private int age; private String email; } ``` 1.5 编写接口(UserMapper) ```java @Repository public interface UserMapper extends BaseMapper { } ``` 1.6 测试 ```java @SpringBootTest class MybatisplusApplicationTests { @Autowired private UserMapper userMapper; @Test void contextLoads() { List users = userMapper.selectList(null); users.forEach(System.out::println); } } ``` ​ 我看完当时学完的表情,这尼玛也太简单了吧。 ![v2-ba22e4ebc42b37bbb2140dce9a76105c_720w](./img/v2-ba22e4ebc42b37bbb2140dce9a76105c_720w.jpg) 仔细想想其实就是以下几步 1. 导入依赖mybatis-plus的依赖 2. 编写pojo类 3. 编写接口 4. 测试 #### 比起mybatis原版的操作这里少了什么? ​ 少了编写xml文件,不需要编写SQL语句, #### 为什么我们可以少写这一步呢? ​ 我们在接口上面继承了一个抽象类 extends BaseMapper ​ T 是一个泛型,往这上面丢入我们想要操作的pojo类,就可以自动生成对应的方法。 ## 2. 配置日志 日志为了让我们去查看执行的sql语句 ```properties mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ``` ## 3.CRUD扩展 ### 3.1插入操作 ```java @SpringBootTest class MybatisplusApplicationTests { @Autowired private UserMapper userMapper; @Test void contextLoads() { User user = new User(); user.setAge(20); user.setEmail("1260570909@qq.com"); user.setName("summer"); userMapper.insert(user); List users = userMapper.selectList(null); users.forEach(System.out::println); } } ``` ![1586605871205](./img/1586605871205.png) 我们发现我们没有设置id,但是mybatis-plus却给我们生成这么一串的id? ### 3.2主键生成策略 1.如何配置主键生成策略? 我们在id上面添加主键 @TableId(type = IdType.ID_WORKER),就可以配置。 ```java public class User { @TableId(type = IdType.ID_WORKER) private Long id; } ``` 2. 主键生成策略的种类: 我们可以根据需求去选择,mybatis-plus中默认的是 ID_WORKER。 使用的是一个雪花算法的方法计算出的id。 一般我们也会选择自增的策略AUTO,不过我们要记得在数据库的主键上添加自增的属性 ```java AUTO(0), NONE(1), INPUT(2), ID_WORKER(3), UUID(4), ID_WORKER_STR(5); ``` ### 注意点: ```java private Long id; ``` id 要写为long 类型的数据 不然会报错 mybatis-plus中会自动帮我们生产id,但是id类型是long ,不是int型的 ### 3.3更新操作 ```java @Test void updatamybatis(){ User user = new User(); user.setId(20L); user.setName("summer"); int update = userMapper.updateById(user); System.out.println(update); List users = userMapper.selectList(null); users.forEach(System.out::println); } ``` mybatis-plus 会帮我们自动生成SQL语句 ### 3.4自动填充 在我们的数据库字段中都会有create_time, update_time这两个字段,我们希望他可以自己改变,而不是我们手动的改变 1.数据库级别 ​ 我们在数据中将这两个字段设置为如下就数据库就会自动更新了 ![Snipaste_2020-04-11_22-28-11](./img/Snipaste_2020-04-11_22-28-11.png) 2.代码级别 ​ 以往我们都会用new Data来更新,这样又笨重有麻烦,而且会忘记。 ​ 现在我们可以自动填充了 1.在代码上写上注解 ```java @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; ``` 2.编写配置类 ```java @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime",new Date(),metaObject); } } ``` 3.测试运行 ```java @Test void contextLoads() { User user = new User(); user.setAge(20); user.setEmail("1260570909@qq.com"); user.setName("summer"); userMapper.insert(user); List users = userMapper.selectList(null); users.forEach(System.out::println); } ``` ![Snipaste_2020-04-12_09-30-14](./img/Snipaste_2020-04-12_09-30-14.png) 自动填充成功!! ### 3.5乐观锁 乐观锁:认为什么都不会出现问题,什么都不会加锁,只有出现问题之后才会去更新对应的值。 悲观锁:认为什么都是会出问题的,什么操做都会加锁。 ##### mysql 中我们如何实现乐观锁? 1.我们在表中的加入字段version 2.在spring中注册乐观锁 ```java @EnableTransactionManagement @Configuration // 配置类 public class MyBatisPlusConfig { // 注册乐观锁插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } } ``` 3.模拟插队的情况: ```java @Test void versionTest() { User user = userMapper.selectById(20L); user.setAge(20); user.setEmail("212121@qq.com"); user.setName("pppnut"); User user2 = userMapper.selectById(20L); user.setAge(20); user.setEmail("212121@qq.com"); user.setName("蜜桃"); userMapper.updateById(user2); userMapper.updateById(user); } ``` ``` ​```sql UPDATE user SET name=?, age=?, email=?, version=?, update_time=? WHERE id=? AND version=? ``` 上述是执行的sql语句,先查数据库中的版本好是否和现在的一致,一致就说明之前没有人对我的数据进行修改,不一致就说明我们的数据被修改,现在的操作取消 ### 3.6查询操作 ```java @Test void selectTest() { //根据id查询 User user = userMapper.selectById(20L); //根据id批量查询 List users = userMapper.selectBatchIds(Arrays.asList(26L,27L,28L)); //根据map的条件查询 HashMap map = new HashMap<>(); map.put("name","夏天"); map.put("age",0); List users1 = userMapper.selectByMap(map); System.out.println(user); users.forEach(System.out::println); users1.forEach(System.out::println); } ``` ### 3.7分页查询 如何使用? 1.在mybatis-plus中添加分页插件 ```java //分页插件 @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } ``` 2. ```java @Test void pageTest() { Page userPage = new Page<>(1,4); userMapper.selectPage(userPage, null); userPage.getRecords().forEach(System.out::println); System.out.println(userPage.getTotal()); System.out.println(userPage.getSize()); } ``` ### 3.8删除操作 ```java @Test void deleteTest(){ //通过id删除 int i = userMapper.deleteById(1); //批量删除 int i1 = userMapper.deleteBatchIds(Arrays.asList(11,12,13)); HashMap map = new HashMap<>(); map.put("name","夏天"); map.put("age",20); //条件删除 int i2 = userMapper.deleteByMap(map); System.out.println(i); System.out.println(i1); System.out.println(i2); } ``` ### 3.9逻辑删除 管理员可以查看被删除的记录!防止数据的丢失,类似于回收站! 1.在数据库中添加字段deleted 2.添加类 ```java @TableLogic //逻辑删除 private Integer deleted; ``` 3.配置 ```java // 逻辑删除组件! @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); } ``` ```xml # 配置逻辑删除 mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0 ``` ## 4.条件构造器wrapper 写一些复杂的sql就可以使用它来替代! ```java Wrapper Wrapper = new Wrapper<>(); ``` ##### 基本的条件: 1. 大于 > Greater than #gt 2. 小于 < Less than #lt 3. 等于 = Equals #qe 类比ge,le,ne 4. between 5. notBetween 6. like ...... 其他去官网查找 https://mp.baomidou.com/guide/wrapper.html#setsql