zoukankan      html  css  js  c++  java
  • Java SSM入门(四)——Mybatis延迟加载、缓存、注解和小结

    iwehdio的博客园:https://www.cnblogs.com/iwehdio/

    1、延迟加载

    • 在查询用户时,用户下的账户信息应该是什么时候使用什么时候查询(用户的账户比较多时)。

    • 在查询账户时,账户的所属用户信息,应该随着账户查询一起查询(账户的用户只有一个)。

    • 延迟加载就是,在真正使用数据时才发起查询,不用的时候不加载,是按需加载。

    • 立即加载就是,不管是否使用,一调用方法马上发起查询。

    • 一对多和多对多一般是延迟加载。

    • 多对一和一对一一般是立即加载。

    • 在全局配置文件中开启延迟加载的全局开关:

      <settings>
          <setting name="lazyLoadingEnabled" value="true"/>
          <setting name="aggressiveLazyLoading" value="true"/>
      </settings>
      
    • 一对一延迟加载的配置:

      • AccountDao.xml中:

        <resultMap id="accountUserMap" type="cn.iwehdio.Domin.Account">
            <id property="id" column="id"></id>
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
        
            <association property="user" column="uid" javaType="cn.iwehdio.Domin.User" select="cn.iwehdio.Dao.UserDao.findById">
        
            </association>
        </resultMap>
        <!-- 配置查询所有,id是UserDao中的方法名称, 其中包含的是sql语句 -->
        <select id="findAll" resultMap="accountUserMap">
            select * from account;
        </select>
        
      • <association>标签配置延迟加载,其中的select属性指向了所要进行延迟加载进行的查询,值为 Dao全类名 + 方法名。column指向了查询的输入参数。

    • 一对多延迟加载的配置:

      • UserDao.xml中:

        <resultMap id="userAccountMap" type="cn.iwehdio.Domin.User">
            <id property="id" column="id"></id>
            <id property="username" column="username"></id>
            <id property="address" column="address"></id>
            <id property="sex" column="sex"></id>
            <id property="birthday" column="birthday"></id>
            <collection property="accounts" ofType="cn.iwehdio.Domin.Account" select="cn.iwehdio.Dao.AccountDao" column="id"></collection>
        </resultMap>
        
        
        <!-- 配置查询所有,id是UserDao中的方法名称, 其中包含的是sql语句 -->
        <select id="findAll" resultMap="userMap">
            select * from user;
        </select>
        
        • 使用 <collection>标签中的select属性指向所要延迟加载的方法,column属性为参数输入。
      • AccountDao.xml中:

        <select id="findAccountByUid" resultType="cn.iwehdio.Domin.Account">
            select * from account where uid = #{uid};
        </select>
        

    2、缓存

    • 缓存是存在内存中的临时数据,适用于经常查询且不经常改变的,数据的正确与否对最终结果影响不大时。经常改变的数据不适合用缓存。

    • Mybatis中的一级缓存:

      • 指的是Mybatis中SqlSession对象的缓存。
      • 当执行查询后,结果会被同时存入SqlSession提供的区域,该区域的结构是一个 Map。
      • 再次查询同样的数据时,Mybatis会先去SqlSession中查询。
      • 当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
      • 比如连续进行两次同样的查询时,第一次从数据库中查询,第二次从缓存中查询。但是如果这之间使用了不同的SqlSession对象则不行。
      • 也可以使用SqlSession的clearCache()方法清除缓存。
    • Mybatis中触发清空一级缓存的情况:

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

      • 指的是Mybatis中SqlSessionFactory的缓存。

      • 同一个SqlSessionFactory创建的SqlSession共享二级缓存。

      • 二级缓存的使用:

        1. 让Mybatis支持二级缓存,在主配置文件中配置。

          <settings>
              <setting name="cacheEnabled" value="true"/>
          </settings>
          
        2. 在当前的映射文件支持二级缓存。添加<cache/>标签。

        3. 让当前操作支持二级缓存,在select标签中配置<userCache>为true。

      • 二级缓存中存放的是数据而不是对象,两次从缓存中获取的不是同一个对象。

    3、注解开发

    • 注解配置的是映射配置文件,主配置文件不能省略。

    • Mybatis中针对CRUD有四个注解:

      • @Select(sql语句)
      • @Insert(sql语句)。
      • @Update(sql语句)。
      • @Delete(sql语句)。
    • 如果已经使用注解开发,resources下 与Dao接口的对应路径中不能存在 xml 配置文件,否则会报错。

    • 注解创建实体类属性与数据库列的对应关系:

      • 如果属性名与列名不同,可以使用@Results注解。

      • @Results注解使用方法:

        @Results(id="userMap',value={
            @Result(id=true,column="id",property="id"),
            @Result(column="name",property="uname"),
        })
        
        • @Results下的id属性可以用来索引这个映射关系。
        • @Result下的id属性指定该属性是否是主键,column属性指定数据库列名,property属性指定实体类属性名。
        • 可以使用@ResultMap("userMap")注解复用这个映射。
    • 一对一/多对一的注解配置:

      • 使用@Result下的@One注解。

      • @One注解使用方法:

        @Results(id="userMap',value={
            @Result(id=true,column="id",property="id"),
            @Result(id=true,column="uid",property="uid"),
            @Result(property="user",column="uid",one=@One(select="cn.iwehdio.dao.UserDao.findById",fetchType=FetchType.EAGER))
        })
        
        • 一对一/多对一查询时,所关联的查询使用@Result,property属性指定封装的返回值,column属性指定查询的输入参数。
        • @One注解表示是一对一/多对一查询,select属性是所要进行查询依据的全类名+方法名,fetchType属性为LAZY表示延迟加载,为EAGER表示同步加载。
        • 一般一对一/多对一查询用同步加载,一对多/多对多用延迟加载。
    • 一对多/多对多的注解配置:

      • 使用@Result下的@Many注解。
      • @Many注解使用方法:与@one类似。fetchType属性设置为LAZY。
    • 注解开发使用二级缓存:

      • 在主配置文件中开启全局设置开启二级缓存。
      • 在Dao接口上添加注解@CacheNameSpace(blocking=true)

    4、小结

    1、配置文件

    • 主配置文件约束:

      <?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">
      
    • 主配置文件环境:

      <!-- Mybatis主配置文件 -->
      <configuration>
          <!-- 配置mysql环境 -->
          <environments default="mysql">
              <environment id="mysql">
                  <!-- 配置事务类型 -->
                  <transactionManager type="JDBC"></transactionManager>
                  <!-- 配置数据源(连接池) -->
                  <dataSource type="POOLED">
                      <!-- 配置连接数据库的四个基本信息 -->
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                      <property name="username" value="root"/>
                      <property name="password" value="root"/>
                  </dataSource>
              </environment>
          </environments>
      
          <!-- 指定映射配置文件的位置,映射配置文件指的是每个Dao独立的配置文件 -->
          <mappers>
              <mapper resource="" />
          </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=""></mapper>
      

    2、主配置文件下的标签

    • <mapper>标签:

      • resource属性:xml配置的接口。
      • class属性:注解配置的接口。
    • <properties>标签:

      • 通过指定外部属性文件指定信息。
      • 通过${}获取配置文件的信息。
    • <typeAliases>标签:

      • 配置 domain 中类的别名。
      • type属性:所要配置别名的全类名。
      • alias属性:所要配置的别名。
    • <package>标签:

      • name属性:所指向的包名。

      • 定义在<configuration>标签下:

        • 指定配置别名的包,该包下的所有实体类都会注册别名,并且类名就是别名。
        • 制定后在映射配置文件中,全类名都可以直接写别名。
      • 定义在<mappers>标签下:

        • 指定dao接口所在的包,当指定后就不需要写<mapper>标签了。
    • 延迟加载的全局开关:

      <settings>
          <setting name="lazyLoadingEnabled" value="true"/>
          <setting name="aggressiveLazyLoading" value="true"/>
      </settings>
      
    • 二级缓存的全局开关:

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

    3、映射配置文件下的标签

    • <mapper>标签:

      • namespace属性:指定了要实现的是哪一个Dao接口。
    • <select>标签:

      • <mapper>标签下,表示查询语句。
      • id属性:所要实现的接口中的方法名。
      • resultType:结果所要封装为的全类名。
      • parameterType:输入的参数的全类名。
    • <insert>标签:

      • <mapper>标签下,表示插入语句。

      • 获取插入后的数据id:

        <selectKey keyProperty="id" keyColumn="id" resultType="Integer" order="AFTER">
            select last_insert_id();
        </selectKey>
        
    • <update>标签:

      • <mapper>标签下,表示更新语句。
    • <delete>标签:

      • <mapper>标签下,表示删除语句。
    • <resultMap>标签:

      • 配置查询结果的列名和实体类属性名的对应关系。

      • id属性:进行sql操作的标签下可用resultMap属性指向该id,表示使用该映射关系。

      • <id>标签:表示主键。property属性表示封装为的实体类中的属性名,column属性表示数据库中的列名。

      • <result>标签:表示非主键。

      • <association>标签表示了实体类之间的关系。

        • 其中包含了封装类的<id>标签和<result>标签。一般用于一对一/多对一。

        • property属性同上。

        • column属性:表示输入的查询参数(数据库中的列)。如果没有使用#{}也可以不写。使用延迟加载必须写。

        • javaType属性:表示了所要封装成的实体类结果。

        • select属性:指向了所要进行延迟加载进行的查询,值为 Dao全类名 + 方法名。此时标签内不再写property属性和column属性。

      • <collection>属性:

        • 其中包含了封装类的<id>标签和<result>标签。一般用于一对多/多对多。
        • property属性同上。
        • column属性:表示输入的查询参数(数据库中的列)。如果没有使用#{}也可以不写。使用延迟加载必须写。
        • ofType属性:所要封装为集合的泛型。
        • select属性:指向了所要进行延迟加载进行的查询,值为 Dao全类名 + 方法名。此时标签内不再写property属性和column属性。
    • <if>标签:

      • 在SQL语句中,实现动态sql。
      • test属性:表示判断的条件,为true时拼接<if>中的语句。
    • <where>标签:

      • 其中可以包含<if>标签,不需要在sql语句中写where 1=1了。

    iwehdio的博客园:https://www.cnblogs.com/iwehdio/

  • 相关阅读:
    POJ_1523 SPF (Tarjan 求割点)
    POJ 3177&& 3352
    POJ 基础数据结构
    Bellman Ford, SPFA 学习笔记(含有负权的单源最短路径)
    HDU_3062 Party (2SAT)
    POJ二分图最大匹配的简单题目
    POJ 2553 The Bottom of a Graph (Trajan 强连通分量 缩点)
    POJ_3678 Katu Puzzle (2SAT)
    HDU_3836 Equivalent Set (Trajan 强连通分量 缩点)
    POJ1904 King's Quest(Tarjan 求缩点)
  • 原文地址:https://www.cnblogs.com/iwehdio/p/13033906.html
Copyright © 2011-2022 走看看