(四)MyBatis之关联查询和缓存

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。(四)MyBatis之关联查询和缓存,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

关联查询分为

  • 一对一
  • 一对多
  • 多对一
  • 多对多

resultMap属性

  • id:resultMap的唯一标识
  • type:Java实体类类型

resultMap子元素

  • id:一般对应数据库中该行的主键id,设置此项可提高MyBatis性能
  • result:映射到JavaBean的某个“简单类型”属性
  • association:映射到JavaBean的某个“复杂类型”属性,比如JavaBean类
  • collection:映射到JavaBean的某个“复杂类型”属性,比如集合

association

  • 复杂的类型关联,一对一多对一
  • 内部嵌套:映射一个嵌套JavaBean属性
  • 属性

    property:映射数据库列的实体对象的属性
    javaType:完整Java类名或别名
    resultMap:引用外部resultMap

  • 子元素

    id
    result

    • property:映射数据库列的实体对象的属性
    • column:数据库列名或者别名

4.1 一对一(一个qq用户qqUser对应一个 个人信息baseInfo)

  • 实体类
    在这里插入图片描述
  • QQUserMapper.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">
    
    <!--namespace是命名空间,要与对应的接口的路径保持一致(如果没有创建该接口,MyBatis在内部编译时会自动创建)-->
    <mapper namespace="com.ebuy.dao.QQUserMapper">
    
        <resultMap id="qqUserMap" type="com.ebuy.pojo.QQUser">
            <result property="qqid" column="qqid"/>
            <result property="password" column="password"/>
            <result property="lastlogtime" column="lastlogtime"/>
            <result property="onlines" column="onlines"/>
            <result property="levels" column="levels"/>
            <!--关联表  一对一,一个qq号账户对应一个  个人用户信息-->
            <association property="baseInfo" javaType="com.ebuy.pojo.BaseInfo">
                <id property="qqid" column="qqid"/>
                <result property="nickname" column="nickname"/>
                <result property="sex" column="sex"/>
                <result property="age" column="age"/>
                <result property="province" column="province"/>
                <result property="city" column="city"/>
                <result property="address" column="address"/>
                <result property="phone" column="phone"/>
            </association>
        </resultMap>
    
    
        <!--关联查询所有用户信息——一对一-->
        <select id="selectQQUserAll" resultMap="qqUserMap">
            select * from qquser a,baseinfo b where a.qqid = b.qqid
        </select>
    
    </mapper>
    

    在这里插入图片描述

  • QQUserMapper接口
    /** * @author 一宿君(CSDN : qq_52596258) * @date 2021-07-07 10:08:36 */public interface QQUserMapper {    /**     *     * @return     */    List<QQUser> selectQQUserAll();}
  • QQUserMapperTest
    /**     * 利用接口引用,调用mapper映射文件中的方法     * @throws IOException     */    @Test    public void selectQQUserAll() throws IOException {        SqlSession sqlSession = MyBatisUtil.createSqlSession();        QQUserMapper qqUserMapper = sqlSession.getMapper(QQUserMapper.class);        List<QQUser> qqUserList = qqUserMapper.selectQQUserAll();        for(QQUser qqUser:qqUserList){            System.out.println(qqUser);        }        MyBatisUtil.closeSqlSession(sqlSession);    }

4.2 多对一(多个用户SystemUser对应一个角色SystemRole),结构上与一对一的形式一致

  • SystemUser
    在这里插入图片描述
  • SystemUserMapper.xml
    <!--namespace是命名空间,要与对应的接口的路径保持一致(如果没有创建该接口,MyBatis在内部编译时会自动创建)-->	<mapper namespace="com.ebuy.dao.SystemUserMapper">		    <resultMap id="userMap" type="com.ebuy.pojo.SystemUser">	        <result property="userinfouid" column="userinfo_uid"/>	        <result property="userinfologinid" column="userinfo_loginid"/>	        <result property="userinfoname" column="userinfo_name"/>	        <result property="userinfo_password" column="userinfo_password"/>	        <result property="userinfo_sex" column="userinfo_sex"/>	        <result property="userinfo_email" column="userinfo_email"/>	        <result property="userinfo_mobile" column="userinfo_mobile"/>	        <result property="userinfo_status" column="userinfo_status"/>	        <!--<result property="userinfo_roleid" column="userinfo_roleid"/>	        <result property="userinfo_rolename" column="role_name"/>-->		        <!--关联查询,一对一-->	        <association property="systemRole" javaType="com.ebuy.pojo.SystemRole">	            <!--关联查询中的唯一标识-->	            <id property="role_id" column="userinfo_roleid"/>	            <result property="role_name" column="role_name"/>	            <result property="role_code" column="role_code"/>	            <result property="role_description" column="role_description"/>	        </association>	    </resultMap>	    	    <!--关联查询表system_userinfo和表system_role,查询结果是多对一,也就是多个用户对应一个角色-->	    <select id="selectUserAll" resultMap="userMap">	        /*select * from system_userinfo*/	        select a.*,b.role_name from system_userinfo a,system_role b where a.userinfo_roleid = b.role_id	    </select>	</mapper>

    在这里插入图片描述

  • SystemUSerMapper接口
    /**     * 关联查询(多对一)     * @return     */    List<SystemUser> selectUserAllByAssociation();
  • SysteUserMapperTest
    @Test    public void selectUserAllByAssociation(){        SqlSession sqlSession = MyBatisUtil.createSqlSession();        SystemUserMapper systemUserMapper = sqlSession.getMapper(SystemUserMapper.class);        List<SystemUser> systemUserList = systemUserMapper.selectUserAllByAssociation();        for(SystemUser s:systemUserList){            System.out.println(s);        }        MyBatisUtil.closeSqlSession(sqlSession);    }

