Mybatis高级查询:一对多的用法

<collection>集合的嵌套结果映射就是指通过一次SQL查询将所有的结果查询出来,然后映射到不同的对象中。在一对多的关系中,主表一条数据会对应关联表的多条数据。因此一般查询时会查询出多条结果,按照一对多的数据映射时,最终的结果数会小于等于查询的总记录数。

使用场景:在博客系统中,文章分类自身包含多个子类

实体类如下:

@Data
public class ArticleType {
    private Integer id;

    private String text;

    private String href;

    private String parentid;

    private String publishdate;

    private String updatedate;
    
    private List<ArticleType> nodes; 

    private List<Integer> tags; 
}
<?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 namespace="com.blog.mapper.ArticleTypeMapper" >
  <resultMap id="BaseResultMap" type="com.blog.model.ArticleType" >
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="text" property="text" jdbcType="VARCHAR" />
    <result column="href" property="href" jdbcType="VARCHAR" />
    <result column="parentid" property="parentid" jdbcType="VARCHAR" />
    <result column="publishDate" property="publishdate" jdbcType="VARCHAR" />
    <result column="updateDate" property="updatedate" jdbcType="VARCHAR" />
    <collection property="nodes" ofType="com.blog.model.ArticleType">
    	<id column="nodeid" property="id" jdbcType="INTEGER" />
    	<result column="nodetext" property="text" jdbcType="VARCHAR" />
    	<result column="nodehref" property="href" jdbcType="VARCHAR" />
    	<result column="nodeparentid" property="parentid" jdbcType="VARCHAR" />
    	<result column="nodepublishDate" property="publishdate" jdbcType="VARCHAR" />
    	<result column="nodeupdateDate" property="updatedate" jdbcType="VARCHAR" />
 
    </collection>
    
  </resultMap>
  <sql id="Base_Column_List" >
    id, text, href, parentid, publishDate, updateDate
  </sql>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from articletype
    where id = #{id,jdbcType=INTEGER}
  </select>
  
  <select id="selectArticleTypes" resultMap="BaseResultMap">
         select 
             a.id,
             a.text,
             a.href,
             a.parentid,
             a.publishDate,
             a.updateDate,
             b.id nodeid,
             b.text nodetext,
             b.href nodehref,
             b.parentid nodeparentid,
             b.publishdate nodepublishdate,
             b.updateDate nodeupdatedate
            
         	 from articleType a
             left outer join articleType b on b.parentid=a.id
             
             where a.parentid is null
     </select>
  
  
</mapper>

查询之后形成如下数据结构

[{
	"href": "#parent1",
	"id": 1,
	"nodes": [{
		"href": "#child1",
		"id": 2,
		"parentid": "1",
		"publishdate": "2019-02-16",
		"text": "框架"
	}, {
		"href": "#child4",
		"id": 7,
		"nodes": [],
		"parentid": "1",
		"publishdate": "2019-02-16",
		"text": "多线程"
	}],
	"publishdate": "2019-02-16",
	"text": "Java"
}, {
	"href": "#parent2",
	"id": 4,
	"nodes": [{
		"href": "#child2",
		"id": 5,
		"nodes": [],
		"parentid": "4",
		"publishdate": "2019-02-16",
		"text": "Oracle"
	}, {
		"href": "#child3",
		"id": 6,
		"nodes": [],
		"parentid": "4",
		"publishdate": "2019-02-16",
		"text": "Mysql"
	}],
	"publishdate": "2019-02-16",
	"text": "数据库"
}]

Mybatis结果集的合并原理 

Mybatis在处理结果集时,首先会根据resultMap中配置的<id>属性判断结果是否相同,<id>属性相当于表记录的主键,如果<id>相同则认为是相同的记录则合并。如果resultMap没有配置<id>属性,则会把resultMap中配置的所有字段进行比较,如果所有字段都相同则合并。只要有一个不相同都不合并。
因此建议所有resultMap都配置<id>属性以提高查询效率。

多层树结构问题

使用collection对不会迭代查询,子元素中如何还有子元素并没有办法直接查询出来,试了很多方法也没有办法,如果有知道的小伙伴看到还希望能不吝指教,我在实际应用中因为可以确定文章类型的结构层次为3层,所以在<collection>下又包装了一层<collection>,这样就可以获取到三层数据

猜你喜欢

转载自blog.csdn.net/aawmx123/article/details/87516331