MyBatis研习录(09)——MyBatis一对多查询


C语言自学完备手册(33篇)

Android多分辨率适配框架

JavaWeb核心技术系列教程

HTML5前端开发实战系列教程

MySQL数据库实操教程(35篇图文版)

推翻自己和过往——自定义View系列教程(10篇)

走出思维困境,踏上精进之路——Android开发进阶精华录

讲给Android程序员看的前端系列教程(40集免费视频教程+源码)


版权声明

  • 本文原创作者:谷哥的小弟
  • 作者博客地址:http://blog.csdn.net/lfdfhl

概述

在本节教程中,我们来学习MyBatis的一对多查询。在此,我们以部门和员工为例介绍一对多:每个员工属于一个部门,一个部门有多个员工。

数据准备

DROP DATABASE IF EXISTS mybatisDatabase;
CREATE DATABASE mybatisDatabase;
USE mybatisDatabase;
CREATE TABLE department(
  departmentID INT PRIMARY KEY auto_increment,
  departmentName VARCHAR(50)
);

CREATE TABLE employee(
  employeeID INT primary key auto_increment,
  employeeName VARCHAR(50),
  employeeDepartmentID INT,
  FOREIGN KEY(employeeDepartmentID) REFERENCES department(departmentID)
);

INSERT INTO department(departmentName) VALUES('财务部');
INSERT INTO department(departmentName) VALUES('技术部');
INSERT INTO department(departmentName) VALUES('行政部');

INSERT INTO employee(employeeName,employeeDepartmentID) VALUES('lucy',1);
INSERT INTO employee(employeeName,employeeDepartmentID) VALUES('lili',1);
INSERT INTO employee(employeeName,employeeDepartmentID) VALUES('momo',2);
INSERT INTO employee(employeeName,employeeDepartmentID) VALUES('mymy',2);
INSERT INTO employee(employeeName,employeeDepartmentID) VALUES('xuxu',3);
INSERT INTO employee(employeeName,employeeDepartmentID) VALUES('xexe',3);

SELECT * FROM department;

SELECT * FROM employee;

搭建开发环境

创建普通的Java工程,结构如下:
在这里插入图片描述

Employee

