Mybatis-Plus一对多及分页
需求中一个商品对应多个类型的多个图片,由于商品信息和商品相关图片是分表根据商品id关联存的,所以这就涉及到了关联查询。对这个不是很了解,所以网上搜了一圈,说的那叫一个花里胡哨啊,好几种方式以及贴的代码,看的人脑阔疼,尝试出了一种比较简单的方式,分享一下。
首先分享一下我的代码,两个实体类,即代表两张表。一个商品类,一个商品图片类。一个商品对应好多张图片,一对多的关系。采用Mapper.xml实现,看网上有完全基于注解实现的,看了一下比较懵,xml比较熟悉。
商品类(重点看最后两个list类型的字段):
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 产品类别,1:原材料,2:设备
*/
@TableField("type")
private Integer type;
/**
* 产品名称
*/
@TableField("name")
private String name;
/**
* 品牌
*/
@TableField("brand")
private String brand;
/**
* 产地
*/
@TableField("place")
private String place;
/**
* 价格
*/
@TableField("price")
private Integer price;
/**
* 库存量
*/
@TableField("stock")
private Integer stock;
/**
* 运费
*/
@TableField("carriage")
private Integer carriage;
/**
* 销量
*/
@TableField("sales_volume")
private Integer salesVolume;
/**
* 采购次数
*/
@TableField("purchase_number")
private Integer purchaseNumber;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 商品展示图列表
*/
private List<Images> showImages;
/**
* 商品详情图列表
*/
private List<Images> infoImages;
}
商品图片类:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Images implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 图片id
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 图片地址
*/
@TableField("url")
private String url;
/**
* 图片优先级,从小到大优先级依次减小
*/
@TableField("url")
private Integer order;
/**
* 图片类型,1:展示图,2:详情图
*/
@TableField("type")
private Integer type;
/**
* 备注
*/
@TableField("remark")
private String remark;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
}
ProductMapper.java
@Mapper
public interface ProductMapper extends BaseMapper<Product> {
// IPage<Product> getProduct(IPage page, @Param("id") Integer id);
IPage<Product> getProduct(IPage page);
List<Images> getShowImages(Long productId);
List<Images> getInfoImages(Long productId);
}
ProductMapper.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.angsi.lianlian.mapper.ProductMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.angsi.lianlian.model.Product">
<id column="id" property="id" />
<result column="type" property="type" />
<result column="name" property="name" />
<result column="brand" property="brand" />
<result column="place" property="place" />
<result column="price" property="price" />
<result column="stock" property="stock" />
<result column="carriage" property="carriage" />
<result column="sales_volume" property="salesVolume" />
<result column="purchase_number" property="purchaseNumber" />
<result column="update_time" property="updateTime" />
<result column="create_time" property="updateTime" />
<collection property="showImages" column="id" select="getShowImages" />
<collection property="infoImages" column="id" select="getInfoImages" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, type, name, brand, place, price, stock, carriage, sales_volume, purchase_number
</sql>
<select id="getProduct" resultMap="BaseResultMap">
select * from mall.product
</select>
<select id="getShowImages" resultType="com.angsi.lianlian.model.Images">
select *from mall.images where product_id = #{productId} and type = 1
</select>
<select id="getInfoImages" resultType="com.angsi.lianlian.model.Images">
select *from mall.images where product_id = #{productId} and type = 2
</select>
</mapper>
xml说明:
- xml上面的映射resultMap中使用collection标签来完成一对多。
- collection标签中property属性的值跟Product实体类中的最后两个List属性对应,查出的多条图片的数据会映射到Product这两个属性中。
- collection标签中column属性值为prodcut中的id,要根据这个id去images表中查询图片。
- collection标签中id属性值为查询图片的sql id。
测试代码
void getProduct() {
// 构建分页对象
IPage<Product> page = new Page<Product>(1, 10);
IPage<Product> product = mapper.getProduct(page);
System.out.println(JSON.toJSONString(product));
}
注:使用mybatis-plus分页功能记得加入分页拦截器,否则分页不会生效。
测试结果:
{
"current": 1,
"pages": 1,
"records": [
{
"id": 1,
"infoImages": [{
"createTime": 1583231923000,
"id": 2,
"order": 2,
"remark": "q",
"type": 2,
"updateTime": 1583231923000,
"url": "b"
}],
"name": "test",
"showImages": [{
"createTime": 1583231918000,
"id": 1,
"order": 1,
"remark": "q",
"type": 1,
"updateTime": 1583231918000,
"url": "a"
}],
"updateTime": 1583231907000
},
{
"id": 2,
"infoImages": [{
"createTime": 1583235037000,
"id": 4,
"order": 2,
"remark": "b",
"type": 2,
"updateTime": 1583235030000,
"url": "d"
}],
"name": "test2",
"showImages": [{
"createTime": 1583235033000,
"id": 3,
"order": 1,
"remark": "q",
"type": 1,
"updateTime": 1583235028000,
"url": "d"
}],
"updateTime": 1583234967000
}
],
"searchCount": true,
"size": 10,
"total": 2
}
测试日志:
2020-03-03 19:46:41.997 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.mapper.ProductMapper.getProduct : ==> Preparing: SELECT COUNT(1) FROM mall.product
2020-03-03 19:46:42.033 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.mapper.ProductMapper.getProduct : ==> Parameters:
2020-03-03 19:46:42.078 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.mapper.ProductMapper.getProduct : ==> Preparing: select * from mall.product LIMIT ?,?
2020-03-03 19:46:42.089 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.mapper.ProductMapper.getProduct : ==> Parameters: 0(Long), 10(Long)
2020-03-03 19:46:42.110 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getShowImages : ====> Preparing: select *from mall.images where product_id = ? and type = 1
2020-03-03 19:46:42.113 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getShowImages : ====> Parameters: 1(Long)
2020-03-03 19:46:42.129 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getShowImages : <==== Total: 1
2020-03-03 19:46:42.130 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.b.s.m.intercept.SqlLogInterceptor : Time:20 ms - ID:com.angsi.lianlian.mapper.ProductMapper.getShowImagesExecute SQL:select *from mall.images where product_id = 1 and type = 1
2020-03-03 19:46:42.133 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getInfoImages : ====> Preparing: select *from mall.images where product_id = ? and type = 2
2020-03-03 19:46:42.135 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getInfoImages : ====> Parameters: 1(Long)
2020-03-03 19:46:42.150 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getInfoImages : <==== Total: 1
2020-03-03 19:46:42.151 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.b.s.m.intercept.SqlLogInterceptor : Time:16 ms - ID:com.angsi.lianlian.mapper.ProductMapper.getInfoImagesExecute SQL:select *from mall.images where product_id = 1 and type = 2
2020-03-03 19:46:42.152 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getShowImages : ====> Preparing: select *from mall.images where product_id = ? and type = 1
2020-03-03 19:46:42.155 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getShowImages : ====> Parameters: 2(Long)
2020-03-03 19:46:42.169 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getShowImages : <==== Total: 1
2020-03-03 19:46:42.170 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.b.s.m.intercept.SqlLogInterceptor : Time:14 ms - ID:com.angsi.lianlian.mapper.ProductMapper.getShowImagesExecute SQL:select *from mall.images where product_id = 2 and type = 1
2020-03-03 19:46:42.170 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getInfoImages : ====> Preparing: select *from mall.images where product_id = ? and type = 2
2020-03-03 19:46:42.173 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getInfoImages : ====> Parameters: 2(Long)
2020-03-03 19:46:42.187 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.m.ProductMapper.getInfoImages : <==== Total: 1
2020-03-03 19:46:42.188 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.b.s.m.intercept.SqlLogInterceptor : Time:16 ms - ID:com.angsi.lianlian.mapper.ProductMapper.getInfoImagesExecute SQL:select *from mall.images where product_id = 2 and type = 2
2020-03-03 19:46:42.188 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.a.l.mapper.ProductMapper.getProduct : <== Total: 2
2020-03-03 19:46:42.188 DEBUG [lianlian-pay,,,] 14776 --- [ main] c.b.s.m.intercept.SqlLogInterceptor : Time:94 ms - ID:com.angsi.lianlian.mapper.ProductMapper.getProductExecute SQL:select * from mall.product LIMIT 0,10
{"current":1,"pages":1,"records":[{"id":1,"infoImages":[{"createTime":1583231923000,"id":2,"order":2,"remark":"q","type":2,"updateTime":1583231923000,"url":"b"}],"name":"test","showImages":[{"createTime":1583231918000,"id":1,"order":1,"remark":"q","type":1,"updateTime":1583231918000,"url":"a"}],"updateTime":1583231907000},{"id":2,"infoImages":[{"createTime":1583235037000,"id":4,"order":2,"remark":"b","type":2,"updateTime":1583235030000,"url":"d"}],"name":"test2","showImages":[{"createTime":1583235033000,"id":3,"order":1,"remark":"q","type":1,"updateTime":1583235028000,"url":"d"}],"updateTime":1583234967000}],"searchCount":true,"size":10,"total":2}
通过日志和数据,可以看出,在查询商品之后,查询了商品图片,实现我想要的一对多分页。