Top

JAVA SPRINGMYBATIS02 UNIT04

  1. 主键映射使用案例
  2. 多对一嵌套查询映射使用案例
  3. 多对一嵌套结果映射使用案例
  4. 一对多嵌套查询映射使用案例
  5. 一对多嵌套结果映射使用案例
  6. 鉴别器使用案例

1 主键映射使用案例

1.1 问题

新增员工时,自动生成主键,并且将主键值注入给传入的实体对象,从而可以通过实体对象得到该主键值。

1.2 方案

主键映射有2种方式:

这种方式针对的是Oracle数据库,语法如下:

<insert id="addDept" parameterType=“Dept">

<selectKey keyProperty="deptno“

order="BEFORE” resultType=“java.lang.Integer">

select dept_seq.nextval from dual

</selectKey>

insert into T_DEPT (DEPTNO,DNAME,LOC)

values (#{deptno},#{dname},#{loc})

</insert>

可见自动递增的方式十分简单,非自动递增的方式略微复杂,本案例只演示复杂的方式,即非自动递增的方式。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建项目

复制项目SpringUnit03,创建新项目SpringUnit04,删除EmpDao接口中的方法以及EmpMapper.xml中的SQL,本案例中要写一些新内容。

步骤二:增加保存员工的方法

在EmpDao中增加保存员工的方法,代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;

/**
 * 员工表的DAO组件
 */
@MyBatisRepository
public interface EmpDao {

#cold_bold	void save(Emp emp);

}

步骤三:实现保存员工的方法

在EmpMapper.xml中增加SQL,实现保存员工,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

#cold_bold	<!-- 保存一条员工数据 -->
#cold_bold	<insert id="save"
#cold_bold		parameterType="com.tarena.entity.Emp">
#cold_bold		<selectKey keyProperty="empno"
#cold_bold		 order="BEFORE" resultType="java.lang.Integer">
#cold_bold			select emp_seq.nextval from dual
#cold_bold		</selectKey>
#cold_bold		insert into t_emp values(
#cold_bold			#{empno},
#cold_bold			#{ename,jdbcType=VARCHAR},
#cold_bold			#{job,jdbcType=VARCHAR},
#cold_bold			#{mgr,jdbcType=NUMERIC},
#cold_bold			#{hiredate,jdbcType=DATE},
#cold_bold			#{sal,jdbcType=NUMERIC},
#cold_bold			#{comm,jdbcType=NUMERIC},
#cold_bold			#{deptno,jdbcType=NUMERIC}
#cold_bold		)
#cold_bold	</insert>
	
</mapper>

步骤四:测试保存员工的方法

创建Junit测试类TestMapping,并增加测试保存员工的方法,代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
}

执行该方法,控制台输出效果如下图:

图-1

1.4 完整代码

本案例的完整代码如下所示:

EmpDao完整代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;

/**
 * 员工表的DAO组件
 */
@MyBatisRepository
public interface EmpDao {

	void save(Emp emp);

}

EmpMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 保存一条员工数据 -->
	<insert id="save"
		parameterType="com.tarena.entity.Emp">
		<selectKey keyProperty="empno"
		 order="BEFORE" resultType="java.lang.Integer">
			select emp_seq.nextval from dual
		</selectKey>
		insert into t_emp values(
			#{empno},
			#{ename,jdbcType=VARCHAR},
			#{job,jdbcType=VARCHAR},
			#{mgr,jdbcType=NUMERIC},
			#{hiredate,jdbcType=DATE},
			#{sal,jdbcType=NUMERIC},
			#{comm,jdbcType=NUMERIC},
			#{deptno,jdbcType=NUMERIC}
		)
	</insert>
	
</mapper>

TestMapping完整代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
}

2 多对一嵌套查询映射使用案例

2.1 问题

查询员工时,自动查询出他所在的部门。

2.2 方案

使用嵌套查询映射,分别写出查询员工和查询部门的SQL,然后通过配置自动的将查询到的部门装配给员工。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:增加关联属性

在Emp中增加关联属性,用于封装员工对应的部门信息,代码如下:

package com.tarena.entity;

import java.sql.Date;

/**
 * 员工表的实体类
 */
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;
	
