Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载)

奋斗吧
奋斗吧
擅长邻域:未填写

标签: Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载) Python博客 51CTO博客

2023-05-07 18:24:10 128浏览

Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载),1.一对一实现(resultMap)        使用resultMap将查询到的多个表中的数据映射到多个pojo中(association)   (1)业务


1.一对一实现 (resultMap) 


            使用resultMap将查询到的多个表中的数据映射到多个pojo中(association)


      (1)业务描述


                 业务 : 查询经营信息及其经营者的姓名,生日,家庭住址 一对一查询 使用 resultMap实现


                 经营信息Pojo拓展类实现 :


package cn.labelnet.pojo;

/**
 * 经营信息扩展类,满足查询语句 : select
 * fo.*,fc.username,fc.born_date,fc.family_register_address from f_operation
 * fo,f_client fc where fo.client_id=fc.id; 经营信息的所有信息和客户的姓名,生日,家庭住址 描述:
 * 使用resultmap进行映射,扩展经营信息类 作者 :原明卓 时间 :2015年12月23日 上午10:36:04 版本 :1.0
 */
public class OperationCustionMap extends Operation {

	// 直接将客户信息映射到Client属性中
	private Client client;

	public Client getClient() {
		return client;
	}

	public void setClient(Client client) {
		this.client = client;
	}
}




      (2)Mapper.xml实现


<!-- 业务 : 查询经营信息及其经营者的姓名,生日,家庭住址 一对一查询 使用 resultMap实现 -->
	<select id="findOPerationClientMap" resultMap="operationClient">
		select
		fo.*,
		fc.username,
		fc.born_date,
		fc.family_register_address
		from
		f_operation fo,
		f_client fc
		where
		fo.client_id=fc.id
	</select>




      (3)resultMap 实现


<!-- 一对一查询 -->
	<resultMap type="cn.labelnet.pojo.OperationCustionMap" id="operationClient">

		<id column="id" property="id" />
		<result column="client_id" property="client_id" />
		<result column="operate_infomation_describe" property="operate_infomation_describe" />
		<result column="possess_sharholding" property="possess_sharholding" />
		<result column="operate_address" property="operate_address" />
		<result column="year_avg_income" property="year_avg_income" />
		<result column="begin_operation_time" property="begin_operation_time" />
		<result column="employees_amount" property="employees_amount" />
		<result column="legal_person_name" property="legal_person_name" />
		<result column="legal_person_crd_number" property="legal_person_crd_number" />
		<result column="operate_crd_number" property="operate_crd_number" />
		<result column="update_time" property="update_time" />

		<association property="client" javaType="cn.labelnet.pojo.Client">
			<id column="client_id" property="id" />
			<result column="username" property="username" />
			<result column="bron_date" property="bron_date" />
			<result column="family_register_address" property="family_register_address" />
		</association>

	</resultMap>




      (4)Mapper.java实现


public List<OperationCustionMap> findOPerationClientMap() throws Exception;




      (5)测试


@Test
	public void findOPerationClientMap() throws Exception {
		SqlSession session=sqlFactory.openSession();
		OperationMapper om = session.getMapper(OperationMapper.class);
		List<OperationCustionMap> list = om.findOPerationClientMap();
		
		for (OperationCustionMap oper : list) {
			System.out.print(oper.getLegal_person_name()+" |  ");
			System.out.println(oper.getClient());
		}
		
	}




      (6)结果

Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载)_一对多


        总结:

             使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加对应列名,来完成映射;建议使用resultType ; resultMap有些麻烦,如果有对查询结果有特殊要求,使用resultMap可以完成将关联查询映射到pojo属性中;其中resultMap可以实现延迟加载,而resultType无法实现;


2.一对多实现 

      (1)业务描述


                查询门面经营信息的客户姓名,客户生日,客户家庭住址,资产名称,资产地址,资产市值;


      集合映射 : 在resultMap中使用collection对关联查询到多条记录映射到集合对象中;property将关联查询到的多条记录映射到那个属性上;ofType:指定映射到list集合属性中的pojo类型;
resultMap 可以使用extends 关键字继承;


              经营信息拓展类实现 :


import java.util.List;

/**
 * 查询经营场所及其客户信息和客户资产信息
 * 描述:经营信息拓展类,查询经营信息,客户信息,资产信息
 * 作者 :原明卓
 * 时间 :2015年12月23日 下午4:35:53
 * 版本 :1.0
 */
public class OperationCustionAssetMap extends Operation {

	// 直接将客户信息映射到Client属性中
	private Client client;

	public Client getClient() {
		return client;
	}

	public void setClient(Client client) {
		this.client = client;
	}
	
	//资产信息
	private List<Asset> assets;

	public List<Asset> getAssets() {
		return assets;
	}

