在 MyBatis 的实际开发中,除了传统的 XML 映射方式,使用注解来编写 SQL 语句也变得越来越流行。尤其在 Spring Boot 整合 MyBatis 的项目中,注解开发可以极大地简化代码结构,提高开发效率。
本文将详细讲解 MyBatis 中常用的注解及其使用场景,包括:
类别 | 注解 | 说明 |
---|---|---|
SQL 操作 | @Select , @Insert , @Update , @Delete |
基础的增删改查操作 |
参数绑定 | @Param , @MapKey |
控制参数传递方式 |
结果映射 | @Results , @Result , @One , @Many |
定义对象与表字段的映射关系 |
动态 SQL | @SelectProvider , @InsertProvider 等 |
使用 Java 构建动态 SQL |
其他辅助 | @Options , @Flush |
控制插入主键回填等行为 |
@Select
查询数据@Mapper
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User selectById(Integer id);
}
@Insert
插入数据@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insert(User user);
@Options
可以控制是否使用自动生成主键,并指定主键属性名。@Update
更新数据@Update("UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}")
int update(User user);
@Delete
删除数据@Delete("DELETE FROM users WHERE id = #{id}")
int deleteById(Integer id);
#{}
@Select("SELECT * FROM users WHERE id = #{id}")
User selectById(Integer id);
@Param
注解@Select("SELECT * FROM users WHERE name LIKE CONCAT('%', #{name}, '%') AND status = #{status}")
List<User> findUsers(@Param("name") String name, @Param("status") int status);
@Select("SELECT * FROM users WHERE name LIKE CONCAT('%', #{name}, '%')")
List<User> searchUsers(Map<String, Object> params);
当数据库字段名与实体类属性不一致时,可以使用 @Results
+ @Result
进行映射。
@Results(id = "userResult", value = {
@Result(property = "id", column = "user_id", id = true),
@Result(property = "name", column = "user_name"),
@Result(property = "email", column = "user_email")
})
@Select("SELECT * FROM users WHERE id = #{id}")
@ResultMap("userResult")
User selectById(Integer id);
@Results({
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "orders", column = "id",
one = @One(select = "com.example.mapper.OrderMapper.findByUserId"))
})
@Select("SELECT * FROM users WHERE id = #{id}")
User selectWithOrders(Integer id);
虽然 XML 更适合写复杂的动态 SQL,但 MyBatis 也提供了 @SelectProvider
、@InsertProvider
等注解来构建动态 SQL。
@SelectProvider(type = UserSqlProvider.class, method = "buildFindUserSql")
List<User> findUsersDynamic(Map<String, Object> params);
public class UserSqlProvider {
public String buildFindUserSql(Map<String, Object> params) {
return new SQL() {{
SELECT("*");
FROM("users");
if (params.get("name") != null) {
WHERE("name LIKE CONCAT('%', #{name}, '%')");
}
if (params.get("email") != null) {
WHERE("email = #{email}");
}
}}.toString();
}
}
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users")
List<User> findAll();
@Select("SELECT * FROM users WHERE id = #{id}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "orders", column = "id",
one = @One(select = "com.example.mapper.OrderMapper.findByUserId"))
})
User findById(Integer id);
@Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void save(User user);
@Update("UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}")
void update(User user);
@Delete("DELETE FROM users WHERE id = #{id}")
void deleteById(Integer id);
}
对比项 | 注解方式 | XML 方式 |
---|---|---|
开发效率 | 快速、简洁 | 需要编写 XML 文件 |
动态 SQL 支持 | 相对麻烦 | 灵活强大 |
结果映射 | 繁琐 | 灵活、直观 |
适用场景 | 小型项目、简单业务 | 中大型项目、复杂业务 |
可维护性 | 不如 XML | 更容易维护复杂 SQL |
答:使用 @SelectProvider
、@InsertProvider
等结合 SQL
构建器类实现。
答:使用 @Results
+ @Result
注解定义字段与属性的映射关系。
答:支持,可以通过 @One
或 @Many
设置 fetchType = FetchType.LAZY
实现。
答:不适合,对于复杂查询建议使用 XML 映射文件。