Hibernate之Hibernate+EHCache配置二级缓存实战

来源:互联网 发布:cad迷你看图mac版免费 编辑:程序博客网 时间:2024/05/17 06:20

准备条件:

我使用的版本是:hibernate-release-4.2.2.Final

Hibernate必须的jar包:hibernate-4.2.2\hibernate-release-4.2.2.Final\lib\required下的所有包

数据库驱动jar包:我用的mysql库,mysql-connector-java-5.1.21.jar

EHCache相关jar包:hibernate-4.2.2\hibernate-release-4.2.2.Final\lib\optional\ehcache下的所有包

EHCache配置文件:hibernate-4.2.2\hibernate-release-4.2.2.Final\project\etc下的ehcache.xml文件

下面开始实战:

一.代码结构

二,实体类,自己建一个实体类就行,我的做别的测试多了个实体类

Customer.java:

package com.lanhuigu.hibernate.entity;import java.io.Serializable;import java.util.Date;import java.util.List;import com.sun.jmx.snmp.Timestamp;/** * 创建java持久化类,就是需要被持久化到数据库中的实体类  */public class Customer implements Serializable{private static final long serialVersionUID = 9026723017886524518L;private Long id;private String name;private String email;private String password;private int phone;private boolean married;private String address;private char sex;private String description;private byte[] image;private Date birthday;private Timestamp registeredTime;private Address homeAddress;private Address compAddress;private List<Order> orders;public Customer(){}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public int getPhone() {return phone;}public void setPhone(int phone) {this.phone = phone;}public boolean isMarried() {return married;}public void setMarried(boolean married) {this.married = married;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public char getSex() {return sex;}public void setSex(char sex) {this.sex = sex;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public byte[] getImage() {return image;}public void setImage(byte[] image) {this.image = image;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public Timestamp getRegisteredTime() {return registeredTime;}public void setRegisteredTime(Timestamp registeredTime) {this.registeredTime = registeredTime;}public Address getHomeAddress() {return homeAddress;}public void setHomeAddress(Address homeAddress) {this.homeAddress = homeAddress;}public Address getCompAddress() {return compAddress;}public void setCompAddress(Address compAddress) {this.compAddress = compAddress;}public List<Order> getOrders() {return orders;}public void setOrders(List<Order> orders) {this.orders = orders;}}
Address.java:

package com.lanhuigu.hibernate.entity;import java.io.Serializable;/** * 地址实体类 */public class Address implements Serializable{private static final long serialVersionUID = -1450327776636898762L;private String province;private String city;private String street;private Short zipcode;private Customer customer;public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getStreet() {return street;}public void setStreet(String street) {this.street = street;}public Short getZipcode() {return zipcode;}public void setZipcode(Short zipcode) {this.zipcode = zipcode;}public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}}

三,对象-关系映射文件配置

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping  package="com.lanhuigu.hibernate.entity" ><class name="Customer" table="CUSTOMERS" select-before-update="true" lazy="false" batch-size="3"><!-- 读写并发策略 --><!-- <cache usage="read-write"/> --><!-- 设置主键 --><id name="id" column="ID" type="long"><!-- 主键生成方式--><generator class="increment"/></id><!-- 基本属性,基本属性必须设置在主键之口--><property name="name" column="NAME" type="string" length="25" not-null="true" access="property"/><property name="email" column="EMAIL" type="string" not-null="true" /><property name="password" column="PASSWORD" type="string" not-null="true" /><property name="phone" column="PHONE" type="int" /><property name="address" column="ADDRESS" type="string" /><property name="sex" column="SEX" type="character" /><property name="married" column="IS_MARRIED" type="boolean" /><property name="description" column="DESCRIPTION" type="text" /><property name="image" column="IMAGE" type="binary" /><property name="birthday" column="BIRTHDAY" type="date" /><property name="registeredTime" column="REGISTERED_TIME" type="timestamp" insert="false" update="false"/><!-- 部分类 --><component name="homeAddress" class="Address"><parent name="customer"/><property name="province" type="string" column="HOME_PROVINCE"></property><property name="city" type="string" column="HOME_CITY"></property><property name="street" type="string" column="HOME_STREET"></property><property name="zipcode" type="short" column="HOME_ZIPCODE"></property></component><component name="compAddress" class="Address"><parent name="customer"/><property name="province" type="string" column="COMP_PROVINCE"></property><property name="city" type="string" column="COMP_CITY"></property><property name="street" type="string" column="COMP_STREET"></property><property name="zipcode" type="short" column="COMP_ZIPCODE"></property></component></class></hibernate-mapping>

四,hibernate.cfg.xml配置

<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><!-- hibernate-configuration为hibernate配置头文件 --><hibernate-configuration><!-- 配置session-factory,     SessionFactory是Hibernate的工厂类,              该类负责Hibernate的配置和Hiberante的Session接口中save(),update(),delete(),load(),find()的操作  --><session-factory><!-- 1.数据库连接配置 --><!-- 数据库连接url --><property name="connection.url">jdbc:mysql://192.168.200.12:3306/hbtest</property><!-- 数据库连接用户名 --><property name="connection.username">root</property><!-- 数据库连接口令 --><property name="connection.password">root123</property><!-- 数据库连接驱动 --><property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 数据库方言 --><property name="dialect">org.hibernate.dialect.MySQLDialect</property><!-- 数据库连接池大小配置 --><property name="connection.pool_size">1</property><!-- 配置二级缓存 --><property name="hibernate.cache.use_second_level_cache">true</property><property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property><!-- 开启查询缓存 --><property name="hibernate.cache.use_query_cache">true</property><!-- 一次读的数据库记录数 --><property name="jdbc.fetch_size">50</property><!-- 设定对数据库进行批量删除条数 --><property name="jdbc.batch_size">30</property><!-- 2.是否打印sql配置 --><property name="show_sql">true</property><!-- 3.对象-映射关系文件的位置 --><mapping resource="com/lanhuigu/hibernate/entity/Customer.hbm.xml" /><!-- 指定二级缓存类 ,以及并发访问策略 --><class-cache usage="read-write" class="com.lanhuigu.hibernate.entity.Customer"/></session-factory></hibernate-configuration>

五,ehcache.xml配置

<?xml version="1.0" encoding="UTF-8"?>  <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"      updateCheck="false">    <!-- 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="D:\\mytemp"/>    <!--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="com.lanhuigu.hibernate.entity.Customer"        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.lanhuigu.hibernate.test;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import com.lanhuigu.hibernate.entity.Customer;public class TestHibernate {public static void main(String[] args) {Configuration configuration = new Configuration().configure();SessionFactory sessionFactory = configuration.buildSessionFactory();Session session1 = sessionFactory.openSession();Transaction tr1 = session1.beginTransaction();//加载一个OID为1的对象Customer customer1 = (Customer) session1.get(Customer.class, new Long(1));System.out.println("session1"+customer1.getName());tr1.commit();session1.close();//加载同样OID为2的对象Session session2 = sessionFactory.openSession();Transaction tr2 = session2.beginTransaction();Customer customer2 = (Customer) session2.get(Customer.class, new Long(1));System.out.println("session2"+customer2.getName());tr2.commit();session2.close();}}
控制台输出:

Hibernate:     select        customer0_.ID as ID1_0_0_,        customer0_.NAME as NAME2_0_0_,        customer0_.EMAIL as EMAIL3_0_0_,        customer0_.PASSWORD as PASSWORD4_0_0_,        customer0_.PHONE as PHONE5_0_0_,        customer0_.ADDRESS as ADDRESS6_0_0_,        customer0_.SEX as SEX7_0_0_,        customer0_.IS_MARRIED as IS8_0_0_,        customer0_.DESCRIPTION as DESCRIPT9_0_0_,        customer0_.IMAGE as IMAGE10_0_0_,        customer0_.BIRTHDAY as BIRTHDA11_0_0_,        customer0_.REGISTERED_TIME as REGISTE12_0_0_,        customer0_.HOME_PROVINCE as HOME13_0_0_,        customer0_.HOME_CITY as HOME14_0_0_,        customer0_.HOME_STREET as HOME15_0_0_,        customer0_.HOME_ZIPCODE as HOME16_0_0_,        customer0_.COMP_PROVINCE as COMP17_0_0_,        customer0_.COMP_CITY as COMP18_0_0_,        customer0_.COMP_STREET as COMP19_0_0_,        customer0_.COMP_ZIPCODE as COMP20_0_0_     from        CUSTOMERS customer0_     where        customer0_.ID=?session1testsession2test

七,总结

EHCache配置二级缓存步骤:

(1)ehcache.xml文件放在src下,写入目录,过期数据处理策略等配置

(2)hibernate.cfg.xml中配置二级缓存以及查询缓存

<!-- 配置二级缓存 -->

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

<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

如果hibernate.cache.use_second_level_cache为true表示使用二级缓存,为false关闭二级缓存,当我改为false时,我们控制台输出结果为:

Hibernate:     select        customer0_.ID as ID1_0_0_,        customer0_.NAME as NAME2_0_0_,        customer0_.EMAIL as EMAIL3_0_0_,        customer0_.PASSWORD as PASSWORD4_0_0_,        customer0_.PHONE as PHONE5_0_0_,        customer0_.ADDRESS as ADDRESS6_0_0_,        customer0_.SEX as SEX7_0_0_,        customer0_.IS_MARRIED as IS8_0_0_,        customer0_.DESCRIPTION as DESCRIPT9_0_0_,        customer0_.IMAGE as IMAGE10_0_0_,        customer0_.BIRTHDAY as BIRTHDA11_0_0_,        customer0_.REGISTERED_TIME as REGISTE12_0_0_,        customer0_.HOME_PROVINCE as HOME13_0_0_,        customer0_.HOME_CITY as HOME14_0_0_,        customer0_.HOME_STREET as HOME15_0_0_,        customer0_.HOME_ZIPCODE as HOME16_0_0_,        customer0_.COMP_PROVINCE as COMP17_0_0_,        customer0_.COMP_CITY as COMP18_0_0_,        customer0_.COMP_STREET as COMP19_0_0_,        customer0_.COMP_ZIPCODE as COMP20_0_0_     from        CUSTOMERS customer0_     where        customer0_.ID=?session1testHibernate:     select        customer0_.ID as ID1_0_0_,        customer0_.NAME as NAME2_0_0_,        customer0_.EMAIL as EMAIL3_0_0_,        customer0_.PASSWORD as PASSWORD4_0_0_,        customer0_.PHONE as PHONE5_0_0_,        customer0_.ADDRESS as ADDRESS6_0_0_,        customer0_.SEX as SEX7_0_0_,        customer0_.IS_MARRIED as IS8_0_0_,        customer0_.DESCRIPTION as DESCRIPT9_0_0_,        customer0_.IMAGE as IMAGE10_0_0_,        customer0_.BIRTHDAY as BIRTHDA11_0_0_,        customer0_.REGISTERED_TIME as REGISTE12_0_0_,        customer0_.HOME_PROVINCE as HOME13_0_0_,        customer0_.HOME_CITY as HOME14_0_0_,        customer0_.HOME_STREET as HOME15_0_0_,        customer0_.HOME_ZIPCODE as HOME16_0_0_,        customer0_.COMP_PROVINCE as COMP17_0_0_,        customer0_.COMP_CITY as COMP18_0_0_,        customer0_.COMP_STREET as COMP19_0_0_,        customer0_.COMP_ZIPCODE as COMP20_0_0_     from        CUSTOMERS customer0_     where        customer0_.ID=?session2test
从结果可以看出,执行了两遍sql,第二次查询时,从一级缓存中没有找到对象,去二级缓存中找,还没找到,最后只能查询数据库,所以有两条查询sql.

(3)指定二级缓存类有两种配置:

       第一种是在Customer.hbm.xml配置文件中指定并发访问策略,即为我注释掉的代码:

       <cache usage="read-write"/>

       第二种在hibernate.cfg.xml配置文件中指定缓存类和并发访问策略:

       <class-cache usage="read-write" class="com.lanhuigu.hibernate.entity.Customer"/>

1 0
原创粉丝点击