#cold_bold	/**
#cold_bold	 * 关联属性,用于封装员工对应的部门信息
#cold_bold	 */
#cold_bold	private Dept dept;
#cold_bold
#cold_bold	public Dept getDept() {
#cold_bold		return dept;
#cold_bold	}
#cold_bold
#cold_bold	public void setDept(Dept dept) {
#cold_bold		this.dept = dept;
#cold_bold	}

	public Integer getEmpno() {
		return empno;
	}

	public void setEmpno(Integer empno) {
		this.empno = empno;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public Integer getMgr() {
		return mgr;
	}

	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}

	public Date getHiredate() {
		return hiredate;
	}

	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}

	public Double getSal() {
		return sal;
	}

	public void setSal(Double sal) {
		this.sal = sal;
	}

	public Double getComm() {
		return comm;
	}

	public void setComm(Double comm) {
		this.comm = comm;
	}

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

}

步骤二:增加根据ID查询员工的方法

在EmpDao中增加根据ID查询员工的方法,代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;

/**
 * 员工表的DAO组件
 */
@MyBatisRepository
public interface EmpDao {

	void save(Emp emp);

#cold_bold	Emp findById(int id);

}

步骤三:实现根据ID查询员工的方法

在EmpMapper.xml中增加SQL,实现根据ID查询员工,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 保存一条员工数据 -->
	<insert id="save"
		parameterType="com.tarena.entity.Emp">
		<selectKey keyProperty="empno"
		 order="BEFORE" resultType="java.lang.Integer">
			select emp_seq.nextval from dual
		</selectKey>
		insert into t_emp values(
			#{empno},
			#{ename,jdbcType=VARCHAR},
			#{job,jdbcType=VARCHAR},
			#{mgr,jdbcType=NUMERIC},
			#{hiredate,jdbcType=DATE},
			#{sal,jdbcType=NUMERIC},
			#{comm,jdbcType=NUMERIC},
			#{deptno,jdbcType=NUMERIC}
		)
	</insert>
	
#cold_bold	<!-- 使用嵌套查询,在查询一条员工数据时,关联查询出对应的部门 -->
#cold_bold	<select id="findById"
#cold_bold		parameterType="java.lang.Integer"
#cold_bold		resultMap="empMap">
#cold_bold		select * from t_emp where empno=#{id}
#cold_bold	</select>
#cold_bold	<select id="findDept"
#cold_bold		parameterType="java.lang.Integer"
#cold_bold		resultType="com.tarena.entity.Dept">
#cold_bold		select * from t_dept where deptno=#{deptno}
#cold_bold	</select>
#cold_bold	<resultMap type="com.tarena.entity.Emp" id="empMap">
#cold_bold		<association property="dept" column="deptno"
#cold_bold			javaType="com.tarena.entity.Dept" select="findDept">
#cold_bold		</association>
#cold_bold	</resultMap>
	
</mapper>

步骤四:测试根据ID查询员工的方法

在TestMapping中增加方法,测试根据ID查询员工,代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	//其他方法略
	
#cold_bold	/**
#cold_bold	 * 多对一嵌套查询映射:
#cold_bold	 * 根据ID查询一条员工数据,并查询他所在的部门。
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void test2() {
#cold_bold		ApplicationContext ctx = new ClassPathXmlApplicationContext(
#cold_bold				"applicationContext.xml");
#cold_bold		EmpDao dao = ctx.getBean(EmpDao.class);
#cold_bold		Emp e = dao.findById(1);
#cold_bold		System.out.println(
#cold_bold			e.getEmpno() + " " +
#cold_bold			e.getEname() + " " +
#cold_bold			e.getJob() + " " +
#cold_bold			e.getDept().getDeptno() + " " +
#cold_bold			e.getDept().getDname()
#cold_bold		);
#cold_bold	}
	
}

执行该方法,控制台输出效果如下图:

图-2

2.4 完整代码

本案例的完整代码如下所示:

Emp完整代码如下:

package com.tarena.entity;

import java.sql.Date;

/**
 * 员工表的实体类
 */
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;
	
	/**
	 * 关联属性,用于封装员工对应的部门信息
	 */
	private Dept dept;

	public Dept getDept() {
		return dept;
	}

	public void setDept(Dept dept) {
		this.dept = dept;
	}

	public Integer getEmpno() {
		return empno;
	}

	public void setEmpno(Integer empno) {
		this.empno = empno;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public Integer getMgr() {
		return mgr;
	}

	public void setMgr(Integer mgr) {
		this.mgr = mgr;
	}

	public Date getHiredate() {
		return hiredate;
	}

	public void setHiredate(Date hiredate) {
		this.hiredate = hiredate;
	}

	public Double getSal() {
		return sal;
	}

	public void setSal(Double sal) {
		this.sal = sal;
	}

	public Double getComm() {
		return comm;
	}

	public void setComm(Double comm) {
		this.comm = comm;
	}

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

}

EmpDao完整代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;

/**
 * 员工表的DAO组件
 */
@MyBatisRepository
public interface EmpDao {

