动态 SQL 的使用与优化

动态 SQL 允许根据不同条件拼接 SQL 语句,从而实现对数据库的更精确操作。在这里,我们将探讨如何使用动态 SQL 的标签(如 <if><choose><where><set><foreach><bind>)在映射文件或注解中实现这一功能,并优化代码的可读性和可维护性。

1. 使用 <if> 标签

语法

<if test="条件"> 满足条件的语句 </if>

示例

在查询课程时,可以使用 <if> 标签根据传入参数动态拼接 SQL 语句:

<select id="findCourseAll" resultType="Course">
    SELECT * FROM course WHERE 1=1
    <if test="cid != 0">
        AND cid = #{cid}
    </if>
    <if test="cname != null">
        AND cname = #{cname}
    </if>
    <if test="tid != null">
        AND tid = #{tid}
    </if>
</select>

2. 使用 <choose> 标签

语法

<choose>
    <when test="条件">满足条件的语句</when>
    <otherwise>满不满足条件的语句</otherwise>
</choose>

示例

通过 <choose> 标签,可以实现类似 Java 中 switch 的结构:
条件有先后顺序,越优先要先写 一旦匹配后面不执行

<select id="findCourseAllChoose" resultType="com.yk.bean.Course">
    <include refid="cousql"/>
    <where>
        <choose>
            <when test="cname != null">
                AND cname=#{cname}
            </when>
            <otherwise>
                AND 1=1
            </otherwise>
        </choose>
    </where>
</select>

3. 使用 <where> 标签

特性

  1. 动态添加 WHERE 关键字: 若无条件则不添加;有条件时自动添加 WHERE
  2. 自动去除冗余的 ANDOR: 例如,对于开头为 AND 的语句进行处理。

示例

<select id="findCourseAllWhere" resultType="Course" parameterType="course">
    SELECT * FROM course
    <where>
        <if test="cid != 0">
            AND cid = #{cid}
        </if>
        <if test="cname != null">
            AND cname = #{cname}
        </if>
        <if test="tid != null">
            AND tid = #{tid}
        </if>
    </where>
</select>

4. 使用 <set> 标签

特性

主要用于更新操作,其功能和 <where> 类似,以 SET 开头,支持动态字段更新。该标签会自动处理内容前的逗号。

示例

<update id="updateCourseSet" parameterType="course">
    UPDATE course
    <set>
        <if test="cname != null">
            cname = #{cname},
        </if>
        <if test="tid != null">
            tid = #{tid},
        </if>
    </set>
    <where>
        cid = #{cid}
    </where>
</update>

5. 使用 <foreach> 标签

特性

  • item: 当前元素
  • index: 元素索引
  • collection: 传入的数组或集合
  • open: 开始符
  • close: 结束符
  • separator: 元素间隔符

示例

对于数组参数:

<select id="findCourseAllFor" resultType="com.yk.bean.Course">
    <include refid="cousql"/>
    <where>
        <foreach collection="array" item="x" open="(" separator="," close=")">
            #{x}
        </foreach>
    </where>
</select>

对于集合参数:

<insert id="addStudent">
    INSERT INTO student(sname, birthday, ssex, classid)
    VALUES
    <foreach collection="list" item="stu" separator=",">
        (#{stu.sname}, #{stu.birthday}, #{stu.ssex}, #{stu.classid})
    </foreach>
</insert>

6. 使用 <bind> 标签

<bind> 标签用于定义上下文变量,在动态 SQL 中提升灵活性。
${}和#{}的区别:

  • ${} :字符串的替换 不能防止sql注入

  • #{} :预处理sql语句 ?占位 preparedstatment进行防止sql注入

    模糊查询
    方案一 :concat
    select * from student where sname like concat('%',#{v},'%')
    方案二: 在业务层传入
    select * from student where sname like #{v}
    方案三: sql语法
    select * from student where sname like "%"#{v}"%"

示例

<select id="findCourseAllS" resultType="student">
    <bind name="keyn" value="'%' + _parameter + '%'" />
    SELECT * FROM student WHERE sname LIKE #{keyn}
</select>

7. 主键回填

在插入操作中,可以使用 useGeneratedKeys 属性来实现主键的自动回填。

示例

<insert id="insertClass" parameterType="com.yk.bean.ClassNa" useGeneratedKeys="true" keyProperty="classid">
    INSERT INTO class (classname)
    VALUES (#{classname})
</insert>

总结

动态 SQL 是一种强大而灵活的工具,允许开发者根据需要生成适合的 SQL 语句。通过合理使用各类标签,可以提高 SQL 代码的可读性、可维护性和安全性。掌握这些动态 SQL 技巧将有助于构建更加高效和安全的应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值