首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

Spring中的数据库操作事宜

2012-10-09 
Spring中的数据库操作事务一、Spring中的事务Spring为什么提供对事务的支持?还记得我们在编写OA项目时,为了

Spring中的数据库操作事务

一、Spring中的事务

Spring为什么提供对事务的支持?还记得我们在编写OA项目时,为了统一处理一类事务的多个Dao方法对数据库的操作是在一个事务中进行的,我们添加了一个“*.do”的过滤器,在过滤器中使用当前线程(ThreadLocal)的Session来处理事务。

?

其中我们也曾提到过将事务统一在过滤器中只是为解决一时之需,将事务统一放在Service的方法中才是优雅的做法。我们使用Spring就可以实现将事务统一放在Service的方法上。

?

1.Spring中引入事务

通过外部Bean引入数据源我就不再做总结了,这里直接列出引入Spring中事务类的方法。下面为引入Jdbc的事务管理:

<bean name="transactionManager"ref="dataSource" /></bean><tx:annotation-driven transaction-manager="transactionManager" />
?

“tx”元素指定使用注解进行事务处理的Bean。

?

引入Hibernate的事务管理:

<bean id="sessionFactory"ref="dataSource" /></bean><bean id="transactionManager"ref="sessionFactory" /></bean><tx:annotation-driven transaction-manager="transactionManager" />
?

2.使用Spring的事务

在Service方法上添加事务注解“@Transactional”,此时的Service方法便具有了事务管理。这正是使用AOP的编程思想,在过滤器上添加事务统一管理,也正是AOP的思想。

?

事务的传播性,当一个具有事务的方法调用另一个具有事务的方法时。此时可以设置事务的传播属性,实现不同的需求。事务的传播性有:

传播属性

描述

REQUIRED

如果有事务在运行,当前的方法就在这个事务内运行,否则启动一个新的事务,并在自己的事务内运行。

REQUIRED_NEW

当前的方法必须启动新的事务,并在它自己的事务内运行。如果有事务正在运行,则将它挂起。

SUPPORTS

如果有事务在运行,当前的方法就在这个事务内运行。否则它可以不运行在事务中。

NOT_SUPPORTED

当前的方法 不运行在事务中。如果有运行的事务,将它挂起。

MANDATORY

当前的方法运行在事务内容,如果没有正在运行的事务,则抛异常。

NEVER

当前的方法不应该运行在事务中。如果有运行的事务,则抛异常。

NESTED

如果有事务在运行,当前的方法在这个事务的嵌套事务内运行。否则,启动一个新的事务,并在它自己的事务内运行。

前两项是常用的。

?

“Transactional”注解所具有的属性:

?

?

