Spring3.0学习-注解模式下的Spring3+hibernate3+struts2-事务管理(xml模式和注解模式的事务注入+@Repository@Service@Transactional)

一、前言

最近一段时间学习了《Spring 实战(第3版)》的第5、6章,对Spring直接操作数据库有了一定的认识。由于书中前4章例子相对比较完整,学习起来还算顺利,第5、6章内容不是很多,但是涉及的技术迭代范围较广,例子也不是很完全,知识学习期间走了一些弯路,不过还好,总算是通过各种途径找到了最终想学的东西——注解模式下的Spring+Hibernate的基本使用,在完成Spring和hibernate的结合后,本文将加入struts2,这样一个SSH的小例子就算完成了。


事实上,当我完成文章涉及的例子的时候,最深刻的感悟是,Spring起到了统领的作用,然后是bean,自动扫描或者声明,注入,事务管理,中间插件。

对于初次接触Spring的可以先看一下几篇文章

Spring 3.0 学习-环境搭建和三种形式访问

Spring 3.0 学习-DI 依赖注入_创建Spring 配置-使用一个或多个XML 文件作为配置文件,使用自动注入(byName),在代码中使用注解代替自动注入,使用自动扫描代替xml中bean

 Spring3.0 学习-AOP面向切面编程_Spring AOP的XML配置模式

Spring3.0 学习-AOP面向切面编程_Spring AOP的注解模式即Aspectj模式



二、Spring3+Hibernate3注解模式下的结合

1、相关jar包。

如果jar包缺失或者版本不兼容,开发过程会变得十分纠结,所以务必注意版本问题;

这里我把我自己用到的jar包贴出来,struts2、Spring3是从官网下载的,hibernate3是通过maven一点一点“凑出来的”,还有mysql的驱动jar包,此外,本文使用的jdk1.7版本。




2、数据源配置

我使用的是mysql数据库,数据库名称为 test,由于使用了hibernate自动建表,而且表只有两个字段,所以这里不再多说表结构。

<!-- 定义数据源-注解配置 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		<!-- 初始化创建的数据库连接数 -->
		<property name="initialSize" value="${jdbc.initialSize}"/>
		<!-- 数据库连接池最大的连接数 -->
		<property name="maxActive" value="${jdbc.maxActive}"/>
	</bean>

3、sessionFactory配置

含义可以参考文章 http://www.cnblogs.com/lihaoyang/p/4853712.html

	
	<!--  声明Hibernate 的 Session 工厂-->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	    <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->
		<property name="dataSource" ref="dataSource"/>
		<!-- model里含有具体的实体类若干 -->
		<property name="packagesToScan" value="stu.demo.model"/>
		<!-- 可以更换为下面这句 -->
		<!--
		<property name="annotatedClasses">
            <list>
                <value>stu.demo.model.Person</value>
            </list>
		</property>
		-->
		<property name="hibernateProperties">
			<props>
				<prop key=" hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
				 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html -->
			</props>
		</property>
	</bean>
	

4、Spring具有较为完善的异常表达体系

将异常转化为Spring的表达方式,其实就一句配置文件

<!-- 操作异常转化为Spring的表达方式 -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>


5、transactionManager配置

事务管理器配置

<!-- hibernate事物管理器的声明,txAdvice会调用,所以需要声明,如果使用其他的则直接更换即可,和代码是松耦合的 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>


6、tx配置。通过切面将事务管理器织入到指定“接口的实现”

可以看介绍 http://wcp88888888.iteye.com/blog/1279603

6.1 xml配置

这里注意<aop:config>设置切点,可以是采取下面的限定到一个文件夹,但是为了同时实验xml配置和注解配置,我们使用了限定到一个java文件,本例符合下面事务切面配置的java文件只有两个。

<!-- tx设置事物管理,当然还有其他的设置 ,指定管理者为id="transactionManager"的bean,其实不指定也可以Spring自己会注入但是id=transactionManager的这个bean必须声明-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save" propagation="REQUIRED"/>
			<tx:method name="*" propagation="SUPPORTS" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 设置切面,将事物管理通知给方法 -所有实现PersonService接口的方法,对于事务的意义而言-->
	<aop:config>
		<!-- 限定到一个java文件 -->
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..PersonService.*(..))"/>
		
		<!-- 限定到一个文件夹 -->
		<!--<aop:advisor advice-ref="txAdvice" pointcut="execution(* stu.demo.serviceImpl..*(..))"/>-->
	</aop:config>


