1580 字
约 5 分钟
15
第05章 SQL映射
2026-09-24
无标签
第05章 SQL映射
学习 Mapper XML 文件的编写和各种 SQL 映射配置
学习进度:20% 代码演示按钮 💻 查看完整代码 - 在线IDE体验
🎯 学习目标
📚
理解核心概念
掌握本章的核心概念和基本原理
🔧
掌握实践技能
学会相关的配置方法和实践技巧
💡
了解应用场景
明确在实际项目中的应用场景和最佳实践
📚 学习目标
- 深入理解MyBatis SQL映射文件的结构和作用
- 掌握各种SQL语句的配置方法
- 学会参数映射和结果映射的配置
- 了解动态SQL的使用方法
- 掌握关联查询的配置技巧
SQL映射文件概述
SQL映射文件是MyBatis的核心组件之一,它定义了SQL语句与Java方法的映射关系。通过映射文件,我们可以将复杂的SQL操作封装成简单的方法调用。
映射文件的基本结构
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mybatis.mapping.mapper.UserMapper">
<!-- SQL语句定义 -->
</mapper>
基本SQL语句配置
1. SELECT语句
<!-- 查询所有用户 -->
<select id="selectAllUsers" resultType="User">
SELECT id, name, age, email FROM users
</select>
<!-- 根据ID查询用户 -->
<select id="selectUserById" parameterType="long" resultType="User">
SELECT id, name, age, email FROM users WHERE id = #{id}
</select>
2. INSERT语句
<!-- 插入用户 -->
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (name, age, email) VALUES (#{name}, #{age}, #{email})
</insert>
3. UPDATE语句
<!-- 更新用户 -->
<update id="updateUser" parameterType="User">
UPDATE users SET name = #{name}, age = #{age}, email = #{email} WHERE id = #{id}
</update>
4. DELETE语句
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="long">
DELETE FROM users WHERE id = #{id}
</delete>
参数映射
1. 单个参数
<select id="selectUsersByAge" parameterType="int" resultType="User">
SELECT * FROM users WHERE age = #{age}
</select>
2. 多个参数
<select id="selectUsersByCondition" parameterType="map" resultType="User">
SELECT * FROM users
WHERE name LIKE CONCAT('%', #{name}, '%')
AND age BETWEEN #{minAge} AND #{maxAge}
</select>
3. 对象参数
<insert id="insertUser" parameterType="User">
INSERT INTO users (name, age, email)
VALUES (#{name}, #{age}, #{email})
</insert>
结果映射
1. 基本结果映射
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id"/>
<result property="name" column="user_name"/>
<result property="age" column="user_age"/>
<result property="email" column="user_email"/>
</resultMap>
<select id="selectUsers" resultMap="userResultMap">
SELECT user_id, user_name, user_age, user_email FROM users
</select>
2. 关联映射(一对一)
<resultMap id="userWithProfileMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
<association property="profile" javaType="UserProfile">
<id property="id" column="profile_id"/>
<result property="bio" column="bio"/>
<result property="avatar" column="avatar"/>
</association>
</resultMap>
<select id="selectUsersWithProfile" resultMap="userWithProfileMap">
SELECT u.*, p.id as profile_id, p.bio, p.avatar
FROM users u LEFT JOIN user_profiles p ON u.id = p.user_id
</select>
3. 集合映射(一对多)
<resultMap id="userWithOrdersMap" type="User">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="email" column="email"/>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderNumber" column="order_number"/>
<result property="amount" column="amount"/>
<result property="orderDate" column="order_date"/>
</collection>
</resultMap>
<select id="selectUsersWithOrders" resultMap="userWithOrdersMap">
SELECT u.*, o.id as order_id, o.order_number, o.amount, o.order_date
FROM users u LEFT JOIN orders o ON u.id = o.user_id
</select>
动态SQL
1. if标签
<select id="selectUsersDynamic" parameterType="User" resultType="User">
SELECT * FROM users
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="age != null">
AND age = #{age}
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
</where>
</select>
2. choose、when、otherwise标签
<select id="selectUsersByCondition" parameterType="map" resultType="User">
SELECT * FROM users
<where>
<choose>
<when test="name != null">
name LIKE CONCAT('%', #{name}, '%')
</when>
<when test="email != null">
email = #{email}
</when>
<otherwise>
age > 18
</otherwise>
</choose>
</where>
</select>
3. foreach标签
<select id="selectUsersByIds" parameterType="list" resultType="User">
SELECT * FROM users WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
SQL片段复用
<!-- 定义SQL片段 -->
<sql id="userColumns">
id, name, age, email
</sql>
<!-- 使用SQL片段 -->
<select id="selectAllUsers" resultType="User">
SELECT <include refid="userColumns"/> FROM users
</select>
<select id="selectUserById" parameterType="long" resultType="User">
SELECT <include refid="userColumns"/> FROM users WHERE id = #{id}
</select>
最佳实践
1. 命名规范
- 映射文件名与Mapper接口名保持一致
- namespace与Mapper接口的全限定名一致
- SQL语句的id与Mapper接口的方法名一致
2. 性能优化
- 合理使用resultMap,避免不必要的字段映射
- 使用延迟加载处理关联查询
- 避免N+1查询问题
- 合理使用缓存机制
3. 安全考虑
- 使用参数化查询防止SQL注入
- 避免在SQL中直接拼接用户输入
- 对敏感数据进行适当的权限控制
常见问题与解决方案
Q: 如何处理字段名与属性名不一致的情况?
A: 可以使用resultMap进行字段映射,或者在SQL中使用别名。
Q: 动态SQL中的test条件如何编写?
A: test条件使用OGNL表达式,可以判断null值、空字符串、数值比较等。
Q: 如何处理一对多关联查询的性能问题?
A: 可以使用分步查询配合延迟加载,或者使用嵌套结果映射。
Q: 如何在映射文件中使用自定义的类型处理器?
A: 在resultMap中使用typeHandler属性指定自定义的类型处理器。
实践练习
练习1:基本CRUD操作
为User实体创建完整的CRUD操作映射,包括插入、查询、更新和删除。
练习2:动态查询
实现一个用户搜索功能,支持按姓名、年龄范围、邮箱等条件进行动态查询。
练习3:关联查询
实现用户与订单的一对多关联查询,要求能够查询用户及其所有订单信息。
练习4:批量操作
实现批量插入用户和批量删除用户的功能。
运行示例程序
步骤1:导入项目
将chapter-05-sql-mapping.json导入到IntelliJ IDEA中。
步骤2:配置数据库
确保MySQL数据库运行正常,执行init.sql创建测试数据。
步骤3:运行程序
运行SqlMappingDemo.java,观察各种映射配置的执行效果。
步骤4:查看结果
程序将演示基本映射、参数映射、结果映射和动态SQL的使用。
本章小结
📖 本章小结
本章我们学习了 SQL映射 的相关内容,包括:
- 核心概念和基本原理
- 配置方法和实践技巧
- 应用场景和最佳实践
- 常见问题和解决方案
下一章节 🎉
恭喜完成本章学习!
你已经掌握了 SQL映射 的核心知识
第06章Mapper接口继续学习 MyBatis 的更多特性和应用⏱️预计 30 分钟📊中等难度开始学习 → ← 第04章 📚 课程目录 第06章 →
评论
0 条
还没有评论,先写一条吧。