	void save(Emp emp);

	Emp findById(int id);

}

EmpMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 保存一条员工数据 -->
	<insert id="save"
		parameterType="com.tarena.entity.Emp">
		<selectKey keyProperty="empno"
		 order="BEFORE" resultType="java.lang.Integer">
			select emp_seq.nextval from dual
		</selectKey>
		insert into t_emp values(
			#{empno},
			#{ename,jdbcType=VARCHAR},
			#{job,jdbcType=VARCHAR},
			#{mgr,jdbcType=NUMERIC},
			#{hiredate,jdbcType=DATE},
			#{sal,jdbcType=NUMERIC},
			#{comm,jdbcType=NUMERIC},
			#{deptno,jdbcType=NUMERIC}
		)
	</insert>
	
	<!-- 使用嵌套查询,在查询一条员工数据时,关联查询出对应的部门 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="empMap">
		select * from t_emp where empno=#{id}
	</select>
	<select id="findDept"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Emp" id="empMap">
		<association property="dept" column="deptno"
			javaType="com.tarena.entity.Dept" select="findDept">
		</association>
	</resultMap>
	
</mapper>

TestMapping完整代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
	/**
	 * 多对一嵌套查询映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
}

3 多对一嵌套结果映射使用案例

3.1 问题

查询员工时,自动查询出他所在的部门。

3.2 方案

使用嵌套结果映射,写出员工关联部门的SQL,然后通过配置自动的将查询到的部门装配给员工。

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:增加根据ID查询员工的方法

在EmpDao中增加根据ID查询员工的方法,代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;

/**
 * 员工表的DAO组件
 */
@MyBatisRepository
public interface EmpDao {

	void save(Emp emp);

	Emp findById(int id);
	
#cold_bold	Emp findById2(int id);

}

步骤二:实现根据ID查询员工的方法

在EmpMapper.xml中增加SQL,实现根据ID查询员工,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 保存一条员工数据 -->
	<insert id="save"
		parameterType="com.tarena.entity.Emp">
		<selectKey keyProperty="empno"
		 order="BEFORE" resultType="java.lang.Integer">
			select emp_seq.nextval from dual
		</selectKey>
		insert into t_emp values(
			#{empno},
			#{ename,jdbcType=VARCHAR},
			#{job,jdbcType=VARCHAR},
			#{mgr,jdbcType=NUMERIC},
			#{hiredate,jdbcType=DATE},
			#{sal,jdbcType=NUMERIC},
			#{comm,jdbcType=NUMERIC},
			#{deptno,jdbcType=NUMERIC}
		)
	</insert>
	
	<!-- 使用嵌套查询,在查询一条员工数据时,关联查询出对应的部门 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="empMap">
		select * from t_emp where empno=#{id}
	</select>
	<select id="findDept"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Emp" id="empMap">
		<association property="dept" column="deptno"
			javaType="com.tarena.entity.Dept" select="findDept">
		</association>
	</resultMap>
	
#cold_bold	<!-- 使用嵌套结果,在查询一条员工数据时,关联查询出对应的部门 -->
#cold_bold	<select id="findById2"
#cold_bold		parameterType="java.lang.Integer"
#cold_bold		resultMap="empMap">
#cold_bold		select e.*,d.* from t_emp e
#cold_bold		inner join t_dept d on e.deptno=d.deptno
#cold_bold		where e.empno=#{id}
#cold_bold	</select>
#cold_bold	<resultMap type="com.tarena.entity.Emp" id="empMap2">
#cold_bold		<id property="empno" column="empno"/>
#cold_bold		<result property="ename" column="ename"/>
#cold_bold		<result property="job" column="job"/>
#cold_bold		<result property="mgr" column="mgr"/>
#cold_bold		<result property="hiredate" column="hiredate"/>
#cold_bold		<result property="sal" column="sal"/>
#cold_bold		<result property="comm" column="comm"/>
#cold_bold		<result property="deptno" column="deptno"/>	
#cold_bold		
#cold_bold		<association property="dept" 
#cold_bold			column="deptno" 
#cold_bold			javaType="com.tarena.entity.Dept">
#cold_bold			<id property="deptno" column="deptno"/>
#cold_bold			<result property="dname" column="dname"/>
#cold_bold			<result property="loc" column="loc"/>			
#cold_bold		</association>
#cold_bold	</resultMap>	
</mapper>

步骤三:测试根据ID查询员工的方法

在TestMapping中增加方法,测试根据ID查询员工,代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	//其他方法略
	