6.2注解模式

Spring配置文件部分比较简单

<!-- tx:advice和 切点的替代法-注解-->
	<tx:annotation-driven transaction-manager="transactionManager"/>


java部分,需要注解@Transactional以及其他个性化设置
@Transactional(readOnly=false,isolation=Isolation.DEFAULT)

7、代码结构

本文代码结构包含,Dao接口类,Dao实现类(需注解@Repository),Service接口类,Service实现类(需注解@Service以及6.2注解模式下的@Transactional,调用Dao接口),Model类,Spring配置文件(自动注入,切面设置,bean声明,异常转化等),常量文件(数据库驱动等)和测试jave类。

Person.java为实体类,本例演示保存实体对象到mysql数据库。




8、代码

Mode类:Person.java

package stu.demo.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity(name="PERSON")
@Table(name="PERSON")
public class Person {
	private String username;
	private String password;
	
	@Id
	@Column(name="USERNAME",unique=true,nullable=false)
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	
	@Column(name="PASSWORD")
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	

}



Dao接口类:PersonDao.java

package stu.demo.dao;

import stu.demo.model.Person;

public interface PersonDao {
	//使用当前session完成数据库的相关操作
	public void addPerson(Person person);
}

Dao接口类:Person2Dao.java

package stu.demo.dao;

import stu.demo.model.Person;

public interface Person2Dao {
	public void addPerson(Person person);
}

Dao接口实现类:PersonDaoImpl.java

package stu.demo.daoImpl;

import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import stu.demo.dao.PersonDao;
import stu.demo.model.Person;

@Repository
public class PersonDaoImpl implements PersonDao {
	private SessionFactory sessionFactory;
	
	@Autowired
	public PersonDaoImpl(SessionFactory sessionFactory) {
		// TODO Auto-generated constructor stub
		this.sessionFactory=sessionFactory;
	}
	
	//获取当前session
	private Session currentSession(){	
		return sessionFactory.getCurrentSession();
	}
	
	//使用当前session完成数据库的相关操作
	public void addPerson(Person person){
		currentSession().save(person);
	}

}

Dao接口实现类:Person2DaoImpl.java

package stu.demo.daoImpl;

import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import stu.demo.dao.Person2Dao;
import stu.demo.model.Person;

@Repository
public class Person2DaoImpl implements Person2Dao {	
	private SessionFactory sessionFactory;

	@Autowired
	public Person2DaoImpl(SessionFactory sessionFactory){
		this.sessionFactory=sessionFactory;
	}

	public Session currentSession(){	
		return sessionFactory.getCurrentSession();
	}
	
	/**
	 * 保存新用户
	 */
	public void addPerson(Person person) {
		// TODO Auto-generated method stub
		currentSession().save(person);
	}

}

Service接口类:PersonService.java

package stu.demo.service;

import stu.demo.model.Person;

public interface PersonService {
	public void addPerson(Person person);

}


Service接口类:Person2Service.java

package stu.demo.service;

import stu.demo.model.Person;

public interface Person2Service {
	public void addPerson(Person person);

}


service接口实现类:PersonServiceImpl.java

package stu.demo.serviceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import stu.demo.dao.PersonDao;
import stu.demo.model.Person;
import stu.demo.service.PersonService;

@Service
public class PersonServiceImpl  implements PersonService { 
	
	@Autowired
	private PersonDao personDao;
	
	public void addPerson(Person person) {
		// TODO Auto-generated method stub
		personDao.addPerson(person);

	}

}


service接口实现类:Person2ServiceImpl.java

package stu.demo.serviceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import stu.demo.dao.Person2Dao;
import stu.demo.model.Person;
import stu.demo.service.Person2Service;

@Service
@Transactional(readOnly=false,isolation=Isolation.DEFAULT)
public class Person2ServiceImpl implements Person2Service {
	@Autowired
	private Person2Dao person2dao;
	
	public void addPerson(Person person) {
		// TODO Auto-generated method stub
		person2dao.addPerson(person);
	}

}


常量配置

jdbc.properties

#jdbc settings
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
jdbc.initialSize=5
jdbc.maxActive=10

#hibernate settings
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=false
hibernate.format_sql=false
hibernate.hbm2ddl.auto=update

常量配置

application.properties

内容为空


