Struts2+spring2+hibernate3整合方案
最近闲来无事可做,于是开始学习struts2。Struts2和struts1、webwork2有什么区别我也不说了,网上有很多这方面的资料。以前在项目中从未使用过struts,一直使用spring+hibernate,现在既然学习了Struts,也不能浪费,于是乎开始琢磨着怎么整合这3个框架。整合原理以spring为容器,管理hibernate的DAO和Struts2的Action。
一、准备工作
Struts2.06+spring2.5+hibernate3.2+jdk6.0+myeclipse6.0+tomcat5.5+mysql5.0 以上是整合的原料。下面以一个注册登陆的例子来开始我们的整合过程。
这个例子很简单,下面是它的sql脚本内容:
Create TABLE `user` (
`userid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(16) NOT NULL,
`email` varchar(30) NOT NULL,
PRIMARY KEY (`userid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二、开始行动
包结构可以参考下图
图一
图二
图三
1) Struts部分:建立struts.xml和struts.properties
Struts.xml内容如下:
Struts.properties内容如下:
struts.devMode=false
struts.enable.DynamicMethodInvocation=true
struts.i18n.reload=true
struts.ui.theme=simple
struts.locale=zh_CN
struts.i18n.encoding=UTF-8
struts.objectFactory=spring
struts.objectFactory.spring.autoWire=name
struts.serve.static.browserCache=false
struts.url.includeParams=none
2) 建立User.java和User.hbm.xml、jdbc.properties:
User.java内容如下:
/** *//**
*
* @author flustar * @version 1.0
* Creation date: Dec 23, 2007 1:55:28 PM
*/
package com.firstssh.model;
import java.io.Serializable;
public class User implements Serializable {
private int id;
private String username;
private String password;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
https://www.doczj.com/doc/2313915255.html,ername = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
User.hbm.xml内容:
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"https://www.doczj.com/doc/2313915255.html,/hibernate-mapping-3.0.dtd"> package="com.firstssh.model"> column="username" not-null="true" length="20" /> column="password" not-null="true" length="16" /> column="email" not-null="true" length="30"/>
jdbc.properties内容如下:
datasource.type=mysql
datasource.driverClassName=com.mysql.jdbc.Driver
datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEnc oding=UTF-8
https://www.doczj.com/doc/2313915255.html,ername=root
datasource.password=123456
datasource.maxActive=10
datasource.maxIdle=2
datasource.maxWait=120000
datasource.whenExhaustedAction=1
datasource.validationQuery=select 1 from dual
datasource.testOnBorrow=true
datasource.testOnReturn=false
c3p0.acquireIncrement=3
c3p0.initialPoolSize=3
c3p0.idleConnectionTestPeriod=900
c3p0.minPoolSize=2
c3p0.maxPoolSize=50
c3p0.maxStatements=100
c3p0.numHelperThreads=10
c3p0.maxIdleTime=600
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect=org.hibernate.dialect.MySQLMyISAMDialect
hibernate.jdbc.batch_size=25
hibernate.jdbc.fetch_size=50
hibernate.show_sql=true
hibernate.connection.release_mode=after_transaction
3) Spirng部分:为了清晰把Spring的配置文件拆分成以下几部分applicationContext-dao.xml、appliationContext-service.xml、
applicationContext-hibernate.xml、action- servlet.xml。
applicationContext-hibernate.xml内容:
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigure r">
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> ${hibernate.jdbc.fetch_size} ${hibernate.jdbc.batch_size}
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
class="org.springframework.transaction.interceptor.TransactionInterceptor">
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreat or">
applicationContext-dao.xml内容:
applicationContext-service.xml内容:
action-servlet.xml内容:
scope="prototype">
scope="prototype">
以上几个xml文件的内容暂且不要理会,继续往下看,你就自动明白的,不用我解释。
4)日志部分:log4j.properties 、commons-logging.properties
log4j.properties内容:
# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=INFO, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
https://www.doczj.com/doc/2313915255.html,yout=org.apache.log4j.PatternLayout
https://www.doczj.com/doc/2313915255.html,yout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${firstssh.root}/WEB-INF/logs/firstssh.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
https://www.doczj.com/doc/2313915255.html,yout=org.apache.log4j.PatternLayout
https://www.doczj.com/doc/2313915255.html,yout.ConversionPattern=%d %p [%c] - %m%n
# OpenSymphony Stuff
https://www.doczj.com/doc/2313915255.html,.opensymphony=INFO
https://www.doczj.com/doc/2313915255.html,.apache.struts2=INFO
# Spring Stuff
https://www.doczj.com/doc/2313915255.html,.springframework=INFO
# Hibernate Stuff
https://www.doczj.com/doc/2313915255.html,.hiberante=INFO
commons-logging.properties
内容:
https://www.doczj.com/doc/2313915255.html,mons.logging.Log=https://www.doczj.com/doc/2313915255.html,mons.logging.impl.Log4JLogge r
5)web.xml
xmlns:xsi="https://www.doczj.com/doc/2313915255.html,/2001/XMLSchema-instance" xsi:schemaLocation="https://www.doczj.com/doc/2313915255.html,/xml/ns/j2ee https://www.doczj.com/doc/2313915255.html,/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
6)dwr.xml
三、开始编码:
以下是DAO部分的核心代码:
IGenericDao.java内容如下:
/** *//**
*
* @author flustar
* @version 1.0
* Creation date: Dec 23, 2007 6:19:21 PM
*/
package https://www.doczj.com/doc/2313915255.html,mon.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;
import https://www.doczj.com/doc/2313915255.html,mon.util.PaginationSupport;
public interface IGenericDao
public void saveOrUpdate(T t);
public T load(Serializable ID);
public T get(Serializable ID) ;
public boolean contains(T t) throws DataAccessException ;
public void delete(T t, LockMode lockMode) throws DataAccessException;
public void delete(T t) throws DataAccessException;
public void deleteAll(Collection
public List
throws DataAccessException;
public List
throws DataAccessException;
public List
public List
int maxResults) throws DataAccessException;
public List
public List
Object value) throws DataAccessException ;
public List
Object[] values) throws DataAccessException;
public Object load(Class TClass, Serializable ID, LockMode lockMode)
throws DataAccessException;
public void load(T t, Serializable ID) throws DataAccessException;
public Object load(String TName, Serializable ID, LockMode lockMode)
throws DataAccessException;
public Object load(String TName, Serializable ID)
throws DataAccessException;
public void refresh(T t, LockMode lockMode) throws DataAccessException;
public void refresh(T t) throws DataAccessException;
public Serializable save(T t) throws DataAccessException;
public void saveOrUpdate(String TName, T t) throws DataAccessException;
public void saveOrUpdateAll(Collection
throws DataAccessException;
public void update(T t, LockMode lockMode) throws DataAccessException;
public void update(T t) throws DataAccessException;
public void update(String TName, T t, LockMode lockMode)
throws DataAccessException;
public void update(String TName, T t) throws DataAccessException;
public List
public List
public PaginationSupport findPageByCriteria(
final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex);
public PaginationSupport findPageByQuery( final String hsql, final int pageSize,final int startIndex);
}
GenericDao.java内容如下:
/** *//**
*
* @author flustar
* @version 1.0
* Creation date: Dec 23, 2007 11:23:56 PM
*/
package https://www.doczj.com/doc/2313915255.html,mon.dao;
import java.io.Serializable;
import https://www.doczj.com/doc/2313915255.html,ng.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import https://www.doczj.com/doc/2313915255.html,mons.logging.Log;
import https://www.doczj.com/doc/2313915255.html,mons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import https://www.doczj.com/doc/2313915255.html,mon.util.PaginationSupport;
@SuppressWarnings("unchecked")
public class GenericDao
protected Log logger = LogFactory.getLog(getClass());
protected Class
public GenericDao() {
}
protected Class getEntityClass() {
if (entityClass == null) {
entityClass = (Class
.getGenericSuperclass()).getActualTypeArguments()[0];
logger.debug("T class = " + entityClass.getName());
}
return entityClass;
}
public void saveOrUpdate(T t) {
this.getHibernateTemplate().saveOrUpdate(t);
}
public T load(Serializable ID) {
T load = (T) getHibernateTemplate().load(getEntityClass(), ID);
return load;
}
public T get(Serializable ID) {
T load = (T) getHibernateTemplate().get(getEntityClass(), ID);
return load;
}
public boolean contains(T t) throws DataAccessException {
return getHibernateTemplate().contains(t);
}
public void delete(T t, LockMode lockMode) throws DataAccessException { getHibernateTemplate().delete(t, lockMode);
}
public void delete(T t) throws DataAccessException {
getHibernateTemplate().delete(t);
}
public void deleteAll(Collection
}
public List
throws DataAccessException {
List
value);
return find;
}
public List
throws DataAccessException {
List
values);
return find;
}
public List
return (List
}
public List
int maxResults) throws DataAccessException {
return getHibernateTemplate().findByExample(exampleEntity, firstResult,
maxResults);
}
public List
return getHibernateTemplate().findByExample(exampleEntity);
}
public List
Object value) throws DataAccessException {
return getHibernateTemplate().findByNamedParam(queryString, paramName,
value);
}
public List
return getHibernateTemplate().findByNamedParam(queryString, paramNames,
values);
}
public Object load(Class TClass, Serializable ID, LockMode lockMode)
throws DataAccessException {
return getHibernateTemplate().load(TClass, ID, lockMode);
}
public void load(T t, Serializable ID) throws DataAccessException {
getHibernateTemplate().load(t, ID);