Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载)
标签: Mybatis - 高级映射( 一对多 ,多对多 ,延迟加载) Python博客 51CTO博客
2023-05-07 18:24:10 128浏览
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)结果
总结:
使用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使用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)结果
高级映射总结:
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)结果
(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)展开评论
展开评论
您可能感兴趣的博客