8_2_级联查询

目录

1_立即加载

 2_延迟加载


1_立即加载

功能1:查询所有员工的信息(多对一关联)

经过对比,发现经过在映射文件中配置,测试类的代码大大简化了,无序手动进行关联查询和组装数据了。

功能2:查询10号部门及其该部门员工信息。

Dept和Emp实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept implements Serializable {
    private Integer deptno;
    private String dname;
    private String loc;
    // 当前部门下的所有员工对象的List集合
    private List<Emp> empList;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Emp implements Serializable {
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;
}

DeptMapper和 EmpMapper接口

package com.msb.mapper;
import com.msb.pojo.Dept;
/**
 * @Author: Ma HaiYang
 * @Description: MircoMessage:Mark_7001
 */
public interface DeptMapper {
    Dept findDeptByDeptno(int deptno);
}
package com.msb.mapper;
import com.msb.pojo.Emp;
import java.util.List;
/**
 * @Author: Ma HaiYang
 * @Description: MircoMessage:Mark_7001
 */
public interface EmpMapper {
    List<Emp> findEmpsByDeptno(int deptno);
}

DeptMapper和EmpMapper映射文件

<?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.msb.mapper.DeptMapper">
    <!--Dept findDeptByDeptno(int deptno);
    select="com.msb.mapper.EmpMapper.findEmpsByDeptno" 调用的另一个SQL语句
    javaType="list"  实体类的属性数据类型
    column="deptno"  给另一个SQL语句传入的参数列
    jdbcType="INTEGER" 参数对应JDBC的数据类型
    fetchType="eager"  加载方式 eager 积极加载  lazy延迟加载-->
    <resultMap id="deptJoinEmps" type="dept">
        <id property="deptno" column="deptno"></id>
        <result property="dname" column="dname"></result>
        <result property="loc" column="loc"></result>
        <collection property="empList"
                    select="com.msb.mapper.EmpMapper.findEmpsByDeptno"
                    javaType="list"
                    column="deptno"
                    jdbcType="INTEGER"
                    fetchType="eager"
        >
        </collection>
    </resultMap>
    <select id="findDeptByDeptno" resultMap="deptJoinEmps">
        select * from dept where deptno =#{deptno}
    </select>
</mapper>
<?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.msb.mapper.EmpMapper">
    <!--List<Emp> findEmpsByDeptno(int deptno);-->
    <select id="findEmpsByDeptno" resultType="emp">
        select * from emp where deptno =#{deptno}
    </select>
</mapper>

测试 代码

@Test
public void testFindByDetpno()   {
    DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
    Dept dept = deptMapper.findDeptByDeptno(20);
    System.out.println(dept.getDname());
    System.out.println(dept.getDeptno());
    System.out.println(dept.getLoc());
    List<Emp> empList = dept.getEmpList();
    empList.forEach(System.out::println);
}

 2_延迟加载

延迟加载,又称按需加载。延迟加载的内容等到真正使用时才去进行加载(查询)。多用在关联对象或集合中。

延迟加载的好处:先从单表查询、需要时再从关联表去关联查询,大大降低数据库在单位时间内的查询工作量,将工作在时间上的分配更加均匀,而且单表要比关联查询多张表速度要快。

延迟加载的设置

第一步:全局开关:在sqlMapConfig.xml中打开延迟加载的开关。配置完成后所有的association和collection元素都生效


 
<settings>
      <setting name="lazyLoadingEnabled" value="true"/>
      <setting name="aggressiveLazyLoading" value="true"/>
  </settings>

lazyLoadingEnabled:是否开启延迟加载。是Mybatis是否启用懒加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态

aggressiveLazyLoading:当开启时,任何方法的调用都会懒加载对象的所有属性。否则,每个属性会按需加载,

第二步:分开关:指定的association和collection元素中配置fetchType属性。eager:表示立刻加载;lazy:表示延迟加载。将覆盖全局延迟设置。

以下是一个简单的使用 JDK 8 特性进行级联查询树的例子: ```java public class TreeNode { private Long id; private Long parentId; private String name; private List<TreeNode> children = new ArrayList<>(); // 构造函数、getter 和 setter 方法省略 // 添加子节点 public void addChild(TreeNode node) { children.add(node); } // 获取子节点 public List<TreeNode> getChildren() { return children; } // 级联查询树 public static List<TreeNode> buildTree(List<TreeNode> nodes) { Map<Long, TreeNode> nodeMap = nodes.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity())); List<TreeNode> rootNodes = new ArrayList<>(); for (TreeNode node : nodes) { Long parentId = node.getParentId(); if (parentId == null) { rootNodes.add(node); } else { TreeNode parent = nodeMap.get(parentId); parent.addChild(node); } } return rootNodes; } } ``` 使用上述代码,我们可以将一个节点列表转换为树形结构。例如,如果我们有以下节点列表: ```java List<TreeNode> nodes = Arrays.asList( new TreeNode(1L, null, "A"), new TreeNode(2L, 1L, "B"), new TreeNode(3L, 1L, "C"), new TreeNode(4L, 2L, "D"), new TreeNode(5L, 2L, "E"), new TreeNode(6L, 3L, "F") ); ``` 我们可以使用 `TreeNode.buildTree(nodes)` 方法将其转换为树形结构: ```java List<TreeNode> rootNodes = TreeNode.buildTree(nodes); System.out.println(rootNodes); ``` 输出结果为: ``` [TreeNode(id=1, parentId=null, name=A, children=[TreeNode(id=2, parentId=1, name=B, children=[TreeNode(id=4, parentId=2, name=D, children=[]), TreeNode(id=5, parentId=2, name=E, children=[])]) TreeNode(id=3, parentId=1, name=C, children=[TreeNode(id=6, parentId=3, name=F, children=[])])])] ``` 这个例子中,我们使用了 Java 8 的 Lambda 表达式和 Stream API 来简化代码。其中,`Collectors.toMap()` 方法将节点列表转换为一个以节点 ID 为键、节点对象为值的 Map,方便后续查找父节点。然后,我们遍历节点列表,将每个节点添加到其父节点的 `children` 列表中,最终返回所有根节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值