// 方案1:SQL 中起别名(保证别名与属性名一致) @Select("SELECT id, username, dept_id AS deptId, create_time AS createTime FROM emp WHERE id=#{id}") Emp getById(Integer id);
//当方法参数 ≥ 2 个,或想在 SQL 中使用明确的参数名时,用 @Param 声明。 @Select("SELECT * FROM user WHERE name = #{name} AND age = #{age}") User findByNameAndAge(@Param("name") String name, @Param("age") Integer age);
4.6 条件查询(模糊 + 多参数)
1 2 3 4 5 6 7 8 9 10 11
// ❌ 方式1:${}字符串拼接,存在SQL注入风险,不推荐 @Select("SELECT * FROM emp WHERE name LIKE '%${name}%' AND gender=#{gender}") List<Emp> list(String name, Short gender);
// ✅ 方式2:concat 函数 + #{},预编译,安全推荐 @Select("SELECT * FROM emp " + "WHERE name LIKE CONCAT('%',#{name},'%') " + "AND gender=#{gender} " + "AND entrydate BETWEEN #{begin} AND #{end} " + "ORDER BY update_time DESC") List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
<!-- id = 方法名;resultType = 返回值类型(集合写泛型) --> <selectid="list"resultType="com.example.pojo.Emp"> SELECT * FROM emp WHERE name LIKE CONCAT('%',#{name},'%') ORDER BY update_time DESC </select>
</mapper>
6.3 resultMap vs resultType
对比项
resultType
resultMap
映射方式
Mybatis 自动按字段名/属性名映射
程序员自定义字段与属性对应关系
适用场景
简单查询(字段名与属性名匹配)
多表联查、字段名与属性名不一致
七、动态 SQL
7.1 动态 SQL 标签速查
标签
作用
<if test="条件">
条件为 true 时拼接 SQL 片段
<where>
包裹 <if> 标签,有子内容时才插入 WHERE,自动去掉开头多余的 AND/OR
<set>
配合 <if> 用于 UPDATE 语句,动态插入 SET 关键字,自动去掉末尾多余逗号
<foreach>
遍历集合,用于批量操作(如 IN (...) 子句)
<sql id="名称">
定义可复用的 SQL 片段
<include refid="名称">
引用 <sql> 定义的片段
7.2 动态条件查询(<where> + <if>)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
<selectid="list"resultType="com.example.pojo.Emp"> SELECT * FROM emp <where> <!-- <where> 标签:有子内容才加 WHERE,自动去掉首个多余的 AND --> <iftest="name != null"> AND name LIKE CONCAT('%', #{name}, '%') </if> <iftest="gender != null"> AND gender = #{gender} </if> <iftest="begin != null and end != null"> AND entrydate BETWEEN #{begin} AND #{end} </if> </where> ORDER BY update_time DESC </select>
<!-- 批量删除:DELETE FROM emp WHERE id IN (1,2,3) --> <deleteid="deleteByIds"> DELETE FROM emp WHERE id IN <foreachcollection="ids"item="id"separator=","open="("close=")"> #{id} </foreach> </delete>
<selectid="listUser"resultType="com.example.User"> SELECT id, name, age, email FROM user <where> <iftest="name != null and name != ''"> AND name = #{name} </if> <iftest="age != null"> AND age = #{age} </if> </where> </select>
生成SQL对比
传入参数
最终生成SQL
标签自动处理的部分
name=null, age=20
SELECT ... FROM user WHERE age = ?
删掉了age前的AND
两个参数都为null
SELECT ... FROM user
完全不生成WHERE关键字
两个参数都不为空
SELECT ... WHERE name = ? AND age = ?
正常拼接
二、<set> 标签(自动加SET+删末尾逗号)
核心功能:有更新字段才加SET,自动删除所有字段末尾多余的逗号
Mapper接口
1
intupdateUser(User user);
XML代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
<updateid="updateUser"parameterType="com.example.User"> UPDATE user <set> <iftest="name != null and name != ''"> name = #{name}, </if> <iftest="age != null"> age = #{age}, </if> <iftest="email != null and email != ''"> email = #{email}, </if> </set> WHERE id = #{id} </update>
<selectid="listUserByIds"resultType="com.example.User"> SELECT id, name FROM user <where> <iftest="ids != null and ids.size() > 0"> AND id IN <foreachcollection="ids"item="id"open="("separator=","close=")"> #{id} </foreach> </if> </where> </select>
@Update("update dept set name=#{name}, create_time=#{createTime}, update_time=#{updateTime} where id=#{id}") publicintupdateDept(Dept dept);
@Select("select * from dept where id=#{id}") public Dept findById(Integer id);
/*@Select("select id id2,name name2, create_time createTime2, update_time updateTime2 from dept where id=#{id}") // 通过给列名起别名的方式,只能针对这一个方法生效,其他的sql也得写别名,扩展性很差 public Dept2 findById2(Integer id);*/
<!--动态sql修改数据,如果参数无效,则保持原有的数据不变--> <updateid="updateDept2"> update dept <set> <iftest="name != null and name != ''"> name=#{name}, </if> <iftest="createTime != null"> create_time=#{createTime}, </if> <iftest="updateTime != null"> update_time=#{updateTime} </if> </set> where id=#{id} </update>
<!--批量删除--> <deleteid="deleteByIds"> delete from dept where id in <foreachitem="item"collection="abc"separator=","open="("close=")"> #{item} </foreach> </delete>