zoukankan      html  css  js  c++  java
  • MyBatis的三层级联和二层缓存

           我们这里说的三层级联和二级缓存其实也是MyBatis映射器的知识点,只是因为比较难理解,所以单独拿出来讲解,下面是三层级联的内容;
           我们知道,在数据库中包含着一对一,一对多,多对多的关系,例如,我们希望在查出学生表的时候,能够连着查出学生证表的信息,这就是一对一的关系查询,我们又希望,能够在查出学生表的时候,能够连着查出你每一个学生的多门课程成绩,而课程成绩又与课程相关,所以呢,我们先用学生表与课程表实现一对多的关系,然后,再利用课程表与课程成绩实现一对一的查询,这样的话,你就实现了一对多的关系查询了。最后,我们说了,学生表中有男女性别的区别,那么,如果我要根据性别来分别查询男女的生理特征的话,那么这就是多对多的关系了。下面我们先来讲讲一对一;对了,这三种级联分别对应了三种元素,分别是association,collection,discriminator;
            一对一的关系:association;
            首先,我们按上面的学生表来做例子,Student代表学生,StudentSelfcard代表学生证;思路就是我们先做一个查询学生证的resultMap,然后我们再做一个查询学生表的resultMap,然后我们把查询学生证的resultMap注册到查询学生表的resultMap中去;
    <?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.learn.chapter4.mapper.StudentSelfcardMapper">
        <resultMap type = "com.learn.chapter4.po.StudentSelfcardBean">
        <id property = "id" column = "id"/>
        <id property = "studentId" column = "student_id"/>
        <id property = "native_" column = "native"/>
        <id property = "issueDate" column = "issue_date"/>
        <id property = "endDate" column = "end_date"/>
        <id property = "note" column = "note"/>
    </resultMap>
    <select id = "findStudentSelfcardByStudentId" parameterType = "int" resultMap = "studentSelfcardMap">
        select id,student_id,native,issue_date,end_date,note from t_student_selfcard where student_id = #{studentId}
    </select>
    </mapper>
    

      这个呢,就是我们的学生证查询resultMap定义了,接下来是我们的学生表查询;

    <?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.learn.chapter4.mapper.StudentMapper">
        <resultMap id = "studentMap" type = "com.learn.chpater4.po.StudentBean">
            <id property = "id" column = "id"/>
            <result property = "cnname" column = "cnname"/>
            <result property = "sex" column = "sex" jdbcType = "INTEGER" javaType = "com.learn.chapter4.enums.SexEnum"
            typeHandler = "com.learn.chapter4.typehandler.SexTypeHandler"/>
            <result property = "note" column = "note"/>
            <association property = "studentSelfcard" column = "id" select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
            </resultMap>
            <select id = "getStudent" parameterType = "int" resultMap = "studentMap">
                select id, cnname, sex, note from t_student where id = #{id}
            </select>
        </mapper>
    

      最后,做一下测试就可以了;

    SqlSession sqlSession = null;
    try{
        sqlSession = SqlSessionFactoryUtil.openSqlSession();
        StduentMapper stuMapper = sqlSession.getMapper(StudentMapper.class);
        StudentBean stu = stuMapper.getStudent(1);
    }finally{
        if(sqlSession != null){
            sqlSession.close();
        }
    }
    接下来是collection一对多级联;
    这个时候我们就要先建立一个LectureBean 的POJO来记录课程,而学生课程表则建立一个StudentLectureBean来记录成绩,里面有一个类型为LectureBean属性的lecture,用来记录学生成绩;毕竟学生课程表里面要有多个课程,所以我们建立了一个类型为lectureBean属性的lecture;
    下面是LectureBean和StudentLectureBean设计;
    public class LectureBean{
        private Integer id;
        private String lectureName;
        private String note;
        ...setter and getter...
    }
    public class StudentLectureBean{
        private int id;
        private Integer studentId;
        private LectureBean lecture;
        private BigDecimal grade;
        private String nte;
    }
    

      接下来我们做一对多的级联;

    <?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.learn.chpater4.mapper.StudentMapper">
        <resultMap id = "studentMap" type = "com.learn.chpater4.po.StudentBean">
            <id property = "id" column = "id"/>
            <result property = "cnname" column = "cnname"/>
            <result property = "sex" column = "sex" jdbcType = "INTEGER"
                javaType = "com.learn.chapter4.enums.SexEnum"
                jdbcType = "com.learn.chapter4.typehandler.SexTypeHandler"/>
            <result property = "note" column = "note"/>
            <association property = "studentSelfcard" column = "id" select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
            <collection property = "studentLectureList" column = "id" select = "com.learn.chapter4.mapper.StudentLectureMapper.findStudentLectureByStudentId"/>
        </resultMap>
        <select id = "getStudent" parameterType = "int" resultMap = "studentMap">
            select id, cnname, sex, note from t_student where id = #{id}
        </select>
    </mapper>
    

         StudentLectureMapper.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.learn.chapter4.mapper.StudentLectureMapper">
        <resultMap id = "studentLectureMap" type = "com.learn.chpater4.po.StudentLectureBena">
            <id property = "id" column = "id"/>
            <id property = "studentId" column = "student_id"/>
            <id property = "grade" column = "grade"/>
            <id property = "note" column = "note"/>
            <association property = "lecture" column = "lecture_id" select = "com.learn.chpater4.mapper.LectureMapper.getLecture"/>
        </resultMap>
        <select id = "findStudentLectureByStuId" parameterType = "int" resultMap = "studetntLectureMap">
            select id, student_id,lecture_id,grade,note from t_student_lecture where student_id = #{id}
        </select>
    </mapper>
    

             LectureMapper.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.learn.chapter4.mapper.LectureMapper">
        <select id = "getLecture" parameterType = "int" resultTYpe = "com.learn.chapter4.po.LectureBean">
            select id,lecture_name as lectureName,note from t_lecture where id = #{id}
        </select>
    </mapper>
    

      下面是一对多的测试类;

    Logger logger = Logger.getLogger(Chpater4Main.class);
    SqlSession sqlSession = null;
    try{
        sqlSession = SqlSessionFactoryUtil.openSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        StudentBean student = studentMapper/getStudent(1);
        logger.info(student.getStudentSelfcard().getNative_());
        StudentLectureBean studentLecture = student.getStudentLectureList().get(0);
        LectureBean lecture = studentLecture.getLecture();
        logger.info(student.getCnname() + "	" + lecture.getLectureName())
    }finally{
        if(sqlSession != null){
            sqlSession.close();
        }
    }
    discriminator鉴别器级联;
    先来看个设计;
    public class MaleStudentBean extends StudentBean{
        privaate List<StudentHealthMaleBean> studentHealthMaleList = null;
    }
    public class FemaleStudentBean extends StudentBean{
        private List<StudentHealthFemaleBean> studentHealthFemaleList = null;
    }
    

      下面是鉴别器的内容;

    <?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.learn.chpater4.mapper.StudentMapper">
        <resultMap id = "studentMap" type = "com.learn.chapter4.po.StudentBean">
            <id property = "id" column = "id"/>
            <result property = "cnname" column = "cnname"/>
            <result property = "sex" column = "sex" jdbcType = "INTEGER" typeHandler = "com.learn.chpater4.typeHandler.SexTypeHandler"/>
            <result property = "note" column = "note"/>
            <association property = "studentSelfcard" column = "id" select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
            <collection property = "studentLectureList" column = "id" select = "com.learn.chpater4.mapper.StudentLectureMapper.findStudentLectureByStuId"/>
            <discriminator javaType = "int" column = "sex">
                <case value = "1" resultMap = "maleStudentMap"/>
                <case value = "2" resultMap = "femaleStudentMap"/>
            </discriminator>
        </resultMap>
        <select id = "getStudent" parameterType = "int" resultMap = "studentMap">
            select id,cnname,sex,note form t_student where id = #{id}
        </select>
        <resultMap id = "maleStudentMap" type = "com.learn.chpater4.po.MaleStudentBean" extends = "studentMap">
            <collection property = "studentHealthMaleList" select = "com.learn.chapter4.mapper.StudentHealthMaleMapper.findStudentHealthMaleByStuId" column = "id"/>
        </resultMap>
        <resultMap id = "femaleStudentMap" type = "com.learn.chapter4.po.FemaleStudentBean" extends = "studentMap">
            <collection property = "studentHealthFemaleList" select = "com.learn.chapter4.mapper.StudentHealthFemaleMapper.findStudentHealthFemaleByStuId" column = "id"/>
        </resultMap>
    </mapper>
    

      

    一个是鉴别器的关键代码;
            <discriminator javaType = "int" column = "sex">
    接下来是继承类
        extends = "studentMap"
        接下来是关于延迟加载的问题,我们既然,学了关于级联的相关操作就知道,我们如果只是想要查找某一个对象的话,如果是通过级联,我们可能会不经意地把相关的数据也给查了出来,这样就会造成性能的问题,所以我们提出来两个概念,延迟加载LazyLoadingEnabled和完整加载aggressiveLazyLoading;其中,如果你将延迟加载设置为true,即表示可以按需加载,不然的话就是即时加载,而完整加载的意思是你是按照层次来加载呢?还是一次性全部加载,如果说你想找的课程成绩,而查找课程成绩,你就会相关地查找到学生证信息,但这不是我们想要的,所以,我们这个时候就要按照层次加载了,我们要将aggressiveLazyLoading设置为false,即关闭掉完整加载;
        上面的这两个加载都是通过mybatisXML文件来设置加载的;
    <settings>
        <setting naem = "lazyLoadingEnabled" value = "true"/>
    </settings>
    

      这是开启延迟加载的;

    <setting name = "aggressiveLazyLoading" value = "false"/>
    这个是关闭掉完整加载,实现层次加载;
    但是现在又有一个问题出现了,我们在xml文件中设置的相当于全局变量,而我们有时候有些文件需要实现延迟和层次,而有些又不用,这个时候,我们可以使用局部变量设置的方式来实现;
    代码如下;
    <association property = "studentSelfcard" column = "id" fetchType = "lazy"
        select = "com.learn.chapter4.mapper.StudentSelfcardMapper.findStudentSelfcardByStudentId"/>
        <collection property = "studentLectureList" column = "id" fetchType = "eager" 
        select = "com.learn.chapter4.mapper.StudentLectureMapper.findStudentLectureByStuId"/>
    这个时候,你把aggressiveLazyLoading设置为false,这样的话,完整加载关闭,层次加载实现,而设置为lazy的为延迟层次加载,eager的为即时完整加载了;
        讲完了三层吉级联,我们来讲讲二层缓存;概念较为简单,所谓一级缓存是指建立在SqlSession的层面上的,如果在你的SqlSession还没有commit提交之前的话,用SqlSession所创建出来的对象可以进行多次查询,而二级缓存则是建立在SqlSessionFactory的层面上,能够实现SqlSession的对象共享;
    而默认二级缓存是关闭的,需要手动开启;
    开启的方式也很简单,只需要在映射XML文件配置就可以了;
    <cache/>
    

      

  • 相关阅读:
    HDU4812 D Tree(树的点分治)
    BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)
    HDU4862 Jump(放大边权的费用流)
    SCU3185 Black and white(二分图最大点权独立集)
    HDU3729 I'm Telling the Truth(字典序最大的最大流)
    HDU3586 Information Disturbing(树形DP)
    HDU3657 Game(最小割)
    POJ3162 Walking Race(树形DP+尺取法+单调队列)
    SCU3312 Stockholm Knights(最大流)
    Codeforces 161D Distance in Tree(树的点分治)
  • 原文地址:https://www.cnblogs.com/zxx123/p/8576962.html
Copyright © 2011-2022 走看看