1. 为什么需要MyBatis注解开发?
在传统MyBatis使用中,XML映射文件一直是核心配置方式。但近年来,越来越多的开发者开始转向注解开发模式。这种转变背后有几个关键驱动因素:
首先,XML配置的维护成本较高。一个典型的中型项目可能包含上百个SQL映射文件,随着业务迭代,这些文件会变得难以管理。我曾经接手过一个老项目,光是查找某个SQL语句对应的XML文件就花了半小时——因为开发者在不同模块中分散定义了同名Mapper文件。
其次,注解开发显著提升了开发效率。在IDEA等现代IDE中,我们可以直接通过快捷键跳转到接口方法定义,而不用在XML和Java文件之间来回切换。实测表明,使用注解开发时,CRUD操作的编码速度能提升30%以上。
更重要的是,注解方式让SQL与Java代码保持高度内聚。当我们需要修改某个查询时,所有相关代码都在同一个文件中,避免了"东改西漏"的情况。特别是在处理动态SQL时,这种优势更加明显——我们不再需要反复核对XML中的if/test条件与Java代码中的参数名是否一致。
注意:虽然注解开发有诸多优势,但在处理复杂动态SQL时,XML仍然具有一定可读性优势。建议根据实际场景灵活选择,甚至混合使用两种方式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础注解CRUD实战
2.1 环境准备与基础配置
开始注解开发前,我们需要确保MyBatis环境正确配置。以Spring Boot项目为例,在pom.xml中添加最新依赖:
xml复制<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
在application.properties中配置基本参数:
properties复制mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.default-fetch-size=100
mybatis.configuration.default-statement-timeout=30
2.2 核心注解使用详解
MyBatis提供了以下核心注解来替代XML配置:
- @Select:基础查询注解
java复制@Select("SELECT * FROM users WHERE id = #{id}")
User getUserById(@Param("id") Long id);
- @Insert:插入操作注解,注意返回主键的两种方式
java复制// 方式一:使用useGeneratedKeys
@Insert("INSERT INTO users(name,email) VALUES(#{name},#{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);
// 方式二:适用于非自增主键
@Insert("INSERT INTO users(id,name) VALUES(#{id},#{name})")
@SelectKey(statement = "SELECT uuid()", keyProperty = "id",
before = true, resultType = String.class)
int insertUserWithUUID(User user);
- @Update:更新操作注解
java复制@Update("UPDATE users SET name=#{name} WHERE id=#{id}")
int updateUserName(@Param("id") Long id, @Param("name") String name);
- @Delete:删除操作注解
java复制@Delete("DELETE FROM users WHERE id=#{id}")
int deleteUser(@Param("id") Long id);
2.3 参数处理的进阶技巧
在实际开发中,我们经常需要处理复杂参数:
- Map参数传递:
java复制@Select("SELECT * FROM users WHERE name = #{name} AND email = #{email}")
List<User> selectByMap(Map<String, Object> params);
- 多参数处理(不使用@Param的情况):
java复制@Select("SELECT * FROM users WHERE id = #{arg0} AND name = #{arg1}")
User getUserByIdAndName(Long id, String name);
- 对象嵌套属性:
java复制@Insert("INSERT INTO orders(user_id, amount) VALUES(#{user.id}, #{amount})")
int insertOrder(Order order);
3. 动态SQL的注解实现
3.1 使用@SelectProvider实现动态查询
对于复杂动态SQL,MyBatis提供了Provider注解:
java复制@SelectProvider(type = UserSqlProvider.class, method = "getUserList")
List<User> getUserList(@Param("name") String name,
@Param("email") String email,
@Param("status") Integer status);
对应的SqlProvider类:
java复制public class UserSqlProvider {
public String getUserList(Map<String, Object> params) {
return new SQL() {{
SELECT("*");
FROM("users");
if (params.get("name") != null) {
WHERE("name = #{name}");
}
if (params.get("email") != null) {
WHERE("email = #{email}");
}
if (params.get("status") != null) {
WHERE("status = #{status}");
}
}}.toString();
}
}
3.2 批量操作的优化实现
批量插入是常见需求,注解方式可以这样实现:
java复制@Insert("<script>" +
"INSERT INTO users(name, email) VALUES " +
"<foreach collection='list' item='user' separator=','>" +
"(#{user.name}, #{user.email})" +
"</foreach>" +
"</script>")
int batchInsertUsers(@Param("list") List<User> users);
提示:使用
