hibernate一级缓存(转)

news/2024/5/19 0:21:27 标签: hibernate, session, 数据库, sql, jdbc, iterator

 

hibernate 一级缓存:(缓存的是实体对象)

一级缓存很短和session的生命周期一致,一级缓存也叫session级的缓存或事务缓存

 

哪些方法支持一级缓存:

*get()

*load()

*iterate()  (查询实体对象)

 

如何管理一级缓存:

* session.clear() session.evict()

 

如何避免一次性大量的实体数据入库导致内存溢出

*先flush,再clear

 

如果数据量特别大,考虑采用jdbc实现,如果jdbc也不能满足要求,可以考虑采用数据库本身的特定导入工具

 

一.Load测试: 在同一个session中发出两次load查询

       Student sutdent = (Student)session.load(Student.class,1);

       System.out.println(student.getName());

 

       sutdent = (Student)session.load(Student.class,1);

       System.out.println(student.getName());

       在同一个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库,  第二次load的时候也不会,当使用的时候也不会查询数据库,因为他在缓存里找到,不会发出sql

 

 

Load测试: 开启两个session中发出两次load查询

Student sutdent = (Student)session.load(Student.class,1);

       System.out.println(student.getName());

sessioin.close();

………..

       sutdent = (Student)session.load(Student.class,1);

       System.out.println(student.getName());

       开启两个session中发出两次load查询,第一次load的时候不会去查询数据库,因为他是LAZY的,当使用的时候才去查询数据库,  第二次load的时候也不会,当使用的时候查询数据库,因为session间不能共享一级缓存的数据,因为他会随session的生命周期存在和消亡

 

 

二.Get测试: 在同一个session中发出两次get查询

    Student sutdent = (Student)session.get(Student.class,1);

       System.out.println(student.getName());

 

       sutdent = (Student)session.get(Student.class,1);

       System.out.println(student.getName());

       在同一个session中发出两次get查询, 第一次get的时候去查询数据库,第二次get的时候不会查询数据库,因为他在缓存里找到,不会发出sql

 

 

三.iterate测试: 在同一个session中发出两次iterator查询

Student student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();

System.out.println(student.getName());

 

student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();

System.out.println(student.getName());

       在同一个session中发出两次iterator查询,第一次iterate().next()的时候会发出查询id的sql,使用的时候会发出相应的查询实体对象,第二次iterate().next()的时候会发出查询id的sql,不会发出查询实体对象的sql,因为iterate使用缓存,不会发出sql

 

 

四.Iterate查询属性测试: 同一个session中发出两次查询属性

String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();

System.out.println(name);

 

String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();

System.out.println(name);

       在同一个session中发出两次查询属性, 第一次iterate().next()的时候会发出查询属性的sql,第二次iterate().next()的时候会发出查询属性的sql,iterate查询普通属性,一级缓存不会缓存,所以会发出sql

 

 

五.同一个session中先save,再发出load查询save过的数据

 

       Student stu = new Student();

       stu.setName(“王五”);

 

   Serializable id = session.save(stu);

 

Student sutdent = (Student)session.load(Student.class,id);

       System.out.println(student.getName());

 

      

save的时候,他会在缓存里放一份,不会发出sql,因为save是使用缓存的

六.同一个session中先调用load查询,然后执行sessio.clear()session.evict(),再调用load查询

 

Student sutdent = (Student)session.load(Student.class,1);

       System.out.println(student.getName());

       session.clear();

 

Student sutdent = (Student)session.load(Student.class,1);

       System.out.println(student.getName());

 

 

       sessio.clear()或session.evict()可以管理一级缓存,一级缓存无法取消,但可以管理.

上面的语句都会发出sql 因为一级缓存中的实体被清除了

 

七.向数据库中批量加入1000条数据

 

for(int i=0;i<1000;i++){

       Student student = new Student();

       student.setName(“s” + i);

       session.save(student);

//每20条数据就强制session将数据持久化,同时清除缓存,避免大量数据造成内存溢出

       if( i %20 == 0 ){

              session.flush();

              session.clear();

}

}

(二b)

大家都知道,Hibernate是以JDBC为基础实现的持久层组件,因而其性能肯定会低于直接使用JDBC来访问数据库。因此,为了提高Hibernate的性能,在Hibernate组件中提供了完善的缓存机制来提高数据库访问的性能。

       什么是缓存

       缓存是介于应用程序和物理数据之间的,其作用是为了降低应用程序对物理数据访问的频次从而提高应用系统的性能。缓存思想的提出主要是因为对物理数据的访问效率要远远低于对内存的访问速度,因而采用了将部分物理数据存放于内存当中,这样可以有效地减少对物理数据的访问次数,从而提高系统的性能。

       缓存广泛地存在于我们所接触的各种应用系统中,例如数据库系统、Windows操作系统等,在进行物理数据的访问时无一例外地都使用了缓存机制来提高操作的性能。

       缓存内的数据是对物理数据的复制,因此一个缓存系统所应该包括的最基本的功能是数据的缓存和读取,同时在使用缓存的时候还要考虑缓存中的数据与物理数据的同步,也就是要保持两者是一致的。

       缓存要求对数据的读写速度很高,因此,一般情况下会选用内存作为存储的介质。但如果内存有限,并且缓存中存放的数据量非常大时,也会用硬盘作为缓存介质。缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期。

       为了提高系统的性能,Hibernate也使用了缓存的机制。在Hibernate框架中,主要包括以下两个方面的缓存:一级缓存和二级缓存(包含查询缓存)。Hibernate中缓存的作用主要表现在以下两个方面:

