JavaEE企业级项目开发(第3版)课件 单元6 Spring的数据库开发与事务_第1页
JavaEE企业级项目开发(第3版)课件 单元6 Spring的数据库开发与事务_第2页
JavaEE企业级项目开发(第3版)课件 单元6 Spring的数据库开发与事务_第3页
JavaEE企业级项目开发(第3版)课件 单元6 Spring的数据库开发与事务_第4页
JavaEE企业级项目开发(第3版)课件 单元6 Spring的数据库开发与事务_第5页
已阅读5页,还剩84页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

延迟符SpringJDBC支持Spring的数据库开发与事务SpringDAO框架

DAO(DataAccessObject)是用于访问数据的对象,虽然我们在大多数情况下,将数据保存在数据库中,但这并不是唯一的选择,你也可以将数据存储到文件中或LDAP中。DAO不但屏蔽了数据存储的最终介质的不同,也屏蔽了具体的实现技术的不同。SpringDAO框架

早期,JDBC是访问数据库的主流选择,近几年,数据持久技术获得了长足的发展,Hibernate、iBatis、JPA、JDO成为持久层中争放异彩的实现技术。SpringDAO框架DAO接口层应用好处:可以很容易地构造模拟对象,方便单元测试的开展其次在使用切面时,既可用JDK动态代理也可用CGLib动态代理

Spring以统一的方式整合底层的持久化技术:以统一方式进行调用及事务管理,避免让具体的实现侵入到业务层的代码中。每个持久化实现技术都有各自的异常体系,Spring提供了统一的异常体系,方便定义和具体实现技术无关的DAO接口,以便整合到相同的事务管理体系中。SpringDAO框架Spring典型的数据操作模式:Spring为各种支持的持久化技术提供了简化操作的模板和回调在回调中编写具体的数据操作逻辑使用模板执行数据操作SpringDAO框架Spring为不同的持久化技术所提供的模板类:JDBCorg.springframework.jdbc.core.JdbcDaoSupport

Hibernateorg.springframework.orm.hibernate.HibernateDaoSupport

Hibernate3.0org.springframework.orm.hibernate3.HibernateDaoSupportiBatis

org.springframework.orm.ibatis.SqlMapClientDaoSupport

JPAorg.springframework.orm.jpa.JpaDaoSupport

JDOorg.springframework.orm.jdo.JdoDaoSupport

TopLink

org.springframework.orm.jpa.JpaDaoSupport

这些支持类都继承于dao.support.DaoSupport类,该类实现了InitializingBean接口,在afterPropertiesSet()接口方法中检查模板对象和数据源是否被正确设置,否则将抛出异常。SpringDAO框架

Spring为不同的持久化技术所提供的模板类:所有支持类都是抽象的,目的是希望被继承,而非直接使用。如果直接使用模板类,一般都需要在DAO中定义一个模板对象并提供数据资源。Spring为每一个持久化技术都提供了支持类,支持类中完成这样的功能。只需要扩展支持类就可以直接编写实际的数据访问逻辑。SpringDAO框架不同持久化技术的支持类:ORM持久化技术支持类JDBCorg.springframework.jdbc.core.JdbcDaoSupportHibernateorg.springframework.orm.hibernate.HibernateDaoSupportHibernate3.0org.springframework.orm.hibernate3.HibernateDaoSupportiBatisorg.springframework.orm.ibatis.SqlMapClientDaoSupportJPAorg.springframework.orm.jpa.JpaDaoSupportJDOorg.springframework.orm.jdo.JdoDaoSupportTopLinkorg.springframework.orm.jpa.JpaDaoSupportSpringJDBC支持在使用JDBC类操作数据库时,要处理很多相同、繁琐的细节,如:获取数据库的连接创建Statement处理数据库异常关闭数据库资源等Spring提供了几个类用来简化JDBC

