概述
MyBatis-Plus(简称 MP)是一个基于 MyBatis 的增强工具,旨在简化开发、提高效率。它在 MyBatis 的基础上提供了许多实用的功能,如自动生成代码、强大的 CRUD 操作、分页插件、性能分析插件等。以下是 MyBatis-Plus 的核心知识点:
1.核心特性
- 无侵入:只做增强不做改变,引入 MyBatis-Plus 不会影响现有 MyBatis 功能。
- 强大的 CRUD 操作:内置通用 Mapper 和 Service,只需少量配置即可实现单表大部分 CRUD 操作。
- 支持 Lambda 表达式:通过 Lambda 表达式编写查询条件,避免字段硬编码。
- 自动分页:内置分页插件,支持多种数据库的分页查询。
- SQL 注入器:支持自定义全局 SQL 方法注入。
- ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行 CRUD 操作。
- 代码生成器:自动生成 Entity、Mapper、Service、Controller 等代码,减少重复工作。
- 性能分析插件:支持 SQL 性能分析,输出 SQL 语句及其执行时间。
2. 核心组件
- BaseMapper:提供通用的 CRUD 方法,开发者只需继承
BaseMapper即可使用。 - IService:Service 层接口,提供更丰富的业务层方法。
- ServiceImpl:Service 层实现类,继承后可直接使用。
- QueryWrapper:用于构建查询条件,支持链式调用。
- LambdaQueryWrapper:基于 Lambda 表达式的查询条件构造器,避免字段硬编码。
- UpdateWrapper:用于构建更新条件。
- Page:分页对象,用于分页查询。
3. 常用注解
- @TableName:指定数据库表名。
- @TableId:指定主键字段,支持主键策略(如自增、UUID 等)。
- @TableField:指定数据库字段名,支持字段填充策略(如自动填充创建时间、更新时间)。
- @Version:乐观锁注解,用于实现乐观锁机制。
- @EnumValue:枚举类注解,用于标识枚举值与数据库字段的映射关系。
4. CRUD 操作
- 插入:
insert(T entity) - 删除:
deleteById(Serializable id)、deleteByMap(Map<String, Object> columnMap)、delete(Wrapper<T> wrapper) - 更新:
updateById(T entity)、update(T entity, Wrapper<T> wrapper) - 查询:
selectById(Serializable id)、selectOne(Wrapper<T> wrapper)、selectList(Wrapper<T> wrapper) - 分页查询:
selectPage(Page<T> page, Wrapper<T> wrapper)
5. 条件构造器
-
QueryWrapper:用于构建查询条件。
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name", "张三").ge("age", 18); List<User> userList = userMapper.selectList(queryWrapper); -
LambdaQueryWrapper:基于 Lambda 表达式的条件构造器。
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.eq(User::getName, "张三").ge(User::getAge, 18); List<User> userList = userMapper.selectList(lambdaQueryWrapper);
6. 分页插件
-
配置分页插件:
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } -
使用分页:
Page<User> page = new Page<>(1, 10); // 当前页,每页大小 IPage<User> userPage = userMapper.selectPage(page, null); List<User> userList = userPage.getRecords();
7. 代码生成器
-
通过代码生成器自动生成 Entity、Mapper、Service、Controller 等代码。
java
复制
AutoGenerator generator = new AutoGenerator(); generator.setGlobalConfig(globalConfig); generator.setDataSource(dataSourceConfig); generator.setPackageInfo(packageConfig); generator.setStrategy(strategyConfig); generator.execute();
8. 乐观锁
-
使用
@Version注解实现乐观锁。@Version private Integer version; -
配置乐观锁插件:
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }
9. SQL 注入器
-
自定义全局 SQL 方法:
public class MySqlInjector extends DefaultSqlInjector { @Override public List<AbstractMethod> getMethodList(Class<?> mapperClass) { List<AbstractMethod> methodList = super.getMethodList(mapperClass); methodList.add(new MyCustomMethod()); return methodList; } }
10. 常见问题
- 主键策略:默认使用雪花算法生成主键,支持自增、UUID 等。
- 字段映射:数据库字段名与实体类字段名不一致时,使用
@TableField注解。 - 逻辑删除:通过
@TableLogic注解实现逻辑删除。 - 多数据源:需要额外配置多数据源支持。
11. 性能优化
- 使用缓存(如 Redis)减少数据库查询。
- 避免 N+1 查询问题,使用
@TableField(exist = false)标注非数据库字段。 - 使用索引优化查询性能。
12. 与其他框架集成
- Spring Boot:通过
mybatis-plus-boot-starter快速集成。 - Spring Cloud:结合分布式服务框架使用。
- Swagger:自动生成 API 文档。
13.一级/二级缓存
MyBatis 提供了缓存机制来优化数据库查询性能,主要包括一级缓存和二级缓存。以下是它们的核心知识点:
1. 一级缓存
-
定义:一级缓存是 SqlSession 级别 的缓存,默认开启。
-
作用范围:同一个 SqlSession 中有效。
-
生命周期:
- 当 SqlSession 执行
flush(如执行commit、close或clearCache)时,缓存会被清空。 - 当执行
update、insert、delete操作时,缓存也会被清空。
- 当 SqlSession 执行
-
特点:
- 同一个 SqlSession 中,多次执行相同的 SQL 查询,只会查询一次数据库,后续直接从缓存中获取结果。
- 一级缓存是 MyBatis 默认开启的,无需额外配置。
-
示例:
SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 第一次查询,会访问数据库 User user1 = userMapper.selectById(1); // 第二次查询,直接从一级缓存中获取 User user2 = userMapper.selectById(1); sqlSession.close();
2. 二级缓存
-
定义:二级缓存是 Mapper 级别 的缓存,多个 SqlSession 共享。
-
作用范围:同一个 Mapper 的多个 SqlSession 之间共享。
-
生命周期:
- 二级缓存的生命周期与整个应用相同,只有当数据被更新(如
update、insert、delete)时,缓存才会被清空。
- 二级缓存的生命周期与整个应用相同,只有当数据被更新(如
-
特点:
- 二级缓存需要手动开启。
- 二级缓存可以跨 SqlSession 共享数据。
- 二级缓存默认使用 PerpetualCache 作为缓存实现,但可以配置为其他缓存实现(如 Ehcache、Redis 等)。
-
配置:
-
在 MyBatis 配置文件中启用二级缓存:
<settings> <setting name="cacheEnabled" value="true"/> </settings>运行 HTML
-
在 Mapper XML 文件中配置缓存:
<mapper namespace="com.example.UserMapper"> <cache/> </mapper>运行 HTML
-
实体类需要实现
Serializable接口,因为二级缓存可能将数据序列化到磁盘或通过网络传输。public class User implements Serializable { private static final long serialVersionUID = 1L; // 其他字段 }
-
-
示例:
SqlSession sqlSession1 = sqlSessionFactory.openSession(); UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class); User user1 = userMapper1.selectById(1); sqlSession1.close(); // 关闭 SqlSession1,此时数据会存入二级缓存 SqlSession sqlSession2 = sqlSessionFactory.openSession(); UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = userMapper2.selectById(1); // 从二级缓存中获取数据 sqlSession2.close();
3. 一级缓存 vs 二级缓存
| 特性 | 一级缓存 | 二级缓存 |
|---|---|---|
| 作用范围 | SqlSession 级别 | Mapper 级别 |
| 生命周期 | SqlSession 生命周期内有效 | 应用生命周期内有效 |
| 共享性 | 不共享,仅当前 SqlSession 可用 | 多个 SqlSession 共享 |
| 默认开启 | 是 | 否 |
| 配置方式 | 无需配置 | 需在 Mapper XML 中配置 <cache/> |
| 适用场景 | 单会话内重复查询 | 跨会话共享数据 |
4. 缓存注意事项
-
脏读问题:
- 一级缓存和二级缓存都可能存在脏读问题(即缓存数据与数据库不一致)。
- 解决方法:在更新操作后手动清空缓存。
-
缓存失效:
- 当执行
update、insert、delete操作时,缓存会自动清空。
- 当执行
-
缓存策略:
-
可以通过配置
<cache>标签的属性来设置缓存策略,如:<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>运行 HTML
eviction:缓存回收策略(如 FIFO、LRU)。flushInterval:缓存刷新间隔(毫秒)。size:缓存大小。readOnly:是否只读。
-
5. 自定义缓存
-
MyBatis 支持自定义缓存实现,只需实现
org.apache.ibatis.cache.Cache接口,并在 Mapper XML 中指定:<cache type="com.example.MyCustomCache"/>
6. 性能优化建议
-
一级缓存:
- 适合单会话内重复查询的场景。
- 避免在长时间会话中缓存大量数据,可能导致内存溢出。
-
二级缓存:
- 适合跨会话共享数据的场景。
- 注意缓存的数据量,避免占用过多内存。
- 对于频繁更新的数据,不建议使用二级缓存。
封装springboot-start-mybatis
涉及技术栈
- SpringBootStarter的核心原理
- mybatis
- mybatisPlus
- myBatisPlus-Join
- Maven依赖管理
- mysql
- Druid
实现功能
- 添加分页插件
- 自动填充参数类
环境搭建
1. 新建一个的maven项目
目录结构
在pom.xml导入相关依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.byd</groupId>
<artifactId>frame-framework</artifactId>
<version>${revision}</version>
</parent>
<artifactId>frame-spring-boot-starter-mybatis</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.byd</groupId>
<artifactId>module-common</artifactId>
<version>${revision}</version>
<scope>provided</scope>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>com.byd</groupId>
<artifactId>frame-spring-boot-starter-web</artifactId>
<version>${revision}</version>
<scope>provided</scope> <!-- 设置为 provided,只有 OncePerRequestFilter 使用到 -->
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<optional>true</optional>
</dependency>
<!-- MyBatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<!-- MyBatis 联表查询 -->
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
</dependency>
<!-- Druid 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<!-- H2-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<name>frame-spring-boot-starter-mybatis</name>
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
</project>
这里主要是新建一个maven项目将关于mybatisPlus相关依赖导入
2.新建一个SpringBoot项目
目录结构
在pom.xml导入刚刚新建的maven项目
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.byd</groupId>
<artifactId>frame_parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>test-mybatisplus-demo</artifactId>
<name>test-mybatisplus-demo</name>
<url>http://maven.apache.org</url>
<dependencies>
<!--自定义的mybatis-->
<dependency>
<groupId>com.byd</groupId>
<artifactId>frame-spring-boot-starter-mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
按照常规SpringBoot整合MabytisPlus的方式先把项目数据查出来
3.测试
按照以上步骤完成基本环境搭建后 我们来新增一些功能
扩展功能
1.添加分页插件
编写自动装配的配置类
@SuppressWarnings("SpringComponentScan")
@Configuration
@MapperScan(value = "${frame.info.base-package}", annotationClass = Mapper.class, // 动态配置mapper扫描路径
lazyInitialization = "${mybatis.lazy-initialization:false}") // Mapper 懒加载,目前仅用于单元测试
public class MybatisAutoConfiguration {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
return interceptor;
}
}
MybatisPlusInterceptor是MyBatis-Plus中的一个重要类,它用于配置和注册MyBatis-Plus的拦截器。拦截器是MyBatis提供的一种机制,允许你在SQL执行的不同阶段插入自定义的逻辑。MybatisPlusInterceptor的主要方法
- addInnerInterceptor(InnerInterceptor interceptor) :添加一个内部拦截器。内部拦截器可以拦截SQL语句的执行过程,包括SQL语句的生成、参数的设置、结果的映射等。
- addInnerInterceptor(int index, InnerInterceptor interceptor) :在指定位置添加一个内部拦截器。
- removeInnerInterceptor(InnerInterceptor interceptor) :移除一个内部拦截器。
- removeInnerInterceptor(int index) :移除指定位置的内部拦截器。
- clearInnerInterceptors() :清除所有的内部拦截器。
测试
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoTest {
@Autowired
private AdminUserMapper userMapper;
@Test
public void test() {
Page<AdminUserDO> adminUserDOPage = new Page<>(1, 10);
Page<AdminUserDO> adminUserDOPage1 = userMapper.selectPage(adminUserDOPage, null);
System.out.println(adminUserDOPage1);
}
}
MyBatis-Plus扩展知识
内置拦截器
MyBatis-Plus提供了一些内置的拦截器,你可以直接使用它们,也可以根据自己的需求自定义拦截器。以下是一些常用的内置拦截器:
- PaginationInnerInterceptor:用于处理分页查询。
- TenantLineInnerInterceptor:用于处理多租户。
- OptimisticLockerInnerInterceptor:用于处理乐观锁。
- PerformanceInnerInterceptor:用于性能分析
- DataPermissionInterceptor: 数据权限插件
自定义拦截器
InnerInterceptor接口概述
InnerInterceptor是Mybatis-Plus对Mybatis原生Interceptor接口的增强、提供了更细粒度的拦截方法。它提供MybatisPlusInterceptor统一管理所有插件、每个插件通过现实innerInterceptor接口定义拦截逻辑
核心方法
willDoQuery()/willDoUpdate():判断是否执行查询或更新操作beforeQuery()/beforeUpdate():在sql执行前修改SQL或参数beforePrepare():在sql准备阶段拦截(如设置事务超时)beforeGetBoundSql(): 在获取BoundSql前拦截(如动态表名)
BoundSql是 MyBatis 中的一个核心类,它在 SQL 语句与参数绑定后生成,主要用于表示最终执行的 SQL 语句及其对应的参数映射。当你通过 MyBatis 执行一个查询或更新操作时,MyBatis 首先会解析你定义的 SQL 模板和参数,然后将这些参数绑定到 SQL 语句中形成可直接执行的 SQL 语句,这个结果就是BoundSql对象。
内置插件与使用场景
MyBatis-Plus 提供了多个内置的 InnerInterceptor 实现类,覆盖常见需求:
(1) 分页插件(PaginationInnerInterceptor)
-
功能:自动添加
LIMIT和OFFSET分页语句,支持多数据库类型。 -
配置示例:
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } -
使用:在 Mapper 方法中传入
Page<T>对象即可自动分页25。
(2) 防全表操作插件(BlockAttackInnerInterceptor)
-
功能:阻止无
WHERE条件的全表更新/删除操作。 -
配置示例:
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); -
效果:若执行
update或delete无WHERE条件,抛出异常25。
(3) 数据权限插件(DataPermissionInterceptor)
-
功能:根据用户权限动态添加 SQL 过滤条件(如部门、角色)。
-
实现步骤:
-
自定义
DataPermissionHandler接口,实现getSqlSegment()方法。 -
将
DataPermissionInterceptor添加到插件链中:DataPermissionInterceptor dataInterceptor = new DataPermissionInterceptor(); dataInterceptor.setDataPermissionHandler(new CustomDataPermissionHandler()); interceptor.addInnerInterceptor(dataInterceptor);
-
-
示例:根据用户部门动态拼接
AND dept_id = ?。
(4) 其他插件
- 乐观锁(
OptimisticLockerInnerInterceptor) :通过@Version注解实现版本控制。 - 动态表名(
DynamicTableNameInnerInterceptor) :根据条件动态替换表名52。
自定义 InnerInterceptor
若内置插件不满足需求,可自定义插件。以下是实现步骤:
(1) 继承 InnerInterceptor 接口
public class CustomInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
// 修改 SQL 或参数
String sql = boundSql.getSql();
sql = sql.replace("old_table", "new_table");
PluginUtils.mpBoundSql(boundSql).sql(sql);
}
}
(2) 注册插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new CustomInterceptor());
return interceptor;
}
4. 插件执行顺序与注意事项
-
执行顺序:插件按添加顺序执行,建议顺序为:
- 多租户、动态表名插件
- 分页、乐观锁插件
- 防全表更新、性能分析插件25。
-
性能影响:避免在插件中执行耗时操作(如远程调用)。
-
配置冲突:若同时使用 MyBatis 原生插件和
InnerInterceptor,需注意拦截器链的优先级79。
5. 实际应用案例
案例:SQL 性能监控
通过 PerformanceInterceptor 监控慢查询:
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(1000); // 设置 SQL 最大执行时间(毫秒)
interceptor.addInnerInterceptor(performanceInterceptor);
- 日志输出:超时 SQL 会记录警告信息25。
总结
InnerInterceptor 是 MyBatis-Plus 扩展功能的核心接口,通过合理配置内置插件或自定义实现,可以实现分页、数据权限、SQL 优化等高级功能。使用时需注意插件顺序和性能影响,结合业务场景灵活选择插件组合。
2. 配置日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.配置自动填充参数类
/**
* 装配 自动填充参数类
*/
@Bean
public MetaObjectHandler defaultMetaObjectHandler() {
return new DefaultDBFieldHandler();
}
}
/**
* 通用参数填充实现类
*
* 如果没有显式的对通用参数进行赋值,这里会对通用参数进行填充、赋值
*
* @author hexiaowu
*/
public class DefaultDBFieldHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
if (Objects.nonNull(metaObject) && metaObject.getOriginalObject() instanceof BaseDO) {
BaseDO baseDO = (BaseDO) metaObject.getOriginalObject();
LocalDateTime current = LocalDateTime.now();
// 创建时间为空,则以当前时间为插入时间
if (Objects.isNull(baseDO.getCreateTime())) {
baseDO.setCreateTime(current);
}
// 更新时间为空,则以当前时间为更新时间
if (Objects.isNull(baseDO.getUpdateTime())) {
baseDO.setUpdateTime(current);
}
Long userId = WebFrameworkUtils.getLoginUserId();
// 当前登录用户不为空,创建人为空,则当前登录用户为创建人
if (Objects.nonNull(userId) && Objects.isNull(baseDO.getCreator())){
baseDO.setCreator(userId.toString());
}
// 当前登录用户不为空,更新人为空,则当前登录用户为更新人
if (Objects.nonNull(userId) && Objects.isNull(baseDO.getUpdater())) {
baseDO.setUpdater(userId.toString());
}
}
}
@Override
public void updateFill(MetaObject metaObject) {
// 更新时间为空,则以当前时间为更新时间
Object modifyTime = getFieldValByName("updateTime", metaObject);
if (Objects.isNull(modifyTime)) {
setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
}
// 当前登录用户不为空,更新人为空,则当前登录用户为更新人
Object modifier = getFieldValByName("updater", metaObject);
Long userId = WebFrameworkUtils.getLoginUserId();
if (Objects.nonNull(userId) && Objects.isNull(modifier)) {
setFieldValByName("updater", userId.toString(), metaObject);
}
}
}
4.主键策略
概述
MyBatis-Plus的主键策略用于自动生成数据库表的主键值、简化开发并确保数据唯一性。以下是主键策略的作用、常见策略及选择建议:
一、常见的主键策略
1.自动递增
- Mysql:使用
AUTO_INCREMENT关键字定义自动增长的整数作为主键 - PostgreSQL:
SERIAL或BIGSERIAL类型来实现自动递增 - SQL Server: 使用
IDENTITY属性来指定列自动递增 - Oracle: 没有直接的自动递增特性,但是可以通过序列和触发器实现
使用场景
- 单实例或主从复制环境下的应用。
- 需要简单且高效地生成唯一标识符的情况。
- 对性能要求较高,尤其是写操作频繁的应用
优点:
- 实现简单,易于使用。
- 能够保证在单个数据库内ID的唯一性。
缺点:
- 不适合分布式系统或多主节点环境,因为可能存在冲突风险。
- 可能会暴露业务增长信息。
2.UUID
- 几乎所有现代数据库都支持UUID、通过内置函数如
uuid()、gen_random_uuid()生成全局唯一的标识符。
适用场景:
- 分布式系统或多数据中心部署。
- 需要跨多个数据库实例或服务时保持ID全局唯一。
- 对安全性有要求,不希望轻易推测出下一个ID。
优点:
- 全局唯一性,适用于分布式环境。
- 增加了数据隐私保护,难以猜测ID序列。
缺点:
- 存储空间较大,索引效率低于整型。
- 生成和处理速度较慢。
3.序列
- Oracle:使用
CREATE SEQUENCE语句创建序列对象、并通过.NEXTVAL获取下一个值。 - PostgreSQL:同样支持序列、可以用来为非连续自增的ID提供值
- 其他数据库: 如Mysql8.0+也引入了对序列的支持
适用场景:
- 类似于自动递增的需求,但在某些数据库中提供了更灵活的配置选项。
- 当需要非连续自增的ID值时。
优点:
- 提供了比自动递增更多的控制,如缓存大小、起始值等。
- 在一些情况下可以减少锁竞争,提高并发性能。
缺点:
- 实现上可能比自动递增复杂。
- 同样存在不适合分布式系统的局限性。