J2EE系列之MyBatis学习笔记(六)-- 动态sql

来源:互联网 发布:英国牛津大学知乎 编辑:程序博客网 时间:2024/06/05 09:18

目前为止可能还看不出mybatis与hibernate相比具有什么优势,甚至觉得mybatis比Hibernate还要麻烦一些(需要手动写sql语句)。

这一节就讲述mybatis的特色之一的动态sql。动态sql运行在sql语句中动态的添加条件。下面通过实例进行说明。

1.新建工程MyBatisPro02,按照前面讲过的配置方法配置好。

2.新建Student类:

package com.test.model;public class Student {private Integer id;private String name;private Integer age;public Student(String name, Integer age) {super();this.name = name;this.age = age;}public Student() {super();// TODO Auto-generated constructor stub}public Student(Integer id, String name, Integer age) {super();this.id = id;this.name = name;this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";}}
这里去掉了班级、地址等信息。使用最简单的方式。

3.t_student表还是之前的数据:


4.在实际的开发中查询学生信息的时候,通常都是列出好几种条件供用户选择,用户可能会选择根据几个条件来查询学生信息(比如上一个博客中查询学生信息就有根据id查询,根据gradeId查询。当时写了好几个查询方法,这样的话非常麻烦)。使用动态sql的if条件查询,可以把这些个条件放在一起。StudentMapper中写一个查询接口:

package com.test.mappers;import java.util.List;import java.util.Map;import com.test.model.Student;public interface StudentMapper {public List<Student> searchStudents(Map<String,Object> map);}
这里注意,这个查询学生方法的传入参数是一个map对象,里面是键值对的形式,这样的话可以把查询条件都放在这个map中。
5.StudentMapper.xml中实现这个接口:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.test.mappers.StudentMapper"><resultMap type="Student" id="StudentResult"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/></resultMap><select id="searchStudents" parameterType="Map" resultMap="StudentResult">select * from t_studentwhere 1=1<if test="name!=null">and name like #{name}</if><if test="age!=null">and age=#{age}</if><if test="gradeId!=null">and gradeId = #{gradeId}</if></select></mapper> 


这里使用if条件查询。使用if进行判断,判断有哪些条件,并动态的拼接sql语句。这里面where后面的1=1,添加这个条件的目的是防止map为空。如果map为空的话,此时拼接的sql语句为:select * from t_student where 1=1,这也是查询所有的学生。如果where后面没有1=1,而map为空的时候,此时拼接的sql为:select * from t_student where ,这个时候就会报错了。

6.写测试方法:

package com.test.service;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.ibatis.session.SqlSession;import org.apache.log4j.Logger;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.test.mappers.StudentMapper;import com.test.model.Student;import com.test.util.SqlSessionFactoryUtil;public class StudentTest {private static Logger logger = Logger.getLogger(StudentTest.class);private SqlSession sqlSession = null;private StudentMapper studentMapper = null;@Beforepublic void setUp() throws Exception {sqlSession = SqlSessionFactoryUtil.openSession();studentMapper = sqlSession.getMapper(StudentMapper.class);}@Afterpublic void tearDown() throws Exception {sqlSession.close();}@Testpublic void testSearchStudents() {logger.info("查询学生(带条件)");Map<String,Object> map = new HashMap<String,Object>();//map.put("gradeId", 2);map.put("name", "%李%");//map.put("age", 11);List<Student> studentList = studentMapper.searchStudents(map);for(Student s:studentList){System.out.println(s);}}}
在这个测试方法中,我们可以随意的添加查询条件。比如当前是查询名字中有李的学生。如果查询gradeId为2,名字中有李,年龄等于11的学生,就把注释的语句中的注释去掉即可。运行当前的查询名字中有李的学生,查询结果为:




上面通过if查询实现了多条件查询。


6.choose,when 和otherwise 条件

上面通过if查询实现了多条件查询。还有这样一种请求,只能根据一种条件进行查询,但是这种查询条件是可以选择的。(比如可以根据id进行查询或者根据gradeId查询,或者根据名字查询。这里每次查询都只能用一个条件进行查询,但是这个条件是可选的。)这时就要用到choose,when 和otherwise 条件。

6.1StudentMapper中添加查询方法接口:

public List<Student> searchStudents2(Map<String,Object> map);
6.2StudentMapper.xml中实现这个方法:

<select id="searchStudents2" parameterType="Map" resultMap="StudentResult">select * from t_student<choose><when test="searchBy=='gradeId'">where gradeId=#{gradeId}</when><when test="searchBy=='name'">where name like #{name}</when><otherwise>where age = #{age}</otherwise></choose></select>

这里查询学生的时候根据searchBy的值进行判断,当它的值为gradeId的时候,就是根据gradeId进行查询。当它的值为name的时候就是根据name进行查询。如果不是上面的两种情况,就根据age进行查询。

6.3添加测试方法:

@Testpublic void testSearchStudents2() {logger.info("查询学生(带条件)");Map<String,Object> map = new HashMap<String,Object>();map.put("searchBy", "age");map.put("gradeId", 2);map.put("name", "%李%");map.put("age", 11);List<Student> studentList = studentMapper.searchStudents2(map);for(Student s:studentList){System.out.println(s);}}

这里把几个查询条件都放进去。如果想根据gradeId进行查询,就设置searchBy的值为gradeId。这里设置了searchBy的值是age,就是根据age进行查询。

运行这个测试方法:

这里查询到了年龄为11岁的学生信息。


总结:这一节讲的是动态sql,主要讲了if条件和choose,when 和otherwise 条件。其中if条件能够动态的实现多条件联合查询,choose,when 和otherwise 条件能够实现单条件可选的单条件查询。

阅读全文
0 0
原创粉丝点击