Springboot整合MyBatis复杂查询应用

导读:本篇文章讲解 Springboot整合MyBatis复杂查询应用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

环境: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复杂查询应用

Springboot整合MyBatis复杂查询应用

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80038.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!