MyBatisPlus概述
需要的基础:把我的MyBatis、Spring、SpringMVC就可以学习这个了! 为什么要学习它呢?MyBatisPlus可以节省我们大量工作时间,所有的CRUD代码它都可以自动化完成! JPA 、 tk-mapper、MyBatisPlus
偷懒的!
简介
是什么? MyBatis 本来就是简化 JDBC 操作的! 官网:https://mp.baomidou.com/ MyBatis Plus,简化 MyBatis !
快速搭建
导入依赖
<!-- mybatis-plus -->
<!-- mybatis-plus 是自己开发,并非官方的! -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
mapper继承BaseMapper
之前的Mybatis,需要写mapper接口,还需要写它的实现类,实现类中药写所有的CRUD方法,以下为Mybatis:
现在的Mybatis-plus,无须繁琐的CRUD方法,继承了BaseMapper,就已经完成了简单增删改查的方法
下面进行CRUD测试:
package com.mybatisplus.example;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mybatisplus.example.mapper.UserMapper;
import com.mybatisplus.example.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@SpringBootTest
class ExampleApplicationTests {
@Autowired
UserMapper userMapper;
@Test
void contextLoads() {
List<User> userList = userMapper.selectList(null);
userList.forEach(System.out::println);
}
@Test
public void testInsert() throws ParseException {
User user = new User();
user.setBirth("1997-10-14");
user.setGender("男");
user.setName("小马先生");
user.setRole("admin");
user.setSuggestion("所有的不平凡都来自平凡");
System.out.println(user);
int insert = userMapper.insert(user);
System.out.println(insert);
}
@Test
public void testUpdate() throws ParseException {
User user = userMapper.selectById(28);
// user.setBirth("1996-10-1");
user.setSuggestion("所有的不平凡都来自平凡");
userMapper.updateById(user);
}
@Test // 测试乐观锁 成功案例
public void testOptimisticLocker(){
//1、查询用户信息
User user = userMapper.selectById(1);
//2、修改用户信息
user.setName("刘邦");
user.setGender("女");
//3、执行更新操作
userMapper.updateById(user);
}
@Test // 测试乐观锁 失败案例---多线程下
public void testOptimisticLocker2(){
// 线程1
User user = userMapper.selectById(1);
user.setName("刘邦");
user.setGender("女");
//模拟另一个线程执行了插队操作
User user2 = userMapper.selectById(1);
user2.setName("刘备");
user2.setGender("男");
userMapper.updateById(user2);
//自旋锁来多次尝试提交
userMapper.updateById(user);// 如果没有乐观锁就会覆盖插队线程的值!
}
@Test
public void testSelectByid(){
User user = userMapper.selectById(1);
System.out.println(user);
}
@Test //批量查询固定id 集合传入
public void testSelectBuBatchId(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2));
users.forEach(System.out::println);
System.out.println("-------------");
// System.out.println(users.get(1).getName());
}
@Test //用map来指定字段查询
public void testSelectBuBatchId2(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","徐淑高");
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
@Test //测试分页查询
public void testPage(){
Page<User> page = new Page<>(1,5); //current当前页 size大小
userMapper.selectPage(page,null); //wrapper是高级查询
page.getRecords().forEach(System.out::println);
}
@Test
public void testDeleteById(){
userMapper.deleteById(28);
}
@Test
public void testDeleteMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name","小马先生");
userMapper.deleteByMap(map);
}
}
注意:
-
实体类User中,可以对该实体类进行表名绑定(如果表名和实体类名不一致时)
-
对于类建立的Getter、Setter、有参无参可以通过lombok注解来简化
-
阿里的数据库构建规范中,需要给每个表至少拥有create_time、update_time字段,这个可以通过写一个MyMetaObjectHandler类来实现官方给的MetaObjectHandler接口,覆盖重写插入时候的填充策略、更新时候的填充策略,记得用@Component丢进spring中,即可保证在插入时候、更新时候,create_time、update_time字段同步更新,无须手动写时间
-
乐观锁和分页,按照官网进行配置即可,乐观锁需要加一个version字段,在操作数据库时会判断version版本
乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题, 再次更新值测试
悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
我们这里主要讲解 乐观锁机制! 乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion 如果version不对,就更新失败
乐观锁和分页插件对应的config:
package com.mybatisplus.example.config;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@MapperScan("com.mybatisplus.example.mapper")
@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {
//------------注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
//----------分页插件
// 分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}