JavaEE企業(yè)級項目開發(fā)(第3版)課件 單元6 Spring的數(shù)據(jù)庫開發(fā)與事務_第1頁
JavaEE企業(yè)級項目開發(fā)(第3版)課件 單元6 Spring的數(shù)據(jù)庫開發(fā)與事務_第2頁
JavaEE企業(yè)級項目開發(fā)(第3版)課件 單元6 Spring的數(shù)據(jù)庫開發(fā)與事務_第3頁
JavaEE企業(yè)級項目開發(fā)(第3版)課件 單元6 Spring的數(shù)據(jù)庫開發(fā)與事務_第4頁
JavaEE企業(yè)級項目開發(fā)(第3版)課件 單元6 Spring的數(shù)據(jù)庫開發(fā)與事務_第5頁
已閱讀5頁,還剩84頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

延遲符SpringJDBC支持Spring的數(shù)據(jù)庫開發(fā)與事務SpringDAO框架

DAO(DataAccessObject)是用于訪問數(shù)據(jù)的對象,雖然我們在大多數(shù)情況下,將數(shù)據(jù)保存在數(shù)據(jù)庫中,但這并不是唯一的選擇,你也可以將數(shù)據(jù)存儲到文件中或LDAP中。DAO不但屏蔽了數(shù)據(jù)存儲的最終介質的不同,也屏蔽了具體的實現(xiàn)技術的不同。SpringDAO框架

早期,JDBC是訪問數(shù)據(jù)庫的主流選擇,近幾年,數(shù)據(jù)持久技術獲得了長足的發(fā)展,Hibernate、iBatis、JPA、JDO成為持久層中爭放異彩的實現(xiàn)技術。SpringDAO框架DAO接口層應用好處:可以很容易地構造模擬對象,方便單元測試的開展其次在使用切面時,既可用JDK動態(tài)代理也可用CGLib動態(tài)代理

Spring以統(tǒng)一的方式整合底層的持久化技術:以統(tǒng)一方式進行調用及事務管理,避免讓具體的實現(xiàn)侵入到業(yè)務層的代碼中。每個持久化實現(xiàn)技術都有各自的異常體系,Spring提供了統(tǒng)一的異常體系,方便定義和具體實現(xiàn)技術無關的DAO接口,以便整合到相同的事務管理體系中。SpringDAO框架Spring典型的數(shù)據(jù)操作模式:Spring為各種支持的持久化技術提供了簡化操作的模板和回調在回調中編寫具體的數(shù)據(jù)操作邏輯使用模板執(zhí)行數(shù)據(jù)操作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類,該類實現(xiàn)了InitializingBean接口,在afterPropertiesSet()接口方法中檢查模板對象和數(shù)據(jù)源是否被正確設置,否則將拋出異常。SpringDAO框架

Spring為不同的持久化技術所提供的模板類:所有支持類都是抽象的,目的是希望被繼承,而非直接使用。如果直接使用模板類,一般都需要在DAO中定義一個模板對象并提供數(shù)據(jù)資源。Spring為每一個持久化技術都提供了支持類,支持類中完成這樣的功能。只需要擴展支持類就可以直接編寫實際的數(shù)據(jù)訪問邏輯。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類操作數(shù)據(jù)庫時,要處理很多相同、繁瑣的細節(jié),如:獲取數(shù)據(jù)庫的連接創(chuàng)建Statement處理數(shù)據(jù)庫異常關閉數(shù)據(jù)庫資源等Spring提供了幾個類用來簡化JDBC

API的使用SpringJDBC支持JdbcTemplate類:JdbcTemplate構造函數(shù)請求一個DataSource對象來完成初始化。(1)使用JdbcTemplate的execute()方法執(zhí)行SQL語句execute方法使用java.sql.Statement,SQL語句不帶參數(shù),且不返回受影響記錄的計數(shù),更適合于創(chuàng)建和丟棄表的語句。jdbcTemplate.execute("CREATE

TABLE

USER

(user_id

integer,

name

varchar(100)");

SpringJDBC支持JdbcTemplate類:(2)增加、刪除和修改update方法返回的是受影響的記錄數(shù)目的一個計數(shù),如果傳入?yún)?shù)的話,使用的是java.sql.PreparedStatement,更適合于插入,更新和刪除操作。①不帶參數(shù)的更新jdbcTemplate.update("INSERT

INTO

USER

VALUES('"

+

user.getId()

+

"',

'"

+

user.getName()

+

"',

'"

+

user.getSex()

+

"',

'"

+

user.getAge()

+

"')");

SpringJDBC支持JdbcTemplate類:(2)增加、刪除和修改②帶參數(shù)的修改//修改帶參數(shù)jdbcTemplate.update("UPDATE

USER

SET

name

=

?

WHERE

user_id

=

?",

new

Object[]

{name,

id});