Collection

  • 复杂类型集合,一对多
  • 内部嵌套:映射一个嵌套结果集到一个列表
  • 属性

    property:映射数据库列的实体对象的属性
    ofType:完整Java类名或者别名(集合泛型中所包含的类型)
    resultMap:引用外部resultMap

  • 子元素

    id
    result

    • property:映射数据库列的实体对象的属性
    • column:数据库列名或者别名
  • resultMap自动映射(autoMappingBehavior)的三个匹配级别

    NONE:禁止自动匹配
    PARTIAL(默认):自动匹配所有属性,内部嵌套除外
    FULL:自动匹配所有(前提实体类属性和数据库列名保持一致)

4.3 一对多(一个角色SystemRole对应多个用户SystemUser)

  • SystemRole
    在这里插入图片描述
  • SystemRoleMapper.xml
    <!--namespace是命名空间,要与对应的接口的路径保持一致(如果没有创建该接口,MyBatis在内部编译时会自动创建)-->
    <mapper namespace="com.ebuy.dao.SystemRoleMapper">
    
        <resultMap id="roleMap" type="com.ebuy.pojo.SystemRole">
            <id property="role_id" column="role_id"/>
            <result property="role_name" column="role_name"/>
            <result property="role_code" column="role_code"/>
            <result property="role_description" column="role_description"/>
            <!--关联查询   多对一  -->
            <collection property="userInfoList" ofType="com.ebuy.pojo.SystemUser">
                <result property="userinfouid" column="userinfo_uid"/>
                <result property="userinfologinid" column="userinfo_loginid"/>
                <result property="userinfoname" column="userinfo_name"/>
                <result property="userinfo_password" column="userinfo_password"/>
                <result property="userinfo_sex" column="userinfo_sex"/>
                <result property="userinfo_email" column="userinfo_email"/>
                <result property="userinfo_mobile" column="userinfo_mobile"/>
                <result property="userinfo_status" column="userinfo_status"/>
            </collection>
        </resultMap>
    
        <!--关联查询查询system_role表和system_userinfo-->
        <select id="selectRoleAllByCollection" resultMap="roleMap">
            select * from system_role a,system_userinfo b where a.role_id = b.userinfo_roleid
        </select>
    </mapper>
    
  • SystemRoleMapper接口
    /**
         * 关联查询查询system_role表和system_userinfo
         * @return
         */
        List<SystemRole> selectRoleAllByCollection();
    
  • SystemRoleMapperTest
    /**
         * 利用接口引用,调用mapper映射文件中的方法
         * @throws IOException
         */
        @Test
        public void selectRoleAllByCollection(){
            SqlSession sqlSession = MyBatisUtil.createSqlSession();
            SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class);
            List<SystemRole> systemRoleList = systemRoleMapper.selectRoleAllByCollection();
            for(SystemRole s:systemRoleList){
                System.out.println(s.getRole_name() + ":");
                for (SystemUser systemUser:s.getUserInfoList()){
                    System.out.println("\t" + systemUser);
                }
            }
            MyBatisUtil.closeSqlSession(sqlSession);
        }
    

resultMap自动映射(autoMappingBehavior),可在mybatis-conf.xml配置文件中设置在这里插入图片描述

  • 示例1
    在这里插入图片描述
  • 示例2
    在这里插入图片描述

上述是在mybatis-conf.xml配置文件中配置的自动映射,还可以在mapper映射文件中配置自动映射(作用于局部mapper)

  • 示例3
    在这里插入图片描述

MyBatis缓存

  • 一级缓存
  • 二级缓存
  • 二级缓存的配置
    • MyBatis的全局cache配置
    • 在Mapper XML文件中设置缓存,默认情况下是没有开启缓存的
    • 在Mapper XML文件配置支持cache后,如果需要对个别查询进行调整,可以单独设置cache