@Transactional(propagation=Propagation.REQUIRES_NEW, // 事务传播属性isolation=Isolation.READ_COMMITTED,// 事务隔离级别rollbackFor=Exception.class,// 异常回滚unrollbackFor=IOException.class,// 异常不回滚timeout=2, // 超时事务readOnly=false)// 只读事务
?

?

?

属性

类型

描述

propagation

枚举型:Propagation

可选的传播性设置

isolation

枚举型:Isolation

可选的隔离性级别(默认值:ISOLATION_DEFAULT)

readOnly

布尔型

读写型事务 vs. 只读型事务。只读型事务一般用于查询。

timeout

int型(以秒为单位)

事务超时,如果在指定时间内没有完成事务,事务则回滚。

rollbackFor

一组 Class 类的实例,必须是Throwable 的子类

一组异常类,遇到时 必须 进行回滚。默认情况下checked exceptions不进行回滚,仅unchecked exceptions(即RuntimeException的子类)才进行事务回滚。

rollbackForClassname

一组 Class 类的名字,必须是Throwable的子类

一组异常类名,遇到时 必须 进行回滚

noRollbackFor

一组 Class 类的实例,必须是Throwable 的子类

一组异常类,遇到时 必须不 回滚。

noRollbackForClassname

一组 Class 类的名字,必须是Throwable 的子类

一组异常类,遇到时 必须不 回滚

?

使用XML文件配置Spring事务:

<tx:advice id="testTransaction" transaction-manager="transactionManager"><tx:attributes><tx:method name="methodName" propagation="REQUIRED"read-only="false" rollback-for="Expetion" timeout="2" isolation="READ_COMMITTED" /></tx:attributes></tx:advice><aop:config><aop:pointcut expression="execution(* cn.itcast.cc.spring.transaction.*.*(..))"id="aopTransaction" /><aop:advisor advice-ref="testTransaction" pointcut-ref="aopTransaction" /></aop:config>
?

二、Spring整合Hibernate

Spring支持大多数流行的ORM框架,包括HibernateJDO,TopLink,Ibatis和JPA。它这些ORM框架的支持是一致的,因此可以把和Hibernate整合技术应用到其他ORM框架上。Spring2.0同时支持Hibernate2.x和3.x。但Spring2.5只支持Hibernate3.1或更高版本

?

1.Spring中配置SessionFactory

<bean id="sessionFactory"ref="dataSource" /></bean>
?

其中的DataSource是我们在第一天就讲到的使用外部Bean配置数据源。

?

虽然我们使用的数据源是一个Bean,它涉及到Hibernate私有配置的信息被声明在“hibernate.cfg.xml”文件中。但现在我们可以这个外在的“hibernate.cfg.xml”文件,我们需要在上面的baen中添加:


<bean id="sessionFactory"ref="dataSource" /><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property><property name="mappingResources"><list><value>cn/itcast/spring/hibernate/Customer.hbm.xml</value></list></property></bean>
?

OK,SessionFactory已经被我们整合进来了!十分简单,跟其他的类一样。

?

还记得我们昨天使用的JdbcTemplate吗?那是Spring为JDBC提供的支持,Spring也有为Hibernate提供支持:

支持类

JDBC

Hibernate

模板类

JdbcTemplate

HibernateTemplate

DAO支持类

JdbcDaoSupport

HibernateDaoSupport

事务管理类

DataSourceTransactionManager

HibernateTransactionManager

?

使用HibernateTemplate,需要声明一个Bean:

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

?

?

DAO支持类对我们来说比较陌生,HibernateDAO可以通过继承HibernateDaoSupport来继承setSessionFactory()和setHibernateTemplate()方法。然后,只要在DAO方法中调用getHibernateTemplate()方法就可以获取到模板实例。

?

三、Spring整合Struts1.x

?

1.通过注册Servlet监听器ContextLoaderListener,Web应用程序可以加载Spring的ApplicationContext对象。这个监听器会将加载好的ApplicationContext对象保存到Web应用程序的ServletContext中。随后,Servlet或可以访问ServletContext的任意对象就能通过一个辅助方法来访问Spring的应用程序上下文了。

?

<context-param><param-name>contextConfigFile</param-name><param-value>beans.xml</param-value></context-param><listener><listener-class>cn.itcast.cc.spring.SpringServletContextListener</listener-class></listener>
?

在SpringServletContextListener的contextInitialized方法中:

public void contextInitialized(ServletContextEvent arg0) {String cfgFile = arg0.getServletContext().getInitParameter("contextConfigFile");ApplicationContext ac = new ClassPathXmlApplicationContext(cfgFile);arg0.getServletContext().setAttribute("applicationContext", ac);}
?

以后在Action中需要使用SpringIOC容器中的Bean时,就可以先到ServletContext中去获取ApplicationContext,然后再获取相应的Bean。

?

2.在web.xml文件中注册Spring提供的Servlet监听器ContextLoaderListener,它会在当前web应用被加载时将Spring的ApplicationContext保存到ServletContext对象中。

?

ContextLoaderListener监听器通过查找web应用初始化参数contextConfigLocation来获取Bean配置文件的位置。如果有多个Bean配置文件,可以通过逗号或空格进行分隔。contextConfigLocation的默认值为/WEB-INF/applicationContext.xml。若实际的文件和默认值一致则可以省略这个web应用的初始化参数。

<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:beans.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
?

在需要Bean的Action或Servlet中获取Bean的方法:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServletContext());ac.getBean("beanName");}
?

3.通过注册Servlet监听器ContextLoaderListener,Struts应用程序能够加载Spring的ApplicationContext对象,并像在通用的Web应用程序中那样在Servlet上下文中对它进行访问。然而,Spring还提供了更好的,特定于Struts的解决方案。

    在struts配置文件中注册Struts插件来加载应用程序上下文,它会自动引用Servlet监听器加载的应用程序上下文作为它的父上下文,以便可以引用其中声明的Bean。

    <plug-in  className="org.springframework.web.struts.ContextLoaderPlugIn"><set-property property="contextConfigLocation"value="classpath:struts-config.xml,classpath:beans.xml" /></plug-in>
    ?

      Spring提供了一个ActionSupport对象,这是Action类的一个子类,通过它的getWebApplicationContext()方法可以获取到Spring的应用程序上下文。

public  class LoginAction extends ActionSupport {@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {ApplicationContext ac = this.getWebApplicationContext();HelloSpring hs = (HelloSpring) ac.getBean("helloSpring");request.setAttribute("message", hs.hello("changcheng"));return mapping.findForward("success");}}
?

    在spring的应用程序上下文中声明Struts的Action对象,使用Spring的依赖注入来注入Spring应用程序上下文的其他Bean。

?

我们的Action类:

public  class LoginAction extends Action {private HelloSpring helloSpring;public void setHelloSpring(HelloSpring hs) {this.helloSpring = hs;System.out.println("*****注入*****:" + this.helloSpring);}@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response)throws Exception {request.setAttribute("message", this.helloSpring.hello("changcheng"));return mapping.findForward("success");}}
?

在struts-config.xml中将的Action配置为:

<action-mappings><action path="/login"><forward name="success" path="/success.jsp" /></action></action-mappings><controller processor/>
?

在beans.xml中配置:

<bean  id="helloSpring"   /><bean name="/login" ref="helloSpring"/></bean>
?

这种方法也需要“1)”的plug-in。

?

四、SSH整合(SpringStruts1.xHibernate

将上面的二和三放到一起就是SSH整合,佟老师使用一个使用注册的例子演示SSH整合。我只简单说一下思想吧!

?

1).创建动态WEB工程。

2).在web.xml添加spring的“ContextLoaderListener”监听器和Struts的ActionServlet。

3).在Spring的配置文件中引入数据源和Hibernate的SessionFactory和HibernateTransactionManager。

4).为struts添加spring的“DelegatingRequestProcessor”控制器。

5).为Action、Service、Dao添加Spring的AOP注解。

热点排行