架构师

您现在的位置是:首页 > 技术博客 > 框架整合

框架整合

MyBatis一对多级联查询 关联查询 映射查询 xml映射文件配置详解

架构师小跟班 2019-07-13框架整合
Mybatis框架一对多级联查询的场景很多,很多人往往对具体的Xml映射文件配置的细节不太注意,今天笔者就给大家做个详细的讲解。常用的一对多有2种配置方式。 表名字和实体名字

Mybatis框架一对多级联查询的场景很多,很多人往往对具体的Xml映射文件配置的细节不太注意,今天笔者就给大家做个详细的讲解。常用的一对多有2种配置方式。

  • 表名字和实体名字对应,作为讲解,为了易懂,这里只设置了几个必要字段。实体结构如下图:

  • 商品实体Product(对应product表)
  • public class Product {
    
        private String productId;
    
        private String productName;
        
        private Double salePrice;
        
        private List<ProductPic> pics;
    
        public String getProductId() {
            return productId;
        }
    
        public void setProductId(String productId) {
            this.productId = productId == null ? null : productId.trim();
        }
    
        public String getProductName() {
            return productName;
        }
    
        public void setProductName(String productName) {
            this.productName = productName == null ? null : productName.trim();
        }
    
        public Double getSalePrice() {
    	return salePrice;
        }
    
        public void setSalePrice(Double salePrice) {
    	this.salePrice = salePrice;
        }
    
        public List<ProductPic> getPics() {
    	return pics;
        }
    
        public void setPics(List<ProductPic> pics) {
    	this.pics = pics;
        }

    图片实体ProductPic(对应productPic表)

  • public class ProductPic {
    
        private String id;
        /**
         * 商品id
         */
        private String productId;
        /**
         * 图片文件id
         */
        private String attachmentId;

    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 namespace="com.shsc.base.data.common.mapper.dao.ProductMapper">
      <resultMap id="BaseResultMap" type="com.shsc.base.data.common.mapper.entity.CustomerProduct">
        <result column="product_id" jdbcType="VARCHAR" property="productId" />
        <result column="product_name" jdbcType="VARCHAR" property="productName" />
        <result column="sale_price" jdbcType="FLOAT" property="salePrice" />
        <collection property="pics" ofType="com.shsc.base.data.common.mapper.entity.ProductPic" 
        	column="product_id" select="getPics">
        </collection>
      </resultMap>
      
       <select id="getPics" parameterType="java.lang.String" resultType="com.shsc.base.data.common.mapper.entity.ProductPic">
             SELECT id,product_id,attachment_id FROM product_pic  WHERE product_id = #{productId} order by id
    		 <!-- 注意这里的参数productId是指的属性名而不是数据库字段名-->
       </select>
      
       <select id="queryProduct" parameterType="Map" resultMap="BaseResultMap">
    		select 
    		p.id as product_id,
    		p.product_name,
    		p.sale_price
    		from product p
       </select>
    </mapper>

    这种级联查询是将主表(product)的查询结果联合其他表(product_pic)的查询结果,封装成一个对象。主表查询结果中的某一列数据,作为其他表查询的条件。这多个查询是可以跨越多个映射文件的,即可以跨越多个namespace的。使用时,添加上其所在的namespace全路径名即可。关联属性<collection />的数据来源于另一个查询getPics,该查询getPics的动态参数product_id=#{productId}的值则来自于主查询queryProduct的查询结果字段product_id对应的属性名。这种方式符合面向对象的理念,但是涉及嵌套动态级联查询,效率较慢。

  • 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 namespace="com.shsc.base.data.common.mapper.dao.ProductMapper">
      <resultMap id="BaseResultMap" type="com.shsc.base.data.common.mapper.entity.CustomerProduct">
        <result column="product_id" jdbcType="VARCHAR" property="productId" />
        <result column="product_name" jdbcType="VARCHAR" property="productName" />
        <result column="sale_price" jdbcType="FLOAT" property="salePrice" />
        <collection property="pics" ofType="com.shsc.base.data.common.mapper.entity.ProductPic">
    	  <id column="id" property="id"/>
    	  <result column="product_id" property="productId"/>
    	  <result column="attachment_id" property="attachmentId"/>
        </collection>
      </resultMap>
      
       <select id="queryProduct" resultMap="BaseResultMap">
    		select 
    		p.id as product_id,
    		p.product_name,
    		p.sale_price,
    		pic.id,
    		pic.attachment_id
    		from product p,product_pic pic
    		where p.id = pic.product_id
       </select>
    </mapper>

    这种方式是将多张表先进行连接,连为一张表后进行查询。其查询本质是一张表。也只有一个select

    <collection />是集合的意思,即有多个对象,property:指定关联属性,即Product类中的集合属性,ofType:集合属性的泛型类型。这是连接查询效率高一些。

  • 以上2种方式查询出来的数据结构最终如下:

  • [{
    "productId": "8dc1e841-c462-4f3b-a5ac-d915475ff4c3",
    "productName": "白醋",
    "salePrice": 19,
    "pics": [
      {
    	"id": null,
    	"productId": null,
    	"attachmentId": "12759047a0cf4782b87fdcad6acfa4a4",
    	"type": 0
      },
      {
    	"id": null,
    	"productId": null,
    	"attachmentId": "7fdad169dba747b0940bc13fca709671",
    	"type": 0
      },
      {
    	"id": null,
    	"productId": null,
    	"attachmentId": "302e8d178dbf42febe7d66adab3cccbf",
    	"type": 0
      }
    ]},
    {
    "productId": "8dc1e841-c462-4f3b-a5ac-d915475ff4c2",
    "productName": "陈醋",
    "salePrice": 17,
    "pics": [
      {
    	"id": null,
    	"productId": null,
    	"attachmentId": "12759047a0cf4782b87fdcad6acfa4a1",
    	"type": 0
      },
      {
    	"id": null,
    	"productId": null,
    	"attachmentId": "7fdad169dba747b0940bc13fca709656",
    	"type": 0
      }
    ]
    }]

文章评论