一段时间以来时间很忙,自己的技术blog也被当作了"Silent hill"了,呵呵!今天有点时间还是把刚写的例子贴上blog巴。
废话不多说,为了方便还是直接贴代码了。
实验环境:tomcat 5.1 IDE:Eclilpse 4.1 oracle9i Spring1.2 struts1.1 Hibernate3
一、先来看看几个xml巴:
1.先是 applicationContext.xml,其中定义了dbcp和jndi数据库连接池,两种方式连接数据库!
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
<!-- dateSource 普通dbcp连接方式 -->
< bean id ="dataSourcedbcp" class ="org.apache.commons.dbcp.BasicDataSource" >
< property name ="driverClassName" >
< value > oracle.jdbc.driver.OracleDriver </ value >
</ property >
< property name ="url" >
< value > jdbc:oracle:thin:@localhost:1521:CCTV </ value >
</ property >
< property name ="username" >
< value > hib </ value >
</ property >
< property name ="password" >
< value > hib </ value >
</ property >
</ bean >
<!-- dateSource 普通jdbc连接方式 end -->
<!-- dateSource 通过jndi获取连接 -->
< bean id ="dataSource" class ="org.springframework.jndi.JndiObjectFactoryBean" >
< property name ="jndiName" >
< value > java:comp/env/jdbc/testds </ value >
</ property >
</ bean >
<!-- dateSource 通过jndi获取连接 end -->
<!-- 配置hibernate3 SessionFactory 此例子采用hibernate3 规范 -->
< bean id ="sessionFactory" class ="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
< property name ="dataSource" >
< ref local ="dataSource" />
</ property >
<!-- hibernate 数据库相对表的映射文件 -->
< property name ="mappingResources" >
< list >
< value > com/test/common/hibernate/daos/Customer.hbm.xml </ value >
< value > com/test/common/hibernate/daos/Account.hbm.xml </ value >
</ list >
</ property >
<!-- hibernate 数据库相对表的映射文件 end -->
< property name ="hibernateProperties" >
< props >
< prop key ="hibernate.dialect" > org.hibernate.dialect.Oracle9Dialect </ prop >
< prop key ="hibernate.show_sql" > true </ prop > <!-- 是否在控制台输出hibernate 处理过的sql语句?true,falses -->
</ props >
</ property >
</ bean >
<!-- 配置hibernate SessionFactory end -->
<!-- hibernate 事务的处理 -->
< bean id ="transactionManager" class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
< property name ="sessionFactory" >
< ref bean ="sessionFactory" />
</ property >
</ bean >
<!-- hibernate 事务的处理 end -->
<!-- hibernate 事务AddCustomerDAOProxy的transactionAttributes属性中,
定义事务策略将所有以save、remove开始的方法纳入事务管理范围,
如果这些方法抛出异常,在Spring将当前事务回滚,如果方法正常结束,则提交事务。
-->
< bean id ="AddCustomerDAOProxy" class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
< property name ="transactionManager" >
< ref bean ="transactionManager" />
</ property >
< property name ="target" >
< ref local ="customerDAOService" />
</ property >
< property name ="transactionAttributes" >
< props >
< prop key ="insert*" > PROPAGATION_REQUIRED </ prop >
<!-- prop key="get*">PROPAGATION_REQUIRED</prop>
<prop key="set*">PROPAGATION_REQUIRED</prop>
<prop key="modify*">PROPAGATION_REQUIRED,-BoardException</prop>
<prop key="remove*">PROPAGATION_REQUIRED,-BoardException</prop -->
</ props >
</ property >
</ bean >
< bean id ="ShowListDAOProxy" class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
< property name ="transactionManager" >
< ref bean ="transactionManager" />
</ property >
< property name ="target" >
< ref local ="showListDAO" />
</ property >
< property name ="transactionAttributes" >
< props >
<!-- prop key="insert*">PROPAGATION_REQUIRED</prop -->
< prop key ="get*" > PROPAGATION_REQUIRED </ prop >
<!-- prop key="set*">PROPAGATION_REQUIRED</prop>
<prop key="modify*">PROPAGATION_REQUIRED,-BoardException</prop>
<prop key="remove*">PROPAGATION_REQUIRED,-BoardException</prop -->
</ props >
</ property >
</ bean >
<!-- 省略了customerDAOService的服务类1 -->
< bean id ="customerDAOService" class ="com.test.common.springwork.service.customerDAOServiceImpl" >
< property name ="sessionFactory" >
< ref local ="sessionFactory" />
</ property >
< property name ="customerDAO" >
< ref local ="customerDAO" />
</ property >
</ bean >
<!-- adduser DAO -->
< bean id ="customerDAO" class ="com.test.common.hibernate.daos.CustomerDAOImpl" >
< property name ="sessionFactory" >
< ref local ="sessionFactory" />
</ property >
</ bean >
< bean id ="showListDAO" class ="com.test.common.hibernate.daos.ShowListDAOImpl" >
< property name ="sessionFactory" >
< ref local ="sessionFactory" />
</ property >
</ bean >
<!-- action forward!!! this name is mapping in struts-config.xml ,use action proxy to do it -->
< bean name ="/jsp/addPerson" class ="com.test.common.struts.actions.AddPersonAction" singleton ="false" >
< property name ="customerDAOService" >
< ref local ="AddCustomerDAOProxy" />
</ property >
</ bean >
< bean name ="/jsp/ShowListAction" class ="com.test.common.struts.actions.ShowListAction" singleton ="false" >
< property name ="showListDAO" >
< ref local ="ShowListDAOProxy" />
</ property >
</ bean >
<!-- test tools! -->
<!-- bean id="wordCaseUtil" class="com.test.common.springwork.dao.WordTools">
<property name="UpperAction">
<ref bean="UpperAction" />
</property>
<property name="LowerAction">
<ref bean="LowerAction" />
</property>
</bean -->
< bean id ="UpperAction" class ="com.test.common.springwork.dao.UpperAction" />
< bean id ="LowerAction" class ="com.test.common.springwork.dao.LowerAction" />
<!-- test tools! end! -->
</ beans >
接着看一下tomcat在server.xml的datasource的配置:
< Context docBase ="E:/workspace/test/WebRoot" path ="/test" reloadable ="true" debug ="0" >
< Resource name ="jdbc/testds" auth ="Container" type ="javax.sql.DataSource" />
< ResourceParams name ="jdbc/testds" >
< parameter >
< name > factory </ name >
< value > org.apache.commons.dbcp.BasicDataSourceFactory </ value >
</ parameter >
< parameter >
< name > driverClassName </ name >
< value > oracle.jdbc.driver.OracleDriver </ value >
</ parameter >
< parameter >
< name > url </ name >
< value > jdbc:oracle:thin:@localhost:1521:wang </ value >
</ parameter >
< parameter >
< name > username </ name >
< value > hib </ value >
</ parameter >
< parameter >
< name > password </ name >
< value > hib </ value >
</ parameter >
< parameter >
< name > maxActive </ name >
< value > 20 </ value >
</ parameter >
< parameter >
< name > maxIdle </ name >
< value > 10 </ value >
</ parameter >
< parameter >
< name > maxWait </ name >
< value > -1 </ value >
</ parameter >
</ ResourceParams >
</ Context >
2.再来看看web.xml的配置!
其中启用了Spring的ContextLoaderListener来做监听,而不是配置servlet
<! DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" >
< web-app >
<!-- log4j 的配置文件 -->
< context-param >
< param-name > log4jConfigLocation </ param-name >
< param-value > /WEB-INF/log4j.properties </ param-value >
</ context-param >
<!-- spring applicationContext的配置 -->
< context-param >
< param-name > contextConfigLocation </ param-name >
< param-value > /WEB-INF/applicationContext.xml </ param-value >
</ context-param >
< listener >
< listener-class > org.springframework.web.context.ContextLoaderListener </ listener-class >
</ listener >
< servlet >
< servlet-name > action </ servlet-name >
< servlet-class > org.apache.struts.action.ActionServlet </ servlet-class >
< init-param >
< param-name > config </ param-name >
< param-value > /WEB-INF/struts-config.xml </ param-value >
</ init-param >
< init-param >
< param-name > debug </ param-name >
< param-value > 3 </ param-value >
</ init-param >
< init-param >
< param-name > detail </ param-name >
< param-value > 3 </ param-value >
</ init-param >
< load-on-startup > 10 </ load-on-startup >
</ servlet >
< servlet-mapping >
< servlet-name > action </ servlet-name >
< url-pattern > *.do </ url-pattern >
</ servlet-mapping >
< taglib >
< taglib-uri > /WEB-INF/struts-bean.tld </ taglib-uri >
< taglib-location > /WEB-INF/struts-bean.tld </ taglib-location >
</ taglib >
< taglib >
< taglib-uri > /WEB-INF/struts-html.tld </ taglib-uri >
< taglib-location > /WEB-INF/struts-html.tld </ taglib-location >
</ taglib >
< taglib >
< taglib-uri > /WEB-INF/struts-logic.tld </ taglib-uri >
< taglib-location > /WEB-INF/struts-logic.tld </ taglib-location >
</ taglib >
< taglib >
< taglib-uri > /WEB-INF/page.tld </ taglib-uri >
< taglib-location > /WEB-INF/page.tld </ taglib-location >
</ taglib >
< resource-ref >
< res-ref-name > jdbc/testds </ res-ref-name >
< res-type > javax.sql.DataSource </ res-type >
< res-auth > Container </ res-auth >
< res-sharing-scope > Shareable </ res-sharing-scope >
</ resource-ref >
</ web-app >
3.web层也就是struts的struts-config.xml的配置略有不同,它需要加上插件,在容器启动时自动加载 applicationContext.xml,并且action可以通过spring beans来以来注入,所以要用到:org.springframework.web.struts.DelegatingActionProxy
<! DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd" >
< struts-config >
< form-beans >
< form-bean name ="addPersonForm" type ="com.test.common.struts.actionforms.AddPersonActionForm" />
</ form-beans >
< action-mappings >
< action
name ="addPersonForm"
validate ="false"
path ="/jsp/addPerson"
scope ="request"
type ="org.springframework.web.struts.DelegatingActionProxy" >
< forward name ="showlist" path ="/jsp/show.jsp" />
< forward name ="msg" path ="/msg/msg.jsp" />
</ action >
< action
path ="/jsp/ShowListAction"
scope ="request"
type ="org.springframework.web.struts.DelegatingActionProxy" >
< forward name ="showlist" path ="/jsp/showlist.jsp" />
< forward name ="msg" path ="/msg/msg.jsp" />
</ action >
</ action-mappings >
< plug-in className ="org.springframework.web.struts.ContextLoaderPlugIn" >
< set-property property ="contextConfigLocation" value ="/WEB-INF/applicationContext.xml" />
</ plug-in >
</ struts-config >
二、需要配置的两个表的hbm.xml也就是hibernate对表的配置文件,其中TBL_CUSTOMER是主表TBL_ACCOUNT是从表,TBL_ACCOUNT有外键:CUSTOMER_ID,本例子的dao层要做对其二表的及联添加!
1。Customer.hbm.xml
<! 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.test.common.hibernate.daos.Customer"
table ="TBL_CUSTOMER"
dynamic-update ="false"
dynamic-insert ="false" >
< id
name ="id"
column ="CUSTOMER_ID"
type ="java.lang.Long"
unsaved-value ="-1"
>
< generator class ="increment" >
</ generator >
</ id >
< set name ="accounts"
inverse = "true"
cascade ="save-update" >
< key column ="CUSTOMER_ID" />
< one-to-many class ="com.test.common.hibernate.daos.Account" />
</ set >
< property
name ="email"
type ="string"
update ="false"
insert ="true"
column ="CUSTOMER_EMAIL"
length ="82"
not-null ="true"
/>
< property
name ="password"
type ="string"
update ="false"
insert ="true"
column ="CUSTOMER_PASSWORD"
length ="10"
not-null ="true"
/>
< property
name ="userId"
type ="string"
update ="false"
insert ="true"
column ="CUSTOMER_USERID"
length ="12"
not-null ="true"
unique ="true"
/>
< property
name ="firstName"
type ="string"
update ="false"
insert ="true"
column ="CUSTOMER_FIRSTNAME"
length ="25"
not-null ="true"
/>
< property
name ="lastName"
type ="string"
update ="false"
insert ="true"
column ="CUSTOMER_LASTTNAME"
length ="25"
not-null ="true"
/>
</ class >
</ hibernate-mapping >
2。Account.hbm.xml
<! 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.test.common.hibernate.daos.Account"
table ="TBL_ACCOUNT"
dynamic-update ="false"
dynamic-insert ="false" >
< id
name ="id"
column ="ACCOUNT_ID"
type ="java.lang.Long"
unsaved-value ="-1"
>
< generator class ="increment" >
</ generator >
</ id >
< many-to-one
name ="customer"
column ="CUSTOMER_ID"
cascade ="save-update"
class ="com.test.common.hibernate.daos.Customer"
/>
< property
name ="accountName"
type ="string"
update ="false"
insert ="true"
column ="ACCOUNT_NAME"
length ="50"
not-null ="true"
/>
< property
name ="type"
type ="string"
update ="false"
insert ="true"
column ="ACCOUNT_TYPE"
length ="1"
not-null ="true"
/>
< property
name ="createDate"
type ="date"
update ="false"
insert ="true"
column ="CREATE_DATE"
not-null ="true"
/>
< property
name ="updateDate"
type ="date"
update ="true"
insert ="true"
not-null ="true"
column ="UPDATE_DATE"
/>
< property
name ="balance"
type ="double"
update ="true"
insert ="true"
column ="ACCOUNT_BALANCE"
not-null ="true"
/>
</ class >
</ hibernate-mapping >
接下来看一看这两个表的dao层接口及实现接口的类:
(1)、accountDao和accountDaoImpl
* @author wangghost
* @deprecated:account数据操作接口!
*/
public interface AccountDAO ... {
public abstract void addAccount(Account account);
}
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/** */ /**
* @author wangghost
* @deprecated:实现account接口!
* @see:AccountDAO.java
*/
public class AccountDAOImpl extends HibernateDaoSupport implements AccountDAO ... {
public void addAccount(Account account) ...{
getHibernateTemplate().save(account);
}
}
(2)、customerDao和customerDaoImpl
* @author wangghost
* @deprecated:customer数据模型接口!
*/
public interface CustomerDAO ... {
public abstract void addCustomer(Customer customer);
public abstract Customer getCustomerAccountInfo(Customer customer);
public abstract void deleteCustomerInfo(Customer customer);
}
对应application-context.xml中的bean
< property name ="sessionFactory" >
< ref local ="sessionFactory" />
</ property >
</ bean >
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/** */ /**
* @author wangghost
* @deprecated:实现customer接口!
* @see:CustomerDAO.java
*/
public class CustomerDAOImpl extends HibernateDaoSupport implements CustomerDAO ... {
public void addCustomer(Customer customer) ...{ //hibernate 被spring 封装接口方法getHibernateTemplate()用它来调用hibernate数据库操作
getHibernateTemplate().save(customer);
getHibernateTemplate().flush();
// TODO Auto-generated method stub
}
public Customer getCustomerAccountInfo(Customer customer) ...{//根据userid得出相应持久化对象
Customer cust = null;
List list = getHibernateTemplate().find("from Customer customer " +
"where customer.userId = ?",new Object[]...{
customer.getUserId()});
// List list = getHibernateTemplate().find("from Customer customer " +
// "where customer.userId = "+customer.getUserId(),Hibernate.STRING); //hibernate 2 写法,这里已经不支持了!
if(list.size() > 0)...{
cust = (Customer) list.get(0);
}
return cust;
}
public void deleteCustomerInfo(Customer customer) ...{
// TODO 自动生成方法存根
}
}
三、service层,由于此例子也无非常简单,但为了遵循三个框架的意见还是添加了service层。
1。接口CustomerDAOService与它的接口实现CustomerDAOServiceImpl:
import com.test.common.struts.actionforms.AddPersonActionForm;
/** */ /**
* @author wangghost
*
* 更改所生成类型注释的模板为 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public interface CustomerDAOService ... {
public abstract void customerService(AddPersonActionForm person,
String userid, java.sql.Date date);
}
import com.test.common.hibernate.daos.Customer;
import com.test.common.hibernate.daos.CustomerDAO;
import com.test.common.struts.actionforms.AddPersonActionForm;
/** */ /**
* @author wangghost
*
* 更改
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public class CustomerDAOServiceImpl implements CustomerDAOService ... {
/** *//**
*
*/
public CustomerDAOServiceImpl() ...{
super();
}
private CustomerDAO customerDAO;
/** *//**
* @return Returns the customerDAO.
*/
public CustomerDAO getCustomerDAO() ...{
return customerDAO;
}
/** *//**
* @param customerDAO
* The customerDAO to set.
*/
public void setCustomerDAO(CustomerDAO customerDAO) ...{
this.customerDAO = customerDAO;
}
/**//*
* @see com.test.common.springwork.service.CustomerDAOService#customerService()
*/
public void customerService(AddPersonActionForm person,String userid,java.sql.Date date) ...{
// let user info into "pojo" customer
Customer customer = new Customer();
customer.setFirstName(person.getFristname().trim());
customer.setLastName(person.getLastname().trim());
customer.setEmail(person.getEmail());
customer.setPassword(person.getPassword().trim());
customer.setUserId(userid);
// customer done!
// account begin!
Account account = new Account();
account.setAccountName(person.getAccountname());
account.setCreateDate(date);
account.setUpdateDate(date);
account.setType(person.getAccounttype());
account.setBalance(Double.valueOf("1.0"));
// account done
account.setCustomer(customer); //建立从表与主表的联系!
customer.getAccounts().add(account); // account与主表建立关系!
customerDAO.addCustomer(customer); // 调用被封装的接口!数据此时将被级联添加的数据库的两个表中!
}
}
四、web层的实现,首先web层有两个action,AddPersonAction添加新用户的action,ShowListAction列表分页的action
1.AddPersonAction
请注意在application-context.xml中的action的配置:
在action中注入了CustomerDAOService也就是业务层。
< property name ="customerDAOService" >
< ref local ="AddCustomerDAOProxy" />
</ property >
</ bean >
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.test.common.hibernate.daos.Account;
import com.test.common.hibernate.daos.Customer;
import com.test.common.hibernate.daos.CustomerDAO;
import com.test.common.springwork.service.CustomerDAOService;
import com.test.common.struts.actionforms.AddPersonActionForm;
// import org.springframework.web.context.ContextLoaderListener;
/** */ /** 请按以下注释开发!!
* <p>Title: test action </p>
* <p>Description: struts action add person</p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: digitalArchive</p>
* @author wangghost
* @version 1.0
*/
public class AddPersonAction extends Action ... {
/** *//**
* struts Action 与spring已整合! 功能:做到级联添加新客户信息!
*/
public AddPersonAction() ...{
super();
}
private static Logger log = Logger.getLogger(AddPersonAction.class);
private CustomerDAOService customerDAOService;
/** *//**
* @return Returns the customerDAOService.
*/
public CustomerDAOService getCustomerDAOService() ...{
return customerDAOService;
}
/** *//**
* @param customerDAOService The customerDAOService to set.
*/
public void setCustomerDAOService(CustomerDAOService customerDAOService) ...{
this.customerDAOService = customerDAOService;
}
/** *//**
* @return Returns the customerDAO.
*/
public ActionForward execute(ActionMapping mapping, ActionForm actionform,
HttpServletRequest request, HttpServletResponse response) ...{
String encoding = request.getCharacterEncoding();// 或取当前编码格式!
if (encoding != null && encoding.equalsIgnoreCase("utf-8"))// 如果是utf-8格式转成gb2312编码格式
response.setContentType("text/html; charset=gb2312");
if (actionform instanceof AddPersonActionForm) ...{ // actionform装载是否是addpersonactionform
AddPersonActionForm person = (AddPersonActionForm) actionform;
String name = person.getFristname().trim()
+ person.getLastname().trim();// name 注意格式“+”
String password = person.getPassword().trim();
String accountname = person.getAccountname();
String accounttype = person.getAccounttype();
String email = person.getEmail();
String userid = person.getUserid();
java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
HashMap keymap = new HashMap(); // 建立hashmap把表单域中的相应的值压进去!
keymap.put("name", name);
keymap.put("password", password);
keymap.put("accountname", accountname);
keymap.put("accounttype", accounttype);
keymap.put("email", email);
StringBuffer buffer = (StringBuffer) BlankString(keymap);
if (buffer.length() > 0) // 注意格式!
...{ // “{” 请折行显示!
request.setAttribute("msg", buffer.toString()); // 如果有错误将跳转到错误收集页面!
return mapping.findForward("msg");
}
this.customerDAOService.customerService(person,userid,date);
return mapping.findForward("showlist");
}
return null;
}
/** *//**
* 把actionForm中的validate表单的验证放到action中
*
* @param keymap
* @return String[]
*/
private StringBuffer BlankString(HashMap keymap) ...{
StringBuffer str = new StringBuffer();
if( ( keymap.get("name") ).equals("") )
...{
str.append("用户名不能为空! ");
}
if( ( keymap.get("password") ).equals("") )
...{
str.append("密码不能为空! ");
}else
...{
if( !( ( ( ( keymap.get("password") ).toString() ).length() >= 4 )
&& ( ( ( keymap.get("password") ).toString() ).length() <= 10 ) ) )
str.append("密码必须在4---10之间! ");
}
if( ( keymap.get("accountname") ).equals("") )
...{
str.append("账户名不能为空 ");
}
if( ( keymap.get("accounttype") ).equals("") )
...{
str.append("账户类型不能为空 ");
}
if( ( keymap.get("email") ).equals("") )
...{
str.append("邮箱不能为空 ");
}else
...{
if( ( keymap.get("email").toString() ).indexOf("@") == -1 )
str.append("email 格式不对!");
}
return str;
}
}
2.ShowListAction功能复杂,要介绍关于分页、以及spring的HibernateCallback()回调功能。
ShowListAction:
再来看看分页,用taglib来实现:
< property name ="showListDAO" >
< ref local ="ShowListDAOProxy" />
</ property >
</ bean >
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import com.test.common.hibernate.daos.Customer;
import com.test.common.hibernate.daos.ShowListDAO;
/** */ /**
* 请按一下注释开发!!
* <p>
* Title: list person info action
* </p>
* <p>
* Description: struts action show the person info
* </p>
* <p>
* Copyright: Copyright (c) 2006
* </p>
* <p>
* Company: digitalArchive
* </p>
*
* @author wangghost
* @version 1.0
*/
public class ShowListAction extends Action ... {
/** *//**
* super
*/
public ShowListAction() ...{
super();
}
private static Logger log = Logger.getLogger(AddPersonAction.class);
private ShowListDAO showListDAO;
/** *//**
* @return Returns the showListDAO.
*/
public ShowListDAO getShowListDAO() ...{
return showListDAO;
}
/** *//**
* @param showListDAO
* The showListDAO to set.
*/
public void setShowListDAO(ShowListDAO showListDAO) ...{
this.showListDAO = showListDAO;
}
public ActionForward execute(ActionMapping mapping, ActionForm actionform,
HttpServletRequest request, HttpServletResponse response) ...{
String encoding = request.getCharacterEncoding();// 或取当前编码格式!
if (encoding != null && encoding.equalsIgnoreCase("utf-8"))// 如果是utf-8格式转成gb2312编码格式
response.setContentType("text/html; charset=gb2312");
ArrayList personDetailList = new ArrayList();
String _page = "1"; //当前页号
String _size = "10"; //总页数
String _choice = ""; //分页标签类型
if (request.getParameter("pageNo") != null
&& request.getParameter("pageSize") != null) ...{
_page = request.getParameter("pageNo");
_size = request.getParameter("pageSize");
_choice = request.getParameter("choice");
}
String total = request.getParameter("total"); // 初识化为0
if (total != null)
_page = currentPageNumber(_choice, _page, total, _size); //获取当前页号
Object[] objectList = (Object[]) showListDAO.GetPersonDetails(
new Customer(), Integer.parseInt(_size), Integer
.parseInt(_page)); //通过showlistdao接口获取总页数和结果集!
personDetailList = (ArrayList) objectList[0];
total = objectList[1].toString();
// set value of page
request.setAttribute("personDetailList",personDetailList);
request.setAttribute("pageNo",_page);
request.setAttribute("pageSize",_size);
request.setAttribute("total",total);
return mapping.findForward("showlist");
}
/** *//**
* <p>
* Description:根据choice类型获取当前页号
* </p>
*
* @param choice
* @param _page
* @param _total
* @param _size
* @return
*/
public String currentPageNumber(String choice, String _page, String _total,
String _size) ...{
int pageNo = Integer.parseInt(_page);
int total = Integer.parseInt(_total);
int pageSize = Integer.parseInt(_size);
// 计算总页数注意格式!
int pages = (total % pageSize == 0) ? total / pageSize : total
/ pageSize + 1;
// 根据操作,重新确定当前页号
if (choice.equals("next"))
pageNo++;
if (choice.equals("prev"))
pageNo--;
if (choice.equals("first"))
pageNo = 1;
if (choice.equals("last"))
pageNo = pages;
// 页号越界处理
if (pageNo > pages)
pageNo = pages;
if (pageNo <= 0)
pageNo = 1;
return String.valueOf(pageNo);
}
}
其中注入了ShowListDAO,下面介绍ShowListDAO和ShowListDAOImpl的内容:
* @author wangghost
*实际的服务类接口
* 更改所生成类型注释的模板为
* 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public interface ShowListDAO ... {
public abstract Object[] GetPersonDetails(Customer customer,int size,final int page);//分页业务方法
}
在application-context.xml中的配置:
< property name ="sessionFactory" >
< ref local ="sessionFactory" />
</ property >
</ bean >
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.test.common.struts.actionforms.PersonDetail;
/** */ /**
* @author wangghost
* @see showListDao.java
* 实现服务类接口。
* 更改所生成类型注释的模板为 窗口 > 首选项 > Java > 代码生成 > 代码和注释
*/
public class ShowListDAOImpl extends HibernateDaoSupport implements ShowListDAO ... {
/** *//**
*
*/
public ShowListDAOImpl() ...{
super();
}
/**//*
* (非 Javadoc)
*
* @see com.test.common.hibernate.daos.ShowListDAO#GetPersonDetails(com.test.common.hibernate.daos.Customer,
* int, int)
*/
public Object[] GetPersonDetails(Customer customer, int size, final int page) ...{//
Object[] ob = new Object[2]; //用来获得条目数,数据记录
ArrayList list = new ArrayList();
int countList = 0;
// Account account = null;
String sql = "select count(c) from Customer c";
// getHibernateTemplate().getSessionFactory().openSession().createCriteria(Customer.class).createAlias()
countList = ((Integer) (getHibernateTemplate().find(sql)).iterator().next()).intValue(); //通过getHibernateTemplate()获取当前主表的总记录数!
final int pagesize = size; //总页数
// 启用spring hibernate回调功能实现分页
list = (ArrayList) getHibernateTemplate().execute(
new HibernateCallback() ...{
public Object doInHibernate(Session session)
throws HibernateException, SQLException ...{
ArrayList personlist = new ArrayList();
//转换sql=select * from Customer c,Account a where c.id = a.id
List list = session.createCriteria(Customer.class)
.createAlias("accounts", "a")
.setFirstResult((page - 1) * pagesize)
.setMaxResults(pagesize)
.list();
// getHibernateTemplate().flush();
// insert into java bean
for (Iterator person = list.iterator(); person.hasNext();) ...{//取出customer表中相应的信息
PersonDetail personDetail = new PersonDetail();
Customer customer = (Customer) person.next();
// personDetail.setBalance(String.valueOf(customer.getBalance()));
personDetail.setName(customer.getFirstName()
+ customer.getLastName());
personDetail.setEmail(customer.getEmail());
personDetail.setPassword(customer.getPassword());
personDetail.setUserid(customer.getUserId());
for (Iterator table = customer.getAccounts().iterator(); table.hasNext();) ...{//取出每条customer表信息对应的account表的信息
Account _account = (Account) table.next();
personDetail.setAccountname(_account
.getAccountName());
personDetail.setCreatedate(_account
.getCreateDate().toString());
personDetail.setBalance(String.valueOf(_account
.getBalance()));
personDetail.setAccounttype(_account.getType());
}
personlist.add(personDetail);
}
return personlist;
}
});
ob[0] = list.clone();
ob[1] = String.valueOf(countList);
return ob;
}
}
1、page.tld
<! DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd" >
< taglib >
< tlibversion > 1.0 </ tlibversion >
< jspversion > 1.1 </ jspversion >
< shortname > page </ shortname >
<!-- ====================page:pager begin===================== -->
< tag >
< name > wangghost </ name >
< tagclass > com.test.common.struts.taglib.page.GhostPageTagSupport </ tagclass >
< bodycontent > JSP </ bodycontent >
< info >
pager tag provide the frame of the page divider
</ info >
< attribute >
< name > total </ name >
< required > true </ required >
< rtexprvalue > true </ rtexprvalue >
</ attribute >
< attribute >
< name > defaultPageSize </ name >
< required > false </ required >
< rtexprvalue > true </ rtexprvalue >
</ attribute >
</ tag >
<!-- ======================page:pager end========================= -->
<!-- ====================page:navigator begin===================== -->
< tag >
< name > showghost </ name >
< tagclass > com.test.common.struts.taglib.page.ShowPageTextTagSupport </ tagclass >
< bodycontent > JSP </ bodycontent >
< info >
navigator tag output the Navigator bar which pre-designed
</ info >
< attribute >
< name > actionLocation </ name >
< required > true </ required >
< rtexprvalue > true </ rtexprvalue >
</ attribute >
</ tag >
<!-- ======================page:navigator end========================= -->
</ taglib >
节约时间下面就直接把代码贴出来了:
2、GhostPageTagSupport:
import java.util.Enumeration;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
/** */ /**
* @author wangghost
*
* TODO 要更改此生成的类型注释的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
public class GhostPageTagSupport extends BodyTagSupport ... {
/** *//**
*
*/
private static final long serialVersionUID = 1L;
/** *//**
* ghost page !
*/
public GhostPageTagSupport() ...{
super();
}
private StringBuffer output; //保存输出
private int pageNo; //当前页面
private int pageSize; //每页记录数
private int index = 1; //起始记录数,缺省为0
private int pages; //总页数
private int total = 0; //记录总数,即需要分页显示的记录总数,初始化默认为0
private int defaultPageSize = 10; //缺省每页记录数,可在导航条中改变每页记录数的值
public int getDefaultPageSize()
...{
return this.defaultPageSize;
}
public void setDefaultPageSize(int newDefaultPageSize)
...{
this.defaultPageSize = newDefaultPageSize;
}
public void setTotal(int newTotal)
...{
this.total = newTotal;
}
public int doStartTag() throws JspTagException
...{
output = new StringBuffer();
handleActionNow(); //初始化分页参数,遍历request中参数
return EVAL_BODY_BUFFERED;
}
/** *//**
* 获得标记内的记录列表内容
*/
public int doAfterBody() throws JspTagException ...{
BodyContent bodyContent = getBodyContent();
if (bodyContent != null) ...{
output.append(bodyContent.getString());
try ...{
bodyContent.clear();
}
catch (IOException ex) ...{
throw new JspTagException("buffer IO Error");
}
}
return SKIP_BODY;
}
/** *//**
* 输出标记内的内容
*/
public int doEndTag() throws JspTagException ...{
BodyContent bodyContent = getBodyContent();
try ...{
if (bodyContent != null) ...{
//输出结束标记
output.append("</form> ");
//输出全部内容
bodyContent.getEnclosingWriter().write(output.toString());
}
}
catch (IOException ex) ...{
throw new JspTagException("Fatal IO Error");
}
return EVAL_PAGE;
}
/** *//**
*
*/
private void handleActionNow() ...{
StringBuffer paramBuffer = new StringBuffer();
HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
HttpSession session = request.getSession();
HashMap params = new HashMap();
String choice = ParamUtil.getParameter(request, "choice");
//获取每页记录数,若没指定,使用默认值
pageSize = ParamUtil.getIntParameter(request, "pageSize", defaultPageSize);
//获取页号
pageNo = ParamUtil.getIntParameter(request, "pageNo", 1);
// 每页记录数越界处理
if (pageSize <= 0)
pageSize = 1;
//计算总页数
pages = (total % pageSize == 0) ? total / pageSize : total / pageSize + 1;
//根据操作,重新确定当前页号
if (choice.equals("next"))
pageNo++;
if (choice.equals("prev"))
pageNo--;
if (choice.equals("first"))
pageNo = 1;
if (choice.equals("last"))
pageNo = pages;
//页号越界处理
if (pageNo > pages)
pageNo = pages;
if (pageNo <= 0)
pageNo = 1;
//起始记录号
index = (pageNo - 1) * pageSize + 1;
//输出表单的头
output.append("<form method='post' name='pager'> ");
//枚举传到的参数!
Enumeration enum;
String name;
String value;
//获取所有提交的参数,并设置表单"<input type='hidden' name='' value=''>"
enum = request.getParameterNames();
while (enum.hasMoreElements()) ...{
name = (String) enum.nextElement();
value = ParamUtil.getParameter(request, name);
//保存查询参数和值
params.put(name, value);
if (name.equals("pageNo") || name.equals("pageSize") || name.equals("choice")) ...{
continue;
}
paramBuffer.append("<input type='hidden' name='" + name + "' value='" + value +
"'> ");
}
//保存分页参数和值
params.put("pageNo", new Integer(pageNo));
params.put("pageSize", new Integer(pageSize));
//保存到session
session.setAttribute("pagerParameters", params);
//保存当前的URI
session.setAttribute("pageURI", request.getRequestURI());
//输出分页参数表单
paramBuffer.append("<input type='hidden' name='pageNo' value='" + pageNo + "'> ");
paramBuffer.append("<input type='hidden' name='pageSize' value='" + pageSize + "'> ");
paramBuffer.append("<input type='hidden' name='choice' value='" + choice + "'> ");
paramBuffer.append("<input type='hidden' name='total' value='" + total + "'> ");
output.append(paramBuffer.toString());
pageContext.setAttribute("pageSize", new Integer(pageSize));
pageContext.setAttribute("pageNo", new Integer(pageNo));
pageContext.setAttribute("total", new Integer(total));
pageContext.setAttribute("pages", new Integer(pages));
pageContext.setAttribute("index", new Integer(index));
}
}
3、ShowPageTextTagSupport:
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
/** */ /**
* @author wangghost
*分页样式类
* TODO 要更改此生成的类型注释的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
public class ShowPageTextTagSupport extends TagSupport ... {
/** *//**
*
*/
private static final long serialVersionUID = 1L;
/** *//**
*
*/
public ShowPageTextTagSupport() ...{
super();
// TODO 自动生成构造函数存根
}
private String actionLocation = ""; //tld 中所跳转的action类路径!
public void setActionLocation(String str)
...{
this.actionLocation = str;
}
public int doStartTag() throws JspException ...{
try ...{
String bar = getNavigatorBar("text");
pageContext.getOut().write(bar);
return SKIP_BODY;
}
catch (IOException ioe) ...{
throw new JspException(ioe.getMessage());
}
}
/** *//**
* @param string
* @return
*/
private String getNavigatorBar(String type) ...{
String bar = "";
String pageNo = ((Integer) pageContext.getAttribute("pageNo")).toString();
String pages = ((Integer) pageContext.getAttribute("pages")).toString();
String total = ((Integer) pageContext.getAttribute("total")).toString();
String pageSize = ((Integer) pageContext.getAttribute("pageSize")).toString();
String nextDisabled = "";
String prevDisabled = "";
if (Integer.parseInt(pageNo) >= Integer.parseInt(pages))
nextDisabled = "disabled";
if (Integer.parseInt(pageNo) <= 1)
prevDisabled = "disabled";
//-------------------------文字型----------------------------//
if (type.equalsIgnoreCase("TEXT")) ...{
String pageSizeInput = "<input type='text' size='2' value='" + pageSize + "' "
+ "onChange="document.pager.choice.value='current';"
+ "this.form.pageSize.value=this.value;this.form.submit();">";
String firstText = "首 页";
String prevText = "上一页";
String nextText = "下一页";
String lastText = "最后一页";
if (prevDisabled.equalsIgnoreCase("")) ...{
firstText = "<a href='' "
+
"onClick="javascript:document.all.choice.value='first';document.forms[0].action='"+actionLocation+"';document.forms[0].submit();return false;">"
+ "首 页"
+ "</a>";
prevText = "<a href='' "
+
"onClick="javascript:document.all.choice.value='prev';document.forms[0].action='"+actionLocation+"';document.forms[0].submit();return false;">"
+ "上一页"
+ "</a>";
}
if (nextDisabled.equalsIgnoreCase("")) ...{
nextText = "<a href='' "
+
"onClick="javascript:document.all.choice.value='next';document.forms[0].action='"+actionLocation+"';document.forms[0].submit();return false;">"
+ "下一页"
+ "</a>";
lastText = "<a href='' "
+
"onClick="javascript:document.all.choice.value='last';document.forms[0].action='"+actionLocation+"';document.forms[0].submit();return false;">"
+ "最后一页"
+ "</a>";
}
String pageNoInput = "<input type='text' size='3' size='2' value='" + pageNo + "' "
+ "onChange="javascript:document.forms[0].pageNo.value=this.value">";
bar = "每页pageSize条记录 | "
+ "共pages页/total条记录 | "
+ "first prev next last | 第pageNo页 "
+
" <input type='submit' value='go' onClick="javascript:document.forms[0].choice.value='current';"> ";
bar = StringUtil.replace(bar, "pageSize", pageSizeInput);
bar = StringUtil.replace(bar, "pages", pages);
bar = StringUtil.replace(bar, "total", total);
bar = StringUtil.replace(bar, "first", firstText);
bar = StringUtil.replace(bar, "prev", prevText);
bar = StringUtil.replace(bar, "next", nextText);
bar = StringUtil.replace(bar, "last", lastText);
bar = StringUtil.replace(bar, "pageNo", pageNoInput);
} /end of if(text)
return bar;
}
public int doEndTag() throws JspTagException
...{
return EVAL_PAGE;
}
}
最后贴出struts view层的代码:
1、showlist.jsp
<% ... @ page language="java" contentType="text/html; charset=GB2312" %>
<% ... @ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<% ... @ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<% ... @ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<% ... @ taglib uri="/WEB-INF/page.tld" prefix="page" %>
<! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
< html >
< head >
< title > 列表页面 </ title >
</ head >
< Style > ...
Input {...}{font-family: verdana;font-size: 9pt;text-decoration: none;background-color: #FFFFFF;height: 20px;border: 1px solid #666666;color:#000000;}
.TableStyle {...}{font-family: verdana;text-decoration: none;width: 170;background-color: #C0D0E8;font-size: 9pt;border:1px dotted #666666;}
</ Style >
< body >
< br >< br >< br >
<% ... int total = Integer.parseInt(request.getAttribute("total").toString()); %>
< logic:present name ="personDetailList" >
< p > 列表信息为: </ p >
< page:wangghost total ="<%=total%>" defaultPageSize ="10" >
< table align ="center" cellpadding ="0" cellspacing ="0" border ="1" class ="TableStyle" width ="100%" >
< tr >
< td >< font size ="3" color ="red" > 姓名 </ font ></ td >
< td >< font size ="3" color ="red" > 密码 </ font ></ td >
< td >< font size ="3" color ="red" > 编码 </ font ></ td >
< td >< font size ="3" color ="red" > 邮箱 </ font ></ td >
< td >< font size ="3" color ="red" > 账户名 </ font ></ td >
< td >< font size ="3" color ="red" > 账户类型 </ font ></ td >
< td >< font size ="3" color ="red" > 创建时间 </ font ></ td >
< td >< font size ="3" color ="red" > 钱 </ font ></ td >
</ tr >
< logic:iterate name ="personDetailList" id ="person" scope ="request" type ="com.test.common.struts.actionforms.PersonDetail" >
< tr >
< td >< bean:write name ="person" property ="name" filter ="true" /></ td >
< td >< bean:write name ="person" property ="password" filter ="true" /></ td >
< td >< bean:write name ="person" property ="userid" filter ="true" /></ td >
< td >< bean:write name ="person" property ="email" filter ="true" /></ td >
< td >< bean:write name ="person" property ="accountname" filter ="true" /></ td >
< td >< bean:write name ="person" property ="accounttype" filter ="true" /></ td >
< td >< bean:write name ="person" property ="createdate" filter ="true" /></ td >
< td >< bean:write name ="person" property ="balance" filter ="true" /></ td >
</ tr >
</ logic:iterate >
< tr >
< page:showghost actionLocation ="/test/jsp/ShowListAction.do" />
</ tr >
</ table >
< table align ="center" cellpadding ="0" cellspacing ="0" border ="0" >
< tr >< td ></ page:wangghost ></ td ></ tr >
</ table >
</ logic:present >
< logic:notPresent name ="personDetailList" >
< table align ="center" cellpadding ="0" cellspacing ="0" >
< tr >< TH >< font color ="red" size ="4" > 列表初始化失败! </ font ></ TH ></ tr >
</ table >
</ logic:notPresent >
</ body >
</ html >
2.addperson.jsp
<% ... @ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
< html:html >
< body >
< p >< font size =4 color =red > The Test for Hibernate + Spring + Struts: </ font ></ p >
< html:form action ="/jsp/addPerson" method ="post" >
< table border =0 >
< tr >
< td > 姓: </ td >< td >< html:text property ="fristname" /></ td >
< td > 名: </ td >< td >< html:text property ="lastname" /></ td >
</ tr >
< tr >
< td > 邮箱: </ td >< td >< html:text property ="email" /></ td >
< tr >
< tr >
< td > 密码: </ td >< td >< html:password property ="password" /></ td >
</ tr >
< tr >
< td > 账户名称: </ td >< td >< html:text property ="accountname" /></ td >
</ tr >
< tr >
< td > 账户类型: </ td >< td >< html:text property ="accounttype" /></ td >
</ tr >
< tr >
< td > 客户编码: </ td >< td >< html:text property ="userid" /></ td >
</ tr >
< tr align ="center" >
< td >< html:submit />< html:reset /></ td >
</ tr >
</ table >
</ html:form >
</ body >
</ html:html >
希望您给出宝贵意见,谢谢。