	public void setAssets(List<Asset> assets) {
		this.assets = assets;
	}
	
	

}




      (2)Mapper.xml 实现


<!-- 业务 : 查询门面经营信息的客户姓名,客户生日,客户家庭住址,资产名称,资产地址,资产市值 一对多查询 -->

	<select id="findOPerationClientAsset" resultMap="operationClientAsset">
		select
		fo.*,
		fc.username,
		fc.born_date,
		fc.family_register_address,
		fa.id fa_id,
		fa.asset_name,
		fa.asset_address,
		fa.asset_market_valuation
		from
		f_operation fo,
		f_client fc,
		f_asset fa
		where
		fo.client_id=fc.id
		and
		fo.id=fa.operation_id
	</select>




      (3)resultMap实现


<!-- 一对一查询 -->
	<resultMap type="cn.labelnet.pojo.OperationCustionMap" id="operationClient">

		<id column="id" property="id" />
		<result column="client_id" property="client_id" />
		<result column="operate_infomation_describe" property="operate_infomation_describe" />
		<result column="possess_sharholding" property="possess_sharholding" />
		<result column="operate_address" property="operate_address" />
		<result column="year_avg_income" property="year_avg_income" />
		<result column="begin_operation_time" property="begin_operation_time" />
		<result column="employees_amount" property="employees_amount" />
		<result column="legal_person_name" property="legal_person_name" />
		<result column="legal_person_crd_number" property="legal_person_crd_number" />
		<result column="operate_crd_number" property="operate_crd_number" />
		<result column="update_time" property="update_time" />

		<association property="client" javaType="cn.labelnet.pojo.Client">
			<id column="client_id" property="id" />
			<result column="username" property="username" />
			<result column="bron_date" property="bron_date" />
			<result column="family_register_address" property="family_register_address" />
		</association>

	</resultMap>

	<resultMap type="cn.labelnet.pojo.OperationCustionAssetMap"
		id="operationClientAsset" extends="operationClient">

		<collection property="assets" ofType="cn.labelnet.pojo.Asset">
			<id column="fa_id" property="id" />
			<result column="asset_name" property="assetName" />
			<result column="asset_address" property="assetAddress" />
			<result column="asset_market_valuation" property="assetMarketValuation" />
		</collection>
	</resultMap>




      (4)Mapper.java实现


public List<OperationCustionAssetMap> findOPerationClientAsset() throws Exception;




       (5)测试


@Test
	public void findOPerationClientAsset() throws Exception {
		SqlSession session=sqlFactory.openSession();
		OperationMapper om = session.getMapper(OperationMapper.class);
		List<OperationCustionAssetMap> list = om.findOPerationClientAsset();
		
		for (OperationCustionAssetMap oper : list) {
			System.out.println("---------------------------------------");
			System.out.println(oper.getId()+" |  ");
			System.out.println(oper.getAssets().size()+" | ");
			System.out.println(oper.getClient());
		}
		
	}




       (6)结果

Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载)_mybatis_02

    

            总结 :

                  mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中;


3.多对多实现


            根据需求,使用resultMap是针对那些对查询结果映射有特殊要求的功能,比如特殊要求映射成list;


       (1)业务描述


查询客户对应的经营信息(多条),资产信息(多条)及其 授权信息(相对与资产信息1条) 主表:客户表 关联表:经营信息,资产信息,授权信息 


               客户信息拓展类 : 


/**
 *客户信息实体拓展类
 * <p>cn.labelnet.pojo
 * 描述 :TODO
 * 
 * <p>作者:原明卓 </p>
 * <p>时间:2015年12月23日 下午8:24:35</p>
 */
public class ClientCustom extends Client{
	
	//一个客户有包含多条经营信息
	private List<OperationCustionCreditMap> operationCustom;

	public List<OperationCustionCreditMap> getOperationCustom() {
		return operationCustom;
	}

	public void setOperationCustom(List<OperationCustionCreditMap> operationCustom) {
		this.operationCustom = operationCustom;
	}
	

}


         经营信息拓展类 :




package cn.labelnet.pojo;

import java.util.List;

/**
 * 经营信息拓展实体类
 * <p>cn.labelnet.pojo
 * 描述 :TODO
 * 
 * <p>作者:原明卓 </p>
 * <p>时间:2015年12月23日 下午8:25:46</p>
 */
public class OperationCustionCreditMap extends Operation{
	
	//一条经营信息有多条资产信息
	private List<AssetCustom> assetCustoms;

	public List<AssetCustom> getAssetCustoms() {
		return assetCustoms;
	}

	public void setAssetCustoms(List<AssetCustom> assetCustoms) {
		this.assetCustoms = assetCustoms;
	}

}


                  资产拓展类 :


/**
 * 资产拓展类
 * <p>cn.labelnet.pojo
 * 描述 :包含一条资产认证信息
 * 
 * <p>作者:原明卓 </p>
 * <p>时间:2015年12月23日 下午8:26:38</p>
 */
