zoukankan      html  css  js  c++  java
  • mybatis xml版延迟加载、立即加载、一级缓存、二级缓存

    1、Mybatis中的延迟加载
    问题:在一对多中,当我们有一个用户,它有100个账户。
    在查询用户的时候,要不要把关联的账户查出来?
    在查询账户的时候,要不要把关联的用户查出来?

    在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
    在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。

    什么是延迟加载
    在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
    什么是立即加载
    不管用不用,只要一调用方法,马上发起查询。

    在对应的四种表关系中:一对多,多对一,一对一,多对多
    一对多,多对多:通常情况下我们都是采用延迟加载。
    多对一,一对一:通常情况下我们都是采用立即加载。

    1.延迟加载(一对一,一对多)

    @Test
        public void testFindAll(){
            List<Account> accounts = accountDao.findAll();
            for(Account account : accounts){
                System.out.println("--------每个account的信息------------");
                System.out.println(account);
                /**
                 * 执行account.getUser时,才加载用户信息
                 */
                System.out.println(account.getUser());
            }
        }

    @Test
    public void testFindAll(){
    List<User> users = userDao.findAll();
    for(User user : users){
    System.out.println("-----每个用户的信息------");
    System.out.println(user);
    System.out.println(user.getAccounts());
    }
    }
     
    public class Account implements Serializable {
    
        private Integer id;
        private Integer uid;
        private Double money;
    
        //从表实体应该包含一个主表实体的对象引用
        private User user;
    }


    public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

    //一对多关系映射:主表实体应该包含从表实体的集合引用
    private List<Account> accounts;
    }
    public interface IAccountDao {
    
        /**
         * 查询所有账户,同时还要获取到当前账户的所属用户信息
         * @return
         */
        List<Account> findAll();
    
        /**
         * 根据用户id查询账户信息
         * @param uid
         * @return
         */
        List<Account> findAccountByUid(Integer uid);
    
    }

    public interface IUserDao {

    /**
    * 查询所有用户,同时还要获取到当前账户的所属用户信息
    * @return
    */
    List<User> findAll();

    /**
    * 根据用户id查询账户信息
    * @param uid
    * @return
    */
    List<User> findById(Integer uid);

    }
     
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 配置properties-->
        <properties resource="jdbcConfig.properties"></properties>
    
        <!--配置参数-->
        <settings>
            <!--开启Mybatis支持延迟加载-->
            <setting name="lazyLoadingEnabled" value="true"/>
            <setting name="aggressiveLazyLoading" value="false"></setting>
        </settings>
    
        <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
        <typeAliases>
            <package name="com.itheima.domain"></package>
        </typeAliases>
    
        <!--配置环境-->
        <environments default="mysql">
            <!-- 配置mysql的环境-->
            <environment id="mysql">
                <!-- 配置事务 -->
                <transactionManager type="JDBC"></transactionManager>
    
                <!--配置连接池-->
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"></property>
                    <property name="url" value="${jdbc.url}"></property>
                    <property name="username" value="${jdbc.username}"></property>
                    <property name="password" value="${jdbc.password}"></property>
                </dataSource>
            </environment>
        </environments>
        <!-- 配置映射文件的位置 -->
        <mappers>
            <package name="com.itheima.dao"></package>
        </mappers>
    </configuration>

    Account.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.itheima.dao.IAccountDao">
    
        <!-- 定义封装account和user的resultMap -->
        <resultMap id="accountUserMap" type="account">
            <id property="id" column="id"></id>
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
            <!-- 一对一的关系映射:配置封装user的内容
            select属性指定的内容:查询用户的唯一标识:
            column属性指定的内容:用户根据id查询时,所需要的参数的值
            -->
            <association property="user" column="uid" javaType="user" select="com.itheima.dao.IUserDao.findById"></association>
        </resultMap>
    
        <!-- 查询所有 -->
        <select id="findAll" resultMap="accountUserMap">
            select * from account
        </select>
    
        <!-- 根据用户id查询账户列表 -->
        <select id="findAccountByUid" resultType="account">
            select * from account where uid = #{uid}
        </select>
    
    </mapper>

    User.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.itheima.dao.IUserDao">
    
        <!-- 定义User的resultMap-->
        <resultMap id="userAccountMap" type="user">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="address" column="address"></result>
            <result property="sex" column="sex"></result>
            <result property="birthday" column="birthday"></result>
            <!-- 配置user对象中accounts集合的映射 -->
            <collection property="accounts" ofType="account" select="com.itheima.dao.IAccountDao.findAccountByUid" column="id"></collection>
        </resultMap>
    
        <!-- 查询所有 -->
        <select id="findAll" resultMap="userAccountMap">
            select * from user
        </select>
    
        <!-- 根据id查询用户 -->
        <select id="findById" parameterType="INT" resultType="user">
            select * from user where id = #{uid}
        </select>
    
    </mapper>

    2、Mybatis中的缓存
    什么是缓存
    存在于内存中的临时数据。
    为什么使用缓存
    减少和数据库的交互次数,提高执行效率。
    什么样的数据能使用缓存,什么样的数据不能使用
    适用于缓存:
    经常查询并且不经常改变的。
    数据的正确与否对最终结果影响不大的。
    不适用于缓存:
    经常改变的数据
    数据的正确与否对最终结果影响很大的。
    例如:商品的库存,银行的汇率,股市的牌价。
    Mybatis中的一级缓存和二级缓存
    一级缓存:
    它指的是Mybatis中SqlSession对象的缓存。
    当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
    该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
    查询是否有,有的话直接拿出来用。
    当SqlSession对象消失时,mybatis的一级缓存也就消失了。

    二级缓存:
    它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
    二级缓存的使用步骤:
    第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
    第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
    第三步:让当前的操作支持二级缓存(在select标签中配置)

    1.一级缓存

      /**
         * 测试一级缓存
         */
        @Test
        public void testFirstLevelCache(){
            User user1 = userDao.findById(41);
            System.out.println(user1);
    
          // sqlSession.close();
         // 再次获取SqlSession对象
         //  sqlSession = factory.openSession();
    
         // sqlSession.clearCache();//此方法也可以清空缓存
    
       userDao = sqlSession.getMapper(IUserDao.class);
    
            User user2 = userDao.findById(41);
            System.out.println(user2);
    
            System.out.println(user1 == user2);
        }
    
        /**
         * 测试缓存的同步
         */
        @Test
        public void testClearlCache(){
            //1.根据id查询用户
            User user1 = userDao.findById(41);
            System.out.println(user1);
    
            //2.更新用户信息
            user1.setUsername("update user clear cache");
            user1.setAddress("北京市海淀区");
            userDao.updateUser(user1);
    
            //3.再次查询id为41的用户
            User user2 = userDao.findById(41);
            System.out.println(user2);
    
            System.out.println(user1 == user2);
        }
    }

    二级缓存

    @Test
        public void testFirstLevelCache(){
            SqlSession sqlSession1 = factory.openSession();
            IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
            User user1 = dao1.findById(41);
            System.out.println(user1);
            sqlSession1.close();//一级缓存消失
    
            SqlSession sqlSession2 = factory.openSession();
            IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
            User user2 = dao2.findById(41);
            System.out.println(user2);
            sqlSession2.close();
    
            System.out.println(user1 == user2);
        }
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 配置properties-->
        <properties resource="jdbcConfig.properties"></properties>
    
        <settings>
            <setting name="cacheEnabled" value="true"/>
        </settings>
        
        <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
        <typeAliases>
            <package name="com.itheima.domain"></package>
        </typeAliases>
    
        <!--配置环境-->
        <environments default="mysql">
            <!-- 配置mysql的环境-->
            <environment id="mysql">
                <!-- 配置事务 -->
                <transactionManager type="JDBC"></transactionManager>
    
                <!--配置连接池-->
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"></property>
                    <property name="url" value="${jdbc.url}"></property>
                    <property name="username" value="${jdbc.username}"></property>
                    <property name="password" value="${jdbc.password}"></property>
                </dataSource>
            </environment>
        </environments>
        <!-- 配置映射文件的位置 -->
        <mappers>
            <package name="com.itheima.dao"></package>
        </mappers>
    </configuration>
    <?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.itheima.dao.IUserDao">
        <!--开启user支持二级缓存-->
        <cache/>
    
        <!-- 查询所有 -->
        <select id="findAll" resultType="user">
            select * from user
        </select>
    
        <!-- 根据id查询用户 -->
        <select id="findById" parameterType="INT" resultType="user" useCache="true">
            select * from user where id = #{uid}
        </select>
    
        <!-- 更新用户信息-->
        <update id="updateUser" parameterType="user">
            update user set username=#{username},address=#{address} where id=#{id}
        </update>
    </mapper>
  • 相关阅读:
    集合及特殊集合arrayList
    二维数组、多维数组
    一维数组

    for循坏的穷举与迭代,while、do while循环
    1.兔子生兔子问题2.打印菱形3.求100以内质数的和
    for循环嵌套
    复习题
    循环语句
    分支语句
  • 原文地址:https://www.cnblogs.com/liuyi13535496566/p/13600924.html
Copyright © 2011-2022 走看看