MyBatis 一對多結果集嵌套查詢
嵌套查詢的實現原理爲兩次查詢,比如產品表爲主表,圖片表爲從表通過product_id字段與產品表id字段關聯實現一對多,嵌套查詢 首先查詢 主表的數據 然後將主表id字段賦值給從表實體類中product_id 字段(productId)然後通過dao接口路徑映射找到對應的MyBatis XMl文件SQL語句ID如:com.liao.dao.DImgMapper.selectDImgByProductId 進行子查詢也就是第二次查詢。然後返回數據
數據庫建表語句和測試數據如下:
數據庫版本爲 MySQL 8.0
產品表
DROP TABLE IF EXISTS `d_product`;
CREATE TABLE `d_product` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '產品ID',
`product_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '產品名稱',
`product_introduction` text CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT '產品介紹',
`product_category` int(11) NULL DEFAULT NULL COMMENT '產品ID',
`product_status` int(1) NULL DEFAULT NULL COMMENT '產品狀態',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '創建時間',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 18 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '產品表' ROW_FORMAT = Dynamic;
INSERT INTO `d_product` VALUES (1, '測試產品名稱修改', '測試產品介紹修改', NULL, 1, '2020-02-02 12:40:06');
INSERT INTO `d_product` VALUES (2, '產品名稱', '產品介紹', NULL, 1, '2020-03-02 18:15:07');
INSERT INTO `d_product` VALUES (3, 'bbb', 'bbb', NULL, 1, '2020-03-01 22:18:40');
圖片表
DROP TABLE IF EXISTS `d_img`;
CREATE TABLE `d_img` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`product_id` int(11) NULL DEFAULT NULL COMMENT '產品圖片ID',
`img` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '圖片',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '創建時間',
PRIMARY KEY (`id`) USING BTREE,
INDEX `product_id`(`product_id`) USING BTREE,
CONSTRAINT `d_img_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES `d_product` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 86 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '產品圖片' ROW_FORMAT = Dynamic;
INSERT INTO `d_img` VALUES (40, 1, '1491803633034_683819.jpg', '2020-03-03 17:21:20');
INSERT INTO `d_img` VALUES (40, 1, '1491803633034_683819.jpg', '2020-03-03 17:21:20');
INSERT INTO `d_img` VALUES (41, 1, '1568950881751_702421.jpg', '2020-03-03 17:21:20');
Java實體類:
// 將這個註解寫在類上之後,就會忽略類中不存在的字段,否則可能會報錯
@JsonIgnoreProperties(value = {
"handler"})
/**
*
* TODO: 產品類
* @author LiAo
* @date 2020/5/20 17:04
*/
public class DProduct {
private Integer id;
private String productName;
private Integer productCategory;
private Integer productStatus;
private Date createTime;
private String productIntroduction;
private List<DImg> dImgs; // 用於存放圖片集合
// .. get set toString
}
/**
*
* TODO: 產品圖片類
* @author LiAo
* @date 2020/5/20 17:05
*/
@JsonIgnoreProperties(value = {
"handler"})
public class DImg {
private Integer id;
private Integer productId;
private String img;
private Date createTime;
// .. get set toString
}
實體類創建好後要編寫Dao接口 和Mapper XML了
持久層接口DAO:
/**
*
* TODO: 產品 Dao接口
* @author LiAo
* @date 2020/5/20 17:08
*/
public interface DProductMapper {
/**
* 產品圖片一對多嵌套
* @param record 查詢條件
* @return 返回參數
*/
List<DProduct> productSelect(DProduct record);
}
產品MyBatis xml:
<!--映射的Dao接口類 可以通過這個路徑找到先關的SQL語句和resultMap 映射-->
<mapper namespace="com.liao.dao.DProductMapper">
<resultMap id="BaseResultMap" type="com.liao.entity.DProduct">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="product_name" property="productName" jdbcType="VARCHAR"/>
<result column="product_category" property="productCategory" jdbcType="INTEGER"/>
<result column="product_status" property="productStatus" jdbcType="INTEGER"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="product_introduction" property="productIntroduction" jdbcType="LONGVARCHAR"/>
</resultMap>
<!--產品圖片一對多查詢映射-->
<!--id:配置映射的名稱-->
<!--type:返回值類型 -->
<!--extends:繼承id爲BaseResultMap的映射 -->
<!--select:子查詢所在的XML綁定的DAO接口路徑.SQL語句id -->
<!--column="{productId = id} productId:從表關聯主表的實體類屬性,作爲子查詢的條件 id:主表中被關聯的數據庫字段-->
<resultMap id="dProductResultMap" type="com.liao.entity.DProduct" extends="BaseResultMap">
<collection property="dImgs" fetchType="lazy"
select="com.liao.dao.DImgMapper.selectDImgByProductId" column="{productId = id}"/>
</resultMap>
<!--查詢語句-->
<select id="productSelect" parameterType="com.liao.entity.DProduct" resultMap="dProductListMapSelect">
select
d.id,
d.product_name,
d.product_category,
d.product_status,
d.create_time,
d.product_introduction
from d_product d
where 1 = 1
<!-- 使用if標籤拼接條件語句 實現動態SQL-->
<if test="id != null and id != ''">
and d.id = #{id}
</if>
<if test="productName != null and productName != ''">
and d.product_name like concat(#{productName},'%')
</if>
<if test="productStatus != null and productStatus != ''">
and d.product_status = #{productStatus}
</if>
<if test="createTime != null and createTime != ''">
and d.create_time like concat(#{createTime},'%')
</if>
<if test="productIntroduction != null and productIntroduction != ''">
and d.product_introduction like concat(#{productIntroduction},'%')
</if>
</select>
</mapper>
圖片MyBatis xml:
<mapper namespace="com.liao.dao.DImgMapper">
<resultMap id="BaseResultMap" type="com.liao.entity.DImg">
<id column="did" property="id" jdbcType="INTEGER"/>
<result column="product_id" property="productId" jdbcType="INTEGER"/>
<result column="img" property="img" jdbcType="VARCHAR"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
</resultMap>
<!--一對多嵌套查詢 子查詢語句-->
<select id="selectDImgByProductId" resultMap="BaseResultMap">
select i.id as did,
i.product_id,
i.img,
i.create_time
from d_img i
where i.product_id = #{productId}
</select>
</mapper>
測試查詢結果
查詢結果爲一個產品對象裏有若干個產品圖片對象。
{
"id": 18,
"productName": "產品添加圖片上傳測試",
"productCategory": null,
"productStatus": 1,
"createTime": "2020-04-14T13:40:40.000+0000",
"productIntroduction": "產品添加圖片上傳測試",
"dImgs": [
{
"id": 92,
"productId": 18,
"img": "01.jpg",
"createTime": "2020-04-26T02:33:04.000+0000"
},
{
"id": 93,
"productId": 18,
"img": "1554103835292_610234.jpg",
"createTime": "2020-04-26T02:33:04.000+0000"
},
{
"id": 94,
"productId": 18,
"img": "1555484699771_582172.jpg",
"createTime": "2020-04-26T02:33:04.000+0000"
},
{
"id": 95,
"productId": 18,
"img": "1554103835292_610234.jpg",
"createTime": "2020-04-26T02:33:04.000+0000"
}
]
},