Hibernate 性能优化及缓存的使用

1 clear()方法的运用:

由于hibernate在查询出来数据之后,会把数据进行缓存,对于同一个session多次大数据的查询,由于缓存会占用一定的内存空间,因此要多用seesion.clear(0方法清空缓存;

2 对于多发的sql语句合理设置tetch:

在关联查询时候,有时候只查询其中一个表里的数据,而hibernate会发出多条sql语句把另外一张表的数据也进行查询,影响性能,可以通过设置fetch的值来进行关联查询时候的懒加载;例如在多对一查询时候 @ManyToOne(cascade=(CascadeType.ALL),fetch=FetchType.LAZY) ;

3  Query的list()和Iterator()方法对比:

list()方法一次查询出全部对象;

Iterator()方法先查询出全部Id,再根据ID作为条件,一次查询一个对象,直到全部查完;

4 合理使用对象属性的懒加载以及load方法;

5 hibernate的缓存机制:

缓存是在内存中开辟一块空间,用来存储数据的,下次再次查找同样的数据,先在缓存中查找,查找不到再查询数据库。hibernate的缓存分为三种:一级缓存(session级别的缓存),二级缓存(SessionFactory级别的缓存)和查询缓存;

一级缓存:

		Configuration cfg=new AnnotationConfiguration().configure();
		SessionFactory sf=cfg.buildSessionFactory();
		Session session=sf.openSession();
		session.beginTransaction();
		Student s1=(Student) session.load(Student.class, 1);
		System.out.println(s1.getSname());
//		session.clear();
		Student s2=(Student) session.load(Student.class, 1);
		System.out.println(s2.getSname());
		session.getTransaction().commit();
		session.close();

两个查询,只发送了一条sql语句,说明第一次查询出来已经将Student缓存到一级缓存中,下次查找从缓存取已经存在,不再发送sql语句;

多个session不能共用一个一级缓存,一级缓存不能跨越session,必须同一个session里才能使用;

二级缓存:

说明:

Hibernate自己没有二级缓存,需要借助其他厂商提供的缓存,默认使用的一种缓存是EHCache;

二级缓存是SessionFactory级别的,可以跨越session,通常放置一些 修改不频繁,经常访问的少量数据;

使用:

1 导入两个所需要的包:EhCache包 ehcache-1.2.3.jar 和 Ehcache使用 的日子包,为阿帕奇的日志包  commons-logging-1.1.1.jar;

2 在配置文件中开启二级缓存,指定二级缓存供应商,加入如下两句配置;

        <property name="cache.use_second_level_cache">true</property>
        <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>		

3 在要使用二级缓存的持久化类中加入注解(用xml配置的方式需要在映射文件中加配置,这里是使用注解的方式),有一个注意的地方,在多对一情况下多的一方存入缓存的时候,多的一方进行配置二级缓存的注解,一的一方也要加入该注解,否则不会使用二级缓存;在一的一方用二级缓存的时候,多的一方可以不用加注解;需要加入的注解是:@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)    位置在类的上面

4  配置二级缓存配置文件 ehcache.xml,放在classPath根目录下;

持久化类:

package com.tem.hib;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
public class Classes {
	@Id
	@GeneratedValue
	private Integer cid;
	private String cname;
	@OneToMany(cascade=(CascadeType.ALL),mappedBy="classes")
	private Set<Student> students=new HashSet<Student>();

	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
	public Integer getCid() {
		return cid;
	}
	public void setCid(Integer cid) {
		this.cid = cid;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}

}
package com.tem.hib;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
//@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
public class Student {
	@Id
	@GeneratedValue
	private Integer sid;
	private String sname;
	@ManyToOne(cascade=(CascadeType.ALL))
	private Classes classes;

	public Classes getClasses() {

		return classes;
	}
	public void setClasses(Classes classes) {
		this.classes = classes;
	}
	public Integer getSid() {
		return sid;
	}
	public void setSid(Integer sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}

}

hibernate配置文件:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
        <property name="connection.username">orcl</property>
        <property name="connection.password">newsnews</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <property name="cache.use_second_level_cache">true</property>
        <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">update</property>
		<!-- <mapping resource="com/tem/hib/Student.hbm.xml"/> -->
		<mapping class="com.tem.hib.Classes" />
		<mapping class="com.tem.hib.Student" />
<!--   		<mapping class="com.tem.hib.Teacher" />
 -->
    </session-factory>

</hibernate-configuration>

二级缓存配置文件

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by
         its value in the running VM.

         The following properties are translated:
         user.home - User's home directory
         user.dir - User's current working directory
         java.io.tmpdir - Default temp file path -->
    <diskStore path="java.io.tmpdir"/>

    <!--Default Cache configuration. These will applied to caches programmatically created through
        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!--Predefined caches.  Add your cache configuration settings here.
        If you do not have a configuration for your cache a WARNING will be issued when the
        CacheManager starts

        The following attributes are required for defaultCache:

        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->

    <!-- Sample cache named sampleCache1
        This cache contains a maximum in memory of 10000 elements, and will expire
        an element if it is idle for more than 5 minutes and lives for more than
        10 minutes.

        If there are more than 10000 elements it will overflow to the
        disk cache, which in this configuration will go to wherever java.io.tmp is
        defined on your system. On a standard Linux system this will be /tmp"
        -->
    <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <!-- Sample cache named sampleCache2
        This cache contains 1000 elements. Elements will always be held in memory.
        They are not expired. -->
    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> -->

    <!-- Place configuration for your caches following -->