package cn.com.pojo;
/**
 * 本文作者:谷哥的小弟 
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public class Employee {
	private Integer employeeID;
	private Integer employeeDepartmentID;
	private String employeeName;
	public Employee() {
		super();
	}
	public Employee(Integer employeeID, Integer employeeDepartmentID, String employeeName) {
		super();
		this.employeeID = employeeID;
		this.employeeDepartmentID = employeeDepartmentID;
		this.employeeName = employeeName;
	}
	public Integer getEmployeeID() {
		return employeeID;
	}
	public void setEmployeeID(Integer employeeID) {
		this.employeeID = employeeID;
	}
	public Integer getEmployeeDepartmentID() {
		return employeeDepartmentID;
	}
	public void setEmployeeDepartmentID(Integer employeeDepartmentID) {
		this.employeeDepartmentID = employeeDepartmentID;
	}
	public String getEmployeeName() {
		return employeeName;
	}
	public void setEmployeeName(String employeeName) {
		this.employeeName = employeeName;
	}
	@Override
	public String toString() {
		return "Employee [employeeID=" + employeeID + ", employeeDepartmentID=" + employeeDepartmentID
				+ ", employeeName=" + employeeName + "]";
	}
	
}

Department

package cn.com.pojo;

import java.util.List;
/**
 * 本文作者:谷哥的小弟 
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public class Department {
	private Integer departmentID;
	private String departmentName;
	private List<Employee> employeeList;
	public Department() {
		super();
	}
	public Department(Integer departmentID, String departmentName, List<Employee> employeeList) {
		super();
		this.departmentID = departmentID;
		this.departmentName = departmentName;
		this.employeeList = employeeList;
	}
	public Integer getDepartmentID() {
		return departmentID;
	}
	public void setDepartmentID(Integer departmentID) {
		this.departmentID = departmentID;
	}
	public String getDepartmentName() {
		return departmentName;
	}
	public void setDepartmentName(String departmentName) {
		this.departmentName = departmentName;
	}
	public List<Employee> getEmployeeList() {
		return employeeList;
	}
	public void setEmployeeList(List<Employee> employeeList) {
		this.employeeList = employeeList;
	}
	@Override
	public String toString() {
		return "Department [departmentID=" + departmentID + ", departmentName=" + departmentName + ", employeeList="
				+ employeeList + "]";
	}
	
}

EmployeeMapper.java

package cn.com.mapper;

import cn.com.pojo.Employee;
/**
 * 本文作者:谷哥的小弟 
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public interface EmployeeMapper {
	public Employee queryEmployeeById(Integer id);
}

DepartmentMapper.java

package cn.com.mapper;

import cn.com.pojo.Department;
/**
 * 本文作者:谷哥的小弟 
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public interface DepartmentMapper {
	
	//依据部门编号查询所属员工
	public Department queryDepartmentById(Integer id);
	
	//依据部门编号利用分步立即查询所属员工
	public Department queryDepartmentByIdTwoStep(Integer id);
}

EmployeeMapper.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="cn.com.mapper.EmployeeMapper">
  
  <select id="queryEmployeeById" resultType="cn.com.pojo.Employee">
	select * from employee where employeeDepartmentID=#{employeeDepartmentID}
  </select>
  
</mapper>

DepartmentMapper.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="cn.com.mapper.DepartmentMapper">
  
  <!-- 依据部门编号查询所属员工 -->
  <select id="queryDepartmentById" resultMap="queryDepartmentByIdResultMap">
	SELECT
		department.*,employee.employeeID,employee.employeeDepartmentID,employee.employeeName
	FROM 
		department LEFT JOIN employee
	ON 
	    department.departmentID = employee.employeeDepartmentID
	WHERE 
		department.departmentID = #{departmentID}
  </select>
  
  <resultMap type="cn.com.pojo.Department" id="queryDepartmentByIdResultMap">
     <id column="departmentID" property="departmentID"/>
     <result column="departmentName" property="departmentName"/>
     <collection property="employeeList" ofType="cn.com.pojo.Employee">
       <id column="employeeID" property="employeeID"/>
       <result column="employeeDepartmentID" property="employeeDepartmentID"/>
       <result column="employeeName" property="employeeName"/>
     </collection>
  </resultMap>
  
  
  
  
  <!-- 依据部门编号利用分步查询所属员工 -->
  <select id="queryDepartmentByIdTwoStep" resultMap="queryDepartmentByIdTwoStepResultMap">
	 select departmentID,departmentName from department where departmentID=#{departmentID}
  </select>
  
  <resultMap type="cn.com.pojo.Department" id="queryDepartmentByIdTwoStepResultMap">
     <id column="departmentID" property="departmentID"/>
     <result column="departmentName" property="departmentName"/>
     <collection property="employeeList" select="cn.com.mapper.EmployeeMapper.queryEmployeeById" column="departmentID"/>
  </resultMap>
  
</mapper>

MybatisTest

package cn.com.test;

import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import cn.com.mapper.DepartmentMapper;
import cn.com.pojo.Department;
/**
 * 本文作者:谷哥的小弟 
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public class MybatisTest {

	static SqlSessionFactory sqlSessionFactory = null;

	public static SqlSessionFactory getSqlSessionFactory() {
		try {
			if (sqlSessionFactory == null) {
				InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
				SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
				sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
			}
			return sqlSessionFactory;
		} catch (Exception e) {
			
		} finally {

		}
		return null;
	}
	
	@Test
	public void testQueryDepartmentById() {
		//获取SqlSession
		SqlSession sqlSession=getSqlSessionFactory().openSession();
		//利用SqlSession得到Mapper接口
		DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);
		//利用SqlSession执行数据操作
		Department department = departmentMapper.queryDepartmentById(1);
		System.out.println(department);
		//关闭SqlSession
		sqlSession.close();
	}
	
	@Test
	public void testQueryDepartmentByIdTwoStep() {
		//获取SqlSession
		SqlSession sqlSession=getSqlSessionFactory().openSession();
		//利用SqlSession得到Mapper接口
		DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);
		//利用SqlSession执行数据操作
		Department department = departmentMapper.queryDepartmentByIdTwoStep(1);
		
		//第一次测试
		String departmentName = department.getDepartmentName();
		System.out.println(departmentName);
		
		//第二次测试
		//List<Employee> employeeList = department.getEmployeeList();
		//System.out.println(employeeList.toString());
		
		//关闭SqlSession
		sqlSession.close();
	}
	
}

log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  
  <!-- 配置数据源 -->
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatisDatabase"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
  
  <!-- 配置mapper -->
  <mappers>
    <mapper resource="cn/com/pojo/DepartmentMapper.xml"/>
    <mapper resource="cn/com/pojo/EmployeeMapper.xml"/>
  </mappers>
  
</configuration>

实验过程及其分析

在此,我们以示例结合试验的方式学习MyBatis一对多查询。

依据部门编号查询所属员工

DepartmentMapper.java

//依据部门编号查询所属员工
public Department queryDepartmentById(Integer id);

DepartmentMapper.xml

<!-- 依据部门编号查询所属员工 -->
  <select id="queryDepartmentById" resultMap="queryDepartmentByIdResultMap">
	SELECT
		department.*,employee.employeeID,employee.employeeDepartmentID,employee.employeeName
	FROM 
		department LEFT JOIN employee
	ON 
	    department.departmentID = employee.employeeDepartmentID
	WHERE 
		department.departmentID = #{departmentID}
  </select>
  
  <resultMap type="cn.com.pojo.Department" id="queryDepartmentByIdResultMap">
     <id column="departmentID" property="departmentID"/>
     <result column="departmentName" property="departmentName"/>
     <collection property="employeeList" ofType="cn.com.pojo.Employee">
       <id column="employeeID" property="employeeID"/>
       <result column="employeeDepartmentID" property="employeeDepartmentID"/>
       <result column="employeeName" property="employeeName"/>
     </collection>
  </resultMap>
  • 1、在select标签中将查询结果交给resultMap标签处理。所以,select标签中resultMap属性的值与resultMap标签中id属性的值相同。
  • 2、resultMap标签中type属性的值表示将查询结果转换JavaBean的类型。
  • 3、resultMap标签中的id子标签用于将查询结果的主键列转换到JavaBean对象对应的属性。其中,column属性表示查询结果的列名,property属性表示JavaBean对象对应的属性
  • 4、resultMap标签中的result 子标签用于将查询结果的非主键列转换到JavaBean对象对应的属性。其中,column属性表示查询结果的列名,property属性表示JavaBean对象对应的属性
  • 5、在处理完Department的简单属性departmentID和departmentName之后再使用collection标签处理Department中List<Employee>类型的employeeList,它也常被称为Department的子集合对象。collection标签的property属性表示子对象的名称,collection标签的ofType属性表示子集合对象中各元素的全路径(类型)。collection标签中的id子标签用于将查询结果的主键列转换到元素对应的属性;其中,column属性表示查询结果的列名,property属性表示元素对应的属性。类似地,collection标签中的result子标签用于将查询结果的非主键列转换到元素对应的属性;其中,column属性表示查询结果的列名,property属性表示元素对应的属性。

MybatisTest.java

@Test
public void testQueryDepartmentById() {
	//获取SqlSession
	SqlSession sqlSession=getSqlSessionFactory().openSession();
	//利用SqlSession得到Mapper接口
	DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);
	//利用SqlSession执行数据操作
	Department department = departmentMapper.queryDepartmentById(1);
	System.out.println(department);
	//关闭SqlSession
	sqlSession.close();
}

测试结果
在这里插入图片描述

依据部门编号利用分步立即查询所属员工

EmployeeMapper.java

public Employee queryEmployeeById(Integer id);

EmployeeMapper.xml

  <select id="queryEmployeeById" resultType="cn.com.pojo.Employee">
	select * from employee where employeeDepartmentID=#{employeeDepartmentID}
  </select>

DepartmentMapper.java

//依据部门编号利用分步立即查询所属员工
public Department queryDepartmentByIdTwoStep(Integer id);

DepartmentMapper.xml

<!-- 依据部门编号利用分步查询所属员工 -->
<select id="queryDepartmentByIdTwoStep" resultMap="queryDepartmentByIdTwoStepResultMap">
select departmentID,departmentName from department where departmentID=#{departmentID}
</select>

<resultMap type="cn.com.pojo.Department" id="queryDepartmentByIdTwoStepResultMap">
   <id column="departmentID" property="departmentID"/>
   <result column="departmentName" property="departmentName"/>
   <collection property="employeeList" select="cn.com.mapper.EmployeeMapper.queryEmployeeById" column="departmentID"/>
</resultMap>
  • 1、在select标签中将查询结果交给resultMap标签处理。所以,select标签中resultMap属性的值与resultMap标签中id属性的值相同。
  • 2、resultMap标签中type属性的值表示将查询结果转换JavaBean的类型。
  • 3、resultMap标签中的id子标签用于将查询结果的主键列转换到JavaBean对象对应的属性。其中,column属性表示查询结果的列名,property属性表示JavaBean对象对应的属性
  • 4、resultMap标签中的result 子标签用于将查询结果的非主键列转换到JavaBean对象对应的属性。其中,column属性表示查询结果的列名,property属性表示JavaBean对象对应的属性
  • 5、在处理完Department的简单属性departmentID和departmentName之后再使用collection标签处理Department中List<Employee>类型的employeeList,它也常被称为Department的子集合对象。思路:使用select标签查询得到的departmentID去employee表中查询该部门的所有员工。我们可使用collection标签的property属性表示子集合对象的名称;select属性表示通过哪个子查询得到该对象 ,其表现形式为:xxxMapper.xml的命名空间.标签id;column属性表示将哪个列做为参数传递给子查询。

MybatisTest.java

@Test
public void testQueryDepartmentByIdTwoStep() {
	//获取SqlSession
	SqlSession sqlSession=getSqlSessionFactory().openSession();
	//利用SqlSession得到Mapper接口
	DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);
	//利用SqlSession执行数据操作
	Department department = departmentMapper.queryDepartmentByIdTwoStep(1);
	
	//第一次测试
	//String departmentName = department.getDepartmentName();
	//System.out.println(departmentName);
	
	//第二次测试
	List<Employee> employeeList = department.getEmployeeList();
	System.out.println(employeeList.toString());
	
	//关闭SqlSession
	sqlSession.close();
}

测试结果
在这里插入图片描述

依据部门编号利用分步延迟查询所属员工

为实现延迟查询需在mybatis-config.xml中配置如下设置:

<!-- 配置延迟加载 -->
<settings>
   <!-- 打开延迟加载开关 -->  
   <setting name="lazyLoadingEnabled" value="true" />  
   <!-- 将积极加载改为消极加载 -->  
   <setting name="aggressiveLazyLoading" value="false"/> 
</settings>

修改后的mybatis-config.xml如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <!-- 配置延迟加载 -->
  <settings>
     <!-- 打开延迟加载开关 -->  
     <setting name="lazyLoadingEnabled" value="true" />  
     <!-- 将积极加载改为消极加载 -->  
     <setting name="aggressiveLazyLoading" value="false"/> 
  </settings>
  
  <!-- 配置数据源 -->
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatisDatabase"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
      </dataSource>
    </environment>
  </environments>
  
  <!-- 配置mapper -->
  <mappers>
    <mapper resource="cn/com/pojo/DepartmentMapper.xml"/>
    <mapper resource="cn/com/pojo/EmployeeMapper.xml"/>
  </mappers>
  
</configuration>
发布了1017 篇原创文章 · 获赞 1976 · 访问量 236万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览