Springboot整合MyBatis复杂查询应用

95 篇文章 3 订阅
60 篇文章 2 订阅

环境:springboot2.3.9.RELEASE + MyBatis + MySQL


依赖及相关配置参见:《Springboot整合MyBatis参数传值方式 》

建立复杂的关联关系

Springboot整合MyBatis复杂查询应用

 

一个用户一个社保卡;一个用户多个角色;

实体类

@Entity
@Table(name = "BC_USERS")
public class Users extends BaseEntity {
  private String username ;
  private String password ;
  private String realName ;
  private String idNo ;
  private String creator;
  @Transient
  private SinCard sinCard ;
  @Transient
  private List<Role> roles = new ArrayList<>() ;
}

因为这里使用jpa帮助生成表,所以这里的SinCard和List<Role>都加了@Transient注解,不然报错;(这里在表上没有建立物理的外键关系)。

@Entity
@Table(name = "BC_SIN_CARD")
public class SinCard extends BaseEntity {
  private String cardNo ;
  private BigDecimal money = BigDecimal.ZERO ;
  private String userId ;
}
@Entity
@Table(name = "BC_ROLES")
public class Role extends BaseEntity {
  private String roleName ;
  private String roleDesc ;
  private String userId ;
}  

Mapper接口及XML

@Mapper
public interface UsersMapper {
  List<Users> queryUsersAndSinCard() ;	
  List<Users> queryUsersAndSinCard2() ;
}

方式1:

<resultMap type="com.pack.domain.Users" id="AssignMapper">
  <id column="id" property="id"/>
  <result column="username" property="username"/>
  <result column="real_name" property="realName"/>
  <result column="id_no" property="idNo"/>
  <association property="sinCard" javaType="com.pack.domain.SinCard">
    <id column="sid" property="id"/>
    <result column="card_no" property="cardNo"/>
    <result column="money" property="money"/>
  </association>
  <collection property="roles" javaType="com.pack.domain.Role">
    <id column="rid" property="id"/>
    <result column="role_name" property="roleName"/>
    <result column="role_desc" property="roleDesc"/>
  </collection>
</resultMap>
<select id="queryUsersAndSinCard" resultMap="AssignMapper">
  SELECT u.*, s.id as sid, s.card_no, s.money,r.id as rid, r.role_name,r.role_desc  FROM bc_users u, bc_sin_card s, bc_roles r where u.id=s.user_id and u.id=r.user_id
</select>

测试:

Springboot整合MyBatis复杂查询应用

 

Springboot整合MyBatis复杂查询应用

 

一条sql查询所有关联的对象。

方式2:

通过嵌套查询;通过另外一个Mapper中的sql进行查询关联对象。

<resultMap type="com.pack.domain.Users" id="AssignMapper">
  <id column="id" property="id"/>
  <result column="username" property="username"/>
  <result column="real_name" property="realName"/>
  <result column="id_no" property="idNo"/>
  <association property="sinCard" column="id" select="com.pack.mapper.SinCardMapper.queryByUserId"/>
  <collection property="roles" javaType="com.pack.domain.Role">
    <id column="rid" property="id"/>
    <result column="role_name" property="roleName"/>
    <result column="role_desc" property="roleDesc"/>
  </collection>
</resultMap>
<select id="queryUsersAndSinCard2" resultMap="AssignMapper">
  SELECT u.*,r.id as rid, r.role_name,r.role_desc  FROM bc_users u,bc_roles r where u.id=r.user_id
</select>

SinCardMapper

<mapper namespace="com.pack.mapper.SinCardMapper">
  <resultMap type="com.pack.domain.SinCard" id="sinCardMap">
    <id column="id" property="id"/>
    <result column="card_no" property="cardNo"/>
    <result column="money" property="money"/>
    <result column="create_time" property="createTime"/>
  </resultMap>
  <select id="queryByUserId" resultMap="sinCardMap">
    SELECT * FROM bc_sin_card t WHERE t.user_id=#{userId}
  </select>
</mapper>
@Mapper
public interface SinCardMapper {
	SinCard queryByUserId(String userId) ;
}

测试:

Springboot整合MyBatis复杂查询应用

 

延迟加载

MyBatis根据对关联对象查询的select语句的执行时机,分为三种类型:直接加载、侵入式延迟加载与深度延迟加载。

  • 直接加载:执行完对主加载对象的 select 语句,马上执行对关联对象的 select 查询。
  • 侵入式延迟: 执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情属性时,就会马上执行关联对象的select查询。
  • 深度延迟: 执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的 select 查询。

开启延迟加载功能。mybatis的延迟加载只对resultMap中的association和collection有作用

mybatis:
  configuration:
    lazy-loading-enabled: true
    aggressive-lazy-loading: false

lazy-loading-enabled:是全局开关。当然我们也可以直接作用在association和collection上也是可以的。

aggressive-lazy-loading:这个属性如果你设置为false,这个延迟加载就不生效了。

Mapper及XML还是上面的queryUsersAndSinCard2方法。

测试:

Springboot整合MyBatis复杂查询应用

 

并没有查询
com.pack.mapper.SinCardMapper.queryByUserId接口。

当把lazy-loading-enabled设置为false时,我们也可以将resultMap中的association和collection属性fetchType="lazy"也是可以的。

当访问主对象时,只是输出该对象,那么关联查询也会查询,同时返回的对象是代理对象

@Test
public void testQuery() {
  System.out.println(usersMapper.queryUsersAndSinCard2().get(0)) ;
}

Springboot整合MyBatis复杂查询应用

 

这里并没有访问延迟加载的对象,只是输出对象,也会查询关联对象。

 

完毕!!!

Springboot整合MyBatis复杂查询应用

 

Springboot整合MyBatis复杂查询应用

 

Springboot整合MyBatis复杂查询应用

 

Springboot整合MyBatis复杂查询应用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值