前言
- Hibernate是一套ORM框架,在这我就不多说了,以前我们用JDBC编程的方式直接访问数据库,但是JDBC相对于Hibernate来说,JDBC没有做数据缓存,也没有做到面向对象得编程。JDBC在进行单表的增删改时,确实不如Hibernate开发效率高,但是使用JDBC后,程序的运行效率要比Hibernate高,毕竟JDBC面对的是直接的Sql语句,而Hibernate还要将操作翻译成Sql语句再执行。好了,简单的将Hibernate于JDBC做了一个对比,下面我用一个小Demo来展示一下Hibernate二级缓存的使用。
Hibernate二级缓存的实用场合
1、数据基本上不发生什么变化。
2、该数据保密性不是很强。
Demo说明
- 在数据库中创建一个权限表,表里面就有两个字段,一个是id,一个是name,利用Hibernate的二级缓存机制,先将表中的一些数据查询出来放入二级缓存中,这时候查询语句就会生成相应的Sql语句,当进行第二次查询的时候,这时候的Hibernate生成的Sql语句就会发生变化,Sql变少了,因为查询的一部分数据不是通过数据库查询的,而是通过二级缓存查询的。
监听器类
public class PrivilegeListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("这是监听器初始化-------------------------------------------------");
PrivilegeDao privilegeDao=new PrivilegeDao();
privilegeDao.putPrivilegesToSecondLevel();
}
Web.xml
<listener>
<listener-class>com.dmsd.sessionfactory.listener.PrivilegeListener</listener-class>
</listener>
3.配置hibernate.cfg.xml
<!-- 二级缓存的供应商-->
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!--
开启二级缓存
-->
<property name="cache.use_second_level_cache">true</property>
<!--
<class-cache usage="read-only" class=""/>
-->
<!--
根据持久化类生成表的策略
validate 通过映射文件检查持久化类与表的匹配
update 每次hibernate启动的时候,检查表是否存在,如果不存在,则创建,如果存在,则什么都不做了
create 每一次hibernate启动的时候,根据持久化类和映射文件生成表
create-drop
-->
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="format_sql">true</property>
<!--
开启二级缓存的统计机制
-->
<property name="generate_statistics">true</property>
<mapping resource="com/dmsd/sessionfactory/domain/Privilege.xml" />
4、TestServlet
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Session session =HibernateUtils.sessionFactory.openSession();
Iterator<Privilege> iterator=session.createQuery("from Privilege").iterate();
while (iterator.hasNext()) {
Privilege privilege = (Privilege) iterator.next();
System.out.println(privilege.getName());
System.out.println(privilege.getPid());
}
5、Privilege实体类
public class Privilege implements Serializable {
private Long pid;
private String name;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
6、 Privilege.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.dmsd.sessionfactory.domain.Privilege">
<cache usage="read-only"/>
<id name="pid" length="5">
<generator class="increment"></generator>
</id>
<property name="name" length="20"></property>
</class>
</hibernate-mapping>
7、PrivilegeDao类
public class PrivilegeDao {
/*
* 在监听器启动的时候,把所有的权限放到二级缓存中
*/
public void putPrivilegesToSecondLevel(){
Session session=HibernateUtils.sessionFactory.openSession();
//list方法只管将对象放入二级缓存,不能取
session.createQuery("from Privilege").list();//把所有的privilege对象放入到二级缓存中
}
}
8、效果图
8.1、程序启动,监听器负责将Privilege表中所有的数据搜出来,放入二级缓存。
8.2、当我们再次请求TestServlet的时候,我们输出pid和name,我们会发现,SQL语句只查询了pid,而name的值是从二级缓存中获取的。如下图所示
小结
- 总体的效果是,当我们启动Tomcat的时候,监听器会自动启动,调用PrivilegeDao查询数据库,然后将数据放入二级缓存,当我们第一次请求TestServlet时候,我们就会将非主键的字段值从二级缓存中拿出来。