Mybatis的映射文件中,前面我们的SQL都是比较简单的,有些时候业务逻辑复杂时,我们的SQL是动态变化的,此时在前面的学习中我们的SQL就不能满足要求了。
有时候的参数是不一定的,以前我们学的都是固定死的,参数的个数也是确定的,动态SQL的参数是不一定的。
在这里我们主要讲解一下if和foreach两种:
准备条件:配置方面用的是代理方式。跟mybatis的的代理开发_Outlier_Lin的博客-优快云博客这个是一样的。
关于if:(我们查询一个但有多个限制条件)
<mapper namespace="com.outlier.mapper.UserMapper">
<select id="findByCondition" resultType="user" parameterType="user">
select * from user
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
<if test="password!=null">
and password=#{password}
</if>
</where>
</select>
</mapper>
进行解释说明一下:这里引入了where标签,就相当于查询里面是一样的。这里关于if标签需要着重讲解一下:if里面的属性test的意思是测试。里面写一个布尔表达式。
这里的id是int型的,如果id为0,在数据库中肯定是没有的,那么就会跳过该标签内部的语句,如果不为0,那么就会把下面的语句和上面的select * from user进行拼接,下面也同理,如果全部都有则最后拼接成为:select * from user where and id=#{id}and username=#{username}and password=#{password}。
假如其中一个没有:例如没有username则会拼接成:select * from user where and id=#{id}and password=#{password}。这样就可以根据用户自己输入的不同参数来进行查询了。
代码测试实例:
全部都有:
其中一个没有:
两个没有:
关于foreach:(比如当我们需要查询id为1,2,3多个这样的数据)
代码实例:
在接口中的的代码:
在映射文件中的代码:
<select id="findByIds" parameterType="list" resultType="user">
select *from user
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
对里面的标签进行阐述:select这些标签就不用说了,我们就说说foreach标签
里面的collection属性表示的是集合的类型,如果我们的参数传的是list我们就写list,如果我们参数里面传的是数组,则传array
open属性:表示的是从什么开始(因为我们这个相当于是拼接,原本的查询代码是select *from user where id in(1,2,3))现在上面我们只写了select *from user 剩下的要我们自己拼接,所以open的意思就是从什么开始,我们这里的意思是从id in ( 开始
close表示的是:从什么结束,我们最后是以“ )”结束。
item表示的项,用来接受集合里面的参数,就像foreach里面写在循环条件里面的那个参数,用来一 一 得到集合里面的值(里面的参数名字可以随便命名)
separator:表示的是分隔符的意思,我们在括号中每个id是以“ ,(逗号)”来进行分割的,这里我们也是要进行分割的。
最后在内部一 一取出id里面的值
测试代码:
效果:
最后我们再说一下sql片段的抽取:
我们上面发现select标签中,我们的select * from user进行重复写了,这样不仅仅麻烦,而且在后面维护的时候,还要挨着改,很麻烦,我们就进行抽取:
这里我们需要用到标签:sql 里面的属性id就是为了好引用。然后把抽取的sql语句写在内部.
然后后面引用的时候需要用到<include>标签。里面的属性 refid就是表示引用的id是什么。
最后总结一下:我们无论是用if还是foreach我们其实都是进行的是拼接。然后常用的是if