Spring 配置文件

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><!-- 一般化的Spring XML 配置 -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:util="http://www.springframework.org/schema/util"
		xmlns:aop="http://www.springframework.org/schema/aop" 
		xmlns:orm="http://www.springframework.org/schema/orm" 
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
				http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
				http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
				http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-3.0.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
				>
	<!-- 使用注解注入 -->
	<context:component-scan base-package="stu.demo.daoImpl"/>
	<context:component-scan base-package="stu.demo.serviceImpl"/>
	
	<!-- 定义受环境影响易变的变量 -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
		<property name="ignoreResourceNotFound" value="true" />
		<property name="locations">
			<list>
				<!-- 标准配置 -->
				<value>classpath:config/application.properties</value>
				<!-- 数据库配置 -->
				<value>classpath:config/jdbc.properties</value>
			</list>
		</property>
	</bean>
	
	<!-- 定义数据源-注解配置 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		<!-- 初始化创建的数据库连接数 -->
		<property name="initialSize" value="${jdbc.initialSize}"/>
		<!-- 数据库连接池最大的连接数 -->
		<property name="maxActive" value="${jdbc.maxActive}"/>
	</bean>
	
	<!--  声明Hibernate 的 Session 工厂-->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	    <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->
		<property name="dataSource" ref="dataSource"/>
		<!-- model里含有具体的实体类若干 -->
		<property name="packagesToScan" value="stu.demo.model"/>
		<!-- 可以更换为下面这句 -->
		<!--
		<property name="annotatedClasses">
            <list>
                <value>stu.demo.model.Person</value>
            </list>
		</property>
		-->
		<property name="hibernateProperties">
			<props>
				<prop key=" hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
				 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html -->
			</props>
		</property>
	</bean>
	
	<!-- 操作异常转化为Spring的表达方式 -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
	
	<!-- hibernate事物管理器的声明,txAdvice会调用,所以需要声明,如果使用其他的则直接更换即可,和代码是松耦合的 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	
	<!-- tx设置事物管理,当然还有其他的设置 ,指定管理者为id="transactionManager"的bean,其实不指定也可以Spring自己会注入但是id=transactionManager的这个bean必须声明-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save" propagation="REQUIRED"/>
			<tx:method name="*" propagation="SUPPORTS" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 设置切面,将事物管理通知给方法 -所有实现PersonService接口的方法,对于事务的意义而言-->
	<aop:config>
		<!-- 限定到一个java文件 -->
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..PersonService.*(..))"/>
		
		<!-- 限定到一个文件夹 -->
		<!--<aop:advisor advice-ref="txAdvice" pointcut="execution(* stu.demo.serviceImpl..*(..))"/>-->
	</aop:config>
	
	<!-- tx:advice和 切点的替代法-注解-->
	<tx:annotation-driven transaction-manager="transactionManager"/>
	</beans>

测试类:HibernatePersonDaoTest.java

package stu.demo.dao;


import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

import stu.demo.model.Person;
import stu.demo.service.Person2Service;
import stu.demo.service.PersonService;
@DirtiesContext
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring/applicationContext.xml"})
@TransactionConfiguration(transactionManager = "defaultTransactionManager",defaultRollback=false)//事务管理
public class HibernatePersonDaoTest {
	@Autowired
	private PersonService personService;
	
	@Autowired
	private Person2Service person2Service;
	
	/**
	 * <tx:advice+切面 配置事务管理
	 */
	@Test
	public void testaddPerson(){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
		
		Person person=new Person();
		
		person.setUsername("JecketOne"+sdf.format(new Date()));
		person.setPassword("123456");
		
		personService.addPerson(person);
		
	}
	
	/**
	 * <tx:annotation-driven 配置事务管理
	 */
	@Test
	public void testaddPerson2(){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
		
		Person person=new Person();
		
		person.setUsername("JecketTwo"+sdf.format(new Date()));
		person.setPassword("123456");
		
		person2Service.addPerson(person);
		
	}

}

测试类运行结果:

看mysql数据库:



三、增加Struts2

接下来,我们将加入struts2的必要的代码,实现一个SSH为框架的web应用,仅仅保存新用户然后在另一个页面显示用户的名字。

我们需要新加入一个jar包用户在spring中使用struts2

struts2-spring-plugin-2.2.3.1.jar


然后依次是controller类,也就是常说的action类,并且在Spring的配置文件中声明这个类为bean,或者使用“<context:component-scan”自动扫描注册为bean,

