Hibernate笔记④--一级二级缓存、N+1问题、saveorupdate、实例代码

一级缓存及二级缓存

一级缓存也是Session 缓存

????一个链接用户的多次查询使用缓存

????跨用户 则无缓存

????hibernate自带的

get和load都会填充并利用一级缓存

二级缓存(需要我们自己配置)

????SessionFactory 缓存

????可以跨用户的

?

list 方法会使用一级缓存 ,但是不会填充一级缓存

iterator会填充过一级缓存 耗时的

?

N+1问题

当我们使用iterate 进行迭代
又要使用内部的数据,则会发送1+n条sql

第一条先load 拿到id 对象改变对象则会改变

再取get每一个的id

?

?

Saveor update


/*

???? * 如果一个对先查找出来的,则会调用update语句

???? * 如果没有查
则调用insert语句

???? */

????public
static
void testSaveorUpdate(Emp e){

????????Session session=HibernateSessionFactory.getSession();

????????Transaction tx=session.beginTransaction();

????????session.saveOrUpdate(e);

????????tx.commit();

????????HibernateSessionFactory.closeSession();

????}

?

?

例子代码


package com.pcx.dao;

?

import java.util.Iterator;

import java.util.List;

?

import org.hibernate.Session;

?

import com.pcx.model1.Dept;

import com.pcx.model1.Emp;

import com.pcx.util.HibernateSessionFactory;

?