</ehcache>

测试类:

package com.tem.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

import com.tem.hib.Classes;

public class Test {

	public static void main(String[] args) {
		Configuration cfg=new AnnotationConfiguration().configure();

		SessionFactory sf=cfg.buildSessionFactory();
		Session session=sf.openSession();
		session.beginTransaction();
		Classes s1=(Classes) session.load(Classes.class, 2);
		System.out.println(s1.getCname());
		session.getTransaction().commit();
		session.close();

		Session session1=sf.openSession();
		session1.beginTransaction();
		Classes s2=(Classes) session1.load(Classes.class, 2);
		System.out.println(s2.getCname());
		session1.getTransaction().commit();
		session1.close();
	}

}

输出结果:

两个session只发送了一条sql语句,说明第一次查询后,数据已被保持在二级缓存;



时间: 2024-10-25 20:45:53

Hibernate 性能优化及缓存的使用的相关文章

Hibernate性能优化之EHCache缓存

像Hibernate这种ORM框架,相较于JDBC操作,需要有更复杂的机制来实现映射.对象状态管理等,因此在性能和效率上有一定的损耗. 在保证避免映射产生低效的SQL操作外,缓存是提升Hibernate的关键之一. 加入缓存可以避免数据库调用带来的连接创建与销毁.数据打包拆包.SQL执行.网络传输,良好的缓存机制和合理的缓存模式能带来性能的极大提升,EHCache就提供了这种良好的缓存机制. 在考虑给系统加入缓存进行优化前,复用SessionFactory是Hibernate优化最优先.最基础的

Mysql性能优化之缓存参数优化

数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所以,要优化数据库,首先第一步需要优化的就是 IO,尽可能将磁盘IO转化为内存IO.本文先从 MySQL 数据库IO相关参数(缓存参数)的角度来进行IO优化: 一.query_cache_size/query_cache_type (global)    Query cache 作用于整个 MySQL Inst

Hibernate性能优化

性能优化 1.Session.clear()的应用 不断分页循环的时候,使用clear()方法. Java中的内存泄漏: 如果使用java打开某一个资源后,一定要关闭,否则就有可能导致内存泄漏.比如:使用java打开一个文件,实际上是java调用了C,C调用了windows底层的API,如果不手动将资源关闭,C语言必须手动回收内存,这就导致了有java引起的内存泄漏. 2.1+N问题 (1)使用@ManyToOne的时候,默认FetchType=EAGER,此时会自动取出One这一方的信息. (

8.Hibernate性能优化

性能优化 1.注意session.clear() 的运用,尤其在不断分页的时候 a) 在一个大集合中进行遍历,遍历msg,取出其中额含有敏感字样的对象 b) 另外一种形式的内存泄漏( //面试题:Java有内存泄漏吗?语法级别没有,但是可由java引起,例如:连接池不关闭,或io读取后不关闭) 2.1+N 问题(典型的面试题) 举例:当存在多对一关系时,多的一方默认是可以取出一的一方的 @ManyToOne 中 默认为fetch=FetchType.Eager 当load多的一方时,也会加载一的

下载性能优化---断点缓存

#import <UIKit/UIKit.h> @interface ViewController :UIViewController<NSURLConnectionDataDelegate> { BOOL isDownLoad;//标识是否正在下载 double receiveTotal;//已经接收数据总的大小 } @property (nonatomic,assign)double totalLength;//下载数据的总的大小 @property (nonatomic,st

Hibernate 性能优化之查询缓存

查询缓存是建立在二级缓存基础之上的,所以与二级缓存特性相似,是共享的,适合修改不是很频繁的数据 查询缓存不是默认开启的,需要设置      1.在cfg文件中配置 <property name="cache.use_query_cache">true</property> 2.在代码中进行设置 query.setCacheable(true);

Hibernate性能优化之SessionFactory重用

Hibernate优化的方式有很多,如缓存.延迟加载以及与SQL合理映射,通过对SessionFactory使用的优化是最基础的. SessionFactory负责创建Session实例,Session相当于JDBC里的Connection. SessionFactory的创建 SessionFactory是通过Configuration来构建的,Configuration会根据配置信息来构建SessionFactory. SessionFactory中保存了对应当前数据库配置的所有映射关系,还

iOS开发UI篇—UITableviewcell的性能优化和缓存机制

iOS开发UI篇—UITableviewcell的性能问题 一.UITableviewcell的一些介绍 UITableView的每一行都是一个UITableViewCell,通过dataSource的 tableView:cellForRowAtIndexPath:方法来初始化每?行 UITableViewCell内部有个默认的子视图:contentView,contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图 辅助指示视图的作?是显示一个表示动作的

第七章 Hibernate性能优化

一对一关联 实体类关系 一对多 多对多 一对一 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保存员工档案的同时分配给员工一个账号. (2)加载员工档案的同时加载账号信息. 1.按照外键映射 步骤一:创建实体类Users1和Resume1 Users1创建如下: public class Users1 { private Integer userid; pr