接着是struts.xml配置文件,有意思的是,在声明<action>标签中的class时,我们可以不写具体的action类的路径直到名字了,而是可以是这个action类在Spring

配置文件中的名字,如果是自动注册的话,就是类名的“非限定类名”,比如类名为PersonAction,其非限定类名就是personAction。

Spring中@Repository用于声明数据访问组件,这里用于声明Dao类的实现,@Service用于声明业务层的组件,@Controller用于声明控制层组件,@Componen是

三者的泛化,可以应用于任何层,在扫描时告诉Spring本标注类时一个bean。

Spring中@Autowired是注入,等同于byType;@Resource也是注入,等同于byName。


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <!-- Spring ApplicationContext配置文件的路径,可使用通配符,多个路径用,号分隔 此参数用于后面的Spring Context Loader -->  
 <context-param>  
  <param-name>contextConfigLocation</param-name>  
  <param-value>classpath:spring/applicationContext.xml</param-value>  
 </context-param>  
 
 <!-- struts2过滤器配置 -->
 <filter>
  <filter-name>MyFilter</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>MyFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
 </filter-mapping>
  <listener>  
  <description>Spring 刷新 Introspector 防止内存泄露</description>  
  <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
 </listener>  
 <listener>  
  <description>Spring ApplicationContext 载入</description>  
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
 </listener>  
 <session-config>  
  <session-timeout>30</session-timeout>  
 </session-config>  

 <welcome-file-list>
  <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>
 <login-config>
  <auth-method>BASIC</auth-method>
 </login-config>
</web-app>

增加的两个jsp页面


index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    <form method="post" action="<%=path %>/test/register.action">
    	用户名:<input type="text" name="username"><br/>
    	密码:<input type="password" name="password"/><br/>
    	<input type="submit" value="提交">
    </form>
  </body>
</html>

success.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    保存成功:<br/>
    用户名:${person.username}<br/>

  </body>
</html>

控制类/action类 


PersonAction.java  ,此类需(@Controller标注且在Spring配置文件设置自动扫描),或者(直接声明为bean)

package stu.demo.action;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

import stu.demo.model.Person;
import stu.demo.service.PersonService;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings("serial")
@Controller
public class PersonAction extends ActionSupport implements ModelDriven<Person> {
	

	private Person person;
	public Person getModel() {
		if(person==null){
			person=new Person();
		}
		return person;
	}
	
	@Autowired
	private PersonService personService;
	
	public String register(){
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddhhmmss");
		getModel().setUsername(sdf.format(new Date())+getModel().getUsername());
		personService.addPerson(getModel());
		
		ActionContext context=ActionContext.getContext();  
	    Map<String, Object> session=context.getSession();  
	    session.put("person", getModel());
		return SUCCESS;
	}
	
	
}

struts2的配置文件,struts.xml

这里使用了父子文件结构


struts.xml

<?xml version="1.0" encoding="UTF-8"?>
	
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
	
<struts>
	<!-- 请求参数的编码方式 -->  
    <constant name="struts.i18n.encoding" value="UTF-8"/>  
    <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 -->  
    <constant name="struts.action.extension" value="action"/>  
    <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开  -->  
    <constant name="struts.configuration.xml.reload" value="true"/>  
    <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开  --><!--  
    <constant name="struts.devMode" value="false"/>  
    --><!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关 闭  --><!--  
    <constant name="struts.serve.static.browserCache" value="false" />  
	
	
	--><!-- 包含的其他配置文件 -->	
	<include file="struts/struts-method.xml"></include>
	
</struts>

struts-method.xml

注意其中对class的两个注释

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
	"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
		<!-- struts-default-package -->
		<package name="test" extends="struts-default" namespace="/test">
			<!--<action name="*" class="stu.demo.action.PersonAction" method="{1}">-->
			<!--在Spring中, PersonAction 已经被注册为bean了,可以使用其id来调用,声明为personAction,自动扫描的话为非限定类名personAction -->
			<action name="*" class="personAction" method="{1}">
			<result name="success">/success.jsp</result>
				<result name="input">/index.jsp</result>
				
			</action>
		</package>
</struts>

最后是Spring配置文件,其实相比上面的配置只是多了一个控制器类的bean声明/自动扫描声明,但是多了一些注释


applicationContext.xml

这个文件已经写到了web.xml中,在web项目启动的时候,会自动加载

'

