8.MyBatis动态SQL标签

 

1. if标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.HashMap;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class Main {

public static void main(String[] args) {
SqlSession session=SqlSessionUtil.getSession();
StudentDao dao=session.getMapper(StudentDao.class);
Map map=new HashMap();
map.put("name", "a");
map.put("startAge", 21);
map.put("endAge", 30);
System.out.println(dao.searchStudent(map));

SqlSessionUtil.close(SqlSessionUtil.getSession());
}
}

StudentDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.node.dao.StudentDao">

<select id="searchStudent" resultType="student">
select * from student where 1=1

<!--
if单分支条件表达式
属性
test, 条件表达式,当表达式为真,则将if中的内容拼接到SQL语句中

注意:test中使用的是一种叫OGNL的表达式,
如果参数对象为Map集合,那么name表示的是Map集合中的key值,obj.get("name")
如果参数对象为实体类,那么name表示类中的属性名, obj.getName()
MyBatis会根据参数类型决定是使用obj.get("name")还是obj.getName();
-->

<if test="name != null and name.trim != ''">
and name like '%' #{name} '%'
</if>

<if test="startAge != null and startAge > 20">
and age > #{startAge}
</if>

<if test="endAge != null and 40 > endAge">
and #{endAge} > age
</if>
</select>
</mapper>

2. where标签

StudentDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.node.dao.StudentDao">

<select id="searchStudent" resultType="student">
select * from student where 1=1

<!--
where 由于自动where条件关键字
如果where标签中拥有内容,那么会在语句的后面自动添加一个where关键字,
并且会自动地取代where标签中的一个逻辑运算符and或者or
-->
<where>
<if test="name != null and name.trim!=''">
and name like '%' #{name} '%'
</if>

<if test="startAge!=null and startAge>20">
and age > #{startAge}
</if>

<if test="endAge!=null and 40>endAge">
and #{endAge} > age
</if>
</where>
</select>
</mapper>

3. choose标签

StudentDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.node.dao.StudentDao">
<select id="searchStudent" resultType="student">
select * from student
<where>
<!-- choose类似于java中switch case语句 -->
<choose>
<!-- when 标签类似于case语句,当when的test属性为真的时候,
则将这个when中的语句拼接到SQL中,那么其他的when将不再执行
-->
<when test="name!=null and name.trim!=''">
name like '%' #{name} '%'
</when>
<when test="startAge!=null and startAge>20">
age>#{startAge}
</when>
<when test="endAge!=null and 40>endAge">
#{endAge}>age
</when>
<!-- otherwise 当所有的when都为假的时候,将otherwise的内容拼接到SQL中,
这个标签是可选的
-->
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
</mapper>

4. foreach标签

collection是这里面比较难得下面我们详细介绍一下实际中的运用:

  • 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  • 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  • 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可
  • 如果传入的参数是多个的时候,我们也可以放在实体类中(这种实际用到也是非常多的)

(1) foreach实现in查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class Main {

public static void main(String[] args) {
SqlSession session=SqlSessionUtil.getSession();
StudentDao dao=session.getMapper(StudentDao.class);

List<Integer> list=new ArrayList<Integer>();
list.add(21);
list.add(23);
list.add(24);
list.add(26);
System.out.println(dao.searchStudentInAge(list));

// Map map=null;
// map.put("ages", list);
// dao.searchStudentInAge(map);

SqlSessionUtil.close(SqlSessionUtil.getSession());
}
}

StudentDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.node.dao.StudentDao">
<select id="searchStudentInAge" resultType="student">
select * from student
<where>
<!-- 如果参数集合不为null,并且长度大于0,则进入if,使用循环拼接SQL
如果list为空或者长度为0,则foreach标签会出错-->
<if test="list!=null and list.size>0">
age in
<!-- foreach 迭代标签,用于循环拼接SQL语句
属性
collection 需要被迭代的集合或数组
如果参数对象是集合,那么填写list
如果参数对象是数组,那么填写array
如果参数对象是实体类或Map collection="ages"

item 被迭代的集合的当前元素对象
open 拼接的SQL以什么符号开始,这个属性只在语句中出现1次
close 拼接的SQL以什么符号结束,这个属性只在语句中出现1次
separator 多个值之间是以什么符号进行分割的,这个属性的值在语句中出现多次
-->
<foreach collection="list" item="obj" open="(" close=")" separator=",">
#{obj}
</foreach>
</if>
</where>
</select>
</mapper>

(2) foreach实现批量插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

public class Main {

public static void main(String[] args) {
SqlSession session=SqlSessionUtil.getSession();
StudentDao dao=session.getMapper(StudentDao.class);

List<Student> list=new ArrayList<Student>();
Student s1=new Student();
s1.setName("An");
s1.setAge(36);
Student s2=new Student();
s2.setName("Bn");
s2.setAge(37);

list.add(s1);
list.add(s2);
dao.batchInsertStudents(list);
SqlSessionUtil.getSession().commit();;

SqlSessionUtil.close(SqlSessionUtil.getSession());
}
}

StudentDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.node.dao.StudentDao">
<insert id="batchInsertStudents">
insert into student(name,age) values
<foreach collection="list" item="obj" separator=",">
<!-- 如果集合泛型为实体类或Map集合,那么obj则为集合中的元素
我们可以使用类似与EL语句获取obj中的属性对用的数据或者key对应的数据
由于我们的List集合泛型成Student,因此obj为Student对象,
因此#{obj.name}是获取Student类中的name属性对应的数据 -->
(#{obj.name},#{obj.age})
</foreach>
</insert>
</mapper>

5. sql标签

StudentDao.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.node.dao.StudentDao">

<!-- sql标签是SQL语句的一个片段,它可以是SQL语句的任何一个部分
这个sql片段不能独立运行,只能被其他的SQL映射引入,用于SQL语句的重用
-->
<sql id="selectStudent">
select name,age from student
</sql>
<sql id="selectStudentByIdWhere">
where id=#{xxx}
</sql>

<select id="selectStudentAll" resultType="Student">
<!-- include标签,用于引入某个SQL片段
属性
refid: 表示本地的某个SQL片段的id
-->
<include refid="selectStudent"/>
</select>

<select id="selectStudentById" resultType="Student">
<include refid="selectStudent"/>
<include refid="selectStudentByIdWhere"/>
</select>
</mapper>