MyBatis 的 @Select 注解支持轻量级 SQL 查询,适用于简单固定场景;支持单表查询、多参数(需 @Param)、多行 SQL,但不支持动态标签;复杂逻辑用 @SelectProvider;关联查询可通过 @Results + @Many 或 JOIN 实现。

MyBatis 通过 @Select 注解可以快速实现轻量级 SQL 查询,无需 XML 文件,适合简单、固定、不频繁变动的查询场景。
基础用法:单表查询 + 参数绑定
在 Mapper 接口方法上直接使用 @Select,SQL 写在注解值中。参数通过 #{} 占位符注入(自动防 SQL 注入):
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(Long id);
<pre class="brush:php;toolbar:false;">@Select("SELECT * FROM user WHERE name LIKE CONCAT('%', #{keyword}, '%')")
List<User> selectByNameLike(String keyword);}
-
#{id}会自动做预编译参数处理,等价于PreparedStatement的setLong(1, id) - 字符串拼接(如
LIKE)建议用数据库函数(如 MySQL 的CONCAT),避免在 Java 层拼接导致注入风险
多参数传递:用 @Param 显式命名
当方法有多个参数时,必须用 @Param 注解指定名称,否则 MyBatis 无法识别:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
立即学习“Java免费学习笔记(深入)”;
@Select("SELECT * FROM user WHERE status = #{status} AND create_time >= #{startTime}")
List<User> selectByStatusAndTime(@Param("status") Integer status,
@Param("startTime") Date startTime);- 不加
@Param时,MyBatis 3.4+ 默认启用useActualParamNames=true,但仅对 JDK8+ 编译且保留调试信息有效,生产环境仍推荐显式标注 - 命名要与
#{}中的名称严格一致
复杂查询:支持多行 SQL 与动态片段(有限)
@Select 支持换行和空格,可写多行提升可读性;但**不支持动态 SQL 标签(如 <if></if>、<where></where>)**。如需动态逻辑,应改用 @SelectProvider:
@Select({
"SELECT u.id, u.name, u.email,",
" COUNT(o.id) AS order_count",
"FROM user u",
"LEFT JOIN `order` o ON u.id = o.user_id",
"WHERE u.status = 1",
"GROUP BY u.id, u.name, u.email",
"ORDER BY order_count DESC"
})
List<UserWithOrderCount> selectUsersWithOrderCount();- 用字符串数组传入,MyBatis 自动拼接为完整 SQL
- 若需条件判断(例如“按姓名查或按 ID 查”),应使用
@SelectProvider配合自定义 SQL 构建类
关联查询:嵌套结果或嵌套查询
注解方式支持 @Results + @Result 实现一对一、一对多映射:
@Select("SELECT * FROM user WHERE id = #{id}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "posts", column = "id",
many = @Many(select = "com.example.mapper.PostMapper.selectByUserId"))
})
User selectUserWithPosts(Long id);-
@Result明确字段映射关系,避免驼峰自动转换失效 -
many = @Many(...)表示一对多,调用另一个 Mapper 方法(N+1 查询,适合数据量小场景) - 若需单次 JOIN 查询,可用
@One或在 SQL 中 JOIN 后用@Results手动映射嵌套对象

















