MyBatis 中的 @Options 注解
1. @Options 注解是什么?
@Options 是 MyBatis 提供的一个注解,它允许你在 MyBatis 的映射器接口(Mapper Interface)的方法上直接配置一些额外的选项和设置。这些设置通常对应着 XML 映射文件中 <select>, <insert>, <update>, <delete> 等标签的属性,但它提供了一种更为简洁的、基于注解的配置方式。
它的核心作用是微调 MyBatis 执行 SQL 语句时的行为,例如控制缓存、设置超时时间、获取自增主键等。
2. 为什么需要 @Options?
在纯 XML 配置中,我们会在标签内设置各种属性,例如:
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id" flushCache="true" timeout="10">
INSERT INTO user (name) VALUES (#{name})
</insert>
当使用注解方式(如 @Insert, @Select)时,这些属性无法直接写在 SQL 语句中。@Options 注解就是为了解决这个问题而生的,它将这些配置选项从 XML 标签中剥离出来,以注解参数的形式提供,使得注解驱动的 SQL 映射更加完整和强大。
3. @Options 的核心属性详解
@Options 提供了多个属性,下面我们来逐一详解其中最常用和重要的几个:
3.1. useGeneratedKeys 和 keyProperty(极其重要)
useGeneratedKeys: (默认false)- 作用: 告诉 MyBatis 要使用 JDBC 的
getGeneratedKeys方法来获取由数据库内部生成的主键(如 MySQL 的AUTO_INCREMENT或 PostgreSQL 的SERIAL)。
- 作用: 告诉 MyBatis 要使用 JDBC 的
keyProperty:- 作用: 指定一个对象属性,MyBatis 会将获取到的自增主键值设置到这个属性中。
- 使用场景: 插入数据后,需要立即获取数据库生成的主键值。
示例:
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("INSERT INTO user (name, email) VALUES (#{name}, #{email})")
int insertUser(User user);
执行完 insertUser 方法后,传入的 user 对象的 id 属性会被自动赋值为新插入记录的自增 ID。
补充:keyColumn
- 作用: 指定数据库表中主键列的名称。通常在主键列名和实体类属性名不一致时使用(如数据库列名为
user_id,实体属性为id)。多数情况下可省略,MyBatis 可以自动识别。
3.2. flushCache(重要)
- 作用: 设置执行该语句后是否清空本地缓存(二级缓存)和一级缓存。
- 可选值:
true/false(默认值因语句类型而异)- 对于
@Insert,@Update,@Delete语句,默认值为true。因为修改了数据,为了保证缓存中的数据是最新的,默认会清空缓存。 - 对于
@Select语句,默认值为false。因为只是查询,不希望清空缓存。
- 对于
- 使用场景: 你可以强制设置某个查询语句执行后清空缓存(
flushCache=true),例如查询一个极其敏感、需要绝对最新的统计信息时。但通常使用默认值即可。
3.3. useCache(重要)
- 作用: 设置该查询语句的结果是否被保存在二级缓存中。
- 可选值:
true/false(对于@Select语句,默认值为true) - 使用场景: 对于实时性要求非常高、或者结果集非常大的查询,可以设置
useCache=false来避免其占用二级缓存空间,保证每次都能获取到最新的数据。
3.4. timeout
- 作用: 设置数据库语句执行的超时时间(单位:秒)。如果超过这个时间,语句仍未执行完,会抛出异常。
- 默认值: 取自全局配置的
defaultStatementTimeout,如果未配置则为无超时限制(依赖数据库驱动)。 - 使用场景: 防止某些复杂查询或批量操作长时间运行,拖垮数据库连接。
3.5. fetchSize
- 作用: 给 JDBC 驱动程序一个提示,希望每次从数据库返回的结果行数。这并不是一个硬性限制,而是一个性能优化提示。
- 使用场景: 处理海量数据(千万级)的查询时,设置一个合理的
fetchSize(如 1000)可以显著减少网络往返次数,提升大数据量读取的性能。小数据量查询无需设置。
3.6. resultSetType
- 作用: 控制结果集(ResultSet)的类型。
- 可选值:
FORWARD_ONLY: 只能向前移动的只读结果集(默认值,性能最好)。SCROLL_INSENSITIVE: 可滚动(向前、向后、定位),但对其他连接所做的更改不敏感。SCROLL_SENSITIVE: 可滚动,且对其他连接所做的更改敏感(数据库支持且驱动实现才行,很少用)。
- 使用场景: 极少数需要结果集滚动的场景,例如在 Java 代码中需要前后移动光标处理数据。99% 的情况用默认的
FORWARD_ONLY即可。
3.7. statementType
- 作用: 指定 MyBatis 创建何种类型的 JDBC
Statement对象。 - 可选值:
STATEMENT: 基本的Statement,直接执行静态 SQL,有 SQL 注入风险。PREPARED: 使用预编译的PreparedStatement(默认值,安全且高效)。CALLABLE: 用于执行存储过程的CallableStatement。
- 使用场景: 除非有特殊理由(如执行动态表名或必须用
Statement),否则永远使用默认的PREPARED。
4. 完整示例
public interface UserMapper {
// 示例1:获取自增主键,并设置超时时间为5秒
@Options(useGeneratedKeys = true, keyProperty = "id", timeout = 5)
@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
int insertUser(User user);
// 示例2:查询时不使用缓存,且执行后清空缓存(强制下次查询读数据库)
@Options(useCache = false, flushCache = Options.FlushCachePolicy.TRUE)
@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById Strict(Integer id);
// 示例3:设置fetchSize以优化大批量数据查询
@Options(fetchSize = 1000)
@Select("SELECT * FROM users")
List<User> getAllUsers();
}
5. 全局设置 vs. @Options 局部设置
需要注意的是,@Options 中设置的属性会覆盖全局配置(在 mybatis-config.xml 中设置的 defaultXXX 属性)。
例如,你在全局配置了 defaultStatementTimeout=30,但在某个方法上的 @Options(timeout=10) 会使得这个方法的超时时间变为 10 秒。这提供了很好的灵活性,允许你对特定语句进行特殊化配置。
总结
| 属性 | 作用 | 常用场景/默认值 |
|---|---|---|
useGeneratedKeys | 是否使用自增主键 | 插入后获取主键(默认false) |
keyProperty | 主键值赋给对象的哪个属性 | 必须与useGeneratedKeys=true配对使用 |
flushCache | 执行后是否清空缓存 | 增删改默认为true,查询默认为false |
useCache | 是否缓存查询结果 | 查询语句默认为true |
timeout | 语句执行超时时间(秒) | 防止长时间运行 |
fetchSize | JDBC驱动抓取结果的行数提示 | 优化大批量数据查询性能 |
resultSetType | 结果集类型 | 一般用默认FORWARD_ONLY |
statementType | 使用的Statement类型 | 一般用默认PREPARED(防注入) |
@Options 注解是 MyBatis 注解开发中一个非常实用的工具,它巧妙地将 XML 标签的属性配置转移到了注解中,使得基于注解的 SQL 映射功能与 XML 方式一样强大
2532

被折叠的 条评论
为什么被折叠?



