映射文件-select(关联查询-仅一个对象)

使用场景:

比如:查询员工信息的同时也要查询出该员工信息的部门信息(同样是一个javaBean)

环境搭建:

Employee类:

package cn.it.mybatis.bean;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

	private Integer id;
	private String lastName;
	private String email;
	private String gender;
	private Department dept;

	public Department getDept() {
		return dept;
	}

	public void setDept(Department dept) {
		this.dept = dept;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
	}

	public Employee(Integer id, String lastName, String email, String gender) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.gender = gender;
	}

	public Employee() {
		super();
		// TODO Auto-generated constructor stub
	}



}

Department类:

package cn.it.mybatis.bean;

public class Department {
	private Integer id;
	private String deptName;

	public Integer getId() {
		return id;
	}

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

	public String getDeptName() {
		return deptName;
	}

	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}

	@Override
	public String toString() {
		return "Department [id=" + id + ", deptName=" + deptName + "]";
	}
}

1.级联属性(属性的属性)封装关联对象

映射文件中的配置: 

给dept属性的属性赋值

<result column="did" property="dept.id"/>

<result column="dept_name" property="dept.deptName"/>

	 <resultMap type="cn.it.mybatis.bean.Employee" id="MyMap2">
	 	<id column="id" property="id"/>
	 	<result column="last_name" property="lastName"/>
	 	<result column="email" property="email"/>
	 	<result column="gender" property="gender"/>
	 	
	 	<!-- 给级联属性(属性的属性)赋值 -->
	 	<result column="did" property="dept.id"/>
	 	<result column="dept_name" property="dept.deptName"/>
	 </resultMap>
	 <!-- public Employee getEmpAndDeptById(Integer id);  -->
	 <select id="getEmpAndDeptById" resultMap="MyMap2">
	 	SELECT e.id id,e.last_name last_name, e.email email, e.gender gender ,d.id did,d.dept_name dept_name
		FROM tbl_dept d,tbl_employee e 
		WHERE d.id = e.d_id AND e.id = #{id}
	 </select>

测试代码:

@Test
	void test10() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

		SqlSession openSession = sqlSessionFactory.openSession();

		try {
			EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);

			Employee employee = mapper.getEmpAndDeptById(2);

			System.out.println(employee);
			System.out.println(employee.getDept());

		} finally {
			openSession.close();
		}
	}

查询结果:

两个对象都封装好了


 2.使用association 定义关联对象的封装规则

	 <!-- association:定义关联的单个对象的封装规则 -->
	 <resultMap type="cn.it.mybatis.bean.Employee" id="MyMap3">
	 	<id column="id" property="id"/>
	 	<result column="last_name" property="lastName"/>
	 	<result column="email" property="email"/>
	 	<result column="gender" property="gender"/>
	 	
	 	<!--
	 		property:指定哪个属性是联合对象
	 		javaType:指定这个属性的类型
	 	-->
	 	<association property="dept" javaType="cn.it.mybatis.bean.Department">
	 		<id column="did" property="id"/>
	 		<result column="dept_name" property="deptName"/>
	 	</association>
	 	
	 </resultMap>
	<!--  public Employee getEmpAndDeptById(Integer id);  -->
	 <select id="getEmpAndDeptById" resultMap="MyMap3">
	 	SELECT e.id id,e.last_name last_name, e.email email, e.gender gender ,d.id did,d.dept_name dept_name
		FROM tbl_dept d,tbl_employee e 
		WHERE d.id = e.d_id AND e.id = #{id}
	 </select>

查询结果:

同样两个对象都封装成功


3. association分步查询

1.DepartmentMapper.xml

        <select id="getDeptById" resultType="cn.it.mybatis.bean.Department">
  		select id,dept_name deptName from tbl_dept where id = #{id}
  	</select>

2.EmployeeMapperPlus.xml

	 <!-- 使用association进行分步查询 
	 	1.先按照员工id查询员工信息
	 	2.根据员工信息中的部门id去部门表查出部门信息
	 	3.将部门设置到员工信息中
	 -->
	 <resultMap type="cn.it.mybatis.bean.Employee" id="MyMapByStep">
	 	<id column="id" property="id"/>
	 	<result column="last_name" property="lastName"/>
	 	<result column="email" property="email"/>
	 	<result column="gender" property="gender"/>
	 	
	 	<!-- association定义单个关联对象的封装规则 
	 		 select:表明当前的属性需要调用select指定的方法查出结果
	 		 column:指定将哪一列的值传给这个查询方法
	 		 
	 		 流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性
	 	-->
	 	<association property="dept" 
	 				 select="cn.it.mybatis.dao.DepartmentMapper.getDeptById"
	 				 column="d_id"
	 				 >
	 		
	 	</association>
	 </resultMap>
	 <!-- public Employee getEmpById2(Integer id); -->
	 <select id="getEmpById2" resultMap="MyMapByStep">
	 	select * from tbl_employee where id = #{id}
	 </select>

查询结果:

分步查询可以开启延迟加载(按需加载)

我们在每一次查询员工信息时都会查询出部门信息,

我们希望的是,部门信息时在我们需要的时候在去查询。

实现:分步查询的基础上再全局配置文件中(settings)添加两个配置

推荐:最好是显示的指定每一个配置,即使它是默认值,这是为了防止版本的更新带了的问题

1.lazyLoadingEnabled

2.aggressiveLazyLoading MyBatis在 3.4.1 及之前的版本默认值为 true)​​​​​​​


测试:

只在全局配置文件中配置lazyLoadingEnabled和aggressiveLazyLoading,其他与分步查询一样:

        <settings>
		<setting name="mapUnderscoreToCamelCase" value="true"/>
		<setting name="lazyLoadingEnabled" value="true"/>
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

测试代码:

@Test
	void test10() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();

		SqlSession openSession = sqlSessionFactory.openSession();

		try {
			EmployeeMapperPlus mapper = openSession.getMapper(EmployeeMapperPlus.class);

			Employee employee = mapper.getEmpById2(2);

			// 只需要员工姓名,不需要部门信息
			System.out.println(employee.getLastName());

			// 现在需要部门信息
			System.out.println(employee.getDept());

		} finally {
			openSession.close();
		}
	}

查询结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值