public class AssetCustom extends Asset{
	
	//一条资产信息,对应一条授权信息
	private Credit credit;

	public Credit getCredit() {
		return credit;
	}

	public void setCredit(Credit credit) {
		this.credit = credit;
	}

}


 


        授权信息实体  :


/**
 * 店面资产授权认证实体类
 * <p>cn.labelnet.pojo
 * 描述 :TODO
 * 
 * <p>作者:原明卓 </p>
 * <p>时间:2015年12月23日 下午7:15:25</p>
 */
public class Credit {
	
	private int id;
	private int assetId;
	private int nowCreditLimit;
	private int frozenLimit;
	private Date updateTime;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getAssetId() {
		return assetId;
	}
	public void setAssetId(int assetId) {
		this.assetId = assetId;
	}
	public int getNowCreditLimit() {
		return nowCreditLimit;
	}
	public void setNowCreditLimit(int nowCreditLimit) {
		this.nowCreditLimit = nowCreditLimit;
	}
	public int getFrozenLimit() {
		return frozenLimit;
	}
	public void setFrozenLimit(int frozenLimit) {
		this.frozenLimit = frozenLimit;
	}
	public Date getUpdateTime() {
		return updateTime;
	}
	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}
	@Override
	public String toString() {
		return "Credit [id=" + id + ", assetId=" + assetId
				+ ", nowCreditLimit=" + nowCreditLimit + ", frozenLimit="
				+ frozenLimit + ", updateTime=" + updateTime + "]";
	}
	
	

}




       (2)Mapper.xml实现


<select id="findClientCredit" resultMap="findClientCreditOperation">
		select
		fc.id fc_id,
		fc.username,
		fc.born_date,
		fc.now_address,
		fo.id fo_id,
		fo.operate_infomation_describe,
		fo.year_avg_income,
		fa.id fa_id,
		fa.asset_name,
		fa.asset_describe,
		fa.asset_address,
		fa.asset_market_valuation,
		ft.id ft_id,
		ft.now_credit_limit,
		ft.frozen_limit,
		ft.update_time
		from
		f_client fc,
		f_operation fo,
		f_asset fa,
		f_credit ft
		where
		fo.client_id=fc.id
		and
		fa.operation_id=fo.id
		and
		ft.asset_id=fa.id
	</select>




        (3) resultMap实现


                

<resultMap type="cn.labelnet.pojo.ClientCustom" id="findClientCreditOperation">

		<!-- 用户信息 -->
		<id column="fc_id" property="id" />
		<result column="username" property="username" />
		<result column="born_date" property="bron_date" />
		<result column="now_address" property="now_address" />

		<!-- 经营信息 -->
		<collection property="operationCustom"
			ofType="cn.labelnet.pojo.OperationCustionCreditMap">
			<id column="fo_id" property="id" />
			<result column="operate_infomation_describe" property="operate_infomation_describe" />
			<result column="year_avg_income" property="year_avg_income" />

			<!-- 资产信息 -->
			<collection property="assetCustoms" ofType="cn.labelnet.pojo.AssetCustom">
				<id column="fa_id" property="id" />
				<result column="asset_name" property="assetName" />
				<result column="asset_describe" property="assetDescribe" />
				<result column="asset_address" property="assetAddress" />
				<result column="asset_market_valuation" property="assetMarketValuation" />

				<!-- 资产授权信息 -->
				<association property="credit" javaType="cn.labelnet.pojo.Credit">
					<id column="ft_id" property="id" />
					<result column="now_credit_limit" property="nowCreditLimit" />
					<result column="frozen_limit" property="frozenLimit" />
					<result column="update_time" property="updateTime" />
				</association>

			</collection>

		</collection>

	</resultMap>



         (4)Mapper.java实现


//多对多查询
	 public List<ClientCustom> findClientCredit() throws Exception;




       (5)测试


@Test
	public void findClientCredit() throws Exception {
		SqlSession session=sqlFactory.openSession();
		OperationMapper om = session.getMapper(OperationMapper.class);
		List<ClientCustom> list = om.findClientCredit();
		
		for (ClientCustom cc : list) {
			
			System.out.println("--------------------------");
			System.out.println("姓名:" + cc.getUsername());
			List<OperationCustionCreditMap> oc = cc.getOperationCustom();
			for (OperationCustionCreditMap occ : oc) {
				System.out.println("经营信息:"+occ);
				
				List<AssetCustom> acs = occ.getAssetCustoms();
				for (AssetCustom ac : acs) {
					System.out.println("资产信息:"+ac+" |  资产授权信息 : "+ac.getCredit());
				}
			}
		}
	}




        (6)结果

Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载)_多对多_03

   

           高级映射总结:


    resultType :将查询结果按照属性名和sql列明一致性映射;

            resultMap:使用association 和 collection 完成一对一和一对多高级映射,对结果有特殊映射要求;

