Loading...

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/

posted @ 2020-06-02 21:38  iwehdio  阅读(131)  评论(0编辑  收藏  举报