API的使用SpringJDBC支持JdbcTemplate类:JdbcTemplate构造函数请求一个DataSource对象来完成初始化。(1)使用JdbcTemplate的execute()方法执行SQL语句execute方法使用java.sql.Statement,SQL语句不带参数,且不返回受影响记录的计数,更适合于创建和丢弃表的语句。jdbcTemplate.execute("CREATE

TABLE

USER

(user_id

integer,

name

varchar(100)");

SpringJDBC支持JdbcTemplate类:(2)增加、删除和修改update方法返回的是受影响的记录数目的一个计数,如果传入参数的话,使用的是java.sql.PreparedStatement,更适合于插入,更新和删除操作。①不带参数的更新jdbcTemplate.update("INSERT

INTO

USER

VALUES('"

+

user.getId()

+

"',

'"

+

user.getName()

+

"',

'"

+

user.getSex()

+

"',

'"

+

user.getAge()

+

"')");

SpringJDBC支持JdbcTemplate类:(2)增加、删除和修改②带参数的修改//修改带参数jdbcTemplate.update("UPDATE

USER

SET

name

=

?

WHERE

user_id

=

?",

new

Object[]

{name,

id});

//插入带参数jdbcTemplate.update("INSERT

INTO

USER

VALUES(?,

?,

?,

?)",

new

Object[]

{user.g

etId(),

user.getName(),

user.getSex(),

user.getAge()});

SpringJDBC支持JdbcTemplate类:(3)JDBC的PreparedStatement①单个更新jdbcTemplate.update("INSERT

INTO

USER

VALUES(?,

?,

?,

?)",

new

PreparedStatementSetter()

{

public

void

setValues(PreparedStatement

ps)

throws

SQLException

{

ps.setString(1,

id);

ps.setString(2,

name);

ps.setString(3,

sex);

ps.setInt(4,

age);

}

});

注意:匿名内部类只能访问外部最终局部变量SpringJDBC支持JdbcTemplate类:(3)JDBC的PreparedStatement②批量更新publicinterfaceBatchPreparedStatementSetter{

voidsetValues(PreparedStatementps,inti)throwsSQLException;

intgetBatchSize();}......publicint[]insertUsers(finalListusers){

Stringsql="INSERTINTOuser(name,age)VALUES(?,?)";

BatchPreparedStatementSettersetter=newBatchPreparedStatementSetter(){

publicvoidsetValues(

PreparedStatementps,inti)throwsSQLException{

Useruser=(User)users.get(i);

ps.setString(1,user.getName());

ps.setInt(2,user.getAge().intValue());}

publicintgetBatchSize(){returnusers.size();}};

returnjdbcTemplate.batchUpdate(sql,setter);}......SpringJDBC支持JdbcTemplate类:(4)查询①使用JdbcTemplate进行查询时,使用queryForXXX()等方法。int

count

=

jdbcTemplate.queryForInt("SELECT

COUNT(*)

FROM

USER");

String

name

=

(String)

jdbcTemplate.queryForObject("SELECT

name

FROM

USER

WHERE

user_id

=

?",

new

Object[]

{id},

java.lang.String.class);

//queryForList返回的List中的对象是MapList

rows

=

jdbcTemplate.queryForList("SELECT

*

FROM

USER");

Iterator

it

=

rows.iterator();

while(it.hasNext())

{

Map

userMap

=

(Map)

it.next();

System.out.print(userMap.get("user_id")

+

"\t");

System.out.print(userMap.get("name")

+

"\t");

System.out.print(userMap.get("sex")

+

"\t");

System.out.println(userMap.get("age")

+

"\t");

}

SpringJDBC支持JdbcTemplate类:(4)查询②JDBC的callback方式—单行查询final

User

user

=

new

User();

jdbcTemplate.query("SELECT

*

FROM

USER

WHERE

user_id

=

?",new

Object[]

{id},

new

RowCallbackHandler()

{

public

void

processRow(ResultSet

rs)

throws

SQLException

{

user.setId(rs.getString("user_id"));

user.setName(rs.getString("name"));

user.setSex(rs.getString("sex").charAt(0));

user.setAge(rs.getInt("age"));

}

});

SpringJDBC支持JdbcTemplate类:(4)查询②JDBC的callback方式—多行查询finalListemployees=newLinkedList();jdbc.query("selectEMPNO,FIRSTNME,LASTNAMEfromEMPLOYEE",newRowCallbackHandler(){

publicvoidprocessRow(ResultSetrs)throwsSQLException{

Employeee=newEmployee();

e.setEmpNo(rs.getString(1));

e.setFirstName(rs.getString(2));

e.setLastName(rs.getString(3));

employees.add(e);

}});

SpringJDBC支持NamedParameterJdbcTemplate类:JdbcTemplate模板类类中所有SQL语句中参数都是使用占位符(?)来表示的,编程麻烦。为了解决这个问题,Spring提供了NamedParameterJdbcTemplate支持命名参数的模板类。NamedParameterJdbcTemplate类封装了JdbcTemplate类,提供了使用命名参数的方式来设置SQL语句中动态值。SpringJDBC支持NamedParameterJdbcTemplate的命名参数操作:(1)指定命名参数SQL中指定命名操作的语法格式为:“:parameterName“(2)设置命名参数使用Map设置命名参数的值:key对应操作的名称,value对应参数的值;使用SqlParameterSource接口的实现类MapSqlParameterSource,本质上还是使用Map传递参数;使用SqlParameterSource接口的实现类BeanPropertySqlParameterSource,使用Bean对象来传递参数,此时Bean对象中属性的名称必须与命名参数保持一致。谢谢观看主讲人:石云延迟符添加申请设计Spring的数据库开发与事务添加申请设计

添加申请是工作流转的基础模块,主要功能是编辑公文,提交给指定部门审批。添加申请的设计应用Servlet与Spring框架结合的方式开发,用户在视图层页面输入申请标题、申请内容,Servlet控制层获取输入的申请信息,并调用模型层的服务方法将申请信息保存到数据库中,最后调用显示所有申请的方法返回到所有申请页面。添加申请设计

添加申请实施分为5个步骤:DAO层、Service层、Servlet控制层、视图层、applicationContex.xml文件配置。本任务重点介绍DAO层实现类的设计、Servlet控制类的设计。添加申请DAO层实现类添加申请DAO层中添加申请方法中使用了JdbcTemplate类,通过执行jdbcTemplate.update()方法保存数据,参数通过PreparedStatement对象传递。//添加申请数据访问层实现类@Data@ComponentpublicclassApplyDAOimplementsIApplyDAO{ @Autowired privateJdbcTemplatejdbcTemplate; @Autowired privateDataSourcedataSource; @Autowired privateDataSourceTransactionManagertransactionManager; privateDefaultTransactionDefinitiondef;//获得所有申请publicListgetAllApply(){Stringsql="select*fromtb_application";ListapplyList=jdbcTemplate.queryForList(sql);returnapplyList;}添加申请DAO层实现类增加申请方法,主要步骤://增加申请publicbooleanaddApply(Applyapply){finalStringtitle=apply.getTitle();finalStringapplyContent=apply.getApplyContent();finalStringapplyDate=apply.getApplyDate();finalintuserId=apply.getUserId();finalintdepartId=apply.getDepartId();finalStringapprovePerson=apply.getApprovePerson();finalStringapproveDate=apply.getApplyDate();finalStringapproveView=apply.getApproveView();finalintstatus=apply.getStatus();

inti=jdbcTemplate.update(newPreparedStatementCreator(){publicPreparedStatementcreatePreparedStatement(Connectioncon)throwsSQLException{Stringsql="insertintotb_applicationvalues(?,?,?,?,?,?,?,?,?)";PreparedStatementps=con.prepareStatement(sql);ps.setString(1,title); ps.setString(2,applyContent); ps.setString(3,applyDate); ps.setInt(4,userId); ps.setInt(5,departId); ps.setString(6,approvePerson); ps.setString(7,approveDate); ps.setString(8,approveView); ps.setInt(9,status); returnps;}});if(i>0){returntrue;}else{returnfalse;}}}添加申请控制Servlet类添加申请控制类负责接收用户输入的申请信息,调用申请服务类添加申请方法保存申请信息到数据库表中,为了能查看已经有的申请,调用查询所有的申请方法,最后返回到显示所有申请的页面。@WebServlet("/applyController")publicclassApplyControllerextendsHttpServlet{IApplyServiceapplyService=null;publicvoidinit(ServletConfigservletConfig)throwsServletException{ServletContextsc=servletConfig.getServletContext();WebApplicationContextwac=WebApplicationContextUtils.getWebApplicationContext(sc);applyService=wac.getBean("applyService",ApplyService.class);}protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseres)throwsServletException,IOException{……if(action.equals("add")){//添加申请SimpleDateFormatsf=newSimpleDateFormat("yyyy-MM-dd");//获取申请时间

Applyapply=newApply();//创建Apply对象apply.setTitle(title);......//调用申请服务方法保存申请booleanresult=applyService.addApply(apply);if(result){res.sendRedirect(this.showAllApply(req));}else{res.sendRedirect("error.jsp");}}}添加申请控制Servlet类获取所有申请方法,主要步骤://获取所有申请publicStringshowAllApply(HttpServletRequestreq){Listapplylist=applyService.getAllApply();ListapplicationList=newArrayList();//将applylist中的Map转换为Apply对象Iteratorit=applylist.iterator();while(it.hasNext()){MapappMap=(Map)it.next();Applyapply=newApply();IntegerapplyId=(Integer)appMap.get("applyId");Stringtitle=(String)appMap.get("title");StringapplyContent=(String)appMap.get("applyContent");StringapplyDate=(String)appMap.get("applyDate");IntegeruserId=(Integer)appMap.get("userId");IntegerdepartId=(Integer)appMap.get("departId");Integerstatus=(Integer)appMap.get("status");apply.setApplyId(applyId);apply.setTitle(title);apply.setApplyDate(applyDate);apply.setUserId(userId);apply.setDepartId(departId);apply.setApproveView(approveView);apply.setStatus(status);applicationList.add(apply);}HttpSessionsession=req.getSession();session.setAttribute("applylist",applicationList);return"showAllAply.jsp";}}运行效果谢谢观看主讲人:石云延迟符编程式事务Spring的数据库开发与事务Spring事务简介

事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性。Spring事务简介

Spring中提供了丰富的事务管理功能,它们超过了EJB并且和EJB一样支持声明式事务,重要的是Spring提供了一致的事务管理,它有如下优点。为不同的事务的API提供一致的编程模式;提供更简单,更易使用的编程式事务管理;支持Spring声明事务;整合Spring对数据访问的抽象。Spring事务简介在Spring中,事务是通过TransactionDefinition接口来定义的。该接口包含与事务属性有关的方法。TransactionDefinition接口中定义的主要方法如下所示。publicinterfaceTransactionDefinition{intgetPropagationBehavior();intgetIsolationLevel();intgetTimeout();booleanisReadOnly();}

Spring事务简介传播行为传播行为定义了事务应用于方法上之边界(Boundaries),它告知何时该开始一个新的事务,或何时事务该被暂停,或方法是否要在事务中进行。Spring事务简介传播行为Spring定义了几个传播行为,常用的传播行为如下所示。PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务;PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行;PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常;PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。

Spring事务简介隔离级别在一个应用程序中,可能有多个事务同时进行,由于事务彼此独立,若读取的是同一个数据,容易发生问题。根据需求的不同,

隔离级别可以根据实际需求,对数据的锁定进行设置。Spring事务简介隔离级别Spring提供了几种隔离级别设置,如下所示。ISOLATION_DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。

Spring事务简介事务超时所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在TransactionDefinition中以int的值来表示超时时间,其单位是秒。Spring事务简介事务的只读属性事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、JMS资源,以及自定义的事务性资源等等。编程式事务Spring提供的事务管理API,可以在代码中灵活控制事务的执行。在底层,Spring仍然将事务操作委托给底层的持久化框架来执行。Spring提供两种方式的编程式事务管理:使用TransactionTemplate和PlatformTransactionManager。编程式事务TransactionTempale采用和其他Spring模板,如JdbcTempalte和HibernateTemplate一样的方法。它使用回调方法,把应用程序从处理取得和释放资源中解脱出来。必须在事务上下文中执行的应用代码看起来像这样,注意使用TransactionCallback可以返回一个值,代码如下:jdbcTemplate.execute("CREATE

TABLE

USER

(user_id

integer,

name

varchar(100)");

Objectresult=tt.execute(newTransactionCallback(){publicObjectdoInTransaction(TransactionStatusstatus){updateOperation1();returnresultOfUpdateOperation2();}});编程式事务TransactionTempale如果没有返回值,使用TransactionCallbackWithoutResult,

代码如下:tt.execute(newTransactionCallbackWithoutResult(){protectedvoiddoInTransactionWithoutResult(TransactionStatusstatus){updateOperation1();updateOperation2();}});编程式事务使用PlatformTransactionManager

可以使用

org.springframework.transaction.PlatformTransactionManager直接管理事务。简单地通过一个bean引用给你的bean传递一个PlatformTransactionManager实现。然后,使用TransactionDefinition和TransactionStatus对象就可以发起事务,回滚和提交。jdbcTemplate.execute("CREATE

TABLE

USER

(user_id

integer,

name

varchar(100)");

DefaultTransactionDefinitiondef=newDefaultTransactionDefinition()def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatusstatus=transactionManager.getTransactionDefinition(def);try{//executeyourbusinesslogichere}catch(MyExceptionex){transactionManager.rollback(status);throwex;}transactionMmit(status);编程式事务【例6-1】编程式事务实例分析。主要步骤:创建用户类;创建数据库访问业务类;创建测试类;创建配置文件。编程式事务【例6-1】编程式事务实例分析。步骤1:创建用户类@DatapublicclassUser{privateStringname;privateStringpassword;privateIntegerage;}编程式事务【例6-1】编程式事务实例分析。步骤2:创建数据库访问业务类publicclassUserDao{privateDataSourcedataSource;privateJdbcTemplatetemplate;publicDataSourcegetDataSource(){returndataSource;}publicvoidsetDataSource(DataSourcedataSource){this.dataSource=dataSource;template=newJdbcTemplate(dataSource);transactionManager=newDataSourceTransactionManager(dataSource);def=newDefaultTransactionDefinition();//异常处理机制def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);}

编程式事务【例6-1】编程式事务实例分析。步骤2:创建数据库访问业务类publicvoidinsert(Useruser){//添加用户Stringname=user.getName();intage=user.getAge().intValue();TransactionStatusstatus=transactionManager.getTransaction(def);try{//下面的SQL有错误,用于测试事务template.update("INSERINTOtb_user2(name,age)"+"VALUES('"+name+"',"+age+")");}catch(DataAccessExceptione){transactionManager.rollback(status);//回滚到status这个状态System.out.println("执行回滚操作了!");throwe;}transactionMmit(status);System.out.println("成功提交了!");}}

编程式事务【例6-1】编程式事务实例分析。步骤3:创建测试类publicclassTestTransaction{publicstaticvoidmain(String[]args){//加载配置文件ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");//获取UserDao实例UserDaodao=(UserDao)applicationContext.getBean("userDao");Useruser=newUser();user.setName("cf");user.setPassword("123");user.setAge(1);dao.insert(user);}}

编程式事务【例6-1】编程式事务实例分析。步骤4:创建配置文件<context:property-placeholderlocation="classpath:perties"/> <!--配置数据源--><beanid="dataSource"class="mons.dbcp2.BasicDataSource"> <propertyname="driverClassName"value="${db.driver}"/> <propertyname="url"value="${db.url}"/> <propertyname="username"value="${db.username}"/> <propertyname="password"value="${db.password}"/> <propertyname="maxIdle"value="5"/> </bean>编程式事务【例6-1】编程式事务实例分析。步骤4:创建配置文件<context:property-placeholderlocation="classpath:perties"/><beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"/> <beanid="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <propertyname="dataSource"ref="dataSource"/> </bean> <!--定义id为userDao的Bean--> <beanid="userDao"class="cn.js.ccit.dao.UserDao"> <propertyname="template"> <refbean="jdbcTemplate"/> </property> <propertyname="dataSource"ref="dataSource"/> </bean>

编程式事务【例6-1】编程式事务实例分析。运行结果:谢谢观看主讲人:石云延迟符修改申请设计Spring的数据库开发与事务修改申请设计

修改申请的主要功能是用户在申请没有审批之前,可以修改申请内容。本任务实施的重点是事务的处理,即在修改时增加事务管理。本任务使用编程式事务管理,实现方式:使用TransactionManager实现编程事务;使用TransactionTemplate类实现编程事务。使用TransactionManager实现编程事务修改申请DAO实现类,增加DataSource、DataSourceTransactionManager、DefaultTransactionDefinition属性的定义,在修改申请代码中增加事务处理。修改申请的代码如下所示。classApplyDAOimplementsIApplyDAO{ @Autowired privateJdbcTemplatejdbcTemplate; @Autowired privateDataSourcedataSource; @Autowired privateDataSourceTransactionManagertransactionManager; privateDefaultTransactionDefinitiondef;使用TransactionManager实现编程事务publicbooleanupdateApply(Applyapply){ //事务管理对象 transactionManager=newDataSourceTransactionManager(dataSource); //事务定义 def=newDefaultTransactionDefinition(); def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); TransactionStatusstatus=transactionManager.getTransaction(def); inti=0; try{ finalintapplyId=apply.getApplyId(); finalStringtitle=apply.getTitle(); finalStringapplyContent=apply.getApplyContent(); finalStringapplyDate=apply.getApplyDate(); i=jdbcTemplate.update(newPreparedStatementCreator(){ publicPreparedStatementcreatePreparedStatement(Connectioncon) throwsSQLException{ Stringsql="updatetb_applicationsettitle=?,applyContent=?,applyDate=?whereapplyId=?"; PreparedStatementps=con.prepareStatement(sql); ps.setString(1,title); ……//设置applyContet、applyDate、applyId参数 returnps;}});使用TransactionManager实现编程事务intj=jdbcTemplate.update(newPreparedStatementCreator(){ publicPreparedStatementcreatePreparedStatement(Connectioncon) throwsSQLException{ //故意设置update为updat Stringsql="updattb_applicationsettitle=?,applyContent=?,applyDate=?whereapplyId=?"; PreparedStatementps=con.prepareStatement(sql); ps.setString(1,title); ps.setString(1,title); ……//设置applyContet、applyDate、applyId参数 returnps;}}); transactionMmit(status);//事务提交 }catch(DataAccessExceptione){ transactionManager.rollback(status);//事务回滚}……}使用TransactionTemplate类实现编程事务使用TransactionTemplate类实现编程事务首先创建TransactionTemplate对象,然后设置事务定义,调用execute()方法实现事务管理。修改的申请的代码如下所示。//修改申请:使用TransactionTemplate管理事务publicbooleanupdateApply(Applyapply){ finalintapplyId=apply.getApplyId(); finalStringtitle=apply.getTitle(); finalStringapplyContent=apply.getApplyContent(); finalStringapplyDate=apply.getApplyDate();transactionManager=newDataSourceTransactionManager(dataSource);//事务管理对象TransactionTemplatetransactionTemplate=newTransactionTemplate(transactionManager); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

使用TransactionTemplate类实现编程事务transactionTemplate.execute(newTransactionCallbackWithoutResult(){protectedvoiddoInTransactionWithoutResult(TransactionStatusstatus){​jdbcTemplate.update(newPreparedStatementCreator(){​publicPreparedStatementcreatePreparedStatement(finalConnectioncon)throwsSQLException{​finalStringsql="updatetb_applicationsettitle=?,applyContent=?,applyDate=?whereapplyId=?";​finalPreparedStatementps=con.prepareStatement(sql);​ps.setString(1,title);​//ps设置applyContent、applyDate、applyId参数​returnps;}});​​使用TransactionTemplate类实现编程事务intj=jdbcTemplate.update(newPreparedStatementCreator(){​publicPreparedStatementcreatePreparedStatement(Connectioncon)​throwsSQLException{​Stringsql="updattb_applicationsettitle=?,applyContent=?,applyDate=?whereapplyId=?";​PreparedStatementps=con.prepareStatement(sql);​ps.setString(1,title);​**……**​//ps设置applyContent、applyDate、applyId参数

​returnps;}});}});​returntrue;}谢谢观看主讲人:石云延迟符基于Spring注解方式的事务管理配置Spring的数据库开发与事务Spring的声明式事务

底层建立在AOP基础上。本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。Spring的声明式事务

声明式事务,有以下优点。不需要通过编程的方式管理事务,不需要在业务逻辑代码中掺杂事务管理的代码。事务管理是一个典型的横切逻辑。AOP为声明式事务提供了简单而强大的支持。只需在配置文件中做相关的事务规则声明(或通过等价的基于标注的方式),便可以将事务规则应用到业务逻辑中。Spring的声明式事务1.基于TransactionInter的声明式事务管理Spring提供了TransactionInterceptor类来实施声明式事务管理功能。Spring的声明式事务<beanid="transactionInterceptor"class="erceptor.TransactionInterceptor"><propertyname="transactionManager"ref="transactionManager"/><propertyname="transactionAttributes"><props><propkey="transfer">PROPAGATION_REQUIRED</prop></props></property></bean><beanid="bankServiceTarget"class="footmark.spring.core.tx.declare.origin.BankServiceImpl"><propertyname="bankDao"ref="bankDao"/></bean><beanid="bankService"class="org.springframework.aop.framework.ProxyFactoryBean"><propertyname="target"ref="bankServiceTarget"/><propertyname="interceptorNames"><list><idrefbean="transactionInterceptor"/></list></property></bean>Spring的声明式事务指定事务属性的取值的规则传播行为[,隔离级别][,只读属性][,超时属性][不影响提交的异常][,导致回滚的异常]传播行为必须设置,取值必须以“PROPAGATION_”开头,具体包括:PROPAGATION_MANDATORYPROPAGATION_NESTEDPROPAGATION_NEVERPROPAGATION_NOT_SUPPORTEDPROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_SUPPORTS隔离级别的取值必须以“ISOLATION_”开头,具体包括:ISOLATION_DEFAULTISOLATION_READ_COMMITTEDISOLATION_READ_UNCOMMITTEDISOLATION_REPEATABLE_READISOLATION_SERIALIZABLESpring的声明式事务示例1:<propertyname="*Service">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20,+AbcException,+DefException,-HijException</property>针对所有方法名以Service结尾的方法,使用PROPAGATION_REQUIRED事务传播行为,事务的隔离级别是ISOLATION_READ_COMMITTED,超时时间为20秒,当事务抛出AbcException或者DefException类型的异常,则仍然提交,当抛出HijException类型的异常时必须回滚事务。这里没有指定“readOnly”,表示事务不是只读的。Spring的声明式事务示例2:<propertyname="test">PROPAGATION_REQUIRED,readOnly</property>针对所有方法名为test的方法,使用PROPAGATION_REQUIRED事务传播行为,并且该事务是只读的。除此之外,其他的属性均使用默认值。比如,隔离级别和超时时间使用底层事务性资源的默认值,并且当发生未检查异常,则回滚事务,发生已检查异常则仍提交事务。Spring的声明式事务【例6-2】Spring支持声明式事务实例。配置文件spring.xml的代码如下:<context:property-placeholderlocation="classpath:perties"/><!--配置数据源--><beanid="dataSource"class="mons.dbcp2.BasicDataSource"> <propertyname="driverClassName"value="${db.driver}"/> <propertyname="url"value="${db.url}"/> <propertyname="username"value="${db.username}"/> <propertyname="password"value="${db.password}"/> <propertyname="maxIdle"value="5"/></bean><beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><propertyname="dataSource"><refbean="dataSource"/></property></bean>

Spring的声明式事务<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"/><!--声明式事务--><beanid="userInfoDao"class="cn.js.ccit.dao.UserInfoDAO"> <propertyname="dataSource"> <refbean="dataSource"/> </property> <propertyname="template"> <refbean="jdbcTemplate"/> </property></bean>

【例6-2】Spring支持声明式事务实例。配置文件spring.xml的代码如下:Spring的声明式事务<!--代理--><beanid="userInfoDAOProxy" class="erceptor.TransactionProxyFactoryBean"> <propertyname="proxyInterfaces"> <list> <value>cn.js.ccit.dao.IUserInfoDAO</value> </list> </property> <propertyname="target"> <refbean="userInfoDao"/> </property> <propertyname="transactionManager"> <refbean="transactionManager"/> </property> <propertyname="transactionAttributes"> <props> <propkey="insert*">PROPAGATION_REQUIRED</prop> </props> </property></bean>

Spring的声明式事务2.基于<tx>命名空间的声明式事务管理Spring3引入了<tx>命名空间,结合使用<aop>命名空间,带给开发人员配置声明式事务的全新体验,配置变得更加简单和灵活。另外,得益于<aop>命名空间的切点表达式支持,声明式事务也变得更加强大。Spring的声明式事务基于<tx>的事务管理示例配置文件如下所示:<beanid="bankService"class="space.BankServiceImpl"><propertyname="bankDao"ref="bankDao"/></bean><tx:adviceid="bankAdvice"transaction-manager="transactionManager"><tx:attributes><tx:methodname="transfer"propagation="REQUIRED"/></tx:attributes></tx:advice><aop:config><aop:pointcutid="bankPointcut"expression="execution(**.transfer(..))"/><aop:advisoradvice-ref="bankAdvice"pointcut-ref="bankPointcut"/></aop:config>Spring的声明式事务如果默认的事务属性就能满足要求,简化后的基于<tx>的事务管理示例配置文件,如下所示:<beanid="bankService"class="space.BankServiceImpl"><propertyname="bankDao"ref="bankDao"/></bean><tx:adviceid="bankAdvice"transaction-manager="transactionManager"><aop:config><aop:pointcutid="bankPointcut"expression="execution(**.transfer(..))"/><aop:advisoradvice-ref="bankAdvice"pointcut-ref="bankPointcut"/></aop:config>基于Spring注解方式的事务管理配置Spring5为事务管理提供了@Transactional注解,通过为@Transactional指定不同的参数,以满足不同的事务管理需求。基于Spring注解方式的事务管理配置参数名称功能描述readOnly该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false。rollbackFor该属性用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则进行事务回滚。rollbackForClassName该属性用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚。noRollbackFor该属性用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚。noRollbackForClassName该属性用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚。propagation该属性用于设置事务的传播

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论