4.延迟加载


                什么是延迟加载?
             resultMap客户实现高级映射使用accocation,collection实现一对一及一对多,association,collection具备延迟加载功能;
     延迟加载:先从单表查询,需要时在从关联表关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快;


       (1)业务描述


                     业务需求 :加载一条经营信息,后延迟加载对应的客户信息 延迟加载 


       (2)Mapper.xml实现


<!-- 业务需求 :加载一条经营信息,后延迟加载对应的客户信息 延迟加载 -->
	<select id="lazyLoadingOperation" parameterType="int" resultMap="lazyLoadingOperationResultMap">
		select * from f_operation where id=#{value}
	</select>




       (3)resultMap 实现 和 statement使用


<!-- 测试延迟加载的resultMap -->
	<resultMap type="cn.labelnet.pojo.OperationCustionClientMap"
		id="lazyLoadingOperationResultMap">
		<!-- 经营信息的数据 -->
		<id column="id" property="id" />
		<result column="client_id" property="client_id" />
		<result column="operate_infomation_describe" property="operate_infomation_describe" />
		<result column="possess_sharholding" property="possess_sharholding" />
		<result column="operate_address" property="operate_address" />
		<result column="year_avg_income" property="year_avg_income" />
		<result column="begin_operation_time" property="begin_operation_time" />
		<result column="employees_amount" property="employees_amount" />
		<result column="legal_person_name" property="legal_person_name" />
		<result column="legal_person_crd_number" property="legal_person_crd_number" />
		<result column="operate_crd_number" property="operate_crd_number" />
		<result column="update_time" property="update_time" />

        <!-- 准备延迟加载的客户信息 -->
        <association property="client" javaType="cn.labelnet.pojo.Client" select="cn.labelnet.mapper.ClientMapper.findClientById" column="client_id">
          
        </association>

	</resultMap>




         

    select 关键字:指定的延迟加载需要执行的statement的id , 其它mapper里面的需要使用namespace.statement的id




               ClientMapper.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 -->
<mapper namespace="cn.labelnet.mapper.ClientMapper">

   <select id="findClientById" parameterType="int" resultType="cn.labelnet.pojo.Client">
       select * from f_client where id=#{value}
   </select>

</mapper>






        (4)Mapper.java实现


//延迟加载
	 OperationCustionClientMap lazyLoadingOperation(int id) throws Exception;




        (5)测试


@Test
	public void testTazyLoadingOperation() throws Exception {
		SqlSession session=sqlFactory.openSession();
		OperationMapper om = session.getMapper(OperationMapper.class);
		OperationCustionClientMap occm = om.lazyLoadingOperation(1);
		System.out.println("经营信息 :"+occm);
		System.out.println("经营的客户信息:"+occm.getClient());
	}




         (6)结果

Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载)_一对多_04

                 (7)配置别忘记了 ,注意顺序


<configuration>

	<properties resource="db.properties"></properties>
	
	<settings>
		<!-- 打开延迟加载的开关 -->
		<setting name="lazyLoadingEnabled" value="true" />
		<!-- 改积极加载为消极加载及按需加载 -->
		<setting name="aggressiveLazyLoading" value="false" />
	</settings>
	
    <typeAliases>
		<typeAlias type="cn.labelnet.pojo.Client" alias="client" />
		<typeAlias type="cn.labelnet.pojo.Operation" alias="operation" />
	</typeAliases>
	
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${oracle.driver}" />
				<property name="url" value="${oracle.url}" />
				<property name="username" value="${oracle.name}" />
				<property name="password" value="${oracle.pass}" />
				<!-- <property name="driver" value="oracle.jdbc.OracleDriver" /> <property 
					name="url" value="jdbc:oracle:thin:@localhost:1521:xe" /> <property name="username" 
					value="hr" /> <property name="password" value="yuan" /> -->
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<package name="cn.labelnet.mapper" />
		<!-- <package name="包名"/> -->
		<!-- mapper.xml -->
		<!-- <mapper resource="mapper/ClientMapper.xml"/> <mapper resource="mapper/OperationMapper.xml"/> -->
	</mappers>
</configuration>




                (8)总结

                    配置延迟加载:SqlMapConfig.xml <settings></settings>

<settings>
			       //打开延迟加载的开关
			     <setting name="lazyLoadingEnabled" value="true"/>
				  //将积极加载改为消极加载及按需加载
				<setting name="aggressiveLazyLoading" value="false"/>
			   <settings>

  


  总结 :使用延迟加载 的方法是先去查询简单的sql,最好是单表,也可以是关联查询,再去按需要加载关联查询其他信息;


  


好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695