//插入帶參數(shù)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語句中參數(shù)都是使用占位符(?)來表示的,編程麻煩。為了解決這個問題,Spring提供了NamedParameterJdbcTemplate支持命名參數(shù)的模板類。NamedParameterJdbcTemplate類封裝了JdbcTemplate類,提供了使用命名參數(shù)的方式來設置SQL語句中動態(tài)值。SpringJDBC支持NamedParameterJdbcTemplate的命名參數(shù)操作:(1)指定命名參數(shù)SQL中指定命名操作的語法格式為:“:parameterName“(2)設置命名參數(shù)使用Map設置命名參數(shù)的值:key對應操作的名稱,value對應參數(shù)的值;使用SqlParameterSource接口的實現(xiàn)類MapSqlParameterSource,本質上還是使用Map傳遞參數(shù);使用SqlParameterSource接口的實現(xiàn)類BeanPropertySqlParameterSource,使用Bean對象來傳遞參數(shù),此時Bean對象中屬性的名稱必須與命名參數(shù)保持一致。謝謝觀看主講人:石云延遲符添加申請設計Spring的數(shù)據(jù)庫開發(fā)與事務添加申請設計

添加申請是工作流轉的基礎模塊,主要功能是編輯公文,提交給指定部門審批。添加申請的設計應用Servlet與Spring框架結合的方式開發(fā),用戶在視圖層頁面輸入申請標題、申請內容,Servlet控制層獲取輸入的申請信息,并調用模型層的服務方法將申請信息保存到數(shù)據(jù)庫中,最后調用顯示所有申請的方法返回到所有申請頁面。添加申請設計

添加申請實施分為5個步驟:DAO層、Service層、Servlet控制層、視圖層、applicationContex.xml文件配置。本任務重點介紹DAO層實現(xiàn)類的設計、Servlet控制類的設計。添加申請DAO層實現(xiàn)類添加申請DAO層中添加申請方法中使用了JdbcTemplate類,通過執(zhí)行jdbcTemplate.update()方法保存數(shù)據(jù),參數(shù)通過PreparedStatement對象傳遞。//添加申請數(shù)據(jù)訪問層實現(xiàn)類@Data@ComponentpublicclassApplyDAOimplementsIApplyDAO{ @Autowired privateJdbcTemplatejdbcTemplate; @Autowired privateDataSourcedataSource; @Autowired privateDataSourceTransactionManagertransactionManager; privateDefaultTransactionDefinitiondef;//獲得所有申請publicListgetAllApply(){Stringsql="select*fromtb_application";ListapplyList=jdbcTemplate.queryForList(sql);returnapplyList;}添加申請DAO層實現(xiàn)類增加申請方法,主要步驟://增加申請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類添加申請控制類負責接收用戶輸入的申請信息,調用申請服務類添加申請方法保存申請信息到數(shù)據(jù)庫表中,為了能查看已經有的申請,調用查詢所有的申請方法,最后返回到顯示所有申請的頁面。@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();//創(chuàng)建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的數(shù)據(jù)庫開發(fā)與事務Spring事務簡介

事務管理對于企業(yè)應用而言至關重要。它保證了用戶的每一次操作都是可靠的,即便出現(xiàn)了異常的訪問情況,也不至于破壞后臺數(shù)據(jù)的完整性。Spring事務簡介

Spring中提供了豐富的事務管理功能,它們超過了EJB并且和EJB一樣支持聲明式事務,重要的是Spring提供了一致的事務管理,它有如下優(yōu)點。為不同的事務的API提供一致的編程模式;提供更簡單,更易使用的編程式事務管理;支持Spring聲明事務;整合Spring對數(shù)據(jù)訪問的抽象。Spring事務簡介在Spring中,事務是通過TransactionDefinition接口來定義的。該接口包含與事務屬性有關的方法。TransactionDefinition接口中定義的主要方法如下所示。publicinterfaceTransactionDefinition{intgetPropagationBehavior();intgetIsolationLevel();intgetTimeout();booleanisReadOnly();}

