本节主要介绍动态SQL,其主要用于解决用户提交的查询条件不确定的情况。用户提交的查询条件不同,执行的SQL也就不同。若针对每种情况都一一列出来,将会出现大量SQL语句。针对这样的情况可以用动态SQL解决。
动态SQL的实现是通过MyBatis提供的各种标签对查询条件做出判断实现动态拼接SQL语句的过程,其条件判断是通过OGNL表达式实现。常用的标签有
< < 小于号
> > 大于号
& & 和
' ' 单引号
" " 双引号
1.源码下载地址
2.测试准备(部分)
/**商品信息*/
create table productinfo(
id int primary key auto_increment, --主键
proName varchar(50),--商品名称
proNo varchar(50), --商品编号
proDescription varchar(200),--商品描述
proAmount decimal(10,2)--价格
);
/**
* 保存
*/
public void saveProductInfo(ProductInfo info);
/**
* 查询测试标签、 标签、标签
* @param statement 查询id
* @param productInfo 参数
* @return
*/
List findProductInfo(String statement,ProductInfo productInfo);
//查询测试foreach标签
List findProductInfoForeach(String statement, Object obj);
//更新
void updatePro(ProductInfo productInfo);
3.常用标签介绍
if标签的执行,当test的值为true时,会将其包含的SQL片段拼接到SQL语句中。如果出现test都为false时,就会只有where,这时语句是有问题的,在where后添加一个"1=1"(全查)或"1!=1"(全不查)的条件。
<!-- if标签 -->
<select id="ifTags" resultType="ProductInfo">
select * from productinfo where 1=1
<if test="proName != null and proName != ''"><!-- 商品名称不为空 -->
and proName = #{proName}
</if>
<if test="proAmount > 10"><!-- 商品金额大于10 -->
and proAmount > #{proAmount}
</if>
</select>
使用where标签时,当有查询条件时,会自动加上where子句。需要注意:第一个if标签中SQL片段,可以不包含and,其他后续的必须包含and。
<!-- where标签 -->
<select id="whereTags" resultType="ProductInfo">
select * from productinfo
<where>
<if test="proName != null and proName != ''"><!-- 商品名称不为空 -->
and proName = #{proName}
</if>
<if test="proAmount > 10"><!-- 商品金额大于10 -->
and proAmount > #{proAmount}
</if>
</where>
</select>
choose标签有点像java中的开关语句switch..case..功能(case 语句含beak)。该标签只可以包含
<select id="chooseTags" resultType="ProductInfo">
select * from productinfo
<where>
<choose>
<when test="proName != null and proName != ''"><!-- 商品名称不为空 -->
and proName = #{proName}
</when>
<when test="proAmount > 10"><!-- 商品金额大于10 -->
and proAmount > #{proAmount}
</when>
<otherwise>
and 1 != 1
</otherwise>
</choose>
</where>
</select>
该标签主要用于实现对数组和集合的遍历。
collection:表示传入过来的参数的数据类型。该参数为必选。要做 foreach 的对象,作为入参时,List 对象默认用 list 代替作为键,数组对象有 array 代替作为键,Map 对象没有默认的键。
大致可分为以下三种情况:
(1).如果传入的是单参数且参数类型是一个List集合,collection属性值为list .
(2).如果传入的是单参数且参数类型是一个array数组,collection的属性值为array .
(3).如果传入的参数是多个,此时最好是将它们封装成一个Map,此时collection属性值就是传入的List或array对象在自己封装的map里面的key.
item: 循环体中的具体对象。
index:在list和数组中,index是元素的序号;在map里index 是元素的 key。
open:表示该语句以什么开始。
close:表示该语句以什么结束。
separator:表示在每次进行迭代之间以什么符号作为分隔符。
<!-- foreach 单参数:数组array -->
<select id="findProductInfoForeachArray" resultType="ProductInfo">
select * from productInfo
<if test="array != null and array.length > 0">
where id in
<foreach collection="array" open="(" close=")" separator="," item="vid">
#{vid}
</foreach>
</if>
</select>
<!-- foreach 单参数:基本类型 list-->
<select id="findProductInfoForeachListInteger" resultType="ProductInfo">
select * from productInfo
<if test="list != null and list.size > 0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="vid">
#{vid}
</foreach>
</if>
</select>
<!-- foreach 单参数:自定义对象 list
List<ProductInfo> param = new ArrayList<ProductInfo>();
param.add(new ProductInfo(11));
param.add(new ProductInfo(23));
-->
<select id="findProductInfoForeachListObj" resultType="ProductInfo">
select * from productInfo
<if test="list != null and list.size > 0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="pro">
#{pro.id}
</foreach>
</if>
</select>
<!-- foreach 多参数:map
Map<Object,Object> map = new HashMap<Object,Object>();
map.put("proName", "商品4号");
map.put("ids", new Object[]{3,4,5,6,7});
-->
<select id="findProductInfoForeachMap" resultType="ProductInfo">
select * from productInfo where proName = #{proName}
<if test="ids != null">
and id in
<foreach collection="ids" open="(" close=")" separator="," item="vid">
#{vid}
</foreach>
</if>
</select>
该标签主要用于定义SQL片段,以便于其他SQL复用。其它标签使用
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。