`

SprignMVC+myBatis整合(四)——动态SQL

 
阅读更多

动态SQL简介:

带台SQL是MyBatis框架中强大特效之一。在一些组合查询页面中刚,需要根据用户输入的查询条件生成不同的查询SQL,这在JDBC或其他相似框架中需要在代码中拼写SQL,经常容易出错,但是在MyBatis中可以解决这种问题。

使用动态SQL元素与JSTL相似,它允许我们在XML中构建不同的SQL语句。常用的元素如下:

判断元素:if,choose

关键字元素:where,set,trim

循环元素:foreach

 

判断元素用法:

if元素

if元素是简单的条件判断逻辑,满足指定条件时追加if元素内的SQL.

<select...>

  SQL语句1

  <if test="条件表达式">

     SQL语句2

  </if>

</select>

 

注意:条件表达式中大于号小于号用 gt,lt

<if test="id != 9">...</if>

<if test="id gt 9">...</if>

<if test="id lt 9">...</if>

	<!-- findById -->
	<select id="findById" parameterType="int" resultType="com.tarena.entity.Emp">
		<if test="6 gt 5">
			select * from t_emp 
		</if>
	</select>

	<!-- findByDept -->
	<select id="findByDept" parameterType="com.tarena.entity.Condition"
		resultType="com.tarena.entity.Emp">
		select * from t_emp
		<if test="deptId != null">
			where deptno=#{deptId}
		</if>
	</select>

 

 注意:findById的传参时, Mapper方法中定义要使用@param(value="id")来指定传递参数的名字,否则执行test元素中的比较表达式会出错,找不到getter/setter方法。

 

/**
	 * 根据id查询员工
	 */
	List<Emp> findById(@Param(value="id") int id);
	/**
	 * 根据部门查询员工
	 */
	List<Emp> findByDept(Condition cond);

 测试代码:

 

	@Test
	public void testFindById() {
		//创建Spring容器
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		//通过容器创建DAO
		EmpDao dao = ctx.getBean(EmpDao.class);
		//调用查询方法
		List<Emp> emp = dao.findById(3);
		System.out.println(emp.size());
	}
 

 

choose元素:

choose元素的作用相当于JAVA中的Switch语句,基本用法和JSTL中使用一样,和otherwist搭配使用。

<select..>

 SQL语句1

 <choose>

   <when test="条件表达式">

        SQL语句2

   </when>

   <otherwise>

        SQL语句3

   </otherwise>

 </choose>

</select>

 

拼关键字元素用法:

where元素主要是用于简化查询语句中where部门的条件判断。where元素可以在<where>元素所在的位置输出一个where关键字,而且还可以将后面的条件多余的and或or关键字去掉。

<select..>

   select 字段 from 表

   <where>

      动态追加条件

   </where>

</select>

 

注意:模糊查询中获取参数的表达式写在单引号中,这里使用${ename}取值而不是#{ename}

 

<select id="findByName" parameterType="java.lang.String"
		resultType="com.tarena.entity.Emp">
		select * from t_emp
		<where>
		  ename like '%${ename}%'
		</where>
	</select>
 

 

  或者直接写上SQL

 

<select id="findByName" parameterType="java.lang.String"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where ename like '%${ename}%'
	</select>
 

 

 

set元素:

    set元素主要是用在更新操作的时候,它的主要功能和where元素相似,主要是在<set>元素所在位置输出一个set关键字,而且还可以去除内容结尾中无关的逗号。

<update...>

    update 表

    <set>

       动态追加更新字段

       <if test="ename!=null">

         ENAME=#{ename},

       </if>         

       <if test="sal!=null">

         SAL=#{sal},

       </if>

       <if test="comm!=null">

         COMM=#{comm},

       </if>

    </set>

    where EMPNO=#{empno}

</update>

 

trim元素:

trim元素的主要功能如下:

-可以在自己包含的内容前加上某前缀,也可以在其后加上某些后缀,预制对应的属性是prefix和suffix;

-可以把包含内容的首部某些内容过滤,即忽略,也可以把尾部的某些内容过滤,对应的属性是prxfixOverrides和suffixOverridex;

-正因为trim有上述功能,所有我们也可以非常简单的利用trim里代替where和set元素的功能

<!-等价于where元素>

<trim prefix="WHERE" prefixOverrides="AND|OR">

 ..

</trim>

<!-等价于set元素>

<trim prefix="SET" prefixOverrides=",">

 ..

 

</trim>

 

进行循环:

foreach元素

foreach元素实现了逻辑循环,可以进行一个集合的迭代,主要用在构建in条件中。

<select ..>

   select * from 表 where 字段 in

   <foreach collection="集合" item="迭代变量" 

     open="(" separator=","close=")">

   #{迭代变量}

   </foreach>

</select>

 

foreach元素非常强大,它允许指定一个集合,声明集合项和索引变量,这些变量可以用在元素体内。它也允许指定开放和关闭的字符串,在迭代之间放置分隔符。

 

<!-- findByIds -->
	<select id="findByIds" parameterType="com.tarena.entity.Condition"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where empno in 
		<!--
			collection指定了要循环的集合; item指定了循环变量; open指定了生成的字符串的开头部分;
			close指定了生成的字符串的结尾部分; separator指定了输出的变量之间的分隔字符。
		-->
		<foreach collection="empIds" item="eid" open="(" close=")"
			separator=",">
			#{eid}
		</foreach>
	</select>
 Condition.java 查询条件类的定义

 

 

/**
 *	查询条件
 */
public class Condition {
	private Integer deptId;
	
	private Double salary;
	
	private List<Integer> empIds;
 

 

下面是综合练习的代码:

Emp.java

 

/**
 * 员工表的实体类
 */
public class Emp {
	private Integer empno;
	private String ename;
	private String job;
	private Integer mgr;
	private Date hiredate;
	private Double sal;
	private Double comm;
	private Integer deptno;
        // .....
}
  EmpDao.java Mapper类接口方法定义

 

/**
 *	员工表的DAO接口。
 *	该接口由MyBatis自动实现,要求将其
 *	扫描到Spring容器中,因此需要追加注解。
 */
@MybatisDao
public interface EmpDao {

	List<Emp> findAll();
	
	List<Emp> findByName(@Param(value="ename") String ename);
	/**
	 * 根据id查询员工
	 */
	List<Emp> findById(@Param(value="id") int id);
	/**
	 * 根据部门查询员工
	 */
	List<Emp> findByDept(Condition cond);
	
	/**
	 * 判断传入的salary的大小
	 * 如果salary大于等于2500,则查询全部大于salary的员工,
	 * 即where sal>#{salary};
	 * 如果salary小于2500,则查询全部大于2500的员工,
	 * 即where sal>2500。
	 */
	List<Emp> findBySalary(Condition cond);
	
	/**
	 * 根据多个条件查询员工,即
	 * 查询出指定部门下,高于指定工资的员工。
	 */
	List<Emp> findByCondition(Condition cond);
	
	/**
	 * 更新员工
	 */
	void update(Emp emp);
	
	/**
	 * 根据一组ID查询出对应的员工
	 */
	List<Emp> findByIds(Condition cond);
	
}
 
EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

<mapper namespace="com.tarena.dao.EmpDao">

	<!-- findAll -->
	<select id="findAll" resultType="com.tarena.entity.Emp">
		select * from t_emp
	</select>
	<!-- findById -->
	<select id="findById" parameterType="int" resultType="com.tarena.entity.Emp">
		<if test="6 gt 5">
			select * from t_emp 
		</if>
	</select>

	<select id="findByName" parameterType="java.lang.String"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where ename like '%${ename}%'
	</select>

	<!-- findByDept -->
	<select id="findByDept" parameterType="com.tarena.entity.Condition"
		resultType="com.tarena.entity.Emp">
		select * from t_emp
		<if test="deptId != null">
			where deptno=#{deptId}
		</if>
	</select>

	<!-- findBySalary -->
	<select id="findBySalary" parameterType="com.tarena.entity.Condition"
		resultType="com.tarena.entity.Emp">
		select * from t_emp
		<choose>
			<when test="salary >= 2500">
				where sal>#{salary}
			</when>
			<otherwise>
				where sal>2500
			</otherwise>
		</choose>
	</select>

	<!-- findByCondition -->
	<select id="findByCondition" parameterType="com.tarena.entity.Condition"
		resultType="com.tarena.entity.Emp">
		select * from t_emp
		<!-- where元素等价于where 1=1 -->
		<!--
			<where> <if test="deptId != null"> and deptno=#{deptId} </if> <if
			test="salary != null"> and sal>#{salary} </if> </where>
		-->
		<!--
			prefix在前面增加一个指定的词; prefixOverrides去掉前面的第一个指定的词; suffix在后面增加一个指定的词;
			suffixOverrides去掉后面的最后一个指定的词。
		-->
		<trim prefix="where" prefixOverrides="and">
			<if test="deptId != null">
				and deptno=#{deptId}
			</if>
			<if test="salary != null">
				and sal>#{salary}
			</if>
		</trim>
	</select>

	<!-- update -->
	<update id="update" parameterType="com.tarena.entity.Emp">
		update t_emp
		<!-- set元素可以生成set关键字,
				另外可以自动去掉最后多余的"," -->
		<!--
			<set> <if test="ename != null"> ename=#{ename}, </if> <if test="job
			!= null"> job=#{job}, </if> <if test="sal != null"> sal=#{sal}, </if>
			</set>
		-->

		<trim prefix="set" suffixOverrides=",">
			<if test="ename != null">
				ename=#{ename},
				</if>
			<if test="job != null">
				job=#{job},
				</if>
			<if test="sal != null">
				sal=#{sal},
				</if>
		</trim>
		where empno=#{empno}
	</update>

	<!-- findByIds -->
	<select id="findByIds" parameterType="com.tarena.entity.Condition"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where empno in 
		<!--
			collection指定了要循环的集合; item指定了循环变量; open指定了生成的字符串的开头部分;
			close指定了生成的字符串的结尾部分; separator指定了输出的变量之间的分隔字符。
		-->
		<foreach collection="empIds" item="eid" open="(" close=")"
			separator=",">
			#{eid}
		</foreach>
	</select>

</mapper>
 
测试类TestEmp.java定义:
package com.tarena.test;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.tarena.dao.EmpDao;
import com.tarena.entity.Condition;
import com.tarena.entity.Emp;


/**
 *	EmpDao测试类
 */
public class TestEmpDao {
	@Test
	public void testFindById() {
		//创建Spring容器
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		//通过容器创建DAO
		EmpDao dao = ctx.getBean(EmpDao.class);
		//调用查询方法
		List<Emp> emp = dao.findById(3);
		System.out.println(emp.size());
	}
	
	@Test
	public void testFindByName() {
		//创建Spring容器
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		//通过容器创建DAO
		EmpDao dao = ctx.getBean(EmpDao.class);
		//调用查询方法  模糊查询
		List<Emp> list = dao.findByName("S");
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " + 
				e.getDeptno()
			);
		}
	}
	
	@Test
	public void testFindAll() {
		//创建Spring容器
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		//通过容器创建DAO
		EmpDao dao = ctx.getBean(EmpDao.class);
		//调用查询方法
		List<Emp> list = dao.findAll();
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " + 
				e.getDeptno()
			);
		}
	}
	
	@Test
	public void testFindByDept() {
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Condition cond = new Condition();
//		cond.setDeptId(20);
		List<Emp> list = dao.findByDept(cond);
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " +
				e.getEname() + " " +
				e.getDeptno()
			);
		}
	}
	
	@Test
	public void testFindBySalary() {
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Condition cond = new Condition();
		cond.setSalary(1000.0);
		List<Emp> list = dao.findBySalary(cond);
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " +
				e.getEname() + " " +
				e.getSal() + " " +
				e.getDeptno()
			);
		}
	}
	
	@Test
	public void testFindByCondition() {
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Condition cond = new Condition();
		cond.setDeptId(20);
		cond.setSalary(2000.0);
		List<Emp> list = dao.findByCondition(cond);
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " +
				e.getEname() + " " +
				e.getSal() + " " +
				e.getDeptno()
			);
		}
	}	
	
	@Test
	public void testUpdate() {
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEmpno(14);
		e.setEname("猪八戒");
		e.setSal(1500.0);
		dao.update(e);
	}
	
	@Test
	public void testFindByIds() {
		ApplicationContext ctx = 
			new ClassPathXmlApplicationContext(
					"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Condition cond = new Condition();
		List<Integer> ids = new ArrayList<Integer>();
		ids.add(3);
		ids.add(7);
		ids.add(8);
		cond.setEmpIds(ids);
		List<Emp> list = dao.findByIds(cond);
		for(Emp e : list) {
			System.out.println(
				e.getEmpno() + " " +
				e.getEname() + " " +
				e.getDeptno()
			);
		}
	}
	
}
 
 
 
分享到:
评论

相关推荐

    Spring+SpringMVC+Mybatis框架整合例子——亲测可用.zip

    Mybatis是一个优秀的持久层框架,它简化了JDBC的繁琐操作,支持SQL语句的动态编写,使得开发者可以直接使用SQL来操作数据库,同时还能保持数据访问的灵活性。Mybatis通过XML或注解方式配置映射文件,将Java对象与...

    maven+springmvc+redis+mybatis整合

    本项目以“maven+springmvc+redis+mybatis整合”为主题,旨在提供一个基于这些技术的集成框架,特别强调了利用Redis作为缓存来提升应用性能。下面将详细阐述这个框架中的各个组成部分以及它们之间的协作。 首先,...

    springboot+mybatis+sqlserver

    【标题】"springboot+mybatis+sqlserver"是一个基于Spring Boot、MyBatis和Microsoft SQL Server构建的基础开发框架,适用于快速开发企业级应用。这个框架整合了三个关键组件,旨在简化开发流程,提高开发效率。 ...

    springboot+mybatis整合实现注册登录

    在本项目中,"springboot+mybatis整合实现注册登录"是一个典型的Web应用程序开发实例,主要涉及Spring Boot和MyBatis两大技术框架的融合应用。Spring Boot简化了Spring应用程序的初始搭建以及开发过程,而MyBatis则...

    springboot+mybatis+bootstrap整合的简单框架

    本项目"springboot+mybatis+bootstrap整合的简单框架"旨在提供一个快速开发的解决方案,将三个流行的开源技术——Spring Boot、MyBatis和Bootstrap融合在一起,以简化Web应用的构建过程。 Spring Boot是由Pivotal...

    SpringBoot+mybatis+Oracle整合代码

    在"SpringBoot+mybatis+Oracle整合代码"中,我们可以学习到以下几个关键知识点: 1. **SpringBoot的自动配置**:SpringBoot的核心特性之一就是自动配置,它能根据项目中的依赖自动配置相应的Bean。在整合MyBatis时...

    springboot+mybatis 整合Demo下载

    MyBatis提供了动态SQL的功能,使得在处理复杂的查询时更加灵活。 3. **整合SpringBoot与MyBatis**: - **添加依赖**:在`pom.xml`文件中,需要引入SpringBoot的starter-web和MyBatis的依赖,以及数据库驱动。 - *...

    SpringBoot+Mybatis整合完整源码

    学习和理解这一整合,不仅有助于提升开发效率,还能让你更好地理解和掌握 Spring Boot 的自动化配置机制以及 Mybatis 的动态 SQL 功能。在实际项目中,你可以根据需求进一步扩展,如集成 Swagger 进行 API 文档管理...

    springboot+mybatis+sqlserver 仓库管理系统

    《SpringBoot+Mybatis+SQLServer构建的仓库管理系统详解》 在现代企业信息化管理中,仓库管理系统扮演着至关重要的角色,它能够有效地管理和追踪库存,提高运营效率。本项目是基于SpringBoot框架,结合Mybatis持久...

    SpringBoot+maven+Mybatis+tkMybatis+WebFlux+pagehelper+Redis+thymeleaf响应式单体项目

    目标:本示例说明SFM...6、如果一切正常,你会看到我们使用SpringBoot整合Spring+MyBatis+tkMabtis+pagehelper+redis+webFlux的响应式单体并高web应用项目。 目的:希望学习springboot开发SFM响应式应用的小白们。

    spting4mvc+mybatis整合实例(入门)

    在本实例中,我们将探讨如何将Spring MVC框架与MyBatis持久层框架进行整合,以构建一个基础的Web应用程序。Spring MVC提供了强大的模型-视图-控制器架构,而MyBatis则是一个轻量级的SQL映射框架,使得数据库操作更为...

    spring+springMvc+mybatis整合工程

    spring+springMvc+mybatis整合后的基础工程,具体整合过程可参考:https://blog.csdn.net/m0_37674755/article/details/89303527

    Spring+SpringMVC+Mybatis框架整合例子(SSM) 下载

    Spring、SpringMVC和Mybatis是Java开发中最常用的三大开源框架,它们的整合使用,通常被称为SSM框架。这个框架组合提供了完整的后端服务解决方案,包括依赖注入(DI)、面向切面编程(AOP)、模型-视图-控制器(MVC...

    SpringBoot+Mybatis -plus+Mysql+Vue渲染整合

    SpringBoot+Mybatis -plus+Mysql+Vue渲染整合,需求为,院系和学生之间的多对一关系管理,外键不可删除,添加学生时完整显示学院姓名,成功添加,删除,修改,查询,模糊查询包括下拉框(院系),区间段(学生年龄)...

    SpringMvc+Spring+Mybatis+Maven+注解方式=整合

    "SpringMvc+Spring+Mybatis+Maven+注解方式"是一个经典的Java后端技术栈,它整合了四个关键组件,为开发人员提供了强大的工具和框架支持。下面将详细讲解这四个组件及其整合方式。 1. **Spring Framework**: ...

    SpringMvc+Spring+Mybatis+Maven整合.part10

    通过SpringMvc+Spring+Mybatis+Maven整合,学习用maven搭建框架

    struts2+spring+mybatis+easyui的实现

    总的来说,"struts2+spring+mybatis+easyui"的实现是一个标准的Java Web项目结构,它利用Maven进行构建管理,通过整合四个组件,实现了后端的业务逻辑处理、数据访问和前端的用户界面展示。这种架构在实际开发中具有...

    struct2+spring+mybatis整合

    struct2+spring+mybatis整合

    SSM(Spring+Struts2+Mybatis)整合步骤

    SSM(Spring+Struts2+Mybatis)整合步骤 纯手写

    Springboot+Mybatis-plus+ SpringMvc+Shiro+Redis企业级报表后台管理系统.rar

    shiro作为安全框架,主流技术 几乎零XML,极简配置 两套UI实现(bootstrap+layer ui),可以自由切换 报表后端采用技术: SpringBoot整合SSM(Spring+Mybatis-plus+ SpringMvc),spring security 全注解式的权限管理和...

Global site tag (gtag.js) - Google Analytics