<?xml version="1.0" encoding="UTF-8"?><!-- 一般化的Spring XML 配置 -->
<beans xmlns="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xmlns:context="http://www.springframework.org/schema/context"
		xmlns:util="http://www.springframework.org/schema/util"
		xmlns:aop="http://www.springframework.org/schema/aop" 
		xmlns:orm="http://www.springframework.org/schema/orm" 
		xmlns:tx="http://www.springframework.org/schema/tx"
		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
				http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
				http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
				http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-3.0.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
				>
	<!-- 使用注解注入  @Autowired-byType和@Resource-byName-->
	<context:component-scan base-package="stu.demo.daoImpl"/><!--@Repository-->
	<context:component-scan base-package="stu.demo.serviceImpl"/><!-- @Service   事务注入@Transactional(readOnly=false,isolation=Isolation.DEFAULT) -->
	<!-- Controller类注册为bean,也可以显示的写为 
	<bean id="personAction" class="stu.demo.action.PersonAction"/>  可以加scope
	 -->
	<context:component-scan base-package="stu.demo.action"/><!-- @Controller-->
	
	<!--<bean id="personAction" class="stu.demo.action.PersonAction"/>
	
	
	--><!-- 定义受环境影响易变的变量 -->
	<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
		<property name="ignoreResourceNotFound" value="true" />
		<property name="locations">
			<list>
				<!-- 标准配置 -->
				<value>classpath:config/application.properties</value>
				<!-- 数据库配置 -->
				<value>classpath:config/jdbc.properties</value>
			</list>
		</property>
	</bean>
	
	<!-- 定义数据源-注解配置 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
		<property name="driverClassName" value="${jdbc.driverClassName}"/>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		<!-- 初始化创建的数据库连接数 -->
		<property name="initialSize" value="${jdbc.initialSize}"/>
		<!-- 数据库连接池最大的连接数 -->
		<property name="maxActive" value="${jdbc.maxActive}"/>
	</bean>
	
	<!--  声明Hibernate 的 Session 工厂-->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	    <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">-->
		<property name="dataSource" ref="dataSource"/>
		<!-- model里含有具体的实体类若干 -->
		<property name="packagesToScan" value="stu.demo.model"/>
		<!-- 可以更换为下面这句 -->
		<!--
		<property name="annotatedClasses">
            <list>
                <value>stu.demo.model.Person</value>
            </list>
		</property>
		-->
		<property name="hibernateProperties">
			<props>
				<prop key=" hibernate.dialect">${hibernate.dialect}</prop>
				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
				<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
				 <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html -->
			</props>
		</property>
	</bean>
	
	<!-- 操作异常转化为Spring的表达方式 -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
	
	<!-- hibernate事物管理器的声明,txAdvice会调用,所以需要声明,如果使用其他的则直接更换即可,和代码是松耦合的 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>
	
	<!-- tx设置事物管理,当然还有其他的设置 ,指定管理者为id="transactionManager"的bean,其实不指定也可以Spring自己会注入但是id=transactionManager的这个bean必须声明-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="save" propagation="REQUIRED"/>
			<tx:method name="*" propagation="SUPPORTS" read-only="false"/>
		</tx:attributes>
	</tx:advice>
	
	<!-- 设置切面,将事物管理通知给方法 -所有实现PersonService接口的方法,对于事务的意义而言-->
	<aop:config>
		<!-- 限定到一个java文件 -->
		<aop:advisor advice-ref="txAdvice" pointcut="execution(* *..PersonService.*(..))"/>
		
		<!-- 限定到一个文件夹 -->
		<!--<aop:advisor advice-ref="txAdvice" pointcut="execution(* stu.demo.serviceImpl..*(..))"/>-->
	</aop:config>
	
	<!-- tx:advice和 切点的替代法-注解-->
	<tx:annotation-driven transaction-manager="transactionManager"/>
	</beans>


启动服务器:

访问http://localhost:8085/SpringHibernate/    (http://localhost:8085/SpringHibernate/)


点击提交



再看数据库的表,在项目启动时,自动建表,提交后,数据库增加一条数据




后期使用maven实现的ssh的例子

完整的ssh代码请查看 https://github.com/Bestcxy/SSH-ajax-axis2-maven-log4j-redis

如果你还没有加入github 请先阅读 http://blog.csdn.net/bestcxx/article/details/63687217



2017年06月12日补充

junit 测试方法可以控制回滚需继承

public class TClassServiceTest extends AbstractTransactionalJUnit4SpringContextTests{








  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值