MyBatis中常用的SQL语句详解
作者:冰糖心书房
MyBatis是一种优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射,本文介绍了MyBatis中常用的SQL语句,包括基本查询、多条件查询、关联查询、分页查询、插入、更新、删除等,并结合MyBatis的特性进行了说明
MyBatis 中常用的 SQL 语句与标准 SQL 语句基本一致,但 MyBatis 提供了一些额外的特性和标签来更方便地构建和管理 SQL 语句。
以下列出 MyBatis 中常用的 SQL 语句,并结合 MyBatis 的特性进行说明:
1. SELECT (查询)
基本查询:
<select id="selectUserById" parameterType="int" resultType="User">
SELECT id, username, password, email FROM users WHERE id = #{id}
</select>id: 该 SQL 语句的唯一标识符,用于在 Java 代码中引用。parameterType: 传入参数的类型 (可选,MyBatis 可以自动推断)。resultType: 查询结果映射的 Java 类型 (POJO)。#{id}: 占位符,表示传入的参数,MyBatis 会自动进行参数绑定和类型转换,防止 SQL 注入。
多条件查询 (动态 SQL):
<select id="selectUsers" parameterType="map" resultType="User">
SELECT id, username, password, email FROM users
<where>
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
</where>
</select><where>: 自动添加WHERE关键字,并处理多余的AND或OR。<if>: 根据条件判断是否包含该 SQL 片段。test: 条件表达式,使用 OGNL 表达式。LIKE: 模糊查询,CONCAT('%', #{username}, '%')用于构建模糊查询条件。
关联查询 (JOIN):
<select id="selectUserWithOrders" parameterType="int" resultMap="userWithOrdersResultMap">
SELECT
u.id AS user_id,
u.username,
o.id AS order_id,
o.order_date
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
<resultMap id="userWithOrdersResultMap" type="User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<collection property="orders" ofType="Order">
<id property="id" column="order_id"/>
<result property="orderDate" column="order_date"/>
</collection>
</resultMap>LEFT JOIN: 左连接,获取用户及其所有订单。resultMap: 自定义结果映射,用于处理复杂的关联关系。<collection>: 映射一对多关系,将订单列表映射到User对象的orders属性。
分页查询 :
<!-- MySQL -->
<select id="selectUsersByPage" parameterType="map" resultType="User">
SELECT id, username, password, email FROM users LIMIT #{offset}, #{pageSize}
</select>
<!-- Oracle -->
<select id="selectUsersByPage" parameterType="map" resultType="User">
SELECT * FROM (
SELECT t.*, ROWNUM rn FROM (
SELECT id, username, password, email FROM users
) t WHERE ROWNUM <= #{endRow}
) WHERE rn > #{startRow}
</select>LIMIT: MySQL 中的分页关键字。ROWNUM: Oracle 中的伪列,用于分页。- 需要根据不同的数据库方言使用不同的分页语法。 MyBatis 提供了
Dialect接口来支持不同的数据库方言。
2. INSERT (插入)
- 基本插入:
<insert id="insertUser" parameterType="User">
INSERT INTO users (username, password, email) VALUES (#{username}, #{password}, #{email})
</insert>- 获取自增主键:
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO users (username, password, email) VALUES (#{username}, #{password}, #{email})
</insert>useGeneratedKeys="true": 启用获取自增主键。keyProperty="id": 指定将自增主键值设置到User对象的哪个属性 (通常是id)。
批量插入 (foreach):
<insert id="batchInsertUsers" parameterType="java.util.List">
INSERT INTO users (username, password, email) VALUES
<foreach collection="list" item="user" separator=",">
(#{user.username}, #{user.password}, #{user.email})
</foreach>
</insert><foreach>: 循环遍历list集合,生成多个插入值。collection: 指定要遍历的集合。item: 集合中每个元素的别名。separator: 分隔符,用于分隔每次循环生成的 SQL 片段。
3. UPDATE (更新)
- 基本更新:
<update id="updateUser" parameterType="User">
UPDATE users SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id}
</update>- 动态更新 (set + if):
<update id="updateUserSelective" parameterType="User">
UPDATE users
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="password != null and password != ''">
password = #{password},
</if>
<if test="email != null and email != ''">
email = #{email},
</if>
</set>
WHERE id = #{id}
</update><set>: 自动添加SET关键字,并处理多余的逗号。- 只更新传入的非空字段。
4. DELETE (删除)
- 基本删除:
<delete id="deleteUserById" parameterType="int">
DELETE FROM users WHERE id = #{id}
</delete>- 批量删除 (foreach):
<delete id="deleteUsersByIds" parameterType="java.util.List">
DELETE FROM users WHERE id IN
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>open: 循环开始前添加的字符串。close: 循环结束后添加的字符串。
5. 其他常用标签和特性
<sql>: 定义可重用的 SQL 片段。
<sql id="userColumns">
id, username, password, email
</sql>
<select id="selectUserById" parameterType="int" resultType="User">
SELECT <include refid="userColumns"/> FROM users WHERE id = #{id}
</select>#{} vs ${}:#{}: 预编译参数,防止 SQL 注入,推荐使用。${}: 字符串替换,直接将值拼接到 SQL 语句中,有 SQL 注入风险,谨慎使用 (例如,用于动态表名或列名)。
typeAliases: 定义类型别名,简化resultType和parameterType的书写。<cache>: 开启二级缓存,提高查询性能。- Result Maps (结果映射): 处理复杂类型和关联关系的映射。
总结
MyBatis 的核心在于将 SQL 语句与 Java 代码分离,并通过 XML 或注解的方式进行配置。 尽可能使用 #{} 进行参数绑定,以防止 SQL 注入。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
