文章目录
- 一、`@Options` 注解简介
- 二、应用场景
- 三、示例演示
- 数据库表结构
- 实体类
- Mapper 接口
- Service 层调用
- 四、`@Options` 常见问题与注意事项
- 主键未回填的问题
- 批量插入时无法回填主键
- 五、总结
一、@Options
注解简介
@Options
是 MyBatis 框架中的注解之一,主要用于配置 SQL 执行的额外选项。常用的配置包括:
useGeneratedKeys
:用于获取数据库自动生成的主键。keyProperty
:将返回的主键映射到 Java 实体类的属性。keyColumn
:数据库中主键列的名称(可选)。flushCache
:是否刷新缓存。timeout
:超时时间。fetchSize
:批量查询时,每次拉取的数据量。
常用语法:
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
useGeneratedKeys = true
:表示启用主键自动生成的功能。keyProperty = "id"
:将自动生成的主键值映射到 Java 实体类的id
属性。keyColumn = "id"
:指定数据库表中的主键列名称(可选,MyBatis 会自动匹配)。
二、应用场景
在使用 MyBatis 执行 INSERT
操作时,如果数据库表的主键是自动生成的(如 MySQL 的自增主键),可以使用 @Options
注解将生成的主键回填到实体类中。
三、示例演示
数据库表结构
假设我们有一张 user
表:
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL,email VARCHAR(100) NOT NULL
);
实体类
创建与数据库对应的实体类:
public class User {private Integer id; // 主键private String username; // 用户名private String email; // 邮箱// Getters 和 Setterspublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}
}
Mapper 接口
在 UserMapper
接口中使用 @Options
注解:
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;public interface UserMapper {@Insert("INSERT INTO user (username, email) VALUES (#{username}, #{email})")@Options(useGeneratedKeys = true, keyProperty = "id") // 自动回填主键int insertUser(User user);
}
#{username}
和#{email}
是 MyBatis 的参数占位符。@Options
注解:useGeneratedKeys = true
:表示启用主键自动生成。keyProperty = "id"
:将生成的主键值赋给User
实体的id
属性。
Service 层调用
在 Service 层调用 insertUser()
方法:
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;public class UserService {@Testpublic void testInsertUser() {SqlSession sqlSession = MyBatisUtil.getSqlSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();user.setUsername("Alice");user.setEmail("alice@example.com");userMapper.insertUser(user);System.out.println("插入用户的主键ID:" + user.getId());sqlSession.commit();sqlSession.close();}
}
- 插入数据后,
user.getId()
将返回自动生成的主键 ID。 - 控制台输出:
插入用户的主键ID:1
四、@Options
常见问题与注意事项
主键未回填的问题
- 问题:有时插入数据后,
id
不会自动回填。 - 原因:
- 数据库表没有设置自增主键。
- 使用了不支持主键自动生成的数据库(如 Oracle)。
- 数据库驱动不支持
useGeneratedKeys
。
- 解决方法:
- 检查表是否为自增主键。
- 使用
keyColumn
显式指定主键字段。 - 检查数据库驱动是否支持主键返回。
✅ 修改:
@Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
批量插入时无法回填主键
- 问题:批量插入时,
useGeneratedKeys
可能只返回第一个主键。 - 解决方法:
- 将批量插入拆分成单条插入。
- 使用
SELECT LAST_INSERT_ID()
获取最后生成的主键。
✅ 批量插入示例:
@Insert({"<script>","INSERT INTO user (username, email) VALUES ","<foreach collection='users' item='user' separator=','>","(#{user.username}, #{user.email})","</foreach>","</script>"
})
@Options(useGeneratedKeys = true, keyProperty = "id")
void batchInsert(@Param("users") List<User> users);
五、总结
useGeneratedKeys = true
:启用自动生成的主键。keyProperty = "id"
:将生成的主键映射到实体类属性。- 在批量插入或复杂 SQL 中可能存在主键回填失败的问题,需要注意。
✅ 实战项目中使用 @Options
能有效减少手动查询主键 ID 的繁琐步骤,同时提高代码效率。