Spring+MyBatis使用collection标签的两种使用方法

目录

项目场景:

实战操作:

1.创建菜单表

2.创建实体

3.创建Mapper

4.创建xml

属性描述:

效率比较:


项目场景:

本文说明了Spring Boot+MyBatis使用collection标签的两种使用方法

  1. 方法一: 关联查询

  2. 方法二: 嵌套select查询


实战操作:

1.创建菜单表

这里只创建一张表,树结构只有两级,方便学习,多表关联是同样的道理

c 复制代码
-- ----------------------------
-- Table structure for menu
-- ----------------------------
DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '角色名称',
  `pid` int(3) NULL DEFAULT NULL COMMENT '0代表父级',
  `order` int(3) NULL DEFAULT NULL COMMENT '排序',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of menu
-- ----------------------------
INSERT INTO `menu` VALUES (1, '审核', 0, 1);
INSERT INTO `menu` VALUES (2, '栏目管理', 0, 2);
INSERT INTO `menu` VALUES (3, '应用审核', 1, 1);
INSERT INTO `menu` VALUES (4, '服务审核', 1, 2);
INSERT INTO `menu` VALUES (5, '角色管理', 2, 1);

2.创建实体

java 复制代码
package com.test.entity;

import lombok.Data;
import java.util.List;

@Data
public class Menu {

    private Integer id;
    private String name;
    private Integer pid;
    private Integer order;

    private List<Menu> menus;

}

3.创建Mapper

java 复制代码
package com.test.dao;

import com.test.entity.Menu;
import java.util.List;

public interface TestMapper{
    //关联查询
	List<Menu> selectMenu();
    //嵌套查询
	List<Menu> selectNestedMenu();
}

4.创建xml

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.test.dao.TestMapper">
    <!-- 公共字段 -->
    <resultMap id="BaseResultMap" type="com.test.entity.Menu">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="pid" property="pid"/>
        <result column="order" property="order"/>
    </resultMap>

    <!-- 方式一、关联查询:执行一次sql -->
    <!-- 定义resultMap -->
    <resultMap id="MenuResultMap" extends="BaseResultMap" type="com.test.entity.Menu">
        <!-- 关联集合映射,columnPrefix前缀,用于区分相同字段 -->
        <collection ofType="com.test.entity.Menu" resultMap="BaseResultMap" property="menus" columnPrefix="menu_">
        </collection>
    </resultMap>

    <!-- 查询语句 -->
    <select id="selectMenu" resultMap="MenuResultMap">
        select r.id ,r.name ,r.pid ,r.order ,
               r1.id AS menu_id ,r1.name AS menu_name ,r1.pid AS menu_pid,r1.order AS menu_order
        FROM menu r
        LEFT JOIN menu r1 ON r.id = r1.pid
        where r.pid=0
        order by r.order,r1.order
    </select>

    <!-- 方式二、嵌套查询:会执行多次sql -->
    <!-- 定义resultMap -->
    <resultMap id="NestedResultMap" extends="BaseResultMap" type="com.test.entity.Menu">
        <!-- 嵌套查询集合映射 -->
        <collection property="menus" column="id" select="selectChildMenu"/>
    </resultMap>

    <!-- 查询所有父级语句 -->
    <select id="selectNestedMenu" resultMap="NestedResultMap">
        select r.id ,r.name ,r.pid ,r.order
        FROM menu r
        where r.pid=0
        order by r.order
    </select>

    <!-- 查询下级 -->
    <select id="selectChildMenu" resultMap="BaseResultMap">
        select r.id ,r.name ,r.pid ,r.order
        FROM menu r
        where r.pid=#{id}
        order by r.order
    </select>

</mapper>

属性描述:

|--------------|---------------------------------------------------------------------------|
| 属性 | 描述 |
| property | 属性名:映射实体类属性名 |
| ofType | 映射集合的类型(指定一对多的集合里面元素的类型) |
| column | 映射数据库字段名,传多个 {"属性名"="参数","属性名"="参数"} |
| select | 用于加载复杂类型属性的映射语句的ID(它会从column 属性指定的列中检索数据,作为参数传递给目标 select 语句) |
| columnPrefix | 给关联的数据库中的 column 添加一个前缀(如果不添加前缀,当 两个表同时有 id 字段,查询结果时一定会产生覆盖,使得两个 id 的值一样) |


效率比较:

方法一(关联查询):只需要执行一次sql语句。

方法二(嵌套select查询):需要执行多次sql语句。

方法一比方法二的效率要高,但是在使用的时候,方法二的代码可重用性要高

比如:这里用的是菜单表,数据量不会太大,可以选择方法二(嵌套select查询)

源码: https://download.csdn.net/download/u011974797/88305627

相关推荐
萧瑟余晖15 小时前
Java深入解析篇十七之Spring Security
java·开发语言·spring
Flittly20 小时前
【雕虫大技】Agent 动态 Skill 供应链安全加固(二):执行隔离沙箱实战
java·spring boot·spring
元界metalite21 小时前
MyBatis多数据源常见难题-事务开始了为何数据源还没选出来
后端·mybatis
霸道流氓气质1 天前
Mysql中慢 SQL 优化实战:减少不必要的 JOIN 关联
sql·mysql·mybatis
BUG指挥官2 天前
Sa-Token和Spring Security对比
java·后端·spring
geminigoth2 天前
Spring AI Alibaba 入门开发一(备份)
java·人工智能·spring
xbgRS2 天前
spring整合mybaits
java·spring·mybatis
ruleslol2 天前
静态依赖注入 VS 动态依赖查询
spring
墨雨晨曦882 天前
Spring AI总结
java·人工智能·spring
用户3126874877202 天前
Spring Boot 异常处理到底怎么玩的?从 DispatcherServlet 到全局兜底的全链路拆解
spring