#cold_bold	/**
#cold_bold	 * 多对一嵌套结果映射:
#cold_bold	 * 根据ID查询一条员工数据,并查询他所在的部门。
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void test3() {
#cold_bold		ApplicationContext ctx = new ClassPathXmlApplicationContext(
#cold_bold				"applicationContext.xml");
#cold_bold		EmpDao dao = ctx.getBean(EmpDao.class);
#cold_bold		Emp e = dao.findById2(1);
#cold_bold		System.out.println(
#cold_bold			e.getEmpno() + " " +
#cold_bold			e.getEname() + " " +
#cold_bold			e.getJob() + " " +
#cold_bold			e.getDept().getDeptno() + " " +
#cold_bold			e.getDept().getDname()
#cold_bold		);
#cold_bold	}
	
}

3.4 完整代码

本案例的完整代码如下所示:

EmpDao完整代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Emp;

/**
 * 员工表的DAO组件
 */
@MyBatisRepository
public interface EmpDao {

	void save(Emp emp);

	Emp findById(int id);
	
	Emp findById2(int id);

}

EmpMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 保存一条员工数据 -->
	<insert id="save"
		parameterType="com.tarena.entity.Emp">
		<selectKey keyProperty="empno"
		 order="BEFORE" resultType="java.lang.Integer">
			select emp_seq.nextval from dual
		</selectKey>
		insert into t_emp values(
			#{empno},
			#{ename,jdbcType=VARCHAR},
			#{job,jdbcType=VARCHAR},
			#{mgr,jdbcType=NUMERIC},
			#{hiredate,jdbcType=DATE},
			#{sal,jdbcType=NUMERIC},
			#{comm,jdbcType=NUMERIC},
			#{deptno,jdbcType=NUMERIC}
		)
	</insert>
	
	<!-- 使用嵌套查询,在查询一条员工数据时,关联查询出对应的部门 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="empMap">
		select * from t_emp where empno=#{id}
	</select>
	<select id="findDept"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Dept">
		select * from t_dept where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Emp" id="empMap">
		<association property="dept" 
			column="deptno"
			javaType="com.tarena.entity.Dept" 
			select="findDept">
		</association>
	</resultMap>
	
	<!-- 使用嵌套结果,在查询一条员工数据时,关联查询出对应的部门 -->
	<select id="findById2"
		parameterType="java.lang.Integer"
		resultMap="empMap">
		select e.*,d.* from t_emp e
		inner join t_dept d on e.deptno=d.deptno
		where e.empno=#{id}
	</select>
	<resultMap type="com.tarena.entity.Emp" id="empMap2">
		<id property="empno" column="empno"/>
		<result property="ename" column="ename"/>
		<result property="job" column="job"/>
		<result property="mgr" column="mgr"/>
		<result property="hiredate" column="hiredate"/>
		<result property="sal" column="sal"/>
		<result property="comm" column="comm"/>
		<result property="deptno" column="deptno"/>	
		
		<association property="dept" 
			column="deptno" 
			javaType="com.tarena.entity.Dept">
			<id property="deptno" column="deptno"/>
			<result property="dname" column="dname"/>
			<result property="loc" column="loc"/>			
		</association>
	</resultMap>	
	
</mapper>

TestMapping完整代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
	/**
	 * 多对一嵌套查询映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 多对一嵌套结果映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test3() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById2(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
}

4 一对多嵌套查询映射使用案例

4.1 问题

查询部门时,自动查询出该部门下所有的员工。

4.2 方案

使用嵌套查询映射,分别写出查询部门和查询员工的SQL,然后通过配置自动的将查询到的员工装配给部门。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:增加关联属性

创建部门实体类Dept,并增加关联属性,用于封装该部门对应的一组员工数据,代码如下:

package com.tarena.entity;

import java.util.List;

public class Dept {

	private Integer deptno;
	private String dname;
	private String loc;
	
	/**
	 * 关联属性,用于封装部门对应的员工信息
	 */
	private List<Emp> emps;

	public List<Emp> getEmps() {
		return emps;
	}

	public void setEmps(List<Emp> emps) {
		this.emps = emps;
	}

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

}

步骤二:增加根据ID查询部门的方法

创建部门DAO接口,并增加根据ID查询部门的方法,代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Dept;

@MyBatisRepository
public interface DeptDao {

	Dept findById(int id);

}

步骤三:实现根据ID查询部门的方法

创建部门映射文件DeptMapper.xml,并增加SQL,实现根据ID查询部门的方法,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 嵌套查询 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="deptMap">
		select * from t_dept where deptno=#{id}
	</select>
	<select id="findEmps"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Dept" id="deptMap">
		<id property="deptno" column="deptno"/>
		<collection property="emps" column="deptno"
			javaType="java.util.ArrayList" 
			select="findEmps" ofType="com.tarena.entity.Emp">
		</collection>
	</resultMap>
	
