MyBatis-Plus 是一个基于 MyBatis 框架的增强工具,提供了一系列简化和增强的功能,用于加快开发人员在使用 MyBatis 进行数据库访问时的效率。
MyBatis-Plus 提供了一种基于注解的方式来定义和映射数据库操作,其中的注解起到了重要作用。
理解:
public interface UserMapper extends BaseMapper<User> {
}
此接口对应的方法为什么会自动触发 user 表的 crud 呢?
默认情况下, 根据指定的<实体类>的名称对应数据库表名,属性名对应数据库的列名!
但是不是所有数据库的信息和实体类都完全映射!
例如: 表名 t_user → 实体类 User 这时候就不对应了!
自定义映射关系就可以使用 mybatis-plus 提供的注解即可!
@TableName("sys_user") //对应数据库表名
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
特殊情况:如果表名和实体类名相同(忽略大小写)可以省略该注解!
其他解决方案:全局设置前缀 (https://www.baomidou.com/pages/56bac0/#基本配置)
mybatis-plus: # mybatis-plus的配置
global-config:
db-config:
table-prefix: sys_ # 表名前缀字符串
@TableName("sys_user")
public class User {
@TableId(value="主键列名",type=主键策略)
private Long id;
private String name;
private Integer age;
private String email;
}
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 主键字段名 |
type | Enum | 否 | IdType.NONE | 指定主键类型 |
值 | 描述 |
---|---|
AUTO | 数据库 ID 自增 (mysql 配置主键自增长) |
ASSIGN_ID(默认) | 分配 ID(主键类型为 Number(Long )或 String)(since 3.3.0),使用接口IdentifierGenerator 的方法nextId (默认实现类为DefaultIdentifierGenerator 雪花算法) |
mybatis-plus:
configuration:
# 配置MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 配置MyBatis-Plus操作表的默认前缀
table-prefix: t_
# 配置MyBatis-Plus的主键策略
id-type: auto
在以下场景下,添加@TableId
注解是必要的:
@TableId
注解来指定实体类中表示主键的字段。@TableId
注解,并通过value
属性指定生成策略。雪花算法(Snowflake Algorithm)是一种用于生成唯一 ID 的算法。它由 Twitter 公司提出,用于解决分布式系统中生成全局唯一 ID 的需求。
在传统的自增 ID 生成方式中,使用单点数据库生成 ID 会成为系统的瓶颈,而雪花算法通过在分布式系统中生成唯一 ID,避免了单点故障和性能瓶颈的问题。
雪花算法生成的 ID 是一个 64 位的整数,由以下几个部分组成:
时间戳:41 位,精确到毫秒级,可以使用 69 年。
节点 ID:10 位,用于标识分布式系统中的不同节点。
序列号:12 位,表示在同一毫秒内生成的不同 ID 的序号。
通过将这三个部分组合在一起,雪花算法可以在分布式系统中生成全局唯一的 ID,并保证 ID 的生成顺序性。
雪花算法的工作方式如下:
需要注意的是,雪花算法依赖于系统的时钟,需要确保系统时钟的准确性和单调性,否则可能会导致生成的 ID 不唯一或不符合预期的顺序。
雪花算法是一种简单但有效的生成唯一 ID 的算法,广泛应用于分布式系统中,如微服务架构、分布式数据库、分布式锁等场景,以满足全局唯一标识的需求。
需要记住的: 雪花算法生成的数字,需要使用 Long 或者 String 类型主键!!
@TableName("sys_user")
public class User {
@TableId
private Long id;
@TableField("nickname")
private String name;
private Integer age;
private String email;
}
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | “” | 数据库字段名 |
exist | boolean | 否 | true | 是否为数据库表字段 |
逻辑删除,可以方便地实现对数据库记录的逻辑删除而不是物理删除。逻辑删除是指通过更改记录的状态或添加标记字段来模拟删除操作,从而保留了删除前的数据,便于后续的数据分析和恢复。
ALTER TABLE USER ADD deleted INT DEFAULT 0 ; # int 类型 1 逻辑删除 0 未逻辑删除
@Data
public class User {
// @TableId
private Integer id;
private String name;
private Integer age;
private String email;
@TableLogic
//逻辑删除字段 int mybatis-plus下,默认 逻辑删除值为1 未逻辑删除 1
private Integer deleted;
}
@Data
public class User {
// @TableId
private Integer id;
private String name;
private Integer age;
private String email;
@TableLogic
//逻辑删除字段 int mybatis-plus下,默认 逻辑删除值为1 未逻辑删除 1
private Integer deleted;
}
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
逻辑删除以后,没有真正的删除语句,删除改为修改语句!
//逻辑删除
@Test
public void testQuick5(){
//逻辑删除
userMapper.deleteById(5);
}
JDBC Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@5871a482] will not be managed by Spring
==> Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 5(Integer)
<== Updates: 1
@Test
public void testQuick6(){
//正常查询.默认查询非逻辑删除数据
userMapper.selectList(null);
}
//SELECT id,name,age,email,deleted FROM user WHERE deleted=0
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
ALTER TABLE USER ADD VERSION INT DEFAULT 1 ; # int 类型 乐观锁字段
updateById(id)
与 update(entity, wrapper)
方法@Version
private Integer version;
//演示乐观锁生效场景
@Test
public void testQuick7(){
//步骤1: 先查询,在更新 获取version数据
//同时查询两条,但是version唯一,最后更新的失败
User user = userMapper.selectById(5);
User user1 = userMapper.selectById(5);
user.setAge(20);
user1.setAge(30);
userMapper.updateById(user);
//乐观锁生效,失败!
userMapper.updateById(user1);
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}
@Test
public void testQuick8(){
User user = new User();
user.setName("custom_name");
user.setEmail("xxx@mail.com");
//Caused by: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Prohibition of table update operation
//全局更新,报错
userService.saveOrUpdate(user,null);
}
MyBatis-Plus 为我们提供了强大的 mapper 和 service 模板,能够大大的提高开发效率
但是在真正开发过程中,MyBatis-Plus 并不能为我们解决所有问题,例如一些复杂的 SQL,多表联查,我们就需要自己去编写代码和 SQL 语句,我们该如何快速的解决这个问题呢,这个时候可以使用 MyBatisX 插件
MyBatisX 一款基于 IDEA 的快速开发插件,为效率而生。