一级缓存(第一次查询出的数据(默认)放入到了缓存中)

  • SystemUserMapperTest
    @Test
        public void count2() throws IOException {
            SqlSession sqlSession = MyBatisUtil.createSqlSession();
            SystemUserMapper systemUserMapper = sqlSession.getMapper(SystemUserMapper.class);
            //第一次查询
            System.out.println(systemUserMapper.count());
            /**
             * 第二次查询(查询到的是一级缓存中的数据,也就是第一次查询出的数据放入到了缓存中)
             * 第二次查询并不会再次创建sqlSession,也就是不会执行SQL语句操作数据库查询
             */
            System.out.println(systemUserMapper.count());
            MyBatisUtil.closeSqlSession(sqlSession);
        } 
    

    在这里插入图片描述

一级缓存(改进,执行两次sql后关闭sqlSession,再次开启sqlSession)

  • SystemUserMapper

    @Test
    public void count2() throws IOException {
        SqlSession sqlSession = MyBatisUtil.createSqlSession();
        SystemUserMapper systemUserMapper = sqlSession.getMapper(SystemUserMapper.class);
    
        System.out.println(systemUserMapper.count());//第一次查询
        /**
         * 第二次查询(查询到的是一级缓存中的数据,也就是第一次查询出的数据放入到了一级缓存中)
         * 第二次查询并不会再次创建sqlSession,也就是不会执行SQL语句操作数据库查询
         */
        System.out.println(systemUserMapper.count());//第二次查询
        MyBatisUtil.closeSqlSession(sqlSession);//关闭sqlSession
    
        sqlSession = MyBatisUtil.createSqlSession();
        systemUserMapper = sqlSession.getMapper(SystemUserMapper.class);
        System.out.println(systemUserMapper.count());//第三次查询
        /**
         * 同理
         * 第四次查询(查询到的是一级缓存中的数据,也就是第三次查询出的数据放入到了一级缓存中)
         * 第四次查询并不会再次创建sqlSession,也就是不会执行SQL语句操作数据库查询
         */
        System.out.println(systemUserMapper.count());//第四次查询
        MyBatisUtil.closeSqlSession(sqlSession);
    }
    

    在这里插入图片描述

    会发现上述执行了两次sql!上述每次开启sqlSession后的第一次不同的SQL查询都会将结果存入到缓存中,一级缓存只要sqlSession关闭就会一直存在,这样对于内存负荷量比较大,而且不利于频繁更新的数据要求。

二级缓存(可设置时效性,解决一级缓存会一直存在的弊端)

  • 首先开启二级缓存
    在这里插入图片描述

  • 在相关映射文件中设置时效性每次最大的缓存记录数

    <cache eviction="FIFO" flushInterval="5000" size="512" readOnly="true"/>
    

    在这里插入图片描述

  • SystemRoleMapperTest

    @Test
        public void selectRoleAllByCollection() throws InterruptedException {
            SqlSession sqlSession = MyBatisUtil.createSqlSession();//开启sqlSession
            SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class);
            List<SystemRole> systemRoleList1 = systemRoleMapper.selectRoleAllByCollection();
            for(SystemRole s:systemRoleList1){
                System.out.println(s.getRole_name() + ":");
                for (SystemUser systemUser:s.getUserInfoList()){
                    System.out.println("\t" + systemUser);
                }
            }
            MyBatisUtil.closeSqlSession(sqlSession);//关闭sqlSession
    
            /**
             * 循环8次,注意二级缓存设置的有效期为5秒
             */
            for (int i = 1; i <= 8; i++) {
                sqlSession = MyBatisUtil.createSqlSession();//开启sqlSession
                systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class);
                System.out.println("第" + i + "次查询---------------------------------");
                List<SystemRole> systemRoleList2 = systemRoleMapper.selectRoleAllByCollection();
                for(SystemRole s:systemRoleList2){
                    System.out.println(s.getRole_name() + ":");
                    for (SystemUser systemUser:s.getUserInfoList()){
                        System.out.println("\t" + systemUser);
                    }
                }
                Thread.sleep(1000);//没循环一次线程等待1秒
                MyBatisUtil.closeSqlSession(sqlSession);//关闭sqlSession
            }
        }
    

    在这里插入图片描述

  • 控制台结果显示:

  • 初始查询
    在这里插入图片描述

  • 第1次循环查询
    在这里插入图片描述

  • 第2次循环查询
    在这里插入图片描述

  • 第3次循环查询
    在这里插入图片描述

  • 第4次循环查询
    在这里插入图片描述

  • 第5次循环查询
    在这里插入图片描述

  • 第6次循环查询
    在这里插入图片描述

  • 第7次循环查询
    在这里插入图片描述

  • 第8次循环查询
    在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/189462.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!