</mapper>

步骤四:测试根据ID查询部门的方法

在TestMapping中增加方法,测试根据ID查询部门的方法,代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {

//其他方法略
	
#cold_bold	/**
#cold_bold	 * 一对多嵌套查询映射:
#cold_bold	 * 查询部门及部门下所有的员工。
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void test4() {
#cold_bold		ApplicationContext ctx = new ClassPathXmlApplicationContext(
#cold_bold				"applicationContext.xml");
#cold_bold		DeptDao dao = ctx.getBean(DeptDao.class);
#cold_bold		Dept d = dao.findById(10);
#cold_bold		System.out.println(
#cold_bold			d.getDeptno() + " " +
#cold_bold			d.getDname() + " " +
#cold_bold			d.getLoc() 
#cold_bold		);
#cold_bold		List<Emp> emps = d.getEmps();
#cold_bold		for(Emp e : emps) {
#cold_bold			System.out.println(
#cold_bold				e.getEmpno() + " " + 
#cold_bold				e.getEname() + " " +
#cold_bold				e.getJob()
#cold_bold			);
#cold_bold		}
#cold_bold	}
	
}

4.4 完整代码

本案例的完整代码如下所示:

Dept完整代码如下:

package com.tarena.entity;

import java.util.List;

public class Dept {

	private Integer deptno;
	private String dname;
	private String loc;
	
	/**
	 * 关联属性,用于封装部门对应的员工信息
	 */
	private List<Emp> emps;

	public List<Emp> getEmps() {
		return emps;
	}

	public void setEmps(List<Emp> emps) {
		this.emps = emps;
	}

	public Integer getDeptno() {
		return deptno;
	}

	public void setDeptno(Integer deptno) {
		this.deptno = deptno;
	}

	public String getDname() {
		return dname;
	}

	public void setDname(String dname) {
		this.dname = dname;
	}

	public String getLoc() {
		return loc;
	}

	public void setLoc(String loc) {
		this.loc = loc;
	}

}

DeptDao完整代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Dept;

@MyBatisRepository
public interface DeptDao {

	Dept findById(int id);

}

DeptMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 嵌套查询 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="deptMap">
		select * from t_dept where deptno=#{id}
	</select>
	<select id="findEmps"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Dept" id="deptMap">
		<id property="deptno" column="deptno"/>
		<collection property="emps" column="deptno"
			javaType="java.util.ArrayList" 
			select="findEmps" ofType="com.tarena.entity.Emp">
		</collection>
	</resultMap>
	
</mapper>

TestMapping完整代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
	/**
	 * 多对一嵌套查询映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 多对一嵌套结果映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test3() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById2(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 一对多嵌套查询映射:
	 * 查询部门及部门下所有的员工。
	 */
	@Test
	public void test4() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		DeptDao dao = ctx.getBean(DeptDao.class);
		Dept d = dao.findById(10);
		System.out.println(
			d.getDeptno() + " " +
			d.getDname() + " " +
			d.getLoc() 
		);
		List<Emp> emps = d.getEmps();
		for(Emp e : emps) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " +
				e.getJob()
			);
		}
	}
	
}

5 一对多嵌套结果映射使用案例

5.1 问题

查询部门时,自动查询出该部门下所有的员工。

5.2 方案

使用嵌套结果映射,写出部门关联员工的SQL,然后通过配置自动的将查询到的员工装配给部门。

5.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:增加根据ID查询部门的方法

在DeptDao中增加根据ID查询部门的方法,代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Dept;

@MyBatisRepository
public interface DeptDao {

	Dept findById(int id);
	
#cold_bold	Dept findById2(int id);

}

步骤二:实现根据ID查询部门的方法

在DeptMapper.xml中增加SQL,实现根据ID查询部门,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 嵌套查询 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="deptMap">
		select * from t_dept where deptno=#{id}
	</select>
	<select id="findEmps"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Dept" id="deptMap">
		<id property="deptno" column="deptno"/>
		<collection property="emps" column="deptno"
			javaType="java.util.ArrayList" 
			select="findEmps" ofType="com.tarena.entity.Emp">
		</collection>
	</resultMap>
	
