再说一边所有的参考都来自官方文档
乐观锁
顾名思义他是很乐观的 官方给出的解释
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
取出记录时,获取当前version
更新时,带上这个version
执行更新时, set version = newVersion where version = oldVersion
如果version不对,就更新失败
我们需要先写一个配置类
@Service
public class MybatisPlusConfig {
@Bean//添加拦截器
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//在内部添加内部对象 乐观锁内部连接对象
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
实体类中添加相应的注解
//添加乐观锁注解
@Version
private Integer version;
测试 这里的version会每次默认加一
@Test
void updateOp(){
//模拟多线程的情况下
User user = userMapper.selectById(1L);
user.setName("阿牛");
//插入队
User user2 = userMapper.selectById(1L);
user2.setName("张三");
userMapper.updateById(user2);
//此时这个就不会修改成功 version已经被修改了
userMapper.updateById(user);
}
分页查询
我们只需要要在拦截器中添加代码就能实现。
DbType.MYSQL这里要使用自己的数据库
//添加分页设置
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
mapper层
extends BaseMapper 这个注解可加可不加
@Repository
public interface UserMapper extends BaseMapper<User> {
IPage<User> selectUser(Page<User> page,Integer state);
}
mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.aw.mybatisplus.mapper.UserMapper">
<select id="selectUser" resultType="com.aw.mybatisplus.model.User">
SELECT id,name FROM user WHERE state=#{state}
</select>
</mapper>
service
public interface UserService {
public IPage<User> selectUserPage(Page<User> page, Integer state);
}
@Service
public class UserServiceImp implements UserService{
@Autowired
private UserMapper userMapper;
@Override
public IPage<User> selectUserPage(Page<User> page, Integer state) {
return userMapper.selectUser(page, state);
}
}
test
@Autowired
private UserServiceImp userServiceImp;
@Test
void Page(){
// Params:
// current – 当前页
// size – 每页显示条数
Page<User> page = new Page<>(1,3);
IPage<User> userIPage = userServiceImp.selectUserPage(page, 1);
System.out.println("总共的条数:"+userIPage.getTotal());
//获取分页记录对象
userIPage.getRecords().forEach(System.out::println);
}
逻辑删除
官方说明
说明:
只对自动注入的sql起效:
插入: 不作限制
查找: 追加where条件过滤掉已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
更新: 追加where条件防止更新到已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
删除: 转变为 更新
例如:
删除: update user set deleted=1 where id = 1 and deleted=0
查找: select id,name,deleted from user where deleted=0
字段类型支持说明:
支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()
附录:
逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。
#使用方法:
application.yml
logic-delete-field: flag这个不生效 不知到位什么
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
实体类中的注解
@TableLogic
private Integer state;
test
@Test
void delete(){
int i = userMapper.deleteById(2L);
System.out.println(i);
}
性能分析
3.4.2已经更改建议使用p6spy
首先是修改配置文件
在url中添加jdbc:后面添加p6spy。
driver 更换成com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/aw?useSSL=false&useUincode=true&characterEncoding=utf-8&serverTimezone=UTC
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
我们还需要在resource目录下面创建一个spy.properties文件
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
test
@Test
void contextLoads() {
List<User> studentList = userMapper.selectList(null);
studentList.forEach(System.out::println);
}