public
class CacheTest {

????public
static
void main(String[] args) {

????????Emp e=fetchTest2();

????????System.out.println(e.getDept());

????}

????//

????public
static
void cacheTest(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????

????????Emp emp1=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????????

????}

????//get和load都是會填充一级缓存的

????public
static
void cacheTest2(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.load(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????

????????Emp emp1=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????????

????}

????

????public
static
void cacheTest3(){

????????Session session=HibernateSessionFactory.getSession();

????????String hql="from Emp e where e.id=1";

????????
?

????????
?

????????

????????List<Emp> emps=session.createQuery(hql).list();

????????for (Emp emp : emps) {

????????????System.out.println(emp.getName());

????????}

????????

????????//这儿没有用上一级缓存

????????List<Emp> emps2=session.createQuery(hql).list();

????????for (Emp emp : emps2) {

????????????System.out.println(emp.getName());

????????}

????????HibernateSessionFactory.closeSession();

????????

????}

????public
static
void testload(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp e=(Emp) session.load(Emp.class, 2);

????????

????????System.out.println(e.getId());

????????System.out.println(e.getName());

????????e.setName("lllll");

????????HibernateSessionFactory.closeSession();

????}

????//n+1问题

????//当我们使用iterate 进行迭代
又要使用内部的数据,则会发送1+n条sql

????//第一条先load拿到id 对象改变9对象则会改变

????

//????再取get每一个的id

????/**

???? *

???? */

????public
static
void cacheTest4(){

????????Session session=HibernateSessionFactory.getSession();

????????String hql="from Emp";

????????

????????Iterator<Emp> iter=session.createQuery(hql).iterate();

????????while (iter.hasNext()) {

????????????Emp e=iter.next();

????????????System.out.println(e.getName());

????????????

????????}

????????HibernateSessionFactory.closeSession();

????????

????}

????/**

???? * 配置二级缓存最好的方式是在每个类的配置
添加 <cache usage="read-only"/>标记

???? */

????public
static
void cacheTest5(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????session.evict(emp);//清理一级缓存 //如果二级缓存关闭的话会查询两次

????????Emp emp1=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????}

????public
static
void cacheTest6(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????session.evict(emp);//清理一级缓存 //如果二级缓存关闭的话会查询两次

????????Session session2=HibernateSessionFactory.getSession();

????????Emp emp1=(Emp) session2.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????}

????/*

???? * 抓取策略

???? * Fetch 为join的话
就没有lazy了
就直接把dept对象都加载了

???? */

????public
static Emp fetchTest2(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.load(Emp.class, 1);

????????Dept d=emp.getDept();

????????

????????

//????????System.out.println(emp.getName());

//????????System.out.println(d.getName());

????????HibernateSessionFactory.closeSession();

????????return emp;

????}

}

?

?

Fecat="join"

fatch 默认只就是select

????join 也将关联的对象一并加载进

来了,并不管是否懒加载

?

错误:No row with the given identifier exists: [com.pcx.model1.Emp#1000]

????at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:386)

说明表中没有本条数据

时间: 2024-12-21 08:22:14

Hibernate笔记④--一级二级缓存、N+1问题、saveorupdate、实例代码的相关文章

Hibernate的一级二级缓存机制配置与测试

特别感谢http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论下我们的N+1的问题. 随笔虽长,但我相信看完的朋友绝对能对hibernate的 N+1问题以及缓存有更深的了解. 一.N+1问题 首先我们来探讨一下N+1的问题,我们先通过一个例子来看一下,什么是N+1问题: list(

具体解释Hibernate中的二级缓存

1.前言 这篇博客再前几篇博客的基础上来解说一下.Hibernate中的二级缓存.二级缓存是属于SessionFactory级别的缓存机制. 第一级别的缓存是Session级别的缓存,是属于事务范围的缓存,由Hibernate管理,一般无需进行干预.第二级别的缓存是SessionFactory级别的缓存.是属于进程范围的缓存. 2.Hibernate二级缓存 1.分类 二级缓存也分为了两种 内置缓存:Hibernate自带的,不可卸载,通常在Hibernate的初始化阶段,Hibernate会把

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

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

详解Hibernate中的二级缓存

1.前言 这篇博客再前几篇博客的基础上来讲解一下,Hibernate中的二级缓存,二级缓存是属于SessionFactory级别的缓存机制.第一级别的缓存是Session级别的缓存,是属于事务范围的缓存,由Hibernate管理,一般无需进行干预.第二级别的缓存是SessionFactory级别的缓存,是属于进程范围的缓存. 2.Hibernate二级缓存 1.分类 二级缓存也分为了两种 内置缓存:Hibernate自带的,不可卸载,通常在Hibernate的初始化阶段,Hibernate会把映

hibernate中的二级缓存

二级缓存使用场景:不经常修改的数据,但是经常的访问的数据会放到缓存中去 一级缓存仅仅是session内部的缓存,用来存取sql语句,比如说连续调用两次相同参数的get方法,就是session缓存 二级缓存是sessiionFactory层面的缓存,即不同线程,不同程序之间的缓存 1.在hibernate.hbm.xml中加载配置 <property name="cache.provider_class">org.hibernate.cache.HashtableCacheP

Hibernate+EhCache配置二级缓存

步骤: 第一步:加入ehcache.jar 第二步: 在src目录下新建一个文件,名为:ehcache.xml 第三步:在hibernate配置文件的<session-factory>下配置 配置的具体信息: ehcache.xml的具体配置: <?xml version="1.0" encoding="UTF-8"?> <!-- maxEntriesLocalHeap: 在内存中缓存的element的最大数目. maxEntriesL

Spring 整合 Hibernate 时启用二级缓存实例详解

写在前面: 1. 本例使用 Hibernate3 + Spring3: 2. 本例的查询使用了 HibernateTemplate: 1. 导入 ehcache-x.x.x.jar 包: 2. 在 applicationContext.xml 文件中找到 sessionFactory 相应的配置信息并在设置 hibernateProperties 中添加如下代码: ? 1 2 3 4 5 6 <!-- 配置使用查询缓存 --> <prop key="hibernate.cach

Hibernate一级缓存、二级缓存

缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中,准确说就是一个数据结构中,这个数据结构通常是或类似HashMap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对象,如果没有则去查询数据库,并将查询出来的对象保存在缓存中,以便下次使用. 1.缓存的伪代码: DAO { HashMap map = new Map(); User getUser(integer id) { User user = map.get(id) if(user == null) { u

Hibernate一级缓存、二级缓存以及查询缓存的关系

转载自http://blog.csdn.net/maoyeqiu/article/details/50209893 前两天总结了一下二级缓存和查询缓存的关系,但是又有一个新的问题,就是查询缓存缓存到二级缓存的数据,在第三次(第一次缓存中没有数据,查询数据库将对应的ID值存入到二级缓存中去,第二次如果是同一个Session那么将会把数据一级缓存中的数据返回,如果不是同一个Session而是同一个sessionfactory,那么将会把二级缓存中的数据返回,同时将数据放入到一级缓存中去)获取的时候,