
14.6 整合Spring完成产品管理案例
通过整合Struts 2、Hibernate以及Spring框架,并使用Spring的IoC容器来负责创建和管理组件,其中组件包括前端的业务控制器中间的业务逻辑组件以及最底层的DAO组件。这些组件都处于Spring的IoC容器的管理下,从而大大降低了各组件之间的耦合度。
14.6.1 使用Spring容器管理SessionFactory
下面通过整合Spring来改进以前的产品管理案例。在以前的案例里,通过代码来手动初始化SessionFactory。现在可以通过Spring来配置和管理SessionFactory。同时该SessionFactory为其他DAO组件的持久化访问提供支持,代码如下所示。
<! -- 定义数据源Bean --> <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/mystruts2</value> </property> <property name="username"> <value>root</value> </property> <property name="password"> <value>root</value> </property> </bean> <! -- 定义SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql">false</prop> </props> </property> <property name="mappingResources"> <list> <value>net/hncu/po/Product.hbm.xml</value> </list> </property> </bean>
14.6.2 使用HibernateTemplate进行数据库操作
Spring还提供了一个模板类HibernateTemplate,其包含大量的简便方法。通过HibernateTemplate模板类可以很方便地完成持久化操作。
在Spring配置文件中定义HibernateTemplate,并为其注入SessionFactory实例,代码如下所示。
<! -- 定义hibernateTemplate --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean>
在Spring配置文件中配置DAO组件,并为其注入HibernateTemplate实例,代码如下所示。
<! -- 配置DAO组件 --> <bean id="productDao" class="net.hncu.dao.ProductDaoImpl"> <property name="hibernateTemplate"> <ref bean="hibernateTemplate"/> </property> </bean>
修改DAO实现类代码,将该DAO实现类继承HibernateDaoSupport。同时通过调用HibernateTemplate的方法来进行持久化访问操作,代码如下所示。
package net.hncu.dao; import java.util.List; import net.hncu.po.Product; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao { // 添加产品 public void save(Product p) { getHibernateTemplate().save(p); } // 删除产品 public void delete(String id) { getHibernateTemplate().delete( getHibernateTemplate().get(Product.class, id)); } //更新产品 public void update(Product p) { getHibernateTemplate().saveOrUpdate(p); } //查询所有产品 public List queryAll() { return getHibernateTemplate().find("from Product"); } //按id查询产品 public Product queryByID(String id) { return (Product) getHibernateTemplate().get(Product.class, id); } }
14.6.3 依赖注入DAO组件
修改业务逻辑组件,为其添加一个ProductDao类型的属性dao,并添加其setter方法。这样业务逻辑组件就能接受Spring容器中注入的DAO组件,代码如下所示。
package net.hncu.service; import java.util.List; import net.hncu.dao.ProductDao; import net.hncu.po.Product; public class ProductServiceImpl implements ProductService{ //DAO组件引用 private ProductDao dao; //设置DAO组件 public void setDao(ProductDao dao) { this.dao = dao; } // 添加产品 public void addProduct(Product p) { //判断是否存在相同ID的产品 if (dao.queryByID(p.getId()) == null) { //如果不存在,而调用DAO组件进行保存 dao.save(p); } else { //否则提示错误信息 System.out.println("id已经存在"); } } // 删除产品 public void deleteProduct(String id) { //判断是否存在相同ID的产品 if (dao.queryByID(id) ! = null) { //如果存在,而调用DAO组件进行删除 dao.delete(id); } else { //否则提示错误信息 System.out.println("id不存在"); } } // 更新产品 public void updateProduct(Product p) { //判断是否存在相同ID的产品 if (dao.queryByID(p.getId()) ! = null) { //如果存在,而调用DAO组件进行更新 dao.update(p); } else { //否则提示错误信息 System.out.println("id不存在"); } } // 查询所有产品 public List queryAllProduct() { //调用DAO组件进行查询 return dao.queryAll(); } // 按id查询产品 public Product queryProductByID(String id) { //调用DAO组件进行查询 return dao.queryByID(id); } }
在Spring配置文件中配置业务逻辑组件组件,并为其注入DAO组件,代码如下所示。
<! -- 配置业务逻辑组件 --> <bean id="productService" class="net.hncu.service.ProductServiceImpl"> <! -- 为业务逻辑组件注入DAO组件 --> <property name="dao" ref="productDao"></property> </bean>
14.6.4 依赖注入业务逻辑组件
修改业务控制器AddAction,为其添加一个ProductService类型的属性ps,并添加其setter方法。这样业务控制器Action就能接受Spring容器中注入的业务逻辑组件,代码如下所示。
package net.hncu.action; import net.hncu.po.Product; import net.hncu.service.ProductService; import com.opensymphony.xwork2.ActionSupport; public class AddAction extends ActionSupport{ //产品ID private String id; //产品名 private String name; //产品价格 private double price; //业务逻辑组件 private ProductService ps; //设置业务逻辑组件 public void setPs(ProductService ps) { this.ps = ps; } //各属性的setter和getter方法 ... ... public String execute() throws Exception { //将接受的参数设置到Product实例中 Product p = new Product(); p.setId(id); p.setName(name); p.setPrice(price); //调用业务逻辑组件保存该产品 ps.addProduct(p); return SUCCESS; } }
修改业务控制器DeleteAction,为其添加一个ProductService类型的属性ps,并添加其setter方法。这样业务控制器Action就能接受Spring容器中注入的业务逻辑组件,代码如下所示。
package net.hncu.action; import net.hncu.service.ProductService; import com.opensymphony.xwork2.ActionSupport; public class DeleteAction extends ActionSupport{ //产品ID private String id; //业务逻辑组件 private ProductService ps; //设置业务逻辑组件 public void setPs(ProductService ps) { this.ps = ps; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String execute() throws Exception { //通过调用业务逻辑组件删除该ID产品 ps.deleteProduct(getId()); return SUCCESS; } }
修改业务控制器ShowAllAction,为其添加一个ProductService类型的属性ps,并添加其setter方法。这样业务控制器Action就能接受Spring容器中注入的业务逻辑组件,代码如下所示。
package net.hncu.action; import java.util.List; import net.hncu.service.ProductService; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class ShowAllAction extends ActionSupport { //业务逻辑组件 private ProductService ps; //设置业务逻辑组件 public void setPs(ProductService ps) { this.ps = ps; } public String execute() throws Exception { //通过调用业务逻辑组件获得所有的产品 List all = ps.queryAllProduct(); //将所有产品List储存在request范围中 ServletActionContext.getRequest().setAttribute("all", all); return SUCCESS; } }
修改业务控制器UpdateAction,为其添加一个ProductService类型的属性ps,并添加其setter方法。这样业务控制器Action就能接受Spring容器中注入的业务逻辑组件,代码如下所示。
package net.hncu.action; import net.hncu.po.Product; import net.hncu.service.ProductService; import com.opensymphony.xwork2.ActionSupport; public class UpdateAction extends ActionSupport{ //产品ID private String id; //产品名 private String name; //产品价格 private double price; //业务逻辑组件 private ProductService ps; //设置业务逻辑组件 public void setPs(ProductService ps) { this.ps = ps; } //各属性的setter和getter方法 ... ... public String execute() throws Exception { //将接受的参数设置到Product实例中 Product p = new Product(); p.setId(id); p.setName(name); p.setPrice(price); //调用业务逻辑组件保存该产品 ps.updateProduct(p); return SUCCESS; } }
在Spring配置文件中配置业务控制器Action,并为其注入业务逻辑组件,代码如下所示。
<! -- 创建ShowAllActon实例 --> <bean id="showAllAction" class="net.hncu.action.ShowAllAction"> <property name="ps" ref="productService"></property> </bean> <! -- 创建AddAction实例 --> <bean id="addAction" class="net.hncu.action.AddAction"> <property name="ps" ref="productService"></property> <! -- 创建DeleteAction实例 --> <bean id="deleteAction" class="net.hncu.action.DeleteAction"> <property name="ps" ref="productService"></property> </bean> <! -- 创建UpdateAction实例 --> <bean id="updateAction" class="net.hncu.action.UpdateAction"> <property name="ps" ref="productService"></property> </bean>
14.6.5 完成Action配置
在“struts.xml”文件中配置业务控制器Action,其中class属性并不是Action类的实际处理类,而是对应Spring容器中的Bean实例,代码如下所示。
<? xml version="1.0" encoding="UTF-8" ? > <! DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <! -- struts为配置文件根元素--> <struts> <constant name="struts.i18n.encoding" value="gb2312"></constant> <! -- Action必须放在指定的包名空间中--> <package name="struts2" extends="struts-default"> <action name="showAll" class="showAllAction"> <! -- 定义处理结果与视图资源之间的关系--> <result name="success">/showAll.jsp</result> </action> <action name="delete" class="deleteAction"> <! -- 定义处理结果与视图资源之间的关系--> <result name="success" type="redirect">showAll.action </result> </action> <action name="add" class="addAction"> <! -- 定义处理结果与视图资源之间的关系--> <result name="success" type="redirect">showAll.action </result> </action> <action name="update" class="updateAction"> <! -- 定义处理结果与视图资源之间的关系--> <result name="success" type="redirect">showAll.action</result> </action> </package> </struts>