Spring事務簡介傳播行為傳播行為定義了事務應用于方法上之邊界(Boundaries),它告知何時該開始一個新的事務,或何時事務該被暫停,或方法是否要在事務中進行。Spring事務簡介傳播行為Spring定義了幾個傳播行為,常用的傳播行為如下所示。PROPAGATION_REQUIRED:支持當前事務,如果當前沒有事務,就新建一個事務;PROPAGATION_SUPPORTS:支持當前事務,如果當前沒有事務,就以非事務方式執(zhí)行;PROPAGATION_MANDATORY:支持當前事務,如果當前沒有事務,就拋出異常;PROPAGATION_REQUIRES_NEW:新建事務,如果當前存在事務,把當前事務掛起。

Spring事務簡介隔離級別在一個應用程序中,可能有多個事務同時進行,由于事務彼此獨立,若讀取的是同一個數(shù)據(jù),容易發(fā)生問題。根據(jù)需求的不同,

隔離級別可以根據(jù)實際需求,對數(shù)據(jù)的鎖定進行設置。Spring事務簡介隔離級別Spring提供了幾種隔離級別設置,如下所示。ISOLATION_DEFAULT:這是一個PlatfromTransactionManager默認的隔離級別,使用數(shù)據(jù)庫默認的事務隔離級別。ISOLATION_READ_UNCOMMITTED:這是事務最低的隔離級別,它允許另外一個事務可以看到這個事務未提交的數(shù)據(jù)。這種隔離級別會產生臟讀,不可重復讀和幻讀。ISOLATION_READ_COMMITTED:保證一個事務修改的數(shù)據(jù)提交后才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的數(shù)據(jù)。

Spring事務簡介事務超時所謂事務超時,就是指一個事務所允許執(zhí)行的最長時間,如果超過該時間限制但事務還沒有完成,則自動回滾事務。在TransactionDefinition中以int的值來表示超時時間,其單位是秒。Spring事務簡介事務的只讀屬性事務的只讀屬性是指,對事務性資源進行只讀操作或者是讀寫操作。所謂事務性資源就是指那些被事務管理的資源,比如數(shù)據(jù)源、JMS資源,以及自定義的事務性資源等等。編程式事務Spring提供的事務管理API,可以在代碼中靈活控制事務的執(zhí)行。在底層,Spring仍然將事務操作委托給底層的持久化框架來執(zhí)行。Spring提供兩種方式的編程式事務管理:使用TransactionTemplate和PlatformTransactionManager。編程式事務TransactionTempale采用和其他Spring模板,如JdbcTempalte和HibernateTemplate一樣的方法。它使用回調方法,把應用程序從處理取得和釋放資源中解脫出來。必須在事務上下文中執(zhí)行的應用代碼看起來像這樣,注意使用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實現(xiàn)。然后,使用TransactionDefinition和TransactionStatus對象就可以發(fā)起事務,回滾和提交。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】編程式事務實例分析。主要步驟:創(chuàng)建用戶類;創(chuàng)建數(shù)據(jù)庫訪問業(yè)務類;創(chuàng)建測試類;創(chuàng)建配置文件。編程式事務【例6-1】編程式事務實例分析。步驟1:創(chuàng)建用戶類@DatapublicclassUser{privateStringname;privateStringpassword;privateIntegerage;}編程式事務【例6-1】編程式事務實例分析。步驟2:創(chuàng)建數(shù)據(jù)庫訪問業(yè)務類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:創(chuàng)建數(shù)據(jù)庫訪問業(yè)務類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這個狀態(tài)System.out.println("執(zhí)行回滾操作了!");throwe;}transactionMmit(status);System.out.println("成功提交了!");}}

編程式事務【例6-1】編程式事務實例分析。步驟3:創(chuàng)建測試類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:創(chuàng)建配置文件<context:property-placeholderlocation="classpath:perties"/> <!--配置數(shù)據(jù)源--><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:創(chuàng)建配置文件<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的數(shù)據(jù)庫開發(fā)與事務修改申請設計