#cold_bold	<!-- 嵌套结果 -->
#cold_bold	<select id="findById2"
#cold_bold		parameterType="java.lang.Integer"
#cold_bold		resultMap="deptMap2">
#cold_bold		select d.*,e.* from t_dept d 
#cold_bold		inner join t_emp e on d.deptno=e.deptno
#cold_bold		where d.deptno=#{id}
#cold_bold	</select>
#cold_bold	<resultMap type="com.tarena.entity.Dept" id="deptMap2">
#cold_bold		<id property="deptno" column="deptno"/>
#cold_bold		<result property="dname" column="dname"
#cold_bold			jdbcType="VARCHAR" javaType="string"/>
#cold_bold		<result property="loc" column="loc"
#cold_bold			jdbcType="VARCHAR" javaType="string"/>		
#cold_bold		<collection property="emps" ofType="com.tarena.entity.Emp"
#cold_bold			javaType="java.util.ArrayList" column="deptno">
#cold_bold			<id property="empno" column="empno"/>
#cold_bold			<result property="ename" column="ename"/>
#cold_bold			<result property="job" column="job"/>
#cold_bold			<result property="mgr" column="mgr"/>
#cold_bold			<result property="hiredate" column="hiredate"/>
#cold_bold			<result property="sal" column="sal"/>
#cold_bold			<result property="comm" column="comm"/>
#cold_bold			<result property="deptno" column="deptno"/>			
#cold_bold		</collection>
#cold_bold	</resultMap>	
	
</mapper>

步骤三:测试根据ID查询部门的方法

在TestMapping中增加方法,测试根据ID查询部门,代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {

//其他方法略
	
#cold_bold	/**
#cold_bold	 * 一对多嵌套结果映射:
#cold_bold	 * 查询部门及部门下所有的员工。
#cold_bold	 */
#cold_bold	@Test
#cold_bold	public void test5() {
#cold_bold		ApplicationContext ctx = new ClassPathXmlApplicationContext(
#cold_bold				"applicationContext.xml");
#cold_bold		DeptDao dao = ctx.getBean(DeptDao.class);
#cold_bold		Dept d = dao.findById2(10);
#cold_bold		System.out.println(
#cold_bold			d.getDeptno() + " " +
#cold_bold			d.getDname() + " " +
#cold_bold			d.getLoc() 
#cold_bold		);
#cold_bold		List<Emp> emps = d.getEmps();
#cold_bold		for(Emp e : emps) {
#cold_bold			System.out.println(
#cold_bold				e.getEmpno() + " " + 
#cold_bold				e.getEname() + " " +
#cold_bold				e.getJob()
#cold_bold			);
#cold_bold		}
#cold_bold	}	
	
}

5.4 完整代码

本案例的完整代码如下所示:

DeptDao完整代码如下:

package com.tarena.dao;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Dept;

@MyBatisRepository
public interface DeptDao {

	Dept findById(int id);
	
	Dept findById2(int id);

}

DeptMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">

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

	<!-- 嵌套查询 -->
	<select id="findById"
		parameterType="java.lang.Integer"
		resultMap="deptMap">
		select * from t_dept where deptno=#{id}
	</select>
	<select id="findEmps"
		parameterType="java.lang.Integer"
		resultType="com.tarena.entity.Emp">
		select * from t_emp where deptno=#{deptno}
	</select>
	<resultMap type="com.tarena.entity.Dept" id="deptMap">
		<id property="deptno" column="deptno"/>
		<collection property="emps" column="deptno"
			javaType="java.util.ArrayList" 
			select="findEmps" ofType="com.tarena.entity.Emp">
		</collection>
	</resultMap>
	
	<!-- 嵌套结果 -->
	<select id="findById2"
		parameterType="java.lang.Integer"
		resultMap="deptMap2">
		select d.*,e.* from t_dept d 
		inner join t_emp e on d.deptno=e.deptno
		where d.deptno=#{id}
	</select>
	<resultMap type="com.tarena.entity.Dept" id="deptMap2">
		<id property="deptno" column="deptno"/>
		<result property="dname" column="dname"
			jdbcType="VARCHAR" javaType="string"/>
		<result property="loc" column="loc"
			jdbcType="VARCHAR" javaType="string"/>		
		<collection property="emps" ofType="com.tarena.entity.Emp"
			javaType="java.util.ArrayList" column="deptno">
			<id property="empno" column="empno"/>
			<result property="ename" column="ename"/>
			<result property="job" column="job"/>
			<result property="mgr" column="mgr"/>
			<result property="hiredate" column="hiredate"/>
			<result property="sal" column="sal"/>
			<result property="comm" column="comm"/>
			<result property="deptno" column="deptno"/>			
		</collection>
	</resultMap>	
	
</mapper>

