这片文章是对自己学习的总结。
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>标签。