根据业务不同,编写的sql语句不会是简单的select * from xxx。很多时候是多条件的查询,同时以前在编写jdbc代码时要进行输入参数的判断,防止输入参数为空,导致sql语句执行失败,等等之类的情况,第五节就将描述如何在mybatis中是实现这些判空,拼接等操作。
select直接写法:
select * from flower where name = #{param1} and production = #{param2}
问题:如果输入的参数为空,如果进行判空
一、输入条件的判断,<if test = “”></if>
传入参数name, production
List<Flower> selectMore(String name,String production);
mapper.xml文件中:
<mapper namespace="com.bjsxt.mapper.FlowerMapper">
<!--if标签
if(test){..}
if(test){..}
-->
<select id="selectMore" resultType="flower">
SELECT * from flower where
<!--OGNL表达式-->
<!--只有当第一个参数param1满足非空且不等于空字符串 if标签里面的sql语句才会被拼接进去-->
<if test="param1!=null and param1!=''">
name=#{param1}
</if>
<if test="param2!=null and param2!=''">
and production=#{param2}
</if>
</select>
</mapper>
按照上述写法,假设输入两个参数均为空,那么sql就变成了
select * from flower where
语句错误,提出改进如下,写为where 1=1
<mapper namespace="com.bjsxt.mapper.FlowerMapper">
<!--if标签
if(test){..}
if(test){..}
-->
<select id="selectMore" resultType="flower">
SELECT * from flower where 1=1
<!--OGNL表达式-->
<!--只有当第一个参数param1满足非空且不等于空字符串 if标签里面的sql语句才会被拼接进去-->
<if test="param1!=null and param1!=''">
and name=#{param1}
</if>
<if test="param2!=null and param2!=''">
and production=#{param2}
</if>
</select>
</mapper>
上面的例子引出了sql动态拼接,其实就是使用一些标签加以规范mapper里面的sql写法完成sql拼接
对于上面例子中的where的解决方案,并不是mybatis所提倡的,mybatis提供了where标签来改进这个问题:
<!--Where标签的作用:会自动的增加where关键字,并且会把多余的第一个and去掉-->
<select id="selectMore2" resultType="flower">
SELECT * from flower
<!--OGNL表达式-->
<where>
<if test="param1!=null and param1!=''">
<!--第一个条件前的and可加可不加-->
name=#{param1}
</if>
<if test="param2!=null and param2!=''">
and production=#{param2}
</if>
</where>
</select>
下面介绍在where标签中使用的另外一组标签choose when
<!--
if(){..}
else if(){..}
else if(){..}
else {}
-->
<select id="selectMore4" resultType="flower">
SELECT * from flower
<where>
<choose>
<when test="param1!=null and param1!=''">
name=#{param1}
</when>
<when test="param2!=null and param2!=''">
and production=#{param2}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
那么这种写法跟上面的ififif的区别就是,这种写法更类似于if else ,只找到满足条件的一个语句拼接上去
SqlSession sqlSession = factory.openSession(true);
//[4]执行方法
FlowerMapper mapper = sqlSession.getMapper(FlowerMapper.class);
情况一:
List<Flower> list = mapper.selectMore4("玫瑰花","");
情况二:
List<Flower> list = mapper.selectMore4("玫瑰花","中国");
情况一和情况二的日志输出相同:
这个结果就表明,当找到了一个满足情况的sql后,后续的sql均不会被拼接上去
那么如果所有条件都不满足条件呢?就要额外添加一个otherwise标签
作用:where 1 = 1