mybatis plus
常用注解
官方文档写的很清楚了
https://baomidou.com/guide/annotation.html#tablename
package com.rainbow.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.time.LocalDateTime;
@TableName(value = "user")
public class User {
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
@TableField(value = "username")
private String username;
@TableField(value = "password")
private String password;
@TableField(value = "age")
private Integer age;
@TableLogic
@TableField(value = "is_delete")
private Integer isDelete;
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(value = "update_time", fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", isDelete=" + isDelete +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getIsDelete() {
return isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
public LocalDateTime getCreateTime() {
return createTime;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public LocalDateTime getUpdateTime() {
return updateTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
}
逻辑删除
文档也写的很清楚了
https://baomidou.com/guide/logic-delete.html#%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95
添加一is_delete
个字段用于标识逻辑删除
通用service
首先service接口继承通用service接口 泛型为实体类
public interface UserService extends IService<User> {
}
然后service实体类基础通用service实体类 第一个泛型为mapper接口 mapper接口中必须继承通用maper 第二个泛型为实体类
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {
}
控制台输出SQL语句
在application.yml
中配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
自动填充
实体类中添加相关注解
Handle实现 MetaObjectHandler类
不知道为何一边查询一边更新无法自动填充。。是因为事务吗?
官方文档写的很清楚了 https://baomidou.com/guide/auto-fill-metainfo.html
package com.rainbow.handle;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class MetaObjectHandle implements MetaObjectHandler {
private Logger logger = LoggerFactory.getLogger(MetaObjectHandle.class);
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
public void updateFill(MetaObject metaObject) {
logger.info("更新自动填充中....");
this.strictUpdateFill(
metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
}
}
优化
可以判断是否有字段 如果有在进行自动填充
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
if (metaObject.hasSetter("auth")) {
this.strictInsertFill(metaObject, "auth", LocalDateTime.class, LocalDateTime.now());
}
}
分页插件
配置 文档写的很清楚了
https://baomidou.com/guide/page.html
@Configuration
public class MybatisPlusPageConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor =
new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mybatisPlusInterceptor;
}
}
调用时构造一个IPage对象查询计科
IPage<User> page = new Page<>(0, 2);
IPage<User> page1 = userDao.selectPage(page, null);
乐观锁
什么时候使用乐观锁?
乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。
mybati plus 乐观锁
官网文档写的很清楚了 https://baomidou.com/guide/interceptor-optimistic-locker.html#optimisticlockerinnerinterceptor
数据库表中的默认字段默认值必须为0 否则无法更改成功
仅支持 updateById(id) 与 update(entity, wrapper) 方法
测试 我们可以设置获取两个重复的对象 并重复更新
@Test
void contextLoads() {
User user1 = userService.getById(1402460655026982913L);
User user2 = userService.getById(1402460655026982913L);
user1.setAge(111);
if(userService.updateById(user1)){
System.out.println("user1 更新成功");
} else {
System.out.println("user1 更新失败,该记录已被其他人修改!");
}
user2.setAge(222);
if(userService.updateById(user2)){
System.out.println("user2 更新成功");
} else {
System.out.println("user2 更新失败,该记录已被其他人修改!");
}
}
可以看到控制台输出 加锁成功
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律