一.基本概念
po是持久化对象,它只是对物理数据实体的一种对象表示。
vo是值对象,准确地讲,它是业务对象。
formbean只是html表单的封装,起到在控制层弱化的request中存储数据的作用,将request的get方法转
变为对象的存取值。
二.缓存策略比较
jive
1.jive的缓存策略的过程描述:
(1)条件查询的时候,jive用 select id from table_name where …. (只选择id字段)这样的sql语句查询数据库,来获得一个id列表。
(2) jive根据id列表中的每个id,首先查看缓存中是否存在对应id的数据对象:如果存在,那么直接取出,加入到 结果列表中;如果不存在,那么通过一条select * from table_name where id = {id value} 这样的sql查询数据库,取出对应的数据对象,放入到结果列表,并把这个数据对象按照id放入到缓存中。
(3) id查询的时候,jive执行类似第(2)步的过程,先从缓存中查找该id,查不到,再查询数据库,然后把结果放入到缓存。
(4) 删除、更新、增加数据的时候,同时更新缓存。
2.jive缓存策略的优点:
(1) id查询的时候,如果该id已经存在于缓存中,那么可以直接取出。节省了一条数据库查询。
(2) 当多次条件查询的结果集相交的情况下,交集里面的数据对象不用重复从数据库整个获取,直接从缓存中获取即可。比如,第一次查询的id列表为{1, 2},然后根据id列表的id从数据库中一个一个取出数据对象,结果集为{a(id = 1), b(id = 2)}。下一次查询的id列表为{2, 3},由于id = 2的数据对象已经存在于缓存中,那么只要从数据库中取出id = 3的数据对象即可。
3.jive缓存策略的缺点:
(1) 在根据条件查找数据对象列表的过程中,dao的第(1)步用来获得id列表的那一次数据库查询,是必不可少的。
(2) 如果第(1)步返回的id列表中有n个id,在最坏的命中率(缓存中一个对应id都没有)情况下,jive还要再查询n次数据库。最坏情况下,共需要n + 1数据库查询。
hibernate
hibernate用session类包装了数据库连接从打开到关闭的过程。session内部维护一个数据对象集合,包括了本session内选取的、操作的数据对象。这称为session内部缓存,是hibernate的第一级最快缓存,属于hibernate的既定行为,不需要进行配置。
session的生命期很短,存在于session内部的第一级最快缓存的生命期当然也很短,命中率自然也很低。当然,这个session内部缓存的主要作用是保持session内部数据状态同步。如果需要跨session的命中率较高的全局缓存,那么必须对hibernate进行二级缓存配置。一般来说,同样数据类型(class)的数据对象,共用一个二级缓存(或其中的同一块)。
1.hibernate二级缓存策略的过程描述:
(1)条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的sql语句查询数据库,一次获得所有的数据对象。
(2) 把获得的所有数据对象根据id放入到第二级缓存中。
(3) 当hibernate根据id访问数据对象的时候,首先从session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照id放入到缓存。
(4) 删除、更新、增加数据的时候,同时更新缓存。
2.hibernate二级缓存策略的优点:
(1) 具有jive缓存策略同样的第(1)条优点:id查询的时候,如果该id已经存在于缓存中,那么可以直接取出。节省了一条数据库查询。
(2) 不具有jive缓存策略的第(2)条缺点,即hibernate不会有最坏情况下的 n + 1次数据库查询。
3.hibernate二级缓存策略的缺点:
(1) 同jive缓存策略的第(1)条缺点一样,条件查询的时候,第(1)步的数据库查询语句是不可少的。而且hibernate选择所有的字段,比只选择id字段花费的时间和空间都多。
(2) 不具备jive缓存策略的第(2)条优点。条件查询的时候,必须把数据库对象从数据库中整个取出,即使该数据库的id已经存在于缓存中。
hibernate的query缓存策略
可以看到,jive缓存和hibernate的二级缓存策略,都只是针对于id查询的缓存策略,对于条件查询则毫无作用。(尽管jive缓存的第(2)个优点,能够避免重复从数据库获取同一个id对应的数据对象,但select id from …这条数据库查询是每次条件查询都必不可少的)。
为此,hibernate提供了针对条件查询的query缓存。
1.hibernate的query缓存策略的过程描述:
(1) 条件查询的请求一般都包括如下信息:sql, sql需要的参数,记录范围(起始位置rowstart,最大记录个数maxrows),等。
(2) hibernate首先根据这些信息组成一个query key,根据这个query key到query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据query key放入到query缓存中。
(3) query key中的sql涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的query key都要从缓存中清空。
2.hibernate的query缓存策略的优点
(1) 条件查询的时候,如果query key已经存在于缓存,那么不需要再查询数据库。命中的情况下,一次数据库查询也不需要。
3.hibernate的query缓存策略的缺点
(1) 条件查询涉及到的表中,如果有任何一条记录增加、删除、或改变,那么缓存中所有和该表相关的query key都会失效。
比如,有这样几组query key,它们的sql里面都包括table1。
sql = select * from table1 where c1 = ? …., parameter = 1, rowstart = 11, maxrows = 20.
sql = select * from table1 where c1 = ? …., parameter = 1, rowstart = 21, maxrows = 20.
sql = select * from table1 where c1 = ? ….., parameter = 2, rowstart = 11, maxrows = 20.
sql = select * from table1 where c1 = ? ….., parameter = 2, rowstart = 11, maxrows = 20.
sql = select * from table1 where c2 = ? …., parameter = ‘abc’, rowstart = 11, maxrows = 20.
当table1的任何数据对象(任何字段)改变、增加、删除的时候,这些query key对应的结果集都不能保证没有发生变化。很难做到根据数据对象的改动精确判断哪些query key对应的结果集受到影响。最简单的实现方法,就是清空所有sql包含table1的query key。
(2) query缓存中,query key对应的是数据对象列表,假如不同的query key对应的数据对象列表有交集,那么,交集部分的数据对象就是重复存储的。
比如,query key 1对应的数据对象列表为{a(id = 1), b(id = 2)},query key 2对应的数据对象列表为{a(id = 1), c(id = 3)},这个a就在两个list同时存在了两份。
4.二级缓存和query缓存同步的困惑
假如,query缓存中,一个query key对应的结果列表为{a (id = 1) , b (id = 2), c (id = 3)}; 二级缓存里面有也id = 1对应的数据对象a。
这两个数据对象a之间是什么关系?能够保持状态同步吗?我阅读hibernate的相关源码,没有发现两个缓存之间的这种同步关系。或者两者之间毫无关系。就像我上面所说的,只要表数据发生变化,相关的query key都要被清空。所以不用考虑同步问题。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器