Mybatis 49_基于多结果集的1-1关联

49_基于多结果集的1-1关联

  • 多结果集的1-1关联映射
    • 要修改的地方
    • 项目0517多结果集的1-1

多结果集的1-1关联映射

这种情况比较少见:它要求执行一次数据库查询,就能返回多个结果集。
通常表现为调用存储过程——调用一次,可能返回多个结果集

要修改的地方

  1. SQL语句改为调用存储过程,不再是执行简单的select语句
  2. 元素中使用resultSets为多个结果集指定了名字。
    【注意】: resultSets为多个结果集指定名称时,名称之间只能有逗号分隔符,不能有额外的空格
  3. 元素或中指定如下4个属性(前3个是特有的):
    - column:指定当前表中用于记录关联关系的数据列的列名。
    - foreignColumn:指定关联表中用于记录关联关系的数据列的列名。
    - resultSet: 用哪个结果集来执行映射
    - resultMap:还是同样指定。

项目0517多结果集的1-1

主类

package lee;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.itcheng.app.dao.AddressMapper;
import org.itcheng.app.dao.PersonMapper;
import org.itcheng.app.domain.Address;
import org.itcheng.app.domain.Person;

public class PersonManager
{
	// SqlSessionFactory应该是应用级别
	private static SqlSessionFactory sqlSessionFactory;
	public static void main(String[] args) throws IOException
	{
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		// 1. 创建SqlSessionFactory
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		// 2. 打开SqlSession
		SqlSession sqlSession = sqlSessionFactory.openSession();
		
//		findPerson(sqlSession);
		/* 结果
		 * DEBUG [main] org.itcheng.app.dao.PersonMapper.getPerson ==>  Preparing: {call p_get_person_address(?)} 
		 * DEBUG [main] org.itcheng.app.dao.PersonMapper.getPerson ==> Parameters: 3(Integer)
		 * DEBUG [main] org.itcheng.app.dao.PersonMapper.getPerson <==      Total: 1
		 * DEBUG [main] org.itcheng.app.dao.PersonMapper.getPerson <==      Total: 1
		 * DEBUG [main] org.itcheng.app.dao.PersonMapper.getPerson <==    Updates: 0
		 * 孙二娘
		 * -----------------
		 * 孟州黑店
		 * */
	
		findAddresses(sqlSession);
		/* 结果
		 * DEBUG [main] org.itcheng.app.dao.AddressMapper.findAddressesById ==>  Preparing: {call p_get_address_person(?)} 
		 * DEBUG [main] org.itcheng.app.dao.AddressMapper.findAddressesById ==> Parameters: 1(Integer)
		 * DEBUG [main] org.itcheng.app.dao.AddressMapper.findAddressesById <==      Total: 4
		 * DEBUG [main] org.itcheng.app.dao.AddressMapper.findAddressesById <==      Total: 4
		 * DEBUG [main] org.itcheng.app.dao.AddressMapper.findAddressesById <==    Updates: 0
		 * 洛阳城 --> 武松
		 * 云梦泽 --> 鲁智深
		 * 孟州黑店 --> 孙二娘
		 * 逍遥派 --> 无涯子
		 * -----------------
		 * */
	}
	
	public static void findPerson(SqlSession sqlSession)
	{
		PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);
		
		Person p = personMapper.getPerson(3);
		System.out.println(p.getName());
		System.out.println("-----------------");
		
		// Person获取关联实体是延迟加载,要等到真正访问关联实体时才去执行额外的SELECT语句
		System.out.println(p.getAddr().getDetail());
		
		// 4. 提交事务
		sqlSession.commit();
		// 5. 关闭资源
		sqlSession.close();	
	}
	
	public static void findAddresses(SqlSession sqlSession)
	{
		AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);
		
		List<Address> addrList = addressMapper.findAddressesById(1);
		//  由于Address获取关联实体是立即加载,因此它会立即执行额外的SELECT语句
		// 对于立即加载策略,即使不访问关联实体,它也会立即执行额外的SELECT语句
		addrList.forEach(e -> {
			System.out.println(e.getDetail() + " --> " + e.getPerson().getName());
		});
		System.out.println("-----------------");
		
		// 4. 提交事务
		sqlSession.commit();
		// 5. 关闭资源
		sqlSession.close();	
	}	
		
}

接口类

package org.itcheng.app.dao;

import java.util.List;

import org.itcheng.app.domain.Address;

// Mapper组件相当于DAO组件
public interface AddressMapper
{
	List<Address> findAddressesById(Integer id);
}
package org.itcheng.app.dao;

import org.itcheng.app.domain.Person;

// Mapper组件相当于DAO组件
public interface PersonMapper
{
	Person getPerson(Integer id);
}

配置文件


DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="org.itcheng.app.dao.AddressMapper">

	<select id="findAddressesById" resultMap="addrMap" statementType="CALLABLE"
		resultSets="addrs,persons">
		{call p_get_address_person(#{id, mode=IN, jdbcType=INTEGER})}
	select>

	<resultMap type="address" id="addrMap">
		<id column="addr_id" property="id"/>
		<result column="addr_detail" property="detail"/>
		
		<association property="person" 
			column="owner_id"
			foreignColumn="person_id"
			resultSet="persons"
			resultMap="org.itcheng.app.dao.PersonMapper.personMap" />
	resultMap>
mapper>

DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="org.itcheng.app.dao.PersonMapper">
	<select id="getPerson" resultMap="personMap" statementType="CALLABLE"
		resultSets="persons,addrs">
		{call p_get_person_address(#{id})}
	select>
	
	<resultMap type="person" id="personMap">
		<id column="person_id" property="id"/>
		<result column="person_name" property="name"/>
		<result column="person_age" property="age"/>
				
		<association property="addr"
			column="person_id" foreignColumn="owner_id"
			resultSet="addrs"
			resultMap="org.itcheng.app.dao.AddressMapper.addrMap"/>
	resultMap>
mapper>

存储过程

delimiter $$
-- 创建存储过程
create procedure p_get_address_person(in id int)
begin
    select * from address_inf where addr_id > id;
    select * from person_inf where person_id in 
    (select owner_id from address_inf where addr_id > id);
end $$

-- 创建存储过程
create procedure p_get_person_address(in id int)
begin
    select * from person_inf where person_id = id;
    select * from address_inf where owner_id in
    (select person_id from person_inf where person_id = id);
end $$
delimiter ;

你可能感兴趣的:(mybatis,oracle,数据库)