Mybatis常用动态sql用法

对数据库进行操作无非有四类:增、删、改、查;但我们进行实操时常常有各种不同的需求,这些需求有时区别不大,或许只有一个字段、一个参数的区别,那我们要实现这个需求,再写一个方法就会有些重复繁杂,而且调用时也会容易出错。

动态sql,很好的解决了上述问题,它可以根据不同条件对sql语句进行拼接,从而可以实现更加灵活准确的操作。

接下来,就来讲述常用的动态sql用法:

  1. if 元素:单条件分支判断

比如说,我现在有两个需求,我想查询学生表里女学生的信息,也想查询每个班级的学生信息;
如果没有学习动态sql,可能需要分别写两个查询方法,但现在我们可以利用动态sql,把这两个需求灵活的融合在同一个方法里;

 select * from student where 1=1
 	<if test="ssex!=null">and ssex=#{ssex}</if> 
 	<if test="classid!=0">and classid=#{classid}</if>

通过 if 标签的test属性来判断性别ssex是否不为空,或班级号classid是否不等于0,如果ssex不为空成立,那么标签之间的sql语句就会被拼接到where后,classid也是同理。

如此这一条sql语句其实可以实现三个需求:查性别、班号、性别和班号,既简单又灵活。但if标签需要特别注意 and 和逗号的使用,因为顺序并不是固定的,可以在where后添加一个恒成立的条件,或者使用where标签。

  1. where :where辅助
select * from student
 	<where>
 	<if test="ssex!=null">and ssex=#{ssex}</if> <if test="classid!=0">and classid=#{classid}</if>
 	</where>

这条sql语句较上面那条使用了where标签,来看看它的作用。我利用log4j.properties来查看最终运行的sql语句。

// ssex==null且classid==0
DEBUG [main] - ==>  Preparing: select * from student 
// ssex==null且classid!=0
DEBUG [main] - ==>  Preparing: select * from student WHERE classid=? 
// ssex!=null且classid!=0
DEBUG [main] - ==>  Preparing: select * from student WHERE ssex=? and classid=? 

从上面的sql执行语句来看:

  • 当条件全都不成立时,表名后并没有where关键字
  • 当条件成立时,表名后会添加一个where关键字,同时会把where后第一个条件的and去掉
  • 当条件成立时,会把where后第一个条件的and去掉

where标签的作用就是这样,它更加方便我们使用动态sql。

  1. choose:多条件分支判断

多条件分支判断和单条件分支判断的作用差不多,但是单条件分支判断可以执行多个条件,而多条件分支判断只能执行一个条件,相当于java的switch case。

select * from student 
<where>
 	<choose>
 		<when test="sid!=0">and sid=#{sid}</when>
 		<when test="sname!=null">and sname=#{sname}</when>
 		<when test="classid!=0">and classid=#{classid}</when>
 		<otherwise></otherwise>
 	</choose>
 </where>
//条件参数
stu.setClassid(1);
stu.setSname("李云");
DEBUG [main] - ==>  Preparing: select * from student WHERE sname=? 

choose标签后有多个条件成立时,它会按照when标签条件的顺序来执行。如上面:sname和classid都成立,但是在sql语句中sname排在classid之前,所以最终执行的是sname条件。

  1. set :修改辅助

set标签常用于对数据库表进行修改操作,它和where标签的作用类似;

  • 在表名后添加一个set关键字
  • 将最后一个要修改的字段后的逗号去掉
update student
	<set>
		<if test="ssex!=null"> ssex=#{ssex},</if> 
		<if test="classid!=0"> classid=#{classid},</if>
		<if test="sname!=null"> sname=#{sname},</if>
	</set>
	<where>sid=#{sid}</where>
//执行语句
DEBUG [main] - ==>  Preparing: update student SET ssex=?, classid=? WHERE sid=? 
  1. trim :万能标签,常用于新增

trim标签有4个属性:

  • prefix:前面加一个
  • prefixOverrides:前面去掉一个
  • suffix:后面加一个
  • suffixOverrides:后面去掉一个

所以trim标签可以代替where标签和set标签,但其最常用的是新增操作。

update student
	<trim prefix="set" suffixOverrides=",">
		<if test="ssex!=null"> ssex=#{ssex},</if> 
		<if test="classid!=0"> classid=#{classid},</if>
		<if test="sname!=null"> sname=#{sname},</if>
	</trim>
<where>sid=#{sid}</where>
//DEBUG [main] - ==>  Preparing: update student set classid=?, sname=? WHERE sid=? 

这是一个修改的例子,在前面加一个set关键字,在最后sname后去掉一个逗号。


insert into student
 <trim prefix="(" suffix=")" suffixOverrides=",">
 	<if test="ssex!=null"> ssex,</if> 
 	<if test="classid!=0">classid,</if>
 	<if test="sname!=null"> sname,</if>
 	<if test="birthday!=null">birthday,</if>
 </trim>
 value
 <trim prefix="(" suffix=")" suffixOverrides=",">
 	<if test="ssex!=null"> #{ssex},</if> 
 	<if test="classid!=0">#{classid},</if>
 	<if test="sname!=null"> #{sname},</if>
 	<if test="birthday!=null">#{birthday},</if>
 </trim>
 //DEBUG [main] - ==>  Preparing: insert into student ( ssex, classid, sname ) value ( ?, ?, ? ) 

这是对于新增的应用,在前面加一个单括号,在最后加另一个单括号,sname后去掉一个逗号。
trim标签如果运用熟练也是非常方便的。

  • foreach:循环标签

foreach循环标签,顾名思义,是用于循环的。

当我想要查询某几个特定sid的学生信息时,要用到in关键字,那么in后面数据要怎么传进去呢?我们都知道同一数据类型的数据可以使用集合和数组,但是parameterType并没有和集合和数组相对应的,这个时候 foreach标签就可以发挥作用了。

foreach标签有6个属性:

  • collection:表名参数类型,array:数组,list:集合
  • open:开始时加什么
  • close:结束时加什么
  • item:要循环的元素(起名)
  • separator:元素之间的分隔符
  • index:当前循环元素的位置下标
//DEBUG [main] - ==>  Preparing: select * from student WHERE sid in ( ? , ? , ? , ? , ? , ? , ? )
select * from student where sid in
 	<foreach collection="list" open=" (" close=")" separator="," item="x">
 		#{x}
 	</foreach> 

对比执行语句,在开始的时候加了一个单括号,各个元素间用逗号分隔,在最后加另一个单括号,对集合起名为x,进行循环。

  1. bind:变量定义标签,常用于模糊查询

bind标签有2个属性:

  • name:变量名
  • value:变量值,其中_parameter指传递进来的参数
<bind name="s" value="_parameter+'%'"/>
 	select * from where sname like #{s};
 //DEBUG [main] - ==>  Preparing: select * from student where sname like ?; 

bind标签是这几个标签中较为难记的,因为涉及到字符串的拼接,所以相比较之下有些复杂。

在此说一下,以上动态sql标签是基于sqlMapper进行的;如果使用注解时要运用动态sql,要注意script标签包裹,具体的动态sql用法和sqlMapper是一样的,在此就不细讲了,希望以上内容对大家有用。最后再放一个注解动态sql的案例。

@Select("")
	public Card findCard(Card c);

你可能感兴趣的:(mybatis,sql,数据库)