zoukankan      html  css  js  c++  java
  • mybatis的缓存和注解开发(4)

    第四天:mybatis的缓存和注解开发
     mybatis中的加载时机(查询的时机)
     mybatis中的一级缓存和二级缓存
     mybatis的注解开发
      单表CRUD
      多表查询


    一、今日内容概要

    1、Mybatis中的延迟加载
     问题:在一对多中,当我们有一个用户,它有100个账户。
           在查询用户的时候,要不要把关联的账户查出来?
           在查询账户的时候,要不要把关联的用户查出来?
      
           在查询用户时,用户下的账户信息应该是,什么时候使用,什么时候查询的。
           在查询账户时,账户的所属用户信息应该是随着账户查询时一起查询出来。
     什么是延迟加载
      在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
     什么是立即加载
      不管用不用,只要一调用方法,马上发起查询。
     
     在对应的四种表关系中:一对多,多对一,一对一,多对多
      一对多,多对多:通常情况下我们都是采用延迟加载。
      多对一,一对一:通常情况下我们都是采用立即加载。
    2、Mybatis中的缓存
     什么是缓存
      存在于内存中的临时数据。
     为什么使用缓存
      减少和数据库的交互次数,提高执行效率。
     什么样的数据能使用缓存,什么样的数据不能使用
      适用于缓存:
       经常查询并且不经常改变的。
       数据的正确与否对最终结果影响不大的。
      不适用于缓存:
       经常改变的数据
       数据的正确与否对最终结果影响很大的。
       例如:商品的库存,银行的汇率,股市的牌价。
     Mybatis中的一级缓存和二级缓存
      一级缓存:
       它指的是Mybatis中SqlSession对象的缓存。
       当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。
       该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中
       查询是否有,有的话直接拿出来用。
       当SqlSession对象消失时,mybatis的一级缓存也就消失了。
      
      二级缓存:
       它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
       二级缓存的使用步骤:
        第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)
        第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)
        第三步:让当前的操作支持二级缓存(在select标签中配置)
    3、Mybatis中的注解开发  

    二、Mybatis中的延迟加载

    1.一对一实现延迟加载

    IAccountDao.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>

    SqlMapConfig.xml

    <?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>

    2.多对多实现延迟加载

    IUserDao.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集合的映射 -->
          (批注:在映射配置文件中 调用相关联的一方的根据id查询的方法) <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>

    三、Mybatis中的缓存

    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);
        }

     一级缓存是SqlSession范围的缓存,当调用SqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。 

    2.测试二级缓存

        第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)

    <?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>


        第二步:让当前的映射文件支持二级缓存(在IUserDao.xml中配置)

        第三步:让当前的操作支持二级缓存(在select标签中配置)

    <?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支持二级缓存 默认为true-->
        <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>


     四、Mybatis中的注解开发

      1.环境搭建

     2.单表CRUD操作(代理Dao方式)

    sqlMapConfig.xml

    <?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 resource="jdbcConfig.properties"></properties>
        <!--配置别名-->
        <typeAliases>
            <package name="com.itheima.domain"></package>
        </typeAliases>
        <!-- 配置环境-->
        <environments default="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>
        <!-- 指定带有注解的dao接口所在位置 -->
        <mappers>
            <mapper class="com.itheima.dao.IUserDao"></mapper>
          或者
        <package name="com.itheima.dao"></package>
    </mappers> </configuration>

    IUserDao

    package com.itheima.dao;
    
    import com.itheima.domain.User;
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.Update;
    
    import java.util.List;
    
    /**
    
     * 在mybatis中针对,CRUD一共有四个注解
     *  @Select @Insert @Update @Delete
     */
    public interface IUserDao {
    
        /**
         * 查询所有用户
         * @return
         */
        @Select("select * from user")
        List<User> findAll();
    
        /**
         * 保存用户
         * @param user
         */
        @Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
        void saveUser(User user);
    
        /**
         * 更新用户
         * @param user
         */
        @Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
        void updateUser(User user);
    
        /**
         * 删除用户
         * @param userId
         */
        @Delete("delete from user where id=#{id} ")
        void deleteUser(Integer userId);
    
        /**
         * 根据id查询用户
         * @param userId
         * @return
         */
        @Select("select * from user  where id=#{id} ")
        User findById(Integer userId);
    
        /**
         * 根据用户名称模糊查询
         * @param username
         * @return
         */
    //    @Select("select * from user where username like #{username} ")
        @Select("select * from user where username like '%${value}%' ")
        List<User> findUserByName(String username);
    
        /**
         * 查询总用户数量
         * @return
         */
        @Select("select count(*) from user ")
        int findTotalUser();
    }



     3.多表查询操作

    使用注解来解决实体类属性与数据库表列名对应不上的问题

        /**
         * 查询所有用户
         * @return
         */
        @Select("select * from user")
        @Results(id="userMap",value={
                @Result(id=true,column = "id",property = "userId"),
                @Result(column = "username",property = "userName"),
                @Result(column = "address",property = "userAddress"),
                @Result(column = "sex",property = "userSex"),
                @Result(column = "birthday",property = "userBirthday"),
               
        })
        List<User> findAll();

    mybatis注解开发一对一的查询配置

    public interface IAccountDao {
    
        /**
         * 查询所有账户,并且获取每个账户所属的用户信息
         * @return
         */
        @Select("select * from account")
        @Results(id="accountMap",value = {
                @Result(id=true,column = "id",property = "id"),
                @Result(column = "uid",property = "uid"),
                @Result(column = "money",property = "money"),
                @Result(property = "user",column = "uid",one=@One(select="com.itheima.dao.IUserDao.findById",fetchType= FetchType.EAGER))
        })
        List<Account> findAll();
    
        /**
         * 根据用户id查询账户信息
         * @param userId
         * @return
         */
        @Select("select * from account where uid = #{userId}")
        List<Account> findAccountByUid(Integer userId);
    }

    mybatis注解开发一对多的查询配置

    package com.itheima.dao;
    
    import com.itheima.domain.User;
    import org.apache.ibatis.annotations.*;
    import org.apache.ibatis.mapping.FetchType;
    
    import java.util.List;
    
    
    @CacheNamespace(blocking = true)
    public interface IUserDao {
    
        /**
         * 查询所有用户
         * @return
         */
        @Select("select * from user")
        @Results(id="userMap",value={
                @Result(id=true,column = "id",property = "userId"),
                @Result(column = "username",property = "userName"),
                @Result(column = "address",property = "userAddress"),
                @Result(column = "sex",property = "userSex"),
                @Result(column = "birthday",property = "userBirthday"),
                @Result(property = "accounts",column = "id",
                        many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
                                    fetchType = FetchType.LAZY))
        })
        List<User> findAll();
    
        /**
         * 根据id查询用户
         * @param userId
         * @return
         */
        @Select("select * from user  where id=#{id} ")
        @ResultMap("userMap")
        User findById(Integer userId);
    
        /**
         * 根据用户名称模糊查询
         * @param username
         * @return
         */
        @Select("select * from user where username like #{username} ")
        @ResultMap("userMap")
        List<User> findUserByName(String username);
    
    
    }

    4. 缓存的配置

         第一步:让Mybatis框架支持二级缓存(在SqlMapConfig.xml中配置)

    <?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 resource="jdbcConfig.properties"></properties>
        <!--配置开启二级缓存-->
        <settings>
            <setting name="cacheEnabled" value="true"/>
        </settings>
    
        <!--配置别名-->
        <typeAliases>
            <package name="com.itheima.domain"></package>
        </typeAliases>
        <!-- 配置环境-->
        <environments default="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>
        <!-- 指定带有注解的dao接口所在位置 -->
        <mappers>
           <package name="com.itheima.dao"></package>
        </mappers>
    </configuration>


        第二步:让当前的操作支持二级缓存(在select标签中配置)

    @CacheNamespace(blocking = true)
    public interface IUserDao {
    
        /**
         * 查询所有用户
         * @return
         */
        @Select("select * from user")
        @Results(id="userMap",value={
                @Result(id=true,column = "id",property = "userId"),
                @Result(column = "username",property = "userName"),
                @Result(column = "address",property = "userAddress"),
                @Result(column = "sex",property = "userSex"),
                @Result(column = "birthday",property = "userBirthday"),
                @Result(property = "accounts",column = "id",
                        many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
                                    fetchType = FetchType.LAZY))
        })
        List<User> findAll();

    测试方法

        @Test
        public void testFindOne(){
            SqlSession session = factory.openSession();
            IUserDao userDao = session.getMapper(IUserDao.class);
            User user = userDao.findById(57);
            System.out.println(user);
    
            session.close();//释放一级缓存
    
            SqlSession session1 = factory.openSession();//再次打开session
            IUserDao userDao1 = session1.getMapper(IUserDao.class);
            User user1 = userDao1.findById(57);
            System.out.println(user1);
    
    
            session1.close();
    
        }
     
  • 相关阅读:
    JavaScript自动化构建工具grunt、gulp、webpack介绍
    开始使用 Vuejs 2.0 ---简单总结2
    开始使用 Vuejs 2.0 ---简单总结1
    Bootboxjs快速制作Bootstrap的弹出框效果
    FlexSlider是一个非常出色的jQuery滑动切换插件
    CSS实现背景透明,文字不透明(兼容各浏览器)
    jquery中attr和prop的区别
    GitHub 的分支创建与合并
    [译]使用NuGet管理共享代码
    [译]Nuget.Server
  • 原文地址:https://www.cnblogs.com/lsk-130602/p/12202311.html
Copyright © 2011-2022 走看看