ZC又找了个测试,我也尝试了一下。他的标题是男怕入错行,女怕嫁错郎,这个……郎怎么测试呀? http://quizfarm.com/test.php?q_id=119158 You scored as Mathematics. You should be a Math major! Like Pythagoras, you are analytical, rational, and when are always ready to tackle the problem head-on!
What is your Perfect Major? (PLEASE RATE ME!!<3) |
Author: tin
[ZT]傻子
嘿!请不要突击享受!
体验经济与牙膏
Webwork 2.2的Action是否使用Spring的prototype获取的性能对比
本文在060216进行了修改,因为发现了测试中的错误!注意5.5和7的内容。
1、引子:
其实是ajoo的这篇“Nuts和Spring 1.2.6 效率对比”和“IoC容器的prototype性能测试 ”,他们在Javaeye上详细讨论了Spring的prototype的缺陷。
Spring的prototype指的就是singleton="false"的bean,具体可以看Spring参考手册“3.2.5. To singleton or not to singleton”介绍。
2、Webwork 2.2的Spring结合问题:
Webwork 2.2已经抛弃自己的IoC,默认使用Spring的IoC。
上在OpenSymphony的官方Wiki,和jscud后来的几篇文章中没有特别提出prototype的问题。但是托他们的福,我们已经顺利的使Spring和Webwork良好的协同工作起来了。
可是而后的一些问题却把prototype的问题搞得神秘起来……
ajoo的测试中指出Spring的prototype性能很差,参见后面参考中的一篇文章和Javaeye的讨论。
而后又发现robbin在Javaeye的Wiki上面的“集成webwork和spring”中的最后注到:
“注意:目前并不推荐使用Spring来管理Webwork Action,因为对于prototype类型的bean来说,Spring创建bean和调用bean的效率是很低的!更进一步信息请看IoC容器的prototype性能测试”
这就使我们常用的Spring+Webwork2.2的连接中使用的prototype的问题被摆出来了。
我现在的项目中使用了prototype的方式将Webwork Action使用Spring进行显示的装配,我担心这个性能的问题会很严重,所以今天花了半天时间具体测试了一下。
3、Prototype VS autowire的解释:
我不知道怎么命名两种方式好,所以这里先做个解释:
spring的配置中Action会有个id,如:
<property name="someDAO">
<ref bean="someDAO" />
</property>
</bean>
我指的prototype方式就是在xwork中这样配置:
而autowire方式就是指在xwork中这样配置:
看起来相同,但其实不同(我以前发过帖子,其中说这几种方法都可,但是其实它们的机制是不同的。
4、Portotye和autowire在XWork的SpringObjectFactory中是如何运作的:
我们先看一下代码,就能明白两者的区别了:
try {
return appContext.getBean(beanName);
} catch (NoSuchBeanDefinitionException e) {
Class beanClazz = getClassInstance(beanName);
return buildBean(beanClazz, extraContext);
}
}
public Object buildBean(Class clazz, Map extraContext) throws Exception {
Object bean;
try {
bean = autoWiringFactory.autowire(clazz, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
} catch (UnsatisfiedDependencyException e) {
// Fall back
bean = super.buildBean(clazz, extraContext);
}
bean = autoWiringFactory.applyBeanPostProcessorsBeforeInitialization(bean, bean.getClass().getName());
// We don’t need to call the init-method since one won’t be registered.
bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean, bean.getClass().getName());
return autoWireBean(bean, autoWiringFactory);
}
public Object autoWireBean(Object bean) {
return autoWireBean(bean, autoWiringFactory);
}
如果按照autowire配置会使用第二个buildBean方法,而prototype会使用第一个buildBean方法。
5、我的测试,首先测试SpringObjectFactory的理论效率:
protected FileSystemXmlApplicationContext appContext;
protected SpringObjectFactory sof = null;
protected Map map = null;
final String[] paths = {
"WebRoot/WEB-INF/applicationContext.xml",
"WebRoot/WEB-INF/spring-daos.xml",
"WebRoot/WEB-INF/spring-actions.xml"
};
protected void setUp() throws Exception {
super.setUp();
appContext = new FileSystemXmlApplicationContext(paths);
sof = new SpringObjectFactory();
sof.setApplicationContext(appContext);
sof.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
map = new HashMap();
}
public void testSpringObjectFacotyWithAutowire() {
long begin = System.currentTimeMillis();
try {
for (int i = 0; i <
sof.buildBean("com.wqh.action.XinfangNewsAction", map);
}
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("**************************Used time:" +
(begin – end));
}
public void testSpringObjectFacotyWithPrototype() {
long begin = System.currentTimeMillis();
try {
for (int i = 0; i < 100000; i++) {
sof.buildBean("xinfangNewsAction", map);
}
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("**************************Used time:" +
(begin – end));
}
public void testSpringObjectFacotyWithSpringProxyableObjectFactory() {
sof = new SpringProxyableObjectFactory();
sof.setApplicationContext(appContext);
sof.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
long begin = System.currentTimeMillis();
try {
for (int i = 0; i < 100000; i++) {
sof.buildBean("com.wqh.action.XinfangNewsAction", map);
}
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("**************************Used time:" +
(begin – end));
}
}
重要的是测试结果:
**************************Used time:-16875
**************************Used time:-80500
**************************Used time:-12703(使用SpringProxyableObjectFactory()这个实现)
prototype是autowire运行时间的4.77X倍,十分可观。
5.5 巨大的反差,原来是我搞错了配置,发现了幕后黑手:
第二天,我又重新运行了5里面的测试。但是结果令人吃惊,运行了十多次,结果于昨天反差巨大,prototype方式获得的bean反而性能最快!
摘要两次测量结果
**************************Autowire Used time:-17578
**************************Prototype Used time:-7609
**************************Proxy Used time:-13063
———————————————–
**************************Autowire Used time:-17047
**************************Prototype Used time:-7609
**************************Proxy Used time:-12797
这是为什么呢?我百思不得其解,问题出在哪里呢?后来经过跟踪svn里面的提交纪录。我发现,我在昨天测试以后,把spring配置文件中的<beans default-autowire="autodetect">变成了<beans>。也就是没有打开自动检测的autowire!
而后就真相大白了。我有配置上default-autowire="autodetect"进行测试,结果:
**************************Autowire Used time:-16937
**************************Prototype Used time:-79750
**************************Proxy Used time:-12578
这和昨天的测试结果完全相同。也就是说我昨天写的4.77x的结果其实没有实际意义。倒是说明了Spring和Webwork集成的文章上面说的default-autowire="autodetect"是很坏的实践,即失去了name的灵活性也带来了巨大的性能损失。
而如果使用默认的Spring autowire配置下,prototype的性能已经很好了,实际上它工作起来应该是最快的。
6、在实际的Web项目中的性能对比:
我使用了我的一个小项目,就是反复调用一个action获取一个页面,其中有一个DAO注入。使用了JMeter进行了一个测试:2个线程,间隔0.5秒,循环50次,对比“据和报告中的”Throughput,单位/sec。
使用autowire方式:Avg. 148.34(吞吐量越高越好)
使用prototype方式:Avg. 138.5
也就是说在实际应用中两者也是有性能差距的,后者大约是前者性能的93%。
具体代码我不放出了,因为意义不大,大家也可以自己动手试验一下。
补充说明:
首先注意这个测试是在default-autowire="autodetect"下进行的。
测试的这个Action其实是一个空Action,它没有调用service和DAO,只是直接return SUCCESS,然后dispatcher到一个静态内容的jsp页面。我的本意是为了能够在获取Action占据的时间比例比较高的情况下分析性能区别。但是实际上却间接的夸大了在真正的实际应用中的性能差距。实际应用中如果加上service、DAO等逻辑的执行时间、模板View的渲染时间还有广域网上的网络传输时间,那么获取Action实例的时间差距可能就微乎其微了。
7、后续:
经过今天的思考,可以说完全改变了想法,重新汇总一下:
a、在不使用default-autowire="autodetect"时,Webwork 2.2的xwork中的action class使用spring的bean id配置的理论性能最好。而且,我认为如果不是为了追求配置上的简单,严重推荐关闭spring的default-autowire。
b、在使用default-autowire="autodetect、name、class"时,需要考虑你的需求。如果不使用Spring AOP提供的功能则在Webwork 2.2的xwork中的action class使用class全名比较好。如果使用Spring AOP的功能,则还是使用bean id。
c、在Spring中是否使用default-autowire是个需要慎重考虑的问题。autowire如果打开,命名会受到限制(class则更不推荐,受限更大,参考相关文档),它所带来的配置简化我认为只算是小小的语法糖果,背后却是吃掉它所埋下的隐患。
d、6中的测试还是有些说明意义的。7%的性能差距是在使用了default-autowire的方式下得出的,其中测试的那个action其实没有执行什么逻辑,而是一个直接dispatcher到success view的action,如果有商业逻辑包装,则性能差据估计会更小。因为实际上Action的执行过程、service、DAO等逻辑的执行过程和模板View的渲染过程(网络延迟)才是耗时大户。所以,关于性能应该下的结论是,prototype与否,在实际应用中性能差距是很小的,基本可以忽略不计。我们讨论的更多是编码的更好的实践。
e、autowire不使用Spring AOP相对还是trade off,因为虽然配置简单一点,但是对于使用Spring的声明性事务等内容会带来麻烦。虽然XML不那么好,但是显示配置带来的好处还是很多的。
f、谢谢robbin的提示。关于事务我也是无奈,放弃Action事务后难道给DAO多封装一层事务?如何没有事务依然使用HibernateDAOSurpport?Acegi的确不适合Web,使用WW的Inteceptor可以实现更舒适的解决方案。
g、SpringProxyableObjectFactory的问题……使用上难道只能改代码?找了半天没有这个东西的介绍。看来还是需要看看代码。不过发现现在Webwork和Xwork的代码又变动了很多……
h、我的测试是在Webwork2.2+Spring 1.2.6环境下测试的
8、参考资源:
Nuts和Spring 1.2.6 效率对比
http://www.javaeye.com/pages/viewpage.action?pageId=786
IoC容器的prototype性能测试
http://forum.javaeye.com/viewtopic.php?t=17622&postdays=0&postorder=asc&start=0
JavaEye的Wiki:集成webwork和spring
http://www.javaeye.com/pages/viewpage.action?pageId=860
WebWork – Spring官方Wiki
http://www.opensymphony.com/webwork/wikidocs/Spring.html
webwork2 + spring 结合的几种方法的小结
http://forum.javaeye.com/viewtopic.php?t=9990
WebWork2.2中结合Spring:"新的方式"
http://www.blogjava.net/scud/archive/2005/09/21/13667.html
我为什么不推荐对Action进行事务控制
http://www.javaeye.com/pages/viewpage.action?pageId=1205
我为什么不推荐使用Acegi
http://www.javaeye.com/pages/viewpage.action?pageId=1199
关于存储过程和直接执行SQL对比
需要注意以下几点:
1、从数据库角度,存储过程总是要比它所对应的纯SQL要慢。
2、存储过程目的在于简化特别复杂的SQL复合应用的场景。
3、但是对于一个拥有多条SQL的存储过程来说,它可以提升效率。因为减少了SQL传输的网络延迟。所以说SQL复杂时,存储过程可以增加实际的运行效率。注意对比第1条,第一条是对应服务器调用,这条对应实际的网络环境。
4、还有就是存储过程很容易减少多条SQL之间数据传递的麻烦(有可能带来没有实际意义的中间变量),可以在服务器端把它们隐藏。
所以我想应该考虑这几点来选择存储过程:
1、拥有复杂的数据操作,需要SQL复合。
2、中间传递的临时数据过多或者过大的时候。
// CallableStatement cstmt = conn.prepareCall("begin ? := md5( ? ); end;"); // oracle syntax
cstmt.registerOutParameter(1, Types.VARCHAR); // set out parameters
cstmt.setString(2, "idea"); // set in parameters
cstmt.execute();
String md5Str = cstmt.getString(1); // Getting OUT Parameter Values
cstmt.close();
对不起,我的Angel
Mysql5的存储过程的权限Bug
java.sql.SQLException: Driver requires declaration of procedure to either contain a ‘\nbegin’ or ‘\n’ to follow argument declaration, or SELECT privilege on mysql.proc to parse column types.
at com.mysql.jdbc.DatabaseMetaData.getCallStmtParameterTypes(DatabaseMetaData.java:6953)
at com.mysql.jdbc.DatabaseMetaData.getProcedureColumns(DatabaseMetaData.java:2721)
at com.mysql.jdbc.CallableStatement.determineParameterTypes(CallableStatement.java:1048)
at com.mysql.jdbc.CallableStatement.<init>(CallableStatement.java:83)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:1255)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:1232)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.mchange.v2.c3p0.stmt.GooGooStatementCache$2.run(GooGooStatementCache.java:333)
at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:354)
仔细思考,换用了root登陆就可以了。感觉明显是权限privileges的问题。
所以其实应该是这个提示or SELECT privilege on mysql.proc to parse column types。
可是google不到这个问题所在,因为没有mysql.proc这个权限,但是有人说这是一个bug。
后来我发现,其实它是指mysql这个库的proc表的SELECT权限,添加上就工作正常了……
其实原因是这样的,原先测试时使用的xinfangweb的用户有两个,一个是localhost,另一个是%,前者的权限是全的,后者被限制了,哈哈。
HQL的中文问题小议
hql的String中包括了中文以后就会出错。
经过多次查询,转码(多字节、单字节)还是不能解决问题,说明某些环节压根就对多字节支持不正常。
后来经过多次试验,发现是hibernate3的hql语法解释器org.hibernate.hql.ast.ASTQueryTranslatorFactory出的问题,看到有人推荐用org.hibernate.hql.classic.ClassicQueryTranslatorFactory代替。
那当然是不可以的,否则相当于退回Hibernate2。
解决方法是不要在hql中写中文。
而是去使用?占位符和setParameters。
比如在Spring HibernateTemplate里面可以:
String hql = "select count(*) from Xinfangnews xfnews where xfnews.shifoufabu = 0 and (xfnews.title like ? or xfnews.content like ?)";
Object[] parameters = { "%" + keyWord + "%", "%" + keyWord + "%" };
getHibernateTemplate().find(hql, parameters);
如此可以运行了。
不过我走了点弯路:
本来写成"like ‘%?%’",然后往里面插keyWord,告诉我找不到?占位符。后来才想到”中的?已经不是占位符了。
然后就解决了:
所以就是说不能在HQL进行语法解析之前插入中文,而需要在解析之后插入。
还要注意,我试验了一下,在Mysql5中已经指定了使用UTF-8语言的时候,不必须在Hibernate连接的地方指明使用jdbc的encoding:
如很多人说需要这样配置:<prop key="hibernate.connection.url">jdbc:mysql://10.206.21.171:3306/xinfangweb?useUnicode=true&characterEncoding=GBK&autoReconnect=true</prop>
但实际上是用这样的配置:<prop key="hibernate.connection.url">jdbc:mysql://10.206.21.171:3306/xinfangweb</prop>
也是可以工作的,当然还是写上比较稳妥。
Generic Hibernate DAO试验
我们项目升级Weblogic 9.1,所以可以用JDK5的东西了。
先试验一下GenericHibernateDAO,作为一个DAO的基类,实现了一些简单的方法,方便子DAO封装。
使用方法类似:
public class HibernateTownDAO extends GenericHibernateDAO<Town>
implements ITownDAO{
{
public HibernateTownDAO() { super(Town.class); } }
}
这个东西基本上是从EclipseWork里面来的……
http://www.matrix.org.cn/thread.shtml?topicId=34892&forumId=26
http://www.javaworld.com.tw/roller/page/ingramchen?entry=2005_10_20_G…
还参考了limo的Blog和limo与徐x赠送的部分代码,thx
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import java.util.Iterator;
* @author TIN
* @comment
* @param <E>
*
* 范型的抽象HibernateDAO,继承于Spring提供的HibernateDaoSupport,该DAO封装了大部分的Domain对象访问方法。
* 使用范型的目的在于可以显示的规定传入/返回的类型。直接的目的在于减少使用DAO时的强行类型转换。
*
* TODO:getTopsByProperty(int, String)方法
* TODO:execute(HibernateCallback callback)方法?
* TODO:execute(HQL hql)方法?
* TODO:execute(SQL sql)方法?
* TODO:findByCriteria(Criterion… criterion)方法?
* TODO:getAOfflineListCopy(List list)方法?获取一个离线list,可以在部分地方获取session无关的List,避免使用OpenSessionInView
* TODO:String getPersistentObjectName()方法?
* TODO:使用变长参数修改一些传入Properties和Value的地方,扩展一些方法
* TODO:研究一下DetachedCreteria
*
*/
this.clazz = clazz;
}
* @see com.goldnet.dao.IDAO.IGenericDAO#saveOrUpdate(java.lang.Object,
* java.io.Serializable)
* @deprecated
*
* @param newObject 持久化的类
* @param id 持久化类的标识id
*
* 存储一个Entity,由于它的实现方式与HibernateDAO的saveOrUpdate雷同,都检测了id是否存在,但却多一个参数
* 所以暂时部推荐,但是该实现对saveOrUpdate机理表现比较清晰,所以没有删除
*/
public void saveOrUpdate(E newObject, Serializable id) {
if ((id != null) && !getHibernateTemplate().contains(id)) {
E dbObject = this.loadById(id);
BeanUtils.copyProperties(dbObject, newObject);
} catch (Exception e) {
logger.error(e, e);
}
}
logger.debug("[saveOrUpdate with id Parameter] Entity<"
+ this.clazz.getName() + ">.");
logger
.debug("this method is deprecated! Please use saveOrUpdate(Object) instead.");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#saveOrUpdate(java.lang.Object)
*
* @param newObject 持久化的类
*
* 持久化一个Entity,一般用在不知持久化的是VO或PO时
*/
public void saveOrUpdate(E newObject) {
if (logger.isDebugEnabled()) {
logger
.debug("[saveOrUpdate] Entity<" + this.clazz.getName()
+ ">.");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#save(java.lang.Object)
*
* @param object 持久化的类
*
* 持久化一个Entity,用在持久化PO时
*/
public void save(E object) {
if (logger.isDebugEnabled()) {
logger.debug("[save] Entity<" + this.clazz.getName() + ">.");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#update(java.lang.Object)
*
* @param object 持久化的类
*
* 持久化一个Entity,符合jsr-220规范,用在持久化一个VO的Entity(但是它已经在库中存在)时,持久化它并返回它的PO
*/
@SuppressWarnings("unchecked")
public E merge(E object) {
if (logger.isDebugEnabled()) {
logger.debug("[merge] Entity<" + this.clazz.getName() + ">.");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#isEntityWithPropertyOfValueExist(java.lang.String,
* java.lang.Object)
*
* @param propertyName Entity属性的名称
* @param value Entity属性的值
* @return
*
* 具有propertyName的Entity是否存在?如果true则存在,如果false则不存在。
*/
public boolean isEntityWithPropertyOfValueExist(String propertyName,
Object value) {
if (logger.isDebugEnabled()) {
logger.debug("[isEntityWithPropertyOfValueExist] Entity<"
+ this.clazz.getName() + ">, propName=" + propertyName
+ ", value=" + value + ".");
}
"from " + this.clazz.getName() + " table where table."
+ propertyName + "=?", value).size() > 0) {
return true;
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#isEntityIdExist(java.io.Serializable)
*
* @param id Entity的标识id
* @return
*
* 具有该id的Entity是否存在?如果true则存在,如果false则不存在。用来检测一个VO是否已经有对应的PO存在
*/
public boolean isEntityIdExist(Serializable id) {
if (logger.isDebugEnabled()) {
logger.debug("[isEntityIdExist] Entity<" + this.clazz.getName()
+ "> with id=" + id + ".");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#delete(java.lang.Object)
*
* @param object Entity对象
*
* 删除一个Entity
*/
public void delete(E object) {
if (logger.isDebugEnabled()) {
logger.debug("[delete] Entity<" + this.clazz.getName() + ">.");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#deleteById(java.io.Serializable)
*
* @param id Entity的标识id
*
* 根据Entity的标识id删除一个Entity
*/
public void deleteById(Serializable id) {
if (logger.isDebugEnabled()) {
logger.debug("[deleteById] Entity<" + this.clazz.getName()
+ "> with id=" + id + ".");
}
getHibernateTemplate().get(this.clazz, id));
}
* @see com.goldnet.dao.IDAO.IGenericDAO#deleteByProperty(java.lang.String,
* java.lang.Object)
*
* @param propertyName Entity属性的名称
* @param value Entity属性的值
*
* 删除一组具有相同propertyName属性值(value)的Entity,用来批量删除
*/
@SuppressWarnings("unchecked")
public void deleteByProperty(String propertyName, Object value) {
Iterator<E> result = listByProperty(propertyName, value).iterator();
delete(result.next());
}
logger.debug("[deleteByProperty] Entity<" + this.clazz.getName()
+ ">, propName=" + propertyName + ", value=" + value + ".");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#loadById(java.io.Serializable)
*
* @param id Entity的标识id
* @return
*
* 根据Entity的标识id获取一个Entity的PO
*/
@SuppressWarnings("unchecked")
public E loadById(Serializable id) {
if (logger.isDebugEnabled()) {
logger.debug("[loadById] Entity<" + this.clazz.getName() + ">, id="
+ id + ".");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#loadByProperty(java.lang.String,
* java.lang.Object)
*
* @param propertyName Entity属性的名称
* @param value Entity属性的值
* @return
*
* TODO:判断结果是否是unique?
* 获取一个具有相同propertyName属性值(value)的Entity,注意改属性必须是unique的,否则改方法将没有意义
*/
@SuppressWarnings("unchecked")
public E loadByProperty(String propertyName, Object value) {
Collection result = getHibernateTemplate().find(
"from " + this.clazz.getName() + " table where table."
+ propertyName + "=?", value);
Iterator<E> it = result.iterator();
logger.debug("[loadByProperty] Entity<" + this.clazz.getName()
+ ">, propName=" + propertyName + ", value=" + value + ".");
}
return it.next();
} else {
return null;
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#loadEntitySum()
*
* @return
*
* 获取一种Entity的总数
*/
public int loadEntitySum() {
if (logger.isDebugEnabled()) {
logger.debug("[loadEntitySum] Entity<" + this.clazz.getName()
+ ">.");
}
"select count(*) from " + this.clazz.getName()).iterator()
.next()).intValue();
}
* @see com.goldnet.dao.IDAO.IGenericDAO#loadEntitySumByProperty(java.lang.String,
* java.lang.Object)
*
* @param propertyName Entity属性的名称
* @param value Entity属性的值
* @return
*
* 获取一组具有相同propertyName属性值(value)的Entity的个数
*/
public int loadEntitySumByProperty(String propertyName, Object value) {
if (logger.isDebugEnabled()) {
logger.debug("[loadEntitySum] Entity<" + this.clazz.getName()
+ ">, propName=" + propertyName + ", value=" + value + ".");
}
"select count(*) from " + this.clazz.getName()
+ " table where table." + propertyName + "=?", value)
.iterator().next()).intValue();
}
* @see com.goldnet.dao.IDAO.IGenericDAO#loadLastEntity()
*
* @param orderByPropertyName 用来排序的属性的名称
* @return
*
* TODO:和获取Tops是否重复?
* 返回最后一个Entity,用来获取如最新加入的Entity这样的方法
* 注意改方法实际上返回的是降序排列的list中的第一个!
*/
@SuppressWarnings("unchecked")
public E loadLastEntity(final String orderByPropertyName) {
logger.debug("[listLastEntity] Entity<" + this.clazz.getName()
+ "> and orderByPropertyName=" + orderByPropertyName
+ ", Note:it’s DESC.");
}
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazz);
criteria.addOrder(Order.desc(orderByPropertyName));
releaseSession(session);
return criteria.list().iterator().next();
} catch (Exception e) {
logger
.warn("[listLastEntity] faild! the entity list is empty!");
}
}
});
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listAll()
*
* @return
*
* 获取所有的Entity的list
*/
@SuppressWarnings("unchecked")
public Collection<E> listAll() {
if (logger.isDebugEnabled()) {
logger.debug("[listAll] Entity<" + this.clazz.getName() + ">.");
}
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listAllOrderBy(boolean, java.lang.String)
*
* @param isAsc 是否使用升序
* @param orderByPropertyName 排序的属性
* @return
*
* 获取所有的Entity的list,结果按照orderByPropertyName属性升序/降序(isAsc true则升序,否则降序)
*/
@SuppressWarnings("unchecked")
public Collection<E> listAllOrderBy(final boolean isAsc,
final String orderByPropertyName) {
final Class clazztemp = this.clazz;
logger.debug("[listAllOrderBy] Entity<" + this.clazz.getName()
+ ">, isAsc?=" + isAsc + ", orderByPropertyName="
+ orderByPropertyName + ".");
}
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazztemp);
criteria.addOrder(isAsc ? Order
.asc(orderByPropertyName) : Order
.desc(orderByPropertyName));
releaseSession(session);
}
});
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listByPage(int, int)
*
* @param pagesize 页的大小,每页最多Entity个数
* @param pageno 页码
* @return
*
* 获取一页的Entity的list,该页是所有Entity中的第pageno页,每页最多有pagesize个Entity,分页显示Entity时使用
*/
@SuppressWarnings("unchecked")
public Collection<E> listByPage(final int pagesize, final int pageno) {
final Class clazztemp = this.clazz;
logger.debug("[listByPage] Entity<" + this.clazz.getName()
+ ">, pagesize=" + pagesize + ", pageno=" + pageno + ".");
}
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazztemp);
criteria.setFirstResult(pagesize * pageno);
criteria.setMaxResults(pagesize);
releaseSession(session);
}
});
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listByPageOrderBy(int, int, boolean,
* java.lang.String)
*
* @param pagesize 页的大小,每页最多Entity个数
* @param pageno 页码
* @param isAsc 是否使用升序
* @param orderByPropertyName 排序的属性
* @return
*
* 获取一页的Entity的list,该页内容按照orderByPropertyName属性升序/降序(isAsc true则升序,否则降序),该页是所有Entity中的第pageno页,每页最多有pagesize个Entity
* 分页显示排序过的Entity时使用
*/
@SuppressWarnings("unchecked")
public Collection<E> listByPageOrderBy(final int pagesize,
final int pageno, final boolean isAsc,
final String orderByPropertyName) {
final Class clazztemp = this.clazz;
logger.debug("[listByPageOrderBy] Entity<" + this.clazz.getName()
+ ">, pagesize=" + pagesize + ", isAsc?=" + isAsc
+ ", orderByPropertyName" + orderByPropertyName
+ ", pageno=" + pageno + ".");
}
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazztemp);
criteria
.setFirstResult(pagesize * pageno)
.setMaxResults(pagesize)
.addOrder(
isAsc ? Order.asc(orderByPropertyName)
: Order
.desc(orderByPropertyName));
releaseSession(session);
}
});
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listByProperty(java.lang.String,
* java.lang.Object)
*
* @param propertyName Entity属性的名称
* @param value Entity属性的值
* @return
*
* 获取一组具有相同propertyName属性值(value)的Entity的列表list,返回一组符合条件的Entity
*/
@SuppressWarnings("unchecked")
public Collection<E> listByProperty(String propertyName, Object value) {
if (logger.isDebugEnabled()) {
logger.debug("[listByProperty] Entity<" + this.clazz.getName()
+ ">, propertyName" + propertyName + ", value=" + value
+ ".");
}
"from " + this.clazz.getName() + " table where table."
+ propertyName + "=?", value);
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listByPageByProperty(java.lang.String,
* java.lang.Object, boolean, java.lang.String)
*
* @param pagesize 页的大小,每页最多Entity个数
* @param pageno 页码
* @param listByPropertyName Entity属性的名称
* @param value Entity属性的值
* @return
*
* 获取一页的Entity的list,该页内容为具有相同propertyName属性值(value)的Entity,该页是所有符合条件Entity中的第pageno页,每页最多有pagesize个Entity
* 分页显示匹配某一属性值的Entity时使用
*/
@SuppressWarnings("unchecked")
public Collection<E> listByPageByProperty(final int pageno,
final int pagesize, final String listByPropertyName,
final Object value) {
final Class clazztemp = this.clazz;
logger.debug("[listByPageByProperty] Entity<"
+ this.clazz.getName() + ">, pageno=" + pageno
+ ", pagesize=" + pagesize + ", listByPropertyName="
+ listByPropertyName + ", value" + value + ".");
}
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazztemp);
criteria.setFirstResult(pagesize * pageno)
.setMaxResults(pagesize).add(
Restrictions.eq(listByPropertyName,
value));
releaseSession(session);
}
});
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listByPropertyOrderBy(java.lang.String,
* java.lang.Object, boolean, java.lang.String)
*
* @param listByPropertyName Entity属性的名称
* @param value Entity属性的值
* @param isAsc 是否使用升序
* @param orderByPropertyName 排序的属性
* @return
*
* 获取所有的具有匹配propertyName属性值(value)的Entity的list,按照orderByPropertyName属性升序/降序(isAsc true则升序,否则降序)
* 显示匹配属性值的列表且要求排序时使用
*/
@SuppressWarnings("unchecked")
public Collection<E> listByPropertyOrderBy(final String listByPropertyName,
final Object value, final boolean isAsc,
final String orderByPropertyName) {
final Class clazztemp = this.clazz;
logger.debug("[listByPropertyOrderBy] Entity<"
+ this.clazz.getName() + ">, listByPropertyName="
+ listByPropertyName + ", value" + value + ", isAsc?="
+ isAsc + ", orderByPropertyName=" + orderByPropertyName
+ ".");
}
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazztemp);
criteria
.add(Restrictions.eq(listByPropertyName, value))
.addOrder(
isAsc ? Order.asc(orderByPropertyName)
: Order
.desc(orderByPropertyName));
releaseSession(session);
}
});
}
* @see com.goldnet.dao.IDAO.IGenericDAO#listByPageByPropertyOrderBy(int, int,
* java.lang.String, java.lang.Object, boolean, java.lang.String)
*
* @param pagesize 页的大小,每页最多Entity个数
* @param pageno 页码
* @param listByPropertyName Entity属性的名称
* @param value Entity属性的值
* @param isAsc 是否使用升序
* @param orderByPropertyName 排序的属性
* @return
*
* 获取一页的Entity的list,该页内容为具有相同propertyName属性值(value)的Entity,该页内容按照orderByPropertyName属性升序/降序(isAsc true则升序,否则降序),
* 该页是所有符合条件Entity中的第pageno页,每页最多有pagesize个Entity
* 分页显示匹配某一属性值的Entity时使用
*/
@SuppressWarnings("unchecked")
public Collection<E> listByPageByPropertyOrderBy(final int pagesize,
final int pageno, final String listByPropertyName,
final Object value, final boolean isAsc,
final String orderByPropertyName) {
final Class clazztemp = this.clazz;
logger.debug("[listByPageByPropertyOrderBy] Entity<"
+ this.clazz.getName() + ">, pageno=" + pageno
+ ", pagesize=" + pagesize + ", listByPropertyName="
+ listByPropertyName + ", value" + value + ", isAsc?="
+ isAsc + ", orderByPropertyName=" + orderByPropertyName
+ ".");
}
new HibernateCallback() {
public Object doInHibernate(Session session) {
Criteria criteria = session.createCriteria(clazztemp);
criteria
.setFirstResult(pagesize * pageno)
.setMaxResults(pagesize)
.add(Restrictions.eq(listByPropertyName, value))
.addOrder(
isAsc ? Order.asc(orderByPropertyName)
: Order
.desc(orderByPropertyName));
releaseSession(session);
}
});
}
}