Struts2+Hibernate+Spring详细搭建
Download
Report
Transcript Struts2+Hibernate+Spring详细搭建
Struts2+Hibernate+Spring
Spring+Hibernate
+
Spring+Struts2
=
Struts2+Hibernate+Spring
组合开发架构细节
• Action:处理Web请求,提供了基本的view,uptate,
delete等实现,由Spring管理注入
• Manager:隔离事务,包括主要的业务逻辑,也提
供了CRUD及分页的接口。其他资源调度也在这一
层提供接口,如email
• DAO:存取数据的接口,Hibernate实现。包含了基
本的CRUD以及分页功能
• 领域对象:POJO,由Hibernate映射
工程搭建过程
• 1:新建工程
• 2:用Myeclipse为工程添加Hibernate包库:
此处根据实际选择DB Driver(也可先随意选择,因为加入Spring后会删掉Hibernate的
配置文件)
如图:去掉Create SessionFactory class勾选后,Finish完成
• 3:用Myeclipse为工程添加Spring包库
处选中以上支持库以外,还应加上WEB支持包库:
(一般在倒数地六个能找到)
• 此时:工程结构为:
我们只需要applicationContext.xml,所以删掉hibernate.cfg.xml
然后我们要到工程包库中删掉一个冲突的JAR包:asm-2.2.3.jar
方法可如下:
点击展开工程目录的:
>>>
找到并选中后右键:
然后它转移到:
然后右键删除:
完成!
• 对于applicationContext.xml配置文件路径的处理
可将其保留在
这样在web.xml中引用的配置应为
<!--配制Spring加载选项 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
也可放在放在/WEB-INF/下
那么上面红色高亮部分就应改为:/WEB-INF/applicationContext*.xml
* 通配符的作用为使用多配置文件!
• 在applicationContext.xml中进行基本配置
<!-- 配置数据源(mysql) -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value=“jdbc:mysql://localhost:3306/数据源名?useUnicode=true&characterEncoding=utf8">
</property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
一般使用commons.dbcp连接池:所以需要导入它所需要的commons-dbcp.jar和
commons-pool.jar(它们的版本一般无所谓)
<!-- 配置Hibernate sessionFactory-->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="mappingResources">
<list>
<value>…(此处为Hibernate生成的映射xml文件)</value>
</list>
</property>
<!-- 配置数据库方言 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<!-- 配置事务 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
• 用Myeclipse反向生成Hibernate映射文件和
实体类等对象领域(POJO)
若当前没有
视图,先找到:
双击打开数据库连接:
然后找到数据库,并选中要映射的表:
右键:
注意选对存放路径
注意ID Generator的选择!说明如下:
Hibernate中,<id>标签下的可选<generator>子元素是一个Java类的名字,用来为该持久化类的实例生成惟
一标示,所有的生成器都实现net.sf.hibernate.id.IdentifierGenerator接口这是一个非常简单的接口,某些应
用程序可以选择提供它们自己的特定实现当然,Hibernate提供了很多内置的实现下面是一些内置主键生成
器(Key Generator)的意义
1) assigned
主键由外部程序负责生成,无需Hibernate参与。
让应用程序在save()之前为对象分配一个标示符。这是 <generator>元素没有指定
时的默认生成策略。
2)
hilo
通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态。
使用一个高/低位算法高效的生成long, short 或者 int类型的标识符。给定一个
表和字段(默认分别是是 hibernate_unique_key 和next_hi)作为高位值的来源。
高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
3) seqhilo
与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在
Sequence中,适用于支持Sequence的数据库,如Oracle。
使用一个高/低位算法来高效的生成long, short 或者 int类型的标识符,给定一
个数据库序列(sequence)的名字。
4) increment
主键按数值顺序递增此方式的实现机制为在当前应用实例中维持一个变量,以保存
着当前的最大值,之后每次需要生成主键的时候将此值加1作为主键这种方式可能产
生的问题是:如果当前有多个实例访问同一个数据库,那么由于各个实例各自维护
主键状态,不同实例可能生成同样的主键,从而造成主键重复异常因此,如果同一
数据库有多个实例访问,此方式必须避免使用。
用于为long, short或者int类型生成 唯一标识。只有在没有其他进程往同一张表中插
入数据时才能使用。 在集群下不要使用。
5) identity
采用数据库提供的主键生成机制如DB2 SQL Server MySQL中的主键生成机制。
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段
提供支持。 返回的标识符是long, short 或者int类型的。
6) sequence
采用数据库提供的sequence 机制生成主键如Oralce 中的Sequence。在
DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence), 而在
Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
7) native
由Hibernate根据底层数据库自行判断采用identity hilo sequence其中一种作为主键生成
方式
8) uuid.hex
用一个128-bit的UUID算法生成字符串类型的标识符, 这在一个网络中是唯一的(使用
了IP地址)。UUID被编码为一个32位16进制数字的字符串。
由Hibernate基于128 位唯一值产生算法生成16 进制数值(编码后以长度32 的字
符串表示)作为主键例如:5abefd3890cat33llsica3ee43bk222
9) uuid.string
与uuid.hex 类似,只是生成的主键未进行编码(长度16)在某些数据库中可能出现问
题(如PostgreSQL)
10)guid
在MS SQL Server 和 MySQL 中使用数据库生成的GUID字符串。
11)select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
12)foreign
使用另外一个相关联的对象的标识符。通常和<one-to-one>联合起来使用。
一般而言,利用uuid.hex方式生成主键将提供最好的性能和数据库平台适应
性另外由于常用的数据库,如OracleDB2SQLServerMySql 等,都提供了易用
的主键生成机制(Auto-Increase 字段或者Sequence)我们可以在数据库提供
的主键生成机制上,采用generator-class=native的主键生成方式不过值得注意
的是,一些数据库提供的主键生成机制在效率上未必最佳,大量并发insert数据
时可能会引起表之间的互锁
数据库提供的主键生成机制,往往是通过在一个内部表中保存当前主键状
态(如对于自增型主键而言,此内部表中就维护着当前的最大值和递增量),
之后每次插入数据会读取这个最大值,然后加上递增量作为新记录的主键,之
后再把这个新的最大值更新回内部表中,这样,一次Insert操作可能导致数据库
内部多次表读写操作,同时伴随的还有数据的加锁解锁操作,这对性能产生了
较大影响因此,对于并发Insert要求较高的系统,推荐采用uuid.hex 作为主键生
成机制
Finish完成!
• 编写DAO:
先新建一个包用于存放DAO文件:
通过接口来实现! 先创建接口,给接口增加方法:(如CRUD)
package com.DAO;
import java.util.List;
import com.model.Movie;
public interface MovieDAOi
{
public void add(Movie m);
public List showmovies();
public void delete(Long id);
public void update(Movie m);
public Movie getMovie(Long id);
}
• 编写DAO的实现类:
先新建一个包用于存放DAO文件:
实现DAO接口并继承Spring对Hibernate的帮助类:
package com.DAO.Hibernate;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.DAO.MovieDAOi;
import com.model.Movie;
public class MovieDAO extends HibernateDaoSupport implements
MovieDAOi
这个帮助类提供一个方便的方法:
getHibernateTemplate(); 很容易就能得到HibernateTemplate的一个实例.它
也有getSession()和closeSessionIfNecessary()方法,以便于你应为某些原因而不
使用HibernateTempate的情况下执行Hibernate操作。
public class MovieDAO extends HibernateDaoSupport implements MovieDAOi
{
public void add(Movie m)
{
getHibernateTemplate().save(m);
}
public List showmovies()
{
return getHibernateTemplate().find("from movie");
}
public void update(Movie m)
{
getHibernateTemplate().update(m);
}
public void delete(Long id)
{
getHibernateTemplate().delete(getHibernateTemplate().get(Movie.class, id));
}
public Movie getMovie(Long id)
{
Movie m=(Movie)getHibernateTemplate().get(Movie.class, id);
return m;
}
}
• 编写service层(Manager)
也通过接口实现:先创建接口,给接口增加方法
package com.service;
import java.util.List;
import com.model.Movie;
public interface MovieManager
{
public void addMovie(Movie m);
public List showMovies();
public void deleteMovie(Long id);
public void updateMovie(Movie m);
public Movie getMovieMovie(Long id);
}
• 编写service的实现类:
实现service接口,并声明所要用到的DAO接口,创建它的set方法供spring将DAO
的实现类注入进来
public class MovieManagerImpl implements MovieManager
{
private MovieDAOi movieDao; (DAO的接口类)
……
public void setMovieDao(MovieDAOi movieDao)
{
this.movieDao = movieDao;
}
}
• 配置applicationContext.xml:通过Spring来管理各层
<!--定义DAO -->
<bean id="moviekindDao" class="com.DAO.Hibernate.MovieKindDAO">
<property name=“sessionFactory”> bean中声明的
<ref bean=“sessionFactory”/> 所注入的ben
</property>
</bean>
<bean id="movieDao" class="com.DAO.Hibernate.MovieDAO">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 配置service层 -->
<bean id="moviekindManager"
class="com.service.impl.MovieKindManagerImpl">
<property name="moviekindDao">
<ref bean="moviekindDao"/>
</property>
</bean>
<bean id="movieManager" class="com.service.impl.MovieManagerImpl">
<property name="movieDao">
<ref bean="movieDao" />
</property>
</bean>
然后修改applicationContext.xml中sessionFactory的Hibernate映射文件配置
<list>
<value>com/model/Movie.hbm.xml</value>
<value>com/model/MovieKind.hbm.xml</value>
</list>
到此已完成Spring和Hibernate的整合
Spring+Struts2
• 手动导入Struts2类库
如果不需要跟第三方框架集成,把不带-plugin结尾的jar文件都添加入类路径即可。
如果需要跟第三方框架集成,这时候还需要加入对应的-plugin jar文件。例如跟
spring集成,需要加入struts2-spring-plugin-2.x.x.jar
然后在web.xml文件中配置Struts2和Spring。
并在src/下加入struts.properties和struts.xml这两个配置文件
<!--配制Spring加载选项 监听上下文变量 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Spring自动关闭action的过滤器 (配在struts2的过滤器之前,否则可能不生效)-->
<filter>
<filter-name>lazyLoadingFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filterclass>
</filter>
<filter-mapping>
<filter-name>lazyLoadingFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<!-- 配置启动Struts2的CleanUp的 Filter -->
<filter>
<filter-name> struts-cleanup </filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filterclass>
</filter>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
<!-- 配置启动Struts2的 Filter -->
<filter>
<filter-name>struts</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
• 编写Action类:
继承com.opensymphony.xwork2.ActionSupport的ActionSupport类
声明以下变量
private MovieKindManager moviekindManager;//service的接口类set方法供Spring注入
private List mklist;
private MovieKind mk;
private Long kind_id;
//用于返回到视图的List
//传递参数的实体类(由Hibernate生成了)
//用于具体取值的ID
与视图进行交互的数据要创建get、set方法来供Struts2进行操作
package com.action;
import java.util.List;
import com.model.MovieKind;
import com.opensymphony.xwork2.ActionSupport;
import com.service.MovieKindManager;
public class MovieKindAction extends ActionSupport
{
private MovieKindManager moviekindManager;
private List mklist;
private MovieKind mk;
private Long kind_id;
public String add(){
moviekindManager.addMovieKind(mk);
return SUCCESS;
}
public String update(){
return SUCCESS;
}
public String delete(){
moviekindManager.deleteMovieKind(kind_id);
return SUCCESS;
}
public String init(){
this.mk=moviekindManager.getMovieKind(kind_id);
return SUCCESS;
}
public String showmk(){
this.mklist=moviekindManager.showMovieKind();
return SUCCESS;
}
}
• 在struts.xml中配置Action
<!-- 配置struts.objectFactory常量:表示用Spring来处理 -->
<constant name="struts.objectFactory" value="spring"></constant>
<!-- 配置action -->
<package name="movie" extends="struts-default" namespace="/movie">
<action name="addmk" class="addmkBean" method="add">
<result type="redirect-action">listmk.action</result>
</action>
<action name="listmk" class="addmkBean" method="showmk">
<result>listmk.jsp</result>
</action>
</package>
注意:Action的class=“addmkBean” 不是具体的类,只是一个名字,通过Spring
来对action进行对象的注入!通过名字与class=“addmkBean” 来匹配!
method=“add“ 表示该配置处理的方法为add()
<result>listmk.jsp</result> 为返回的视图
• 配置applicationContext.xml:对action进行注入
<!-- 配置action-->
<bean id="addmkBean" class="com.action.MovieKindAction" scope="prototype">
<property name="moviekindManager">
<ref bean="moviekindManager" />
</property>
</bean>
(bean id=“addmkBean“ 与struts.xml中配置的action的class=”addmkBean”来完成匹配
• 编写视图层
addmk.jsp
<body>
请输入电影类别信息:
<s:form action="addmk">
<s:textfield name="mk.name" label="类别名称"></s:textfield>
<s:submit/>
</s:form>
</body>
action=“addmk与struts.xml中配置的action匹配进行action处理(通过web.xml中
的struts2的过滤器来寻找action)
name=“mk.name说明:mk为action类中声明的 private MovieKind mk 实体类变
量.name为MovieKind mk 中实体类的属性,只要名字匹配了,Struts2自动的进
行传值(通过默认拦截器)
listmk.jsp
<body>
<s:iterator value="mklist">
<s:property value="name"/> <br />
</s:iterator>
</body>
value=“mklist为action返回的List变量mklist同样只要名字一样就可以匹配使用
value=”name 为遍历mklist 中实体的具体属性
• 在applicationContext.xml中配置事务管理(aop法)
使用tx来配置事务时应先在xml文件头加上如下红色部分
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
">
然后进行配置:
<!-- 配置事务属性,配置add,delete,updata开始的方法,事务传播属性为required
-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置需要进行事务管理的类, 当前com.service包中的子包、类中的所有方法
需要进行管理,还要参考tx:advice的配置-->
<aop:config>
<aop:pointcut id="allManagerMethod"
expression="execution(* com.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
(* com.service.*.*(..))中几个通配符的含义: 第一个 * 通配 任意返回值类型
(注意后面要跟一个空格!) 第二个 * 通配 包com.service下的任意class 第三
个 * 通配 包com.service下的任意class的任意方法 第四个 .. 通配 方法可以有
0个或多个参数 综上:包com.service下的任意class的具有任意返回值类型、任
意数目参数和任意名称的方法
到此,已完成Struts2+Hibernate+Spring的基本搭建
最后部署、测试、排错!