MyBatis学习(五):动态SQL

关于动态SQL使用时的传参方式
一般情况下映射文件中不写参数,即省略parameterType项,在传参时,将参数名和参数值put入Map对象中,传递Map类对象。在映射文件中直接#{参数名}使用。

if标签用于无条件查询或者单条件查询
可以用与多条件查询,但是需要把控传入的参数不会造成SQL语句的错误
<if></if>标签中的test表示if成立的条件,test=“”引号内为判断条件,如果成立,直接将if标签内的SQL拼接在前面的SQL语句之后。

基本格式:

			<!-- 通过Map传参,Map中是否含有name键 -->
	        <if test="name!=null">
    			where p.name like concat('%',#{name},'%')
    		</if>
    		<!--可以使用多个if语句-->
    		<if test="id!=null">
    			where p.id = #{id}
    		</if>

where标签 用于无条件查询或者多条件查询
where标签的作用:

  • 起where关键字的作用
  • 可以自动去掉SQL语句中不符合SQL语法规则的and、or等连接符

<where></where>标签和标签一起使用,其基本格式如下:

当where标签内的if标签成立时,会将if标签内的语句连接在SQL语句的后面,如果if标签的语句含有无用的and或者or,则自动删去

			<where>
  				<if test="id!=null">
  					and p.id=#{id}
  				</if>
  				<if test="name!=null">
  					and p.name like concat("%",#{name},"%")
  				</if>
  			</where>

set标签用于数据更新时选择条件更新
set标签的作用(和where标签的作用类似,内部使用if标签):

  • 起set关键字的作用
  • 自动添加逗号

基本格式如下:

    <set>
     	<if test="name != null">name=#{name},</if>
     	<if test="price != null">price=#{price}</if>
    </set>

trim标签:字符串的处理,包括拼接字符和去除字符,可以从首部或者尾部

prefix:给sql语句拼接的前缀
suffix:给sql语句拼接的后缀
prefixesToOverride: 去除sql语句前面的关键字或者字符,该关键字或者字符由prefixesToOverride属性指定,假设该属性指定为”AND”,当sql语句的开头为”AND”,trim标签将会去除该”AND”
suffixesToOverride: 去除sql语句后面的关键字或者字符,该关键字或者字符由suffixesToOverride属性指定

实现where标签功能:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>

实现set标签功能:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

choose标签:用于选择条件查询,或者条件存在互斥
<choose></choose>标签同样和<where>标签一起使用
<choose>标签作为<if><\if>标签的补充,相当于if else的功能,<when></when>标签相当于if,<otherwise></otherwise>标签相当于else ,当所有的when条件都不成立时,choose标签才会执行;如果有一个成立,choose标签语句都不会执行。
当有多个<when></when>标签时,相当于if ,else if, else;只会执行条件最先成立的那一个。choose:选择,选择一个标签执行内的语句执行
基本结构如下:

   		<where>
    			<choose>
    				<when test="price!=null">
    					price > #{price}
    				</when>
    				<when test="name!=null">
    					p.name like concat("%",#{name},"%")
    				</when>
    				<otherwise>
    					p.id = 6
    				</otherwise>
    			</choose>
    		</where>

foreach标签用于多值查询(in)
foreach标签就是用于在使用in进行条件查询时,用于构建in后的内容
foreach标签内含有如下元素:
collection :collection属性的值有三个分别是list、array、map三种,分别对应的参数类型为:List、数组、map集合
item : 表示在迭代过程中每一个元素的别名
index :在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
open :前缀
close :后缀
separator :分隔符,表示迭代时每个元素之间以什么分隔

关于collection参数的问题:
foreach 迭代对象必须是实现 Iterator 接口或者是Map类型的对象。

  • 如果在JAVA代码中直接传入List或者数组,直接使用list、array(使用传入的参数名会报错);
  • 如果传入的参数为map类型或者对象类型,参数应该为属性值。比如传入一个Map类型的对象(对象由HashMap类实例化),collection=“key值”,并且要保证key所对应的value值可以使用Iterator进行迭代。如下所示:
	List<Integer> paramesList=new ArrayList<>();
	paramesList.add(1);
	paramesList.add(2);
	paramesList.add(3);
	int[] paramesArray= {1,2,3};
	Map<String,Object> paramesMap=new HashMap<>();
	paramesMap.put("value1", 1);
	paramesMap.put("value2", paramesList);
	paramesMap.put("value3",paramesArray);
//	List<Product> ps=session.selectList("selectProductForeach", parames);
//	List<Product> ps=session.selectList("selectProductForeach", paramesArray);
	List<Product> ps=session.selectList("selectProductForeach", paramesMap);
//	List<Product> ps=session.selectList("selectProductForeach", c);
	for(Product p:ps)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}
	session.close();
    	<!-- foreach 标签的使用  -->
    	<select id="selectProductForeach" resultType="Product">
    		select * from product where id in 
    		<foreach collection="value3" item="item" index="index" open="(" separator="," close=")">
    			#{item}
    		</foreach>
    	</select>

使用value3或者value4时,均可以正常执行。使用value1会产生**Error evaluating expression ‘value1’. Return value (1) was not iterable.**错误。

如果是使用封装的对象,对象含有List集合属性,可以使用如下操作:

/*
public class Category {
	private int id;
	private String name;
	List<Product> products;
}
public class Product {
	private int id;
	private String name;
	private float price;
	private Category category;
}
*/
Category c=session.selectOne("selectCategoryByID",1);
List<Product> ps=session.selectList("selectProductForeach", c);
	<!-- foreach 标签的使用  -->
    	<select id="selectProductForeach" resultType="Product">
    		select * from product where id in 
    		<foreach collection="products" item="item" index="index" open="(" separator="," close=")">
    			#{item.id}
    		</foreach>
    	</select>

bind标签:实现一次字符串的拼接,在本地以字符串加减的形式实现,避免了使用数据库的concat函数
普通模糊查询和使用bind

 	<!-- -bind标签学习 -->
    	<select id="selectProductByNameNB" resultType="Product">
    		select * from product where name like concat("%",#{name},"%")
    	</select>
     	<select id="selectProductByNameBind" resultType="Product">
    		<bind name="likename" value="'%'+name+'%'"/>
    		select * from product where name like #{likename}
    	</select> 

注意value里字符串拼接的方式,字符使用单引号括起来,变量直接+;但是这样也产生了一个问题:
java代码:

	/**************bind标签学习*************/
	List<Product> ps=session.selectList("selectProductByNameNB", "product1");
	for(Product p:ps)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}
	System.out.println("--------------");
	List<Product> ps2=session.selectList("selectProductByNameBind", "product1");
	for(Product p:ps2)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}

运行结果:
在这里插入图片描述
查询时都是传入直接传入字符串参数,select标签中都是省略了parameterType选项,但是普通模糊查询正确运行,使用bind标签却找不到name的值,此处需要使用Map传值才可以,如下:

	Map<String,Object> param=new HashMap<>();
	param.put("name", "product1");
	List<Product> ps2=session.selectList("selectProductByNameBind", param);
	for(Product p:ps2)
	{
		System.out.println(p.getId()+" "+p.getName()+" "+p.getPrice());
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值