Mybatis实现多表查询,级联,缓存

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

一对一关联查询

  • 场景:根据员工编号查询员工信息(Emp表)以及所在部门(Dept表)的信息
  • 需要在Emp实体类中创建一个Dept的属性
<!--Emp findEmpJoinDeptByEmpno(int empno);-->
    <resultMap id="empJoinDept" type="emp">
        <!--设置emp本身的八个属性的映射关系-->
        <id property="empno" column="empno"></id>
        <result property="ename" column="ename"></result>
        <result property="job" column="job"></result>
        <result property="sal" column="sal"></result>
        <result property="hiredate" column="hiredate"></result>
        <result property="mgr" column="mgr"></result>
        <result property="comm" column="comm"></result>
        <result property="deptno" column="deptno"></result>
        <!--
        association 处理一对一
        封装一对一信息关系的标签
        property  emp类的属性名
        javaType  用哪个类的对象给属性赋值
        -->
        <association property="dept" javaType="dept">
            <id column="deptno" property="deptno"></id>
            <result column="dname" property="dname"></result>
            <result column="loc" property="loc"></result>
        </association>
    </resultMap>
    <select id="findEmpJoinDeptByEmpno" resultMap="empJoinDept" >
        select * from
        emp e
        left join dept  d
        on e.deptno =d.deptno
        where empno = #{empno}
    </select>
复制代码

一对多关联查询

  • 场景:根据部门编号查询部门信息(Dept表)以及该部门的所有员工信息(Emp表)
  • 因为一个部门有多名员工,所以我们需要在Dept实体类中封装一个List集合用于存储查询出来的Emp对象
<mapper namespace="com.msb.mapper.DeptMapper">
    <!--Dept findDeptJoinEmpsByDeptno(int deptno);-->
    <resultMap id="deptJoinEmps" type="dept">
        <id column="deptno" property="deptno"></id>
        <result column="dname" property="dname"></result>
        <result column="loc" property="loc"></result>
        <!--处理一对多关系的标签-->
        <collection property="empList" ofType="emp" >
            <!--设置emp本身的八个属性的映射关系-->
            <id property="empno" column="empno"></id>
            <result property="ename" column="ename"></result>
            <result property="job" column="job"></result>
            <result property="sal" column="sal"></result>
            <result property="hiredate" column="hiredate"></result>
            <result property="mgr" column="mgr"></result>
            <result property="comm" column="comm"></result>
            <result property="deptno" column="deptno"></result>
        </collection>
    </resultMap>
    <select id="findDeptJoinEmpsByDeptno" resultMap="deptJoinEmps">
        select * from dept d left join emp e on d.deptno =e.deptno where d.deptno =#{deptno}
    </select>
复制代码

多对多关联查询

  • 场景:根据项目编号查询项目信息,以及参与到该项目中的所有员工信息

image.png

  • 如上图的关联关系,
  • 所以我们需要在Project表中创建一个List集合用于封装ProjectRecord对象,
  • 然后我们在ProjectRecord表中创建一个Emp的属性值用于存储emp对象
<mapper namespace="com.msb.mapper.ProjectMapper">
    <!--Project findProjectJoinEmpsByPid(int pid);-->
    <resultMap id="projectJoinEmps" type="project">
        <id column="pid" property="pid"></id>
        <result column="pname" property="pname"></result>
        <result column="money" property="money"></result>
        <!--一对多 集合属性 collection-->
        <collection property="projectRecords" ofType="projectRecord">
            <id column="empno" property="empno"></id>
            <id column="pid" property="pid"></id>
            <!--一对一 -->
            <association property="emp" javaType="emp">
                <id property="empno" column="empno"></id>
                <result property="ename" column="ename"></result>
                <result property="job" column="job"></result>
                <result property="sal" column="sal"></result>
                <result property="hiredate" column="hiredate"></result>
                <result property="mgr" column="mgr"></result>
                <result property="comm" column="comm"></result>
                <result property="deptno" column="deptno"></result>
            </association>
        </collection>
    </resultMap>
    <select id="findProjectJoinEmpsByPid"  resultMap="projectJoinEmps">
        select * from
        project p
        left join projectrecord pr
        on p.pid = pr.pid
        left join emp e
        on e.empno = pr.empno
        where p.pid= #{pid}
    </select>
复制代码

级联查询(立即加载以及延迟加载)

  • 级联查询是创建l两个接口,两个xml配置文件,相同的的条件查询俩表

  • 级联查询不用手动进行查询和组装数据

  • EmpMapper.xml文件中配置的代码:

前缀 略
<mapper namespace="com.msb.mapper.EmpMapper">
    <!--List<Emp> findEmpsByDeptno(int deptno);-->
    <select id="findEmpsByDeptno" resultType="emp">
        select * from emp where deptno =#{deptno}
    </select>
复制代码
  • DeptMapper.xml文件中配置的代码
<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>
复制代码

一级缓存

image.png

  • mybatis中一级缓存默认开启,将数据存放在SQLSession中,
//如果之间执行了增删改查,sqlSession调用了commit方法,它会自动清空一级缓存
sqlSession.commit();    
复制代码

二级缓存

image.png

  • 二级缓存是以namespace为标记的缓存,得手动开启,
  • 要求实体类必须实例化
  • 全局开关:在sqlMapConfig.xml文件中的标签配置开启二级缓存
	<settings>

    	<setting name="cacheEnabled" value="true"/>

	</settings>
复制代码
  • 分开关:在要开启二级缓存的mapper文件中开启缓存
<mapper namespace="com.msb.mapper.EmployeeMapper">
	<cache/>
</mapper>
复制代码

注解开发

  • 注解开发就在接口中抽象方法的上方写适合写一些基本的查询语句,不经常改的语句
	//查询语句
    @Select("select * from dept where deptno =#{deptno}")
    Dept findByDeptno(int deptno);
    //修改语句
    @Update("update dept set dname =#{dname}, loc =#{loc} where deptno =#{deptno}")
    int updateDept(Dept dept);
    //增加语句
    @Insert("insert into dept values(DEFAULT,#{dname},#{loc})")
    int addDept(Dept dept);
    //删除语句
    @Delete("delete from dept where deptno =#{deptno}")
    int removeDept(int deptno)
复制代码

理想和现实差了十万八千里,我鞭长莫及,却又马不停蹄...

猜你喜欢

转载自juejin.im/post/7088315120668901413