修改申請的主要功能是用戶在申請沒有審批之前,可以修改申請內容。本任務實施的重點是事務的處理,即在修改時增加事務管理。本任務使用編程式事務管理,實現(xiàn)方式:使用TransactionManager實現(xiàn)編程事務;使用TransactionTemplate類實現(xiàn)編程事務。使用TransactionManager實現(xiàn)編程事務修改申請DAO實現(xiàn)類,增加DataSource、DataSourceTransactionManager、DefaultTransactionDefinition屬性的定義,在修改申請代碼中增加事務處理。修改申請的代碼如下所示。classApplyDAOimplementsIApplyDAO{ @Autowired privateJdbcTemplatejdbcTemplate; @Autowired privateDataSourcedataSource; @Autowired privateDataSourceTransactionManagertransactionManager; privateDefaultTransactionDefinitiondef;使用TransactionManager實現(xiàn)編程事務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參數(shù) returnps;}});使用TransactionManager實現(xiàn)編程事務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參數(shù) returnps;}}); transactionMmit(status);//事務提交 }catch(DataAccessExceptione){ transactionManager.rollback(status);//事務回滾}……}使用TransactionTemplate類實現(xiàn)編程事務使用TransactionTemplate類實現(xiàn)編程事務首先創(chuàng)建TransactionTemplate對象,然后設置事務定義,調用execute()方法實現(xiàn)事務管理。修改的申請的代碼如下所示。//修改申請:使用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類實現(xiàn)編程事務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參數(shù)?returnps;}});??使用TransactionTemplate類實現(xiàn)編程事務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參數(shù)

?returnps;}});}});?returntrue;}謝謝觀看主講人:石云延遲符基于Spring注解方式的事務管理配置Spring的數(shù)據(jù)庫開發(fā)與事務Spring的聲明式事務

底層建立在AOP基礎上。本質是對方法前后進行攔截,然后在目標方法開始之前創(chuàng)建或者加入一個事務,在執(zhí)行完目標方法之后根據(jù)執(zhí)行情況提交或者回滾事務。Spring的聲明式事務

聲明式事務,有以下優(yōu)點。不需要通過編程的方式管理事務,不需要在業(yè)務邏輯代碼中摻雜事務管理的代碼。事務管理是一個典型的橫切邏輯。AOP為聲明式事務提供了簡單而強大的支持。只需在配置文件中做相關的事務規(guī)則聲明(或通過等價的基于標注的方式),便可以將事務規(guī)則應用到業(yè)務邏輯中。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的聲明式事務指定事務屬性的取值的規(guī)則傳播行為[,隔離級別][,只讀屬性][,超時屬性][不影響提交的異常][,導致回滾的異常]傳播行為必須設置,取值必須以“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事務傳播行為,并且該事務是只讀的。除此之外,其他的屬性均使用默認值。比如,隔離級別和超時時間使用底層事務性資源的默認值,并且當發(fā)生未檢查異常,則回滾事務,發(fā)生已檢查異常則仍提交事務。Spring的聲明式事務【例6-2】Spring支持聲明式事務實例。配置文件spring.xml的代碼如下:<context:property-placeholderlocation="classpath:perties"/><!--配置數(shù)據(jù)源--><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>命名空間,帶給開發(fā)人員配置聲明式事務的全新體驗,配置變得更加簡單和靈活。另外,得益于<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指定不同的參數(shù),以滿足不同的事務管理需求?;赟pring注解方式的事務管理配置參數(shù)名稱功能描述readOnly該屬性用于設置當前事務是否為只讀事務,設置為true表示只讀,false則表示可讀寫,默認值為false。rollbackFor該屬性用于設置需要進行回滾的異常類數(shù)組,當方法中拋出指定異常數(shù)組中的異常時,則進行事務回滾。rollbackForClassName該屬性用于設置需要進行回滾的異常類名稱數(shù)組,當方法中拋出指定異常名稱數(shù)組中的異常時,則進行事務回滾。noRollbackFor該屬性用于設置不需要進行回滾的異常類數(shù)組,當方法中拋出指定異常數(shù)組中的異常時,不進行事務回滾。noRollbackForClassName該屬性用于設置不需要進行回滾的異常類名稱數(shù)組,當方法中拋出指定異常名稱數(shù)組中的異常時,不進行事務回滾。propagation該屬性用于設置事務的傳播

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論