mybatis-----的延迟加载-----缓存(一级缓存和二级缓存)

1. 延迟加载

resultMap可实现高级映射:association、collection具备延迟加载功能。

延迟加载:先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

(1)使用collection 实现延迟加载

查询用户地址,在关联用户表查询用户名。

用户表实体:

package cn.happy.entity;

import java.util.ArrayList;
import java.util.List;

public class DeptOne {
    private Integer id;
    private String loginName;//登录名
    private String userName;//真实姓名
    private Coder code;//用户地址(用户地址表)

    public Coder getCode() {
        return code;
    }

    public void setCode(Coder code) {
        this.code = code;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

  用户地址表:

package cn.happy.entity;

import java.util.ArrayList;
import java.util.List;

public class Coder {
    private Integer id;//编号
    private Integer userid;//用户表id
    private String  address;//地址
    private List<DeptOne> dept=new ArrayList<DeptOne>();//用户集合

    public List<DeptOne> getDept() {
        return dept;
    }

    public void setDept(List<DeptOne> dept) {
        this.dept = dept;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

  dao层方法:

package cn.happy.dao;

import cn.happy.entity.Coder;

public interface ICoderOneDAO {

    public Coder getByMonyCoderId(int id);
}

  小配置  dao层的 .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
-->
<mapper namespace="cn.happy.dao.ICoderOneDAO">
    <resultMap id="CoderMonyMapper" type="Coder" >
        <id column="id" property="id"></id>
        <result column="address" property="address"></result>
        <collection property="dept" ofType="DeptOne" select="MonyFindById" column="id">
        </collection>
    </resultMap>//这是查询用户名的方法
    <select id="MonyFindById" resultType="DeptOne">
        SELECT id,userName FROM easyby_user
        where id=#{id}
    </select>

//这是只查询用户地址的方法
    <select id="getByMonyCoderId" resultMap="CoderMonyMapper">
        SELECT id,address FROM easybuy_user_address
        where id=#{id}
    </select>
</mapper>

  打开延迟加载:在 大配置 mybatis-config.xml  的里头配置。。。。。。。。。。

 <settings>
        <setting name="lazyLoadingEnabled" value="true"></setting>      <!-- 打开延迟加载的开关 -->  
        <setting name="aggressiveLazyLoading" value="false"></setting>       <!-- 将积极加载改为消息加载即按需加载 -->  
    </settings>

  延迟加载实现========使用单侧:

//一对多 多个sql
    @Test
    public void getByMonyCoderId() throws IOException {
        SqlSession session = sessionFactory.getSqlSession();
        ICoderOneDAO mapper = session.getMapper(ICoderOneDAO.class);
        Coder code = mapper.getByMonyCoderId(1);
        System.out.println(code.getAddress());
        for (DeptOne dept: code.getDept()) {
            System.out.println(dept.getUserName());
        }
        session.close();
    }

 

<!--cglib 依赖-->
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>2.2.2</version>
    </dependency>

如果你使用的是idea 工具,那么像实现延迟加载 需要  上面的依赖。

 单侧的结果:

这就是延迟加载, 先 执行对 用户地址的加载,在加载 用户名。

2.一级缓存

在对数据库的一次会话中,我们有可能会反复地执行完全相同的查询语句,如果不采取一些措施的话,每一次查询都会查询一次数据库,而我们在极短的时间内做了完全相同的查询,那么它们的结果极有可能完全相同,由于查询一次数据库的代价很大,这有可能造成很大的资源浪费。

为了解决这一问题,我们使用mybatis的一级缓存。

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

  (1)证明一级缓存的 存在

查询用户名的方法

  dao层:

public interface IDeptOneDAO {    public DeptOne getByno(int id);}

dao层的 xml 文件:

<mapper namespace="cn.happy.dao.IDeptOneDAO">
    <resultMap id="DeptMapper" type="DeptOne">
        <id column="id" property="id"></id>
        <result column="userName" property="userName"></result>
        <association property="code" javaType="Coder">
            <id column="id" property="id"></id>
            <result column="address" property="address"></result>
        </association>
    </resultMap>
    <select id="getByno" resultMap="DeptMapper">
        SELECT easybuy_user_address.id,address,easyby_user.id,userName FROM easyby_user,easybuy_user_address
        where easybuy_user_address.userid=easyby_user.id AND easyby_user.id=#{id}
    </select>
</mapper>

  单侧的方法:

 @Test
    public void onefind() throws IOException {
        SqlSession session = sessionFactory.getSqlSession();
        IDeptOneDAO mapper = session.getMapper(IDeptOneDAO.class);
        DeptOne dept = mapper.getByno(1);
        System.out.println(dept.getUserName());      //第一次查询完毕
        System.out.println("=============中间分割线===============");      //第二次查询开始
        IDeptOneDAO mapper2= session.getMapper(IDeptOneDAO.class);
        DeptOne dept2 = mapper2.getByno(1);
        System.out.println(dept2.getUserName());
        session.close();
    }

  查看结果:

查看结果,第一次是查询数据获得结果。第二次是没有走数据库的。证明一级缓存的存在。

3. 二级缓存

二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。

在这里我说明,在mybatis中二级缓存是默认开启的。

时间: 2024-11-05 23:27:55

mybatis-----的延迟加载-----缓存(一级缓存和二级缓存)的相关文章

MyBatis从入门到放弃七:二级缓存原理分析

前言 说起mybatis的一级缓存和二级缓存我特意问了几个身边的朋友他们平时会不会用,结果没有一个人平时业务场景中用. 好吧,那我暂且用来学习源码吧.一级缓存我个人认为也确实有些鸡肋,mybatis默认开启一级缓存,支持在同一个会话(sqlsession)同一个statement执行两次,则第二次会默认会使用第一次创建的缓存对象. 二级缓存前一篇粗略介绍了下,默认使用内存对象[PerpetualCache]内部维护一个HashMap对象来存储.那么先来看几张图片[图片来自一位朋友,文章最后参考连

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Mybatis(五) 延迟加载和缓存机制(一级二级缓存)

踏踏实实踏踏实实,开开心心,开心是一天不开心也是一天,路漫漫其修远兮. --WH 一.延迟加载 延迟加载就是懒加载,先去查询主表信息,如果用到从表的数据的话,再去查询从表的信息,也就是如果没用到从表的数据的话,就不查询从表的信息.所以这就是突出了懒这个特点.真是懒啊. Mybatis中resultMap可以实现延迟加载 1.1.查询订单信息,延迟加载用户信息,一对一关系. 1.1.1.开启延迟加载 全局配置文件中,settings标签用来设置全局常量的,这里就用到了. 1 <settings>

Mybatis一级、二级缓存

一级缓存 首先做一个测试,创建一个mapper配置文件和mapper接口,我这里用了最简单的查询来演示. <mapper namespace="cn.elinzhou.mybatisTest.mapper.UserMapper"> <select id="findUsers" resultType="cn.elinzhou.mybatisTest.pojo.User"> SELECT * FROM user </se

MyBatis一级缓存、二级缓存

一.MyBatis一级缓存 MyBatis默认启动一级缓存,一级缓存是SqlSession级别的 注意:有两个因素会使一级缓存失效:  1.对SqlSession进行commit()操作(即对数据库进行了增.删.改操作).数据库中的数据发生了改变,此时若再从内存中读取缓存的数据,则会读取到错误的数据信息,所以此时旧的一级缓存中的数据会清空,当用户下一次执行查询操作时, 会重新从数据库中读取数据并放入一级缓存中  2.关闭SqlSession.一级缓存的设计是每个sqlsession单独使用一个缓

MyBatis 一级缓存与二级缓存

MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3.session.close(); //不是同一个Session对象了 MyBatis二级缓存 需要配置<cache></cache> 是一个映射文件级的缓存 使用Mybatis二级缓存时查询的对象实体类必须序列化实现(实现Serializable接口) 二级缓存使用时 必须使用sess

mybatis学习--缓存(一级和二级缓存)

声明:学习摘要! MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相同的查询语句,完全可以把查询结果存储起来,下次查询同样的内容的时候直接从内存中获取数据即可,这样在某些场景下可以大大提升查询效率. MyBatis的缓存分为两种: 一级缓存,一级缓存是SqlSession级别的缓存,对于相同的查询,会从缓存中返回结果而不是查询数据库 二级缓存,二级

MyBatis 一级缓存和二级缓存及ehcache整合

一级缓存 什么是缓存?? 缓存是存储在内存(cache)中的数据,一般情况都存在内存,在内存数据存储满了,会存储到硬盘上(disk),或是在我们进行一些操作和配置也可以把缓存存储到磁盘中. 缓存的作用是什么?? 缓存的作用可以减轻数据库的压力,减少用户对数据库的访问,可以说用户对数据库进行的重复操作在缓存中就可以实现操作,提高用户体验. 下面这张图是缓存的理解图 曾删改会对缓存造成影响. 写个测试,测试一下缓存是否存在:   答案是肯定的 现在测试一下进行曾删改数据,是否会对缓存造成影响? 二级

mybatis——一级缓存、二级缓存

一.Mybatis缓存 ● MyBatis包含一个非常强大的查询緩存特性,它可以非常方便地定制和配置缓存.绶存可以极大的提升查询效率. ● MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存 ○ 默认情况下,只有一级缓存开启.( SqlSession级别的缓存,也称为本地缓存) ○ 二级缓存需要手动开启和配置,他是基于namespace级别的缓存. ○ 为了提高扩展性, MyBatis定义了缓存接口 Cache.我们可以通过实现 Cache接口来自定义二级缓存 小结:缓存的作用就是提升查

Mybatis 的一级、二级缓存?

1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就 将清空,默认打开一级缓存. 2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源, 如 Ehcache.默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需