TestMapping完整代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
	/**
	 * 多对一嵌套查询映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 多对一嵌套结果映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test3() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById2(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 一对多嵌套查询映射:
	 * 查询部门及部门下所有的员工。
	 */
	@Test
	public void test4() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		DeptDao dao = ctx.getBean(DeptDao.class);
		Dept d = dao.findById(10);
		System.out.println(
			d.getDeptno() + " " +
			d.getDname() + " " +
			d.getLoc() 
		);
		List<Emp> emps = d.getEmps();
		for(Emp e : emps) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " +
				e.getJob()
			);
		}
	}
	
	/**
	 * 一对多嵌套结果映射:
	 * 查询部门及部门下所有的员工。
	 */
	@Test
	public void test5() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		DeptDao dao = ctx.getBean(DeptDao.class);
		Dept d = dao.findById2(10);
		System.out.println(
			d.getDeptno() + " " +
			d.getDname() + " " +
			d.getLoc() 
		);
		List<Emp> emps = d.getEmps();
		for(Emp e : emps) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " +
				e.getJob()
			);
		}
	}	
	
}

6 鉴别器使用案例

6.1 问题

查询汽车表时,将不同类型的汽车自动封装成不同的对象。

6.2 方案

使用鉴别器,根据表中某个字段区别数据,将查询出的数据自动封装成不同类型的对象。

6.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:建表

创建汽车表,并插入预置数据,脚本如下:

CREATE TABLE t_car (
  id NUMBER(11) NOT NULL,
  type VARCHAR2(1) default NULL,
  doorSize NUMBER(11) default NULL,
  boxSize NUMBER(11) default NULL,
  color VARCHAR2(20) default NULL,
  PRIMARY KEY  (id)
  );

insert into t_car values (1,'C',2,null,'红色');
insert into t_car values (2,'C',4,null,'黑色');
insert into t_car values (3,'T',null,1,'蓝色');
insert into t_car values (4,'T',null,2,'蓝色');
commit;

步骤二:创建实体类

创建交通工具实体类Vehicle,封装汽车表中的公用字段,代码如下:

package com.tarena.entity;

/**
 *	交通工具实体类,封装汽车表中公用的字段
 */
public class Vehicle {

	private int id;
	private String type;
	private String color;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

}

创建小汽车实体类,继承于Vehicle,并封装小汽车相关的字段,代码如下:

package com.tarena.entity;

/**
 *	小汽车实体类,封装小汽车相关字段
 */
public class Car extends Vehicle {

	private int doorSize;

	public int getDoorSize() {
		return doorSize;
	}

	public void setDoorSize(int doorSize) {
		this.doorSize = doorSize;
	}
}

创建卡车实体类,继承于Vehicle,并封装卡车相关的字段,代码如下:

package com.tarena.entity;

/**
 *	卡车实体类,封装卡车相关的字段
 */
public class Truck extends Vehicle {

	private int boxSize;

	public int getBoxSize() {
		return boxSize;
	}

	public void setBoxSize(int boxSize) {
		this.boxSize = boxSize;
	}
}

步骤三:创建DAO接口

创建DAO接口VehicleDao,并增加查询全部汽车数据的方法,代码如下:

package com.tarena.dao;

import java.util.List;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Vehicle;

@MyBatisRepository
public interface VehicleDao {

	List<Vehicle> findAll();

}

步骤四:创建映射文件

创建映射文件VehicleMapper.xml,并增加SQL实现查询全部汽车,代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.tarena.dao.VehicleDao">

	<resultMap id="vehicleMap" type="com.tarena.entity.Vehicle">
		<id property="id" column="ID" />
		<result property="color" column="COLOR" />
		<discriminator javaType="java.lang.String" column="TYPE">
			<case value="T" resultType="com.tarena.entity.Truck">
				<result property="boxSize" column="BOXSIZE" />
			</case>
			<case value="C" resultType="com.tarena.entity.Car">
				<result property="doorSize" column="DOORSIZE" />
			</case>
		</discriminator>
	</resultMap>

	<select id="findAll" resultMap="vehicleMap">
		select * from T_CAR
	</select>

</mapper>

步骤五:增加测试方法

在TestMapping中增加方法,测试查询全部汽车的方法,代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	//其他方法略

	/**
	 * 鉴别器:
	 * 查询汽车表,根据类型封装成不同的对象。
	 */
	@Test
	public void test6() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		VehicleDao dao = ctx.getBean(VehicleDao.class);
		List<Vehicle> list = dao.findAll();
		for (Vehicle v : list) {
			System.out.println(v);
		}
	}
	
}

6.4 完整代码

本案例的完整代码如下所示:

Vehicle完整代码如下:

package com.tarena.entity;

