文章目录
动态SQL
什么是动态SQL?
就是当你使用select语句去创建Xml条件查询(ifSelecte),且此条件查询中的条件包含(name、id、entrydate,userName、gender…)时,你会发现当你想要去查询一个只查询关于gender的条件查询,并使用此Xml条件查询(ifSelecte),你会发现此时什么也查不出来:
而如果使用动态查询SQL的话就不会出现上述情况:
一、if 与 where
1、概念
if标签:当做条件查询的时候就可以用此标签来去完成动态SQL语句。
if标签中的test属性:此属性是用来做写入判断条件,是否要执行此if语句。
where标签:此标签可以避免当只执行一条语句的时候会有SQL语法错误,简单来说:当设置此标签时,条件查询中的where以及and这两个关键字可以直接省去。
2、使用语法
<select id="接口的方法名" resultType="返回值的类型">
select from 表名
<where>
<if test="条件语句1">
<!--sql语句-->
</if>
<if test="条件语句2">
<!--sql语句-->
</if>
<!--。。。-->
</where>
order by update_time desc
</select>
3、实例
Xml代码:
<select id="moveIfXmlSelectEmp" resultType="com.chyb.test2.pojo.Emp">
select * from emp
<where>
<if test="name != null">
name like(concat('%',#{name},'%'))
</if>
<if test="gender != null">
gender = #{gender}
</if>
<if test="start != null and end != null">
between #{start} and #{end}
</if>
</where>
order by update_time desc
</select>
测试代码:
// 调用你映射(Mapper)接口(此接口是创建方法的接口)自动封装的实体类,
@Autowired
private EmpMapper userMapper;
// 动态sql,Xml条件查询
@Test
public void testMoveIfXmlSelectEmp(){
List listEmp = userMapper.moveIfXmlSelectEmp(null,(short)1,null,null);
listEmp.stream().forEach(emp ->{
System.out.println(emp);
});
运行结果:
注意
1、在使用if标签的时候要明确你的条件判断是什么。
2、在写入条件的时候,你要对参数列表name变量进行判断,此时就不需要使用#{}而是直接使用name,因为if标签里面的test属性是是使用的java的语句而不是使用sql语句,所以test里面进行判断所需要调用的变量,可以直接调用不需要在加上#{}(参数占位符)。
二、set 与 if
1、概念
set标签:此标签与where标签很像,不过就是此标签是用来维护update更新语句的标签,当使用set标签时,此条update语句将不需要在写set关键字以及需要修改数据之间的字符“,”。
if标签中的test属性:当在set标签内使用if标签的时候,此时的test属性就不是用来写条件判断语句的,而是用来写入,你创建实体类中的变量,当你只想在原数据的基础上修改name属性,而此时就可以将所有修改数据都进行一个判断,并在此test的属性中写入对应的实体类的变量名,这样子当传回来的值为“null”值时就不会修改此属性,保留原来的属性值。
(简单来说:在test属性中写入实体类中的变量名,这时他会自动判断该值是否为“null”若为“null”将·不会修改此属性,保留原来的属性值)
2、使用语法
<update id="接口的方法名">
update emp
<set>
<if test="userName"> username=#{userName}, </if>//userName:实体类中的变量名
<if test="name"> name = #{name}, </if>//name:实体类中的变量名
<if test="gender"> gender=#{gender} </if>//gender:实体类中的变量名
<!--.....需要修改的字段-->
</set>
where id = #{id}
</update>
3、实例
Xml代码:
<update id="moveUpdateEmp">
update emp
<set>
<if test="userName"> username=#{userName}, </if>
<if test="name"> name = #{name}, </if>
<if test="gender"> gender=#{gender}, </if>
<if test="image"> image= #{image}, </if>
<if test="depId"> dept_id=#{depId}, </if>
<if test="updateTime"> update_time=#{updateTime} </if>
</set>
where id = #{id}
</update>
测试代码:
// 调用你映射(Mapper)接口(此接口是创建方法的接口)自动封装的实体类,
@Autowired
private EmpMapper userMapper;
// 动态SQL,Xml更新测试
@Test
public void moveXmlUpdate(){
Emp testEmp = new Emp();
testEmp.setId(1);
testEmp.setUserName("21234");
userMapper.moveUpdateEmp(testEmp);
}
运行结果:
三、foreach
1、概念
foreach标签:看到此标签的人肯定会想到“增强for循环”,实际上此标签与它差不多也是用来做循环用的,列如当你需要批量删除表中的数据时,而删除的条件就是 id in(1,2,3),此时就可以使用foreach标签来去完成此次批量删除。
在你做批量删除的语句为:delect from tableName where id in (1,2,3);
而此时你所需要循环的值只有:1、2、3,而其他的值就需要属性来去进行拼接
collection属性:在上述语句中所填的值为: ids;此值是填写在你调用方法时传递过来的变量名(一般类型为:字典、数组)
item属性:在上述语句中所填的值为 : id;此值代表着需要做出判断的值
separaor属性:在上述语句中所填的值为 :“,” ;此值代表着循环的中间值需要拼接的值
open属性:在上述语句中所填的值为 :“(”;此值代表着在循环前需要拼接的值
close属性:在上述语句中所填的值为 :“)”;此值代表着在循环结束后需要拼接的值
2、使用语法
<delete id="接口的方法名">
delete from tableName where id in <!--id:需要做出循环判断的字段-->
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id<!--用来循环的值-->}
</foreach>
</delete>
3、实例
Xml代码:
<delete id="moveDeletes">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
测试代码:
// 调用你映射(Mapper)接口(此接口是创建方法的接口)自动封装的实体类,
@Autowired
private EmpMapper userMapper;
// 动态SQL,Xml批量删除操作
@Test
public void moveXmlDeletes(){
List<Integer> ids = Arrays.asList(4,5,6);
userMapper.moveDeletes(ids);
}
运行结果:
四、sql、include
1、概念
作用:当你使用select或者其他需要返回多个字段的时候,这时我们可以使用“*”来直接输出全部的值,但是学过Mysql索引的肯定知道这样子的查询效率会降低,但是要是将全部的字段名都写出来又太麻烦就出现了这两个标签来简化了此操作。
sql标签:此标签可将你指定的字段名给绑定起来
id属性:此属性是sql标签的属性,当include标签进行连接时可以通过此属性来进行建立连接
include标签:此标签是用来调用sql标签中的字段名。
refid属性:此属性是include标签的属性,用来与sql标签建立连接用的。
2、使用语法
<sql id="idName">id, username, password, name, gender, image, job, entrydate<!--写入需要的字段名并以","连接--></sql>
<select id="ifXmlSelectEmp" resultType="com.chyb.test2.pojo.Emp">
select <include refid="idName"/> from emp
</select>
3、实例
Xml代码:
<sql id="commonSelect">id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time</sql>
<select id="moveIfXmlSelectEmp" resultType="com.chyb.test2.pojo.Emp">
select
<include refid="commonSelect"/>
from emp
<where>
<if test="name != null">
name like(concat('%',#{name},'%'))
</if>
<if test="gender != null">
gender = #{gender}
</if>
<if test="start != null and end != null">
between #{start} and #{end}
</if>
</where>
order by update_time desc
</select>
测试代码:
// 调用你映射(Mapper)接口(此接口是创建方法的接口)自动封装的实体类,
@Autowired
private EmpMapper userMapper;
// 动态sql,Xml条件查询(使用sql、include)
@Test
public void testMoveIfXmlSelectEmp(){
List listEmp = userMapper.moveIfXmlSelectEmp(null,(short)1,null,null);
listEmp.stream().forEach(emp ->{
System.out.println(emp);
});
}
运行结果:
五、trim
概念
作用:和if标签搭配起来用,可以完成动态的有规律的内容,比如在插入一条数据时,需要给出指定的字段名,和对应的vlaue,而且还不可以进行动态的去判断是否插入此字段,这时就可以使用trim标签即可动态的去插入字段。
trim中的属性:
prefix:此属性是设置在执行trim标签语句中的内容之前,进行插入的字符。
suffix:此属性是设置在执行trim标签语句中的内容之后,进行插入的字符。
suffixOverrides:此属性是完成动态的重要的属性,就是将多余的字符(你设置此属性的字符)删除掉从而达到动态插入的作用,列如在插入语句中的字符“,”。
使用语法
这里我就拿插入来进行示范
<insert>
insert into tableName
<!--这里是动态的设置需要进行赋值的字段名-->
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="className != null and className != ''"> class_name</if>
<if test="total!= null and total != ''"> ,total </if>
</trim>
<!--这里是动态的设置是否传递变量(注意此时的prefix是 “values (”)-->
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="className != null and className != ''"> #{className}</if>
<if test="total!= null and total != ''"> ,#{total} </if>
</trim>
</insert>
实例
XML代码
<insert id="addClass">
insert into class
<trim prefix="(" suffix=") " suffixOverrides=",">
<if test="className != ''"> class_name, </if>
<if test="classBoss != '' "> class_boss, </if>
<if test="monitor != ''"> monitor , </if>
<if test="total != null"> total , </if>
<if test="classHelp != ''"> class_help , </if>
<if test="counsellor != ''"> counsellor , </if>
<if test="updateTime != null"> update_time, </if>
<if test="createTime != null"> create_time </if>
</trim>
<trim prefix=" values (" suffix=")" suffixOverrides=",">
<if test="className != ''"> #{className}, </if>
<if test="classBoss != ''"> #{classBoss} , </if>
<if test="monitor != ''"> #{monitor} , </if>
<if test="total != null"> #{total} , </if>
<if test="classHelp != ''"> #{classHelp} , </if>
<if test="counsellor != ''"> #{counsellor}, </if>
<if test="updateTime != null"> #{updateTime}, </if>
<if test="createTime != null"> #{createTime} </if>
</trim>
</insert>
传递过来的值为:
classManage(
id=null,
total=null,
className=“软件2班”,
classBoss=‘’,
monitor=‘’,
counsellor=‘’,
classHelp=‘’,
updateTime=2024-11-20T20:47:00.023635800,
createTime=2024-11-20T20:47:00.023635800
)
数据库的默认值参数
运行结果
此时数据库里面的内容为:
注意
1、在使用itrim标签时注意别把每个间隔的 “,” 给漏掉了,上面的suffixOverrides属性只是将多余的 “,” 给删除掉,并不是自动添加 “,”
2、在插入语句中使用trim需要用到两次,注意,在这两次当中的每个if标签中的条件判断必须保持一致,不然很有可能会报错
3、在插入语句中使用trim进行给values赋值时,属性prefix应当赋值应当为"values (",而不是“(”。