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

这篇博客介绍了MyBatis中的动态SQL特性,包括if条件查询用于多条件联合查询,以及choose、when和otherwise结构用于实现单条件可选的查询。通过示例展示了如何在Mapper接口和XML配置中使用这些动态SQL来简化和增强SQL查询的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前为止可能还看不出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;
	}
	@Override
	public 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 mapper
PUBLIC "-//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_student
		where 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;
	@Before
	public void setUp() throws Exception {
		sqlSession = SqlSessionFactoryUtil.openSession();
		studentMapper = sqlSession.getMapper(StudentMapper.class);
	}

	@After
	public void tearDown() throws Exception {
		sqlSession.close();
	}

	@Test
	public 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添加测试方法:

@Test
	public 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 条件能够实现单条件可选的单条件查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值