●   通过主键(ID)加载数据的时候

●   延迟加载中

一级缓存

       Hibernate的一级缓存是由Session提供的,因此它只存在于Session的生命周期中,也就是当Session关闭的时候该Session所管理的一级缓存也会立即被清除。

       Hibernate的一级缓存是Session所内置的,不能被卸载,也不能进行任何配置。

       一级缓存采用的是key-value的Map方式来实现的,在缓存实体对象时,对象的主关键字ID是Map的key,实体对象就是对应的值。所以说,一级缓存是以实体对象为单位进行存储的,在访问的时候使用的是主关键字ID。

       虽然,Hibernate对一级缓存使用的是自动维护的功能,没有提供任何配置功能,但是可以通过Session中所提供的方法来对一级缓存的管理进行手工干预。Session中所提供的干预方法包括以下两种。

●   evict() :用于将某个对象从Session的一级缓存中清除。

●   clear() :用于将一级缓存中的对象全部清除。

       在进行大批量数据一次性更新的时候,会占用非常多的内存来缓存被更新的对象。这时就应该阶段性地调用clear()方法来清空一级缓存中的对象,控制一级缓存的大小,以避免产生内存溢出的情况。具体的实现方法如清单14.8所示。

       清单14.8    大批量更新时缓存的处理方法

Session session = sessionFactory.openSession();

Transaction tx = session.beginTransaction();

  

for ( int i=0; i<100000; i++ ) {

    Customer customer = new Customer(……);

    session.save(customer);

    if ( i % 20 == 0 ) {

        //将本批插入的对象立即写入数据库并释放内存

        session.flush();

        session.clear();

    }

}

  

tx.commit();

session.close();


http://www.niftyadmin.cn/n/1051126.html

相关文章

mybatis免sql插件之JpaMapper-以Jpa hibernate的风格写mybatis(实现分页排序功能)

mybatis免sql插件之JpaMapper-以Jpa hibernate的风格写mybatis&#xff08;实现分页排序功能&#xff09; 简介 JpaMapper以Jpa hibernate的风格写mybatis的代码&#xff0c;可以减少手动写sql的烦恼。 优势&#xff1a; 不替换底层实现&#xff0c;仅生成sql并交给mybatis…

蓝桥杯 ADV-237 三进制数位和

蓝桥杯 ADV-237 三进制数位和 题目描述 给定 L 和 R&#xff0c;你需要对于每一个6位三进制数&#xff08;允许前导零&#xff09;&#xff0c;计算其每一个数位上的数字和&#xff0c;设其在十进制下为S。 一个三进制数被判断为合法&#xff0c;当且仅当S为质数&#xff0c;…

hibernate二级缓存:Hibernate缓存Cache配置

今天仔仔细细看了下Hibernate缓存Cache并做了例子实战了把google下网上教程、文章很多 自己小结下: Hibernate缓存Cache分为: 级缓存Cache:在Session级别在Session关闭时候级缓存Cache就失效了 2级缓存Cache:在SessionFactory级别它可以使用区别缓存Cache实现如EhCache、JBossC…

简化mybatis的使用方式:通用插件JpaMapper之CrudMapper

简化mybatis的使用方式&#xff1a;通用插件JpaMapper之CrudMapper 简介 JpaMapper以Jpa hibernate的风格写mybatis的代码&#xff0c;可以减少手动写sql的烦恼。 CrudMapper可以实现简单的增删改查&#xff0c;并提供findBy和deletBy操作&#xff0c;简化mybatis的使用。 …

PCB CE工具取Genesis JOB与STEP内存地址 方法分享

今天无意中在硬盘上找到了<CE工具取Genesis JOB与STEP内存地址 >视频, 这是2013年初由郭兄(永明)远程时录制的一段视频&#xff0c;特别感谢郭兄指引与帮助&#xff0c; 想当初要不是你推出全行业首款VB Genesis接口&#xff0c;我也不会发现原来我如此的热爱Code.人生之…

简化mybatis的使用方式:通用插件JpaMapper之SimpleShardingMapper

简化mybatis的使用方式&#xff1a;通用插件JpaMapper之SimpleShardingMapper 简介 JpaMapper以Jpa hibernate的风格写mybatis的代码&#xff0c;可以减少手动写sql的烦恼。 SimpleShardingMapper可以实现简单分表的增删改查&#xff0c;简化mybatis的使用。 这里介绍如何快…

hibernate缓存:Hibernate获取数据方式和缓存Cache使用

Hibernate获取数据方式有区别几种其和缓存Cache结合使用效果也不尽相同而Hibernate中具体如何使用缓存Cache其实是我们很关心个问题直接涉及到性能方面 缓存Cache在Hibernate中主要有 3个方面:级缓存Cache、 2级缓存Cache和查询缓存Cache&#xff1b;级缓存Cache在Hibernate中对…

codeforces CF981C Useful Decomposition 菊花图性质

$ \rightarrow $ 戳我看CF原题 C. Useful Decompositiontime limit per test: 1 secondmemory limit per test: 256 megabytesinput: standard inputoutput: standard outputRamesses knows a lot about problems involving trees (undirected connected graphs without cycles…