Mybatis学习笔记:动态SQL

这片文章是对自己学习的总结。


SQL元素和参数

在Mybatis的CRUD语句中,可以通过设置一些参数或者标签,来让我们写SQL语句时更加便利。

  • SQL元素

SQL元素的作用就是可以定义一条SQL的一部分,然后以后的SQL语句都可以直接引用它来减少代码量。最常用的场景就是,我们在一个dao层接口的配置文件中进行各种各样的查询,但每次查询的结果都是相同的列。比如下面三条SQL代码

<select id="findById" parameterType="java.lang.Integer" resultType="role">
    select name, id, note, sex, age from t_role where id = #{id};
</select>

<select id="findByName" parameterType="java.lang.String" resultType="role">
    select name, id, note, sex, age from t_role where name = #{name};
</select>

<select id="findUpAge" parameterType="java.lang.Integer" resultType="role">
    select name, id, note, sex, age from t_roel where age > #{age};
</select>

我们发现,这三个查询每次都是要查询name, id, note, sex, age这四个列的值。但每次都这样写重复的列名显得很繁琐,所以我们可以使用SQL元素来让代码显得更精简。

我们可以将name, id, note, sex, age定义成一个SQL元素并取名为roleColumns。

<sql id="roleColumns">
    name, id, note, sex, age
</sql>

然后SQL语句中就可以引用roleColumns。

<select id="findById" parameterType="java.lang.Integer" resultType="role">
    select <include refid="roleColumns"/> from t_role where id = #{id};
</select>

这效果和老老实实将列名一个个写出来是一样的。

最后再说一下SQL元素和各个标签的级别关系:这两者是同级的,都是<mapper>下的同级子标签。

<select id="findById" parameterType="java.lang.Integer" resultType="role">
    select <include refid="roleColumns"/> from t_role where id = #{id};
</select>
<mapper id="com.itheima.UserDao">
    <sql id="roleColumns">
        name, id, note, sex, age
    </sql>
    <select id="findById" parameterType="java.lang.Integer" resultType="role">
        select <include refid="roleColumns"/> from t_role where id = #{id};
    </select>
</mapper>
  • 参数

参数暂时先不说吧·······


#{}和${}的区别

#{}比${}安全。传统的Mysql连接和执行中,为了防止SQL注入问题,会使用到PreparedStatement。使用#{}就相当于使用PreparedStatement。用${}就相当于使用直接赋值。。


动态SQL

  • if标签

if标签里有一个判断,满足判断的话就有代码块中的元素就会被加入到总的sql语句中。比如下面的例子

<select id="com.luckincoffee" resultType="Role" parameterType="String">
    select * from Role where 1 = 1
    <if test="roleName != null">
        and role_name = #{roleName}
    </if>
</select>

如果传进来的参数是null,那执行的SQL语句就是select * from Role where 1 = 1;如果传进来的参数不是null,那执行的SQL语句就是select * from Role where 1 = 1 and role_name = ?。

  • choose,when,otherwise标签

这三个标签是配套使用的,他们的作用相当于switch,case,default。比如下面的例子

<select id="com.luckincoffee" resultType="Role" parameterType="String">
    select * from Role where 1 = 1
    <choose>
        <when test="roleName != null">
            and role_name = #{roleName}
        </when>
        <when test="id != null">
            and id = #{id}
        </when>
        <otherwise>
            and id = 1
        </otherwise>
    </chose>    
</select>

上面这个例子就是,如果提供了roleName就通过roleName查找,提供了id就通过id查找,两者都没提供的话,就默认查找id为1的用户。

  • where标签

在if标签的例子中,我们为了防止SQL语句出现错误,特地在where后加上 1=1 这样的恒等式。

<select id="com.luckincoffee" resultType="Role" parameterType="String">
    select * from Role where 1 = 1
    <if test="roleName != null">
        and role_name = #{roleName}
    </if>
</select>

如果不这样写,写成下面的语句

<select id="com.luckincoffee" resultType="Role" parameterType="String">
    select * from Role where
    <if test="roleName != null">
        and role_name = #{roleName}
    </if>
</select>

当roleName = null时,SQL语句就变成 select * from Role where 。这样会出现错误,所以我们不得不加上1 = 1这样的语句。其实我们大可不这样写,可以使用where标签,比如下面这样。

<select id="com.luckincoffee" resultType="Role" parameterType="String">
    select * from Role 
    <where>
        <if test="roleName != null">
            and role_name = #{roleName}
        </if>
        <if test="id != null">
            and id = #{id}
        </if>
    </where>
</select>

where只有在至少有一个子元素才会插入,并且会智能决定删不删除 and 和 or。

需要注意的是,如果where标签下使用when等非if标签的语句,那么这些非if标签的语句是不受where影响的。where不会给他们自动加上and。

  • foreach标签

foreach标签可以看MyBatis学习笔记:映射器中的<foreach>标签

猜你喜欢

转载自blog.csdn.net/sinat_38393872/article/details/102716596
今日推荐