/**
 *	交通工具实体类,封装汽车表中公用的字段
 */
public class Vehicle {

	private int id;
	private String type;
	private String color;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

}

Car完整代码如下:

package com.tarena.entity;

/**
 *	小汽车实体类,封装小汽车相关字段
 */
public class Car extends Vehicle {

	private int doorSize;

	public int getDoorSize() {
		return doorSize;
	}

	public void setDoorSize(int doorSize) {
		this.doorSize = doorSize;
	}
}

Truck完整代码如下:

package com.tarena.entity;

/**
 *	卡车实体类,封装卡车相关的字段
 */
public class Truck extends Vehicle {

	private int boxSize;

	public int getBoxSize() {
		return boxSize;
	}

	public void setBoxSize(int boxSize) {
		this.boxSize = boxSize;
	}
}

VehicleDao完整代码如下:

package com.tarena.dao;

import java.util.List;

import com.tarena.annotation.MyBatisRepository;
import com.tarena.entity.Vehicle;

@MyBatisRepository
public interface VehicleDao {

	List<Vehicle> findAll();

}

VehicleMapper.xml完整代码如下:

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"      
 "/ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.tarena.dao.VehicleDao">

	<resultMap id="vehicleMap" type="com.tarena.entity.Vehicle">
		<id property="id" column="ID" />
		<result property="color" column="COLOR" />
		<discriminator javaType="java.lang.String" column="TYPE">
			<case value="T" resultType="com.tarena.entity.Truck">
				<result property="boxSize" column="BOXSIZE" />
			</case>
			<case value="C" resultType="com.tarena.entity.Car">
				<result property="doorSize" column="DOORSIZE" />
			</case>
		</discriminator>
	</resultMap>

	<select id="findAll" resultMap="vehicleMap">
		select * from T_CAR
	</select>

</mapper>

TestMapping完整代码如下:

package com.tarena.test;

import java.sql.Date;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tarena.dao.DeptDao;
import com.tarena.dao.EmpDao;
import com.tarena.dao.VehicleDao;
import com.tarena.entity.Dept;
import com.tarena.entity.Emp;
import com.tarena.entity.Vehicle;

/**
 *	测试MyBatis关联映射
 */
public class TestMapping {
	
	/**
	 * 主键映射:新增一条员工数据
	 */
	@Test
	public void test1() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = new Emp();
		e.setEname("张三");
		e.setJob("SALESMAN");
		e.setMgr(3);
		e.setHiredate(
			new Date(System.currentTimeMillis()));
		e.setSal(4000.0);
		e.setComm(650.0);
		e.setDeptno(10);
		dao.save(e);
		System.out.println(e.getEmpno());
	}
	
	/**
	 * 多对一嵌套查询映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test2() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 多对一嵌套结果映射:
	 * 根据ID查询一条员工数据,并查询他所在的部门。
	 */
	@Test
	public void test3() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		EmpDao dao = ctx.getBean(EmpDao.class);
		Emp e = dao.findById2(1);
		System.out.println(
			e.getEmpno() + " " +
			e.getEname() + " " +
			e.getJob() + " " +
			e.getDept().getDeptno() + " " +
			e.getDept().getDname()
		);
	}
	
	/**
	 * 一对多嵌套查询映射:
	 * 查询部门及部门下所有的员工。
	 */
	@Test
	public void test4() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		DeptDao dao = ctx.getBean(DeptDao.class);
		Dept d = dao.findById(10);
		System.out.println(
			d.getDeptno() + " " +
			d.getDname() + " " +
			d.getLoc() 
		);
		List<Emp> emps = d.getEmps();
		for(Emp e : emps) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " +
				e.getJob()
			);
		}
	}
	
	/**
	 * 一对多嵌套结果映射:
	 * 查询部门及部门下所有的员工。
	 */
	@Test
	public void test5() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		DeptDao dao = ctx.getBean(DeptDao.class);
		Dept d = dao.findById2(10);
		System.out.println(
			d.getDeptno() + " " +
			d.getDname() + " " +
			d.getLoc() 
		);
		List<Emp> emps = d.getEmps();
		for(Emp e : emps) {
			System.out.println(
				e.getEmpno() + " " + 
				e.getEname() + " " +
				e.getJob()
			);
		}
	}	
	
	/**
	 * 鉴别器:
	 * 查询汽车表,根据类型封装成不同的对象。
	 */
	@Test
	public void test6() {
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		VehicleDao dao = ctx.getBean(VehicleDao.class);
		List<Vehicle> list = dao.findAll();
		for (Vehicle v : list) {
			System.out.println(v);
		}
	}
	
}