分类: Java
2008-05-19 11:44:06
下面我们需要把hibernate整合进来了,本来考虑到例子的简单性,打算用更简单的类,但既然用三者整合,就是要有良好的设计。我们需要以下几个层次的设计:表现层,业务层,持久层。表现层就是网页;表现层和业务层之间的接口就是网页和action的接口,由struts处理了;业务层包括业务逻辑和事务管理等,由Spring管理,我们只是建立具体处理对象;业务层和持久层之间由数据访问对象DAO处理,持久层交给hibernate处理。贯穿这些层的是领域对象(domain object),即表示现实世界的对象(base object),如订单对象,人物信息对象等等。现在看看我们需要的剩余设计结构。
业务层:放进包service
数据访问对象: 放进包dao
持久层:hibernate
领域对象:放进包bo
既然领域对象是最基本的对象,我们就得首先建立,本例中,可以借助HibernateSynchronizer生成:
首先在mysql中创建表
CREATE TABLE `userinfo` (
`id` int(11) primary key auto_increment,
`username` varchar(20) default NULL,
`Password` varchar(20) default NULL
)
在Eclipse中,建立hibernate的map文件:右键点击WEB-INF(或其他目录都可,后面会提到如何使用该文件),选择newàother,在弹出窗口中选择Hibernate Mapping File。在弹出窗口输入url,用户名和密码后点击Refresh,可以看到你选择的数据库的表,选中userinfo表。输入包bo,用来保存从数据库提取的领域对象。在Properties中将Id generator改为native。
HibernateSynchronizer将在WEB-INF下生成Uerinfo.hbm.xml文件。
右键点击该文件,选择Hibernate SynchronizeràSynchronize Files。将自动生成bo.base.BaseUserinfo和bo.Userinfo类。这两个就是领域对象。工具正好啊!
现在bo包里面的对象自动生成了。
下面建立dao包中对象dao.UserinfoDAO:
package dao; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import bo.Userinfo; //从HibernateDaoSupport继承,从而可以使用getHibernateTemplate().save保存数据。 public class UserinfoDAO extends HibernateDaoSupport { public void save(Userinfo userinfo) { System.out.println("saved!"); getHibernateTemplate().save(userinfo); } } |
再建立service包中的业务对象,service.UserinfoService:
package service; import dao.UserinfoDAO; import bo.Userinfo; package service; public class LoginService { private UserinfoDAO userinfoDAO; public UserinfoDAO getUserinfoDAO() { System.out.println("shit"); return userinfoDAO; } public void setUserinfoDAO(UserinfoDAO userinfoDAO) { System.out.println("LoginService:setAdminDAO"); this.userinfoDAO = userinfoDAO; } public void saveinfo(Userinfo userinfo) { //进行相关业务处理,比如validate之类的。 userinfoDAO.save(userinfo); } } |
好了,所有我们应该建立的对象都生成了,现在把hibernate整合进来再进行一些后续处理。
首先,在applicationContext.xml文件中加入必需的Bean定义,成为如下内容,注意其中注释。
xml version="1.0" encoding="UTF-8"?> DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ""> <beans> <bean name="/login" class="action.LoginAction" singleton="false"> <property name="loginService"> <ref bean="loginService" /> property> bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName"> <value>com.mysql.jdbc.Drivervalue> property> <property name="url"> <value>jdbc:mysql://localhost/mysqlvalue> property> <property name="username"> <value>rootvalue> property> <property name="password"> <value>doerliuvalue> property> bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref local="dataSource" /> property> <property name="mappingResources"> <list> 的map 文件在这里配置了,注意文件的相对位置。 --> <value>../Userinfo.hbm.xmlvalue> list> property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialectprop> <prop key="hibernate.show_sql">trueprop> props> property> bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory"> <ref local="sessionFactory" /> property> bean> <bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref bean="transactionManager" /> property> <property name="target"> <ref local="loginService" /> property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIREDprop> <prop key="get*">PROPAGATION_REQUIRED,readOnlyprop> <prop key="is*">PROPAGATION_REQUIRED,readOnlyprop> props> property> bean> <bean id="loginService" class="service.LoginService"> <property name="userinfoDAO"> <ref bean="userinfoDAO" /> property> bean> <bean id="userinfoDAO" class="dao.UserinfoDAO"> <property name="sessionFactory"><ref local="sessionFactory"/>property> bean> beans> |
最后,LoginAction可以处理请求并和业务层进行交流了。因此需要增加实质性内容:
package action; /* @sample for training. * @author doer.liu@utstarcom * @date */ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.springframework.web.struts.ActionSupport; import bo.Userinfo; import forms.UserInfoForm; import service.LoginService; //我们继承spring提供的Action衍生类org.springframework.web.struts.ActionSupport public class LoginAction extends ActionSupport { LoginService loginService; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { UserInfoForm userInfoForm = (UserInfoForm) form; String username = userInfoForm.getUsername(); String password = userInfoForm.getPassword(); Userinfo userinfo = new Userinfo(); userinfo.setUsername(username); userinfo.setPassword(password); loginService.saveinfo(userinfo);// 保存前台的数据,插入数据库 return mapping.findForward("success"); //返回页。 } public LoginService getLoginService() { return loginService; } public void setLoginService(LoginService loginService) { System.out.println("setLoginService=" + loginService); this.loginService = loginService; } } |
Ok!整个流程到此就走通了。运行看看吧。还有什么说的呢,动手开始吧,在此基础上不断修改测试,再参考相关文档,一切都将越来越简单!——有问题,看日志!
附件是导出的WAR文件,其中lib已被清空,只要加入文中列出的lib文件即可运行(可以将WAR导入eclipse,或者将war文件放到Tomcat的webaspps下)
当然这个例子为了清晰起见,在各种模式,java编程习惯上是不合适的,比如应该面向接口编程,而不是统统拿类,拿对象来处理。应该定义如ILoginService, ILoginDAO等接口,使得系统更灵活,更易移植。当然为了说明,我们这样做是可以原谅的,但工作中切记不要只图简单!否则还不如不用这种高级优秀的构架,因为你一用就把它破坏殆尽了。