MyBatis SQL映射与动态SQL实战指南
MyBatis SQL映射深度解析:从CRUD到动态SQL实战
一、CRUD操作基础
MyBatis的核心功能是通过SQL映射实现数据库操作,我们先从基础的CRUD操作开始。
1. select查询操作
基础查询示例:
<select id="selectUser" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
多参数查询:
<select id="selectUsersByCondition" resultType="User">
SELECT * FROM users
WHERE name = #{name} AND age > #{age}
</select>
实践建议:
- 对于简单查询,优先使用
resultType
自动映射 - 复杂查询建议使用
resultMap
进行显式映射 - 避免使用
SELECT *
,明确列出所需字段
2. insert插入操作
基础插入:
<insert id="insertUser" parameterType="User">
INSERT INTO users(name, age)
VALUES(#{name}, #{age})
</insert>
获取自增主键:
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users(name, age) VALUES(#{name}, #{age})
</insert>
3. update更新操作
<update id="updateUser" parameterType="User">
UPDATE users
SET name=#{name}, age=#{age}
WHERE id=#{id}
</update>
4. delete删除操作
<delete id="deleteUser">
DELETE FROM users WHERE id=#{id}
</delete>
二、动态SQL实战
MyBatis最强大的特性之一就是动态SQL,它允许我们在XML中构建灵活的SQL语句。
1. if条件判断
<select id="findActiveUsers" resultType="User">
SELECT * FROM users
WHERE status = 'ACTIVE'
<if test="name != null">
AND name like #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</select>
2. choose/when/otherwise多重选择
<select id="findUsers" resultType="User">
SELECT * FROM users
WHERE status = 'ACTIVE'
<choose>
<when test="name != null">
AND name like #{name}
</when>
<when test="age != null">
AND age = #{age}
</when>
<otherwise>
AND role = 'DEFAULT'
</otherwise>
</choose>
</select>
3. where/set/trim智能处理
where标签自动处理AND/OR前缀:
<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="name != null">
name like #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
set标签用于更新操作:
<update id="updateUser">
UPDATE users
<set>
<if test="name != null">name=#{name},</if>
<if test="age != null">age=#{age},</if>
</set>
WHERE id=#{id}
</update>
4. foreach遍历集合
<select id="selectUsersInIds" resultType="User">
SELECT * FROM users
WHERE id IN
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
5. bind创建变量
<select id="selectUsers" resultType="User">
<bind name="pattern" value="'%' + name + '%'" />
SELECT * FROM users
WHERE name LIKE #{pattern}
</select>
三、参数处理进阶
1. 各种参数类型示例
简单参数:
User selectUser(@Param("id") int id);
对象参数:
int insertUser(User user);
Map参数:
List<User> selectUsers(Map<String, Object> params);
2. @Param注解使用场景
User selectUser(@Param("id") int id, @Param("name") String name);
对应的XML:
<select id="selectUser" resultType="User">
SELECT * FROM users
WHERE id = #{id} AND name = #{name}
</select>
3. 参数类型处理器
MyBatis内置了常见类型的处理器,如:
- StringTypeHandler
- IntegerTypeHandler
- DateTypeHandler
自定义类型处理器:
@MappedTypes(PhoneNumber.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class PhoneTypeHandler extends BaseTypeHandler<PhoneNumber> {
// 实现抽象方法
}
四、结果映射详解
1. 自动映射 vs 显式映射
自动映射:
<select id="selectUsers" resultType="User">
SELECT id, name, age FROM users
</select>
显式映射:
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<result property="age" column="user_age"/>
</resultMap>
2. 关联查询(association)
<resultMap id="blogResultMap" type="Blog">
<id property="id" column="blog_id"/>
<result property="title" column="blog_title"/>
<association property="author" javaType="Author">
<id property="id" column="author_id"/>
<result property="name" column="author_name"/>
</association>
</resultMap>
3. 集合查询(collection)
<resultMap id="blogResultMap" type="Blog">
<id property="id" column="blog_id"/>
<result property="title" column="blog_title"/>
<collection property="comments" ofType="Comment">
<id property="id" column="comment_id"/>
<result property="content" column="comment_content"/>
</collection>
</resultMap>
4. 鉴别器(discriminator)
<resultMap id="vehicleResult" type="Vehicle">
<id property="id" column="id"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultMap="carResult"/>
<case value="2" resultMap="truckResult"/>
</discriminator>
</resultMap>
五、最佳实践总结
- SQL可读性:保持XML中的SQL格式良好,适当换行和缩进
- 参数安全:始终使用
#{}
防止SQL注入,${}
仅用于动态表名/列名 - 结果映射:复杂对象关系使用显式
resultMap
- 动态SQL:合理使用动态SQL标签,避免过度复杂化
- 性能考虑:大批量操作考虑使用批处理模式
通过掌握这些SQL映射技术,你将能够高效地使用MyBatis进行数据库操作,构建灵活且高性能的数据访问层。