本文是开发基于spring的web应用的入门文章,前端采用Struts MVC框架,中间层采用spring,后台采用Hibernate。
概览
本文包含以下内容:
•配置Hibernate和事务 •装载Spring的applicationContext.xml文件
•建立业务层和DAO之间的依赖关系 •将Spring应用到Struts中
这个例子是建立一个简单的web应用,叫MyUsers,完成用户管理操作,包含简单的数据库增,删,查,该即CRUD(新建,访问,更新,删除)操作。这是一个三层的web应用,通过Action(Struts)访问业务层,业务层访问DAO。应用的总体结构-从web(UserAction)到中间层(UserManager),再到数据访问层(UserDAO),然后将结果返回。
Spring层的真正强大在于它的声明型事务处理,帮定和对持久层支持(例如Hiberate和iBATIS)
以下是完成这个例子的步骤:
1)安装Eclipse插件 2)数据库建表 3)配置Hibernate和Spring
4)建立Hibernate DAO接口的实现类 5)运行测试类,测试DAO的CRUD操作
6)创建一个处理类,声明事务 7)创建Struts Action的测试类
8)创建web层的Action和model 9)运行Action的测试类测试CRUD操作
10)创建jsp文件通过浏览器进行CRUD操作 11)通过浏览器校验jsp
开发环境
Eclipse3.0.1 , MyEclispe 3.8.4, MySQL4.1.8, spring-framework-1.2.6-with-dependencies,Tomcat5.0
数据库建表 use appfuse;
CREATE TABLE app_user (
id int(11) NOT NULL auto_increment,
firstname varchar(20) NOT NULL,
lastname varchar(20) ,
PRIMARY KEY (id)
);
新建项目
新建一个web project,分别add struts,hibernate capabilities.将spring 包中的dist文件夹中的jar文件拷贝到WEB-INF/lib中。
创建持久层O/R mapping
1. 在src/com.jandar.model下用hibernate插件从数据库导出app_user的.hbm.xml文件改名为User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<!-- DO NOT EDIT: This is a generated file that is synchronized -->
<!-- by MyEclipse Hibernate tool integration. -->
<!-- Created Mon Jul 24 11:48:15 CST 2006 -->
<hibernate-mapping package="">
<class name="AppUser" table="app_user">
<id name="id" column="id" type="integer">
<generator class="identity"/>
</id>
<property name="firstName" column="firstname" type="string" not-null="true" />
<property name="lastName" column="lastname" type="string" />
</class>
</hibernate-mapping>
2.在com.jandar.model下分别建 BaseObject.java 和User.java
package com.jandar.model;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
public class BaseObject implements Serializable {
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}
package com.jandar.model;
public class User extends BaseObject {
private Long id;
private String firstName;
private String lastName;
/**
* @return Returns the id.
*/
public Long getId() {
return id;
}
/**
* @param id The id to set.
*/
public void setId(Long id) {
this.id = id;
}
public void getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
创建DAO,访问对象
1. 在src/com.jandar.service.dao新建IDAO.java接口,所有的DAO都继承该接口
package com.jandar.service.dao;
public interface IDAO {
}
2. 在src/com.jandar.service.dao下新建IUserDAO.java接口
package com.jandar.service.dao;
import java.util.List;
public interface IUserDAO extends IDAO {
List getUsers();
User getUser(Integer userid);
void saveUser(User user);
void removeUser(Integer id);
}
该接口提供了访问对象的方法,
3. 在src/com.jandar.service.dao.hibernate下新建UserDAOHiberante.java
package com.jandar.service.dao.hibernate;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
import com.jandar.model.User;
import com.jandar.service.dao.IUserDAO;
public class UserDaoHibernate extends HibernateDaoSupport implements IUserDAO {
private Log log=LogFactory.getLog(UserDaoHibernate.class);
/* (非 Javadoc)
* @see com.jandar.dao.IUserDAO#getUsers()
*/
public List getUsers() {
return getHibernateTemplate().find("from User");
}
/* (非 Javadoc)
* @see com.jandar.dao.IUserDAO#getUser(java.lang.Long)
*/
public User getUser(Integer id) {
// TODO 自动生成方法存根
return (User) getHibernateTemplate().get(User.class,id);
}
/* (非 Javadoc)
* @see com.jandar.dao.IUserDAO#saveUser(com.jandar.model.User)
*/
public void saveUser(User user) {
log.debug("xxxxxxx");
System.out.println("yyyy");
getHibernateTemplate().saveOrUpdate(user);
if(log.isDebugEnabled())
{
log.debug("userId set to "+user.getId());
}
}
/* (非 Javadoc)
* @see com.jandar.dao.IUserDAO#removeUser(java.lang.Long)
*/
public void removeUser(Integer id) {
Object user=getHibernateTemplate().load(User.class,id);
getHibernateTemplate().delete(user);
if(log.isDebugEnabled()){
log.debug("del user "+id);
}
}
}
在这个类中实现了IUserDAO接口的方法,并且继承了HibernateDAOSupport类。这个类的作用是通过hibernate访问、操作对象,进而实现对数据库的操作。
创建业务层,声明事务
业务层主要处理业务逻辑,提供给web层友好的访问接口和实现访问DAO层。用业务层的另一个好处是,可以适应数据访问层从Hibernate技术转移到其他数据访问技术。
1. 在src/com.jandar.service下新建一个IUserManager接口,该接口有几乎于IUserDAO同样的方法,不同的是处理参数,应为IUserManager是供web层访问的。
package com.jandar.service;
import java.util.List;
import com.jandar.model.User;
public interface IUserManager {
User getUser(String userid);
List getUsers();
User saveUser(User user);
void removeUser(String userid);
}
2. 在src/com.jandar.service.spring下新建IUserManager实现类,UserManager.java
package com.jandar.service.spring;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.jandar.model.User;
import com.jandar.service.IUserManager;
import com.jandar.service.dao.IUserDAO;
public class UserManager implements IUserManager {
/* (非 Javadoc)
* @see com.jandar.service.IUserManager#getUser(java.lang.String)
*/
private static Log log=LogFactory.getLog(UserManager.class);
public IUserDAO userDao;
/**
* @return 返回 userDao。
*/
public IUserDAO getUserDao() {
return userDao;
}
/**
* @param userDao 要设置的 userDao。
*/
public void setUserDao(IUserDAO userDao) {
this.userDao = userDao;
}
public User getUser(String userid) {
User user=userDao.getUser(Integer.valueOf(userid));
if(user==null){
log.warn(" user id "+userid+" not found in database");
}
if(log.isDebugEnabled()){
log.debug("get a user with id "+userid);
}
return user;
}
/* (非 Javadoc)
* @see com.jandar.service.IUserManager#getUsers()
*/
public List getUsers() {
// TODO 自动生成方法存根
return userDao.getUsers();
}
/* (非 Javadoc)
* @see com.jandar.service.IUserManager#saveUser(com.jandar.model.User)
*/
public User saveUser(User user) {
// TODO 自动生成方法存根
userDao.saveUser(user);
return user;
}
/* (非 Javadoc)
* @see com.jandar.service.IUserManager#removeUser(java.lang.String)
*/
public void removeUser(String userid) {
// TODO 自动生成方法存根
userDao.removeUser(Integer.valueOf(userid));
}
}
UserManager.java通过访问dao接口实现业务逻辑和数据库操作。同时该类中提供了set方法,运用了Spring的依赖注入机制。但尚未使用spring的AOP和声明事务。
配置applicationContext.xml
在WEB-INF 下新建applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/appfuse</value></property>
<property name="username"><value>root</value></property>
<!-- Make sure <value> tags are on same line - if they''re not,
authentication will fail -->
<property name="password"><value>root</value></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/jandar/model/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="userDAO" class="com.jandar.service.dao.hibernate.UserDAOHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="userManagerTarget" class="com.jandar.service.spring.UserManager">
<property name="userDAO"><ref local="userDAO"/></property>
</bean>
<bean id="userManager"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref local="transactionManager"/></property>
<property name="target"><ref local="userManagerTarget"/></property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean name="/user" class="com.jandar.web.struts.action.UserAction"
singleton="false">
<property name="mgr">
<ref bean="userManager" />
</property>
</bean>
</beans>