MyBatis 一对多嵌套查询

#java #mybatis

项目中有个页面比较复杂,展示的数据同时关联 4 张表。所以用到了 MyBatis 的嵌套查询,记录下自己遇到的问题。
这个页面是投资人页,需要展示投资人基本信息,还有投资的项目信息。
投资人信息关联了会员信息表和投资人信息表,投资的项目信息关联了投资记录表和项目信息表。

先介绍下相关类
我想的就是最后我直接查询到投资人列表,投资人类中 private List<ProjectExtDO> investedProject 存放投资过的项目信息(此信息采用嵌套查询);


//投资人
public class InvestorDO extends MemberDO{

  private Long memberId;
  private String direction;

  	private List<ProjectExtDO> investedProject;
  ...
}

//投资人是继承会员类的,但是是分开的两张表。
//会员信息
public class MemberDO{
  private Long id;
  private String company;
	private String position;
  ...

}

//投资记录类,关联投资人和投资项目的
public class InvestProjectDO{
  private Long id;
  private Long memberId;
  private Long projectId;
  ...
}

//项目信息扩展类
public class ProjectExtDO extends ProjectDO {
  private Long id;
  private String name;
  private String smallLogo;
  ...

}

然后介绍下 xml 文件


<!-- 外层 Sql 语句 -->
<select id="listInvestorAndProject" parameterType="InvestorDO" resultMap="Map1">       
	select i.member_id, i.member_id, i.direction,i.investment_case,i.introduction ,m.nick_name,m.head_image,m.company,m.position
	from investor as i	LEFT JOIN member as m ON m.id = i.member_id
	order by m.head_image desc
  <!-- 分页用的 -->
	<if test="startRow != null and pageSize!=null">
			limit #{startRow},#{pageSize}
		</if>
	</select>


  <resultMap type="com.mayiangel.common.domain.member.InvestorDO" id="Map1">
  <!-- 开启自动映射的话无需配置每个 column 对应的 property -->
  <!-- 最好开启下划线自动转大写(配置项 mapUnderscoreToCamelCase 设为 true) -->  
	<result column="member_id" property="memberId"/>

    <!-- 对应 private List<ProjectExtDO> investedProject -->
    <!-- column 配置传到内层 sql 的参数 -->
	<collection property="investedProject" ofType="com.mayiangel.common.domain.project.ProjectExtDO" column="member_id" select="getInvestedProject">
	</collection>
	</resultMap>

  <!-- #{} 接收外层的传值 -->
	<select id="getInvestedProject"  resultType="ProjectExtDO">
	select p.id,p.name,p.small_logo from invest_project as i LEFT JOIN project as p ON i.project_id = p.id WHERE  i.member_id = #{member_id}
	</select>

还有些问题要注意:
1.默认的懒加载,就是嵌套查询默认是不查询的,只有用到了才开始查询,执行嵌套的 sql。
2.其实一对多的嵌套查询还有另外一种方法,我这种情况适合这种。另外一种可以在官方文档上看看。
3.调试的时候如果碰到莫名其妙的问题最好将 sql 打印出来(我手写的代码,然后嵌套查询里的 from 写成了 form,半天没看出来是啥问题,然后 list 里不管怎么样都是没有数据),最快的方法就是用 log4j,配置下 log4j.logger.com.mayiangel.persistence.dao.member.InvestorMapper=debug。
4.像我这种有继承的类,很可能有属性名重复了,可以用 sql 的 as 备注成其他名字,然后绑定定到其他属性上。
5.还有就是 resultMap 里的 memberId 不知道为啥自动映射没有生效,添加了 result 显示配置映射后正常。

MyBatis 官方文档

There are no comments on this post.