第三章、动态SQL
一、概念
MyBatis提供的SQL语句动态组装功能能处理JDBC的SQL语句拼接需求,
提高了SQL语句的复用性。
二.常用元素
1.if标签
在MyBatis中,<if.>元素是最常用的判断元素,它类似于Java中的if语句,主要用于实现某些简单的条件判断。
Customer.xml
<select id="findCustomerByNameAndJobs"
parameterType="com.lipp.pojo.Customer"
resultType="com.lipp.pojo.Customer">
select * from t_customer
<!--where 1=1 -->
<!-- <where> -->
<trim prefix="where" prefixOverrides="and">
<if test="username !=null and username !=''">
and username like concat('%',#{username}, '%')
</if>
<if test="jobs !=null and jobs !=''">
and jobs= #{jobs}
</if>
</trim>
<!--</where> -->
</select>
测试类
public void findCustomerByNameAndJobsTest(){
SqlSession session = MyBatisUtils.getSession();
Customer customer = new Customer();
customer.setUsername("jack");
customer.setJobs("teacher");
List<Customer> customers =
session.selectList("mapper" + ".CustomerMapper.findCustomerByNameAndJobs",customer);
for (Customer customer2 : customers) {
System.out.println(customer2);
}
session.close();
}
2.trim标签
<trim.>元素用于删除多余的关键字,它可以直接实现<where>元素的功能。
其中property的prefix和suffix分别用于指定前后缀,
实例代码
select * from t_customer
<trim prefix="where" prefixOverrides="and" >
<if test="username !=null and username !=''">
and username like concat('%',#{username}, '%')</if>
<if test="jobs !=null and jobs !=''">
and jobs= #{jobs}</if></trim>
主要解决SQL语句拼接时,遇到where 后立马接AND 、 OR等连接词
3.set
set元素与if元素结合可以只更新需要更新的字段。
如果set元素内包含的内容都为空,则会出现SQL语法错误。
因此,在使用set元素进行字段信息更新时,要确保传入的更新字段不能都为空
4.foreach元素
在遍历参数时,<collection>属性的值是必须指定的。不同情况下,
该属性的取值也是不一样的,主要有以下三种情况:List类型、数值类型、Map类型。
入参为单参数且参数类型是一个List,collection属性值为list。
若入参为单参数且参数类型是一个数组,collection属性值为array。
若传入参数为多参数,就需要把参数封装为一个Map进行处理,collection属性值为Map。
三、例子讲解
需求一
当用户输入的学生姓名不为空,则只根据学生姓名进行学生信息的查询;
当用户输入的学生姓名为空,而学生专业不为空,则只根据学生专业进行学生的查询;
代码:
1.mapper.xml
<select id="findStudentByNameAndMajor"
parameterType="com.lipp.pojo.Student"
resultType="com.lipp.pojo.Student">
select * from dm_student where 1=1
<choose>
<when test="name !=null and name !=''">
and name like concat('%',#{name}, '%')
</when>
<when test="major !=null and major !=''">
and major= #{major}
</when>
<otherwise>
and sno is not null
</otherwise>
</choose>
</select>
该需求是一个查询需求,select的id名字是findStudentByNameAndMajor,
输入数据格式是Student类,用到choose标签,来改进where功能,其中
<when test="name !=null and name !=''">
and name like concat('%',#{name}, '%')
</when>
用于实现当用户输入的学生姓名不为空,则只根据学生姓名进行学生信息的查询;
<when test="major !=null and major !=''">
and major= #{major}
</when>
用于实现输入的学生姓名为空,而学生专业不为空,则只根据学生专业进行学生的查询;
@Test
public void findStudentByNameOrMajorTest() {
// 通过工具类生成SqlSession对象
SqlSession session = MyBatisUtils.getSession();
// Student,封装需要组合查询的条件
Student student = new Student();
// student.setName("张三");
// student.setMajor("英语");
// 执行SqlSession的查询方法,返回结果集
List<Student> students = session.selectList("mapper"
+ ".StudentMapper.findStudentByNameAndMajor", student);
// 输出查询结果信息
for (Student student2 : students) {
// 打印输出结果
System.out.println(student2);
}
// 关闭SqlSession
session.close();
}
需求二
查询出所有id值小于5的学生的信息;
mapper
<select id="findByList" parameterType="java.util.List"
resultType="com.lipp.pojo.Student">
select * from dm_student where id in
<foreach item="id" index="index" collection="list"
open="(" separator="," close=")">
#{id}
</foreach>
</select>
使用foreach进行遍历,通过id返回list
测试类
// 获取SqlSession
SqlSession session = MyBatisUtils.getSession();
// 创建List集合,封装查询id
List<Integer> ids = new ArrayList<Integer>();
// 将小于5的id值放入list中
for (int i = 1; i < 5; i++) {
ids.add(i);
}
// 执行SqlSession的查询方法,返回结果集
List<Student> students = session.selectList("mapper"
+ ".StudentMapper.findByList", ids);
// 输出查询结果信息
for (Student student : students) {
// 打印输出结果
System.out.println(student);
}