




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
延遲符SpringJDBC支持Spring的數(shù)據(jù)庫開發(fā)與事務(wù)SpringDAO框架
DAO(DataAccessObject)是用于訪問數(shù)據(jù)的對(duì)象,雖然我們在大多數(shù)情況下,將數(shù)據(jù)保存在數(shù)據(jù)庫中,但這并不是唯一的選擇,你也可以將數(shù)據(jù)存儲(chǔ)到文件中或LDAP中。DAO不但屏蔽了數(shù)據(jù)存儲(chǔ)的最終介質(zhì)的不同,也屏蔽了具體的實(shí)現(xiàn)技術(shù)的不同。SpringDAO框架
早期,JDBC是訪問數(shù)據(jù)庫的主流選擇,近幾年,數(shù)據(jù)持久技術(shù)獲得了長足的發(fā)展,Hibernate、iBatis、JPA、JDO成為持久層中爭放異彩的實(shí)現(xiàn)技術(shù)。SpringDAO框架DAO接口層應(yīng)用好處:可以很容易地構(gòu)造模擬對(duì)象,方便單元測試的開展其次在使用切面時(shí),既可用JDK動(dòng)態(tài)代理也可用CGLib動(dòng)態(tài)代理
Spring以統(tǒng)一的方式整合底層的持久化技術(shù):以統(tǒng)一方式進(jìn)行調(diào)用及事務(wù)管理,避免讓具體的實(shí)現(xiàn)侵入到業(yè)務(wù)層的代碼中。每個(gè)持久化實(shí)現(xiàn)技術(shù)都有各自的異常體系,Spring提供了統(tǒng)一的異常體系,方便定義和具體實(shí)現(xiàn)技術(shù)無關(guān)的DAO接口,以便整合到相同的事務(wù)管理體系中。SpringDAO框架Spring典型的數(shù)據(jù)操作模式:Spring為各種支持的持久化技術(shù)提供了簡化操作的模板和回調(diào)在回調(diào)中編寫具體的數(shù)據(jù)操作邏輯使用模板執(zhí)行數(shù)據(jù)操作SpringDAO框架Spring為不同的持久化技術(shù)所提供的模板類: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類,該類實(shí)現(xiàn)了InitializingBean接口,在afterPropertiesSet()接口方法中檢查模板對(duì)象和數(shù)據(jù)源是否被正確設(shè)置,否則將拋出異常。SpringDAO框架
Spring為不同的持久化技術(shù)所提供的模板類:所有支持類都是抽象的,目的是希望被繼承,而非直接使用。如果直接使用模板類,一般都需要在DAO中定義一個(gè)模板對(duì)象并提供數(shù)據(jù)資源。Spring為每一個(gè)持久化技術(shù)都提供了支持類,支持類中完成這樣的功能。只需要擴(kuò)展支持類就可以直接編寫實(shí)際的數(shù)據(jù)訪問邏輯。SpringDAO框架不同持久化技術(shù)的支持類:ORM持久化技術(shù)支持類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ù)庫時(shí),要處理很多相同、繁瑣的細(xì)節(jié),如:獲取數(shù)據(jù)庫的連接創(chuàng)建Statement處理數(shù)據(jù)庫異常關(guān)閉數(shù)據(jù)庫資源等Spring提供了幾個(gè)類用來簡化JDBC
API的使用SpringJDBC支持JdbcTemplate類:JdbcTemplate構(gòu)造函數(shù)請(qǐng)求一個(gè)DataSource對(duì)象來完成初始化。(1)使用JdbcTemplate的execute()方法執(zhí)行SQL語句execute方法使用java.sql.Statement,SQL語句不帶參數(shù),且不返回受影響記錄的計(jì)數(shù),更適合于創(chuàng)建和丟棄表的語句。jdbcTemplate.execute("CREATE
TABLE
USER
(user_id
integer,
name
varchar(100)");
SpringJDBC支持JdbcTemplate類:(2)增加、刪除和修改update方法返回的是受影響的記錄數(shù)目的一個(gè)計(jì)數(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①單個(gè)更新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);
}
});
注意:匿名內(nèi)部類只能訪問外部最終局部變量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進(jìn)行查詢時(shí),使用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中的對(duì)象是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ù)都是使用占位符(?)來表示的,編程麻煩。為了解決這個(gè)問題,Spring提供了NamedParameterJdbcTemplate支持命名參數(shù)的模板類。NamedParameterJdbcTemplate類封裝了JdbcTemplate類,提供了使用命名參數(shù)的方式來設(shè)置SQL語句中動(dòng)態(tài)值。SpringJDBC支持NamedParameterJdbcTemplate的命名參數(shù)操作:(1)指定命名參數(shù)SQL中指定命名操作的語法格式為:“:parameterName“(2)設(shè)置命名參數(shù)使用Map設(shè)置命名參數(shù)的值:key對(duì)應(yīng)操作的名稱,value對(duì)應(yīng)參數(shù)的值;使用SqlParameterSource接口的實(shí)現(xiàn)類MapSqlParameterSource,本質(zhì)上還是使用Map傳遞參數(shù);使用SqlParameterSource接口的實(shí)現(xiàn)類BeanPropertySqlParameterSource,使用Bean對(duì)象來傳遞參數(shù),此時(shí)Bean對(duì)象中屬性的名稱必須與命名參數(shù)保持一致。謝謝觀看主講人:石云延遲符添加申請(qǐng)?jiān)O(shè)計(jì)Spring的數(shù)據(jù)庫開發(fā)與事務(wù)添加申請(qǐng)?jiān)O(shè)計(jì)
添加申請(qǐng)是工作流轉(zhuǎn)的基礎(chǔ)模塊,主要功能是編輯公文,提交給指定部門審批。添加申請(qǐng)的設(shè)計(jì)應(yīng)用Servlet與Spring框架結(jié)合的方式開發(fā),用戶在視圖層頁面輸入申請(qǐng)標(biāo)題、申請(qǐng)內(nèi)容,Servlet控制層獲取輸入的申請(qǐng)信息,并調(diào)用模型層的服務(wù)方法將申請(qǐng)信息保存到數(shù)據(jù)庫中,最后調(diào)用顯示所有申請(qǐng)的方法返回到所有申請(qǐng)頁面。添加申請(qǐng)?jiān)O(shè)計(jì)
添加申請(qǐng)實(shí)施分為5個(gè)步驟:DAO層、Service層、Servlet控制層、視圖層、applicationContex.xml文件配置。本任務(wù)重點(diǎn)介紹DAO層實(shí)現(xiàn)類的設(shè)計(jì)、Servlet控制類的設(shè)計(jì)。添加申請(qǐng)DAO層實(shí)現(xiàn)類添加申請(qǐng)DAO層中添加申請(qǐng)方法中使用了JdbcTemplate類,通過執(zhí)行jdbcTemplate.update()方法保存數(shù)據(jù),參數(shù)通過PreparedStatement對(duì)象傳遞。//添加申請(qǐng)數(shù)據(jù)訪問層實(shí)現(xiàn)類@Data@ComponentpublicclassApplyDAOimplementsIApplyDAO{ @Autowired privateJdbcTemplatejdbcTemplate; @Autowired privateDataSourcedataSource; @Autowired privateDataSourceTransactionManagertransactionManager; privateDefaultTransactionDefinitiondef;//獲得所有申請(qǐng)publicListgetAllApply(){Stringsql="select*fromtb_application";ListapplyList=jdbcTemplate.queryForList(sql);returnapplyList;}添加申請(qǐng)DAO層實(shí)現(xiàn)類增加申請(qǐng)方法,主要步驟://增加申請(qǐng)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;}}}添加申請(qǐng)控制Servlet類添加申請(qǐng)控制類負(fù)責(zé)接收用戶輸入的申請(qǐng)信息,調(diào)用申請(qǐng)服務(wù)類添加申請(qǐng)方法保存申請(qǐng)信息到數(shù)據(jù)庫表中,為了能查看已經(jīng)有的申請(qǐng),調(diào)用查詢所有的申請(qǐng)方法,最后返回到顯示所有申請(qǐng)的頁面。@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")){//添加申請(qǐng)SimpleDateFormatsf=newSimpleDateFormat("yyyy-MM-dd");//獲取申請(qǐng)時(shí)間
Applyapply=newApply();//創(chuàng)建Apply對(duì)象apply.setTitle(title);......//調(diào)用申請(qǐng)服務(wù)方法保存申請(qǐng)booleanresult=applyService.addApply(apply);if(result){res.sendRedirect(this.showAllApply(req));}else{res.sendRedirect("error.jsp");}}}添加申請(qǐng)控制Servlet類獲取所有申請(qǐng)方法,主要步驟://獲取所有申請(qǐng)publicStringshowAllApply(HttpServletRequestreq){Listapplylist=applyService.getAllApply();ListapplicationList=newArrayList();//將applylist中的Map轉(zhuǎn)換為Apply對(duì)象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";}}運(yùn)行效果謝謝觀看主講人:石云延遲符編程式事務(wù)Spring的數(shù)據(jù)庫開發(fā)與事務(wù)Spring事務(wù)簡介
事務(wù)管理對(duì)于企業(yè)應(yīng)用而言至關(guān)重要。它保證了用戶的每一次操作都是可靠的,即便出現(xiàn)了異常的訪問情況,也不至于破壞后臺(tái)數(shù)據(jù)的完整性。Spring事務(wù)簡介
Spring中提供了豐富的事務(wù)管理功能,它們超過了EJB并且和EJB一樣支持聲明式事務(wù),重要的是Spring提供了一致的事務(wù)管理,它有如下優(yōu)點(diǎn)。為不同的事務(wù)的API提供一致的編程模式;提供更簡單,更易使用的編程式事務(wù)管理;支持Spring聲明事務(wù);整合Spring對(duì)數(shù)據(jù)訪問的抽象。Spring事務(wù)簡介在Spring中,事務(wù)是通過TransactionDefinition接口來定義的。該接口包含與事務(wù)屬性有關(guān)的方法。TransactionDefinition接口中定義的主要方法如下所示。publicinterfaceTransactionDefinition{intgetPropagationBehavior();intgetIsolationLevel();intgetTimeout();booleanisReadOnly();}
Spring事務(wù)簡介傳播行為傳播行為定義了事務(wù)應(yīng)用于方法上之邊界(Boundaries),它告知何時(shí)該開始一個(gè)新的事務(wù),或何時(shí)事務(wù)該被暫停,或方法是否要在事務(wù)中進(jìn)行。Spring事務(wù)簡介傳播行為Spring定義了幾個(gè)傳播行為,常用的傳播行為如下所示。PROPAGATION_REQUIRED:支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就新建一個(gè)事務(wù);PROPAGATION_SUPPORTS:支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就以非事務(wù)方式執(zhí)行;PROPAGATION_MANDATORY:支持當(dāng)前事務(wù),如果當(dāng)前沒有事務(wù),就拋出異常;PROPAGATION_REQUIRES_NEW:新建事務(wù),如果當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起。
Spring事務(wù)簡介隔離級(jí)別在一個(gè)應(yīng)用程序中,可能有多個(gè)事務(wù)同時(shí)進(jìn)行,由于事務(wù)彼此獨(dú)立,若讀取的是同一個(gè)數(shù)據(jù),容易發(fā)生問題。根據(jù)需求的不同,
隔離級(jí)別可以根據(jù)實(shí)際需求,對(duì)數(shù)據(jù)的鎖定進(jìn)行設(shè)置。Spring事務(wù)簡介隔離級(jí)別Spring提供了幾種隔離級(jí)別設(shè)置,如下所示。ISOLATION_DEFAULT:這是一個(gè)PlatfromTransactionManager默認(rèn)的隔離級(jí)別,使用數(shù)據(jù)庫默認(rèn)的事務(wù)隔離級(jí)別。ISOLATION_READ_UNCOMMITTED:這是事務(wù)最低的隔離級(jí)別,它允許另外一個(gè)事務(wù)可以看到這個(gè)事務(wù)未提交的數(shù)據(jù)。這種隔離級(jí)別會(huì)產(chǎn)生臟讀,不可重復(fù)讀和幻讀。ISOLATION_READ_COMMITTED:保證一個(gè)事務(wù)修改的數(shù)據(jù)提交后才能被另外一個(gè)事務(wù)讀取。另外一個(gè)事務(wù)不能讀取該事務(wù)未提交的數(shù)據(jù)。
Spring事務(wù)簡介事務(wù)超時(shí)所謂事務(wù)超時(shí),就是指一個(gè)事務(wù)所允許執(zhí)行的最長時(shí)間,如果超過該時(shí)間限制但事務(wù)還沒有完成,則自動(dòng)回滾事務(wù)。在TransactionDefinition中以int的值來表示超時(shí)時(shí)間,其單位是秒。Spring事務(wù)簡介事務(wù)的只讀屬性事務(wù)的只讀屬性是指,對(duì)事務(wù)性資源進(jìn)行只讀操作或者是讀寫操作。所謂事務(wù)性資源就是指那些被事務(wù)管理的資源,比如數(shù)據(jù)源、JMS資源,以及自定義的事務(wù)性資源等等。編程式事務(wù)Spring提供的事務(wù)管理API,可以在代碼中靈活控制事務(wù)的執(zhí)行。在底層,Spring仍然將事務(wù)操作委托給底層的持久化框架來執(zhí)行。Spring提供兩種方式的編程式事務(wù)管理:使用TransactionTemplate和PlatformTransactionManager。編程式事務(wù)TransactionTempale采用和其他Spring模板,如JdbcTempalte和HibernateTemplate一樣的方法。它使用回調(diào)方法,把應(yīng)用程序從處理取得和釋放資源中解脫出來。必須在事務(wù)上下文中執(zhí)行的應(yīng)用代碼看起來像這樣,注意使用TransactionCallback可以返回一個(gè)值,代碼如下:jdbcTemplate.execute("CREATE
TABLE
USER
(user_id
integer,
name
varchar(100)");
Objectresult=tt.execute(newTransactionCallback(){publicObjectdoInTransaction(TransactionStatusstatus){updateOperation1();returnresultOfUpdateOperation2();}});編程式事務(wù)TransactionTempale如果沒有返回值,使用TransactionCallbackWithoutResult,
代碼如下:tt.execute(newTransactionCallbackWithoutResult(){protectedvoiddoInTransactionWithoutResult(TransactionStatusstatus){updateOperation1();updateOperation2();}});編程式事務(wù)使用PlatformTransactionManager
可以使用
org.springframework.transaction.PlatformTransactionManager直接管理事務(wù)。簡單地通過一個(gè)bean引用給你的bean傳遞一個(gè)PlatformTransactionManager實(shí)現(xiàn)。然后,使用TransactionDefinition和TransactionStatus對(duì)象就可以發(fā)起事務(wù),回滾和提交。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);編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。主要步驟:創(chuàng)建用戶類;創(chuàng)建數(shù)據(jù)庫訪問業(yè)務(wù)類;創(chuàng)建測試類;創(chuàng)建配置文件。編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。步驟1:創(chuàng)建用戶類@DatapublicclassUser{privateStringname;privateStringpassword;privateIntegerage;}編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。步驟2:創(chuàng)建數(shù)據(jù)庫訪問業(yè)務(wù)類publicclassUserDao{privateDataSourcedataSource;privateJdbcTemplatetemplate;publicDataSourcegetDataSource(){returndataSource;}publicvoidsetDataSource(DataSourcedataSource){this.dataSource=dataSource;template=newJdbcTemplate(dataSource);transactionManager=newDataSourceTransactionManager(dataSource);def=newDefaultTransactionDefinition();//異常處理機(jī)制def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);}
編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。步驟2:創(chuàng)建數(shù)據(jù)庫訪問業(yè)務(wù)類publicvoidinsert(Useruser){//添加用戶Stringname=user.getName();intage=user.getAge().intValue();TransactionStatusstatus=transactionManager.getTransaction(def);try{//下面的SQL有錯(cuò)誤,用于測試事務(wù)template.update("INSERINTOtb_user2(name,age)"+"VALUES('"+name+"',"+age+")");}catch(DataAccessExceptione){transactionManager.rollback(status);//回滾到status這個(gè)狀態(tài)System.out.println("執(zhí)行回滾操作了!");throwe;}transactionMmit(status);System.out.println("成功提交了!");}}
編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。步驟3:創(chuàng)建測試類publicclassTestTransaction{publicstaticvoidmain(String[]args){//加載配置文件ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");//獲取UserDao實(shí)例UserDaodao=(UserDao)applicationContext.getBean("userDao");Useruser=newUser();user.setName("cf");user.setPassword("123");user.setAge(1);dao.insert(user);}}
編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。步驟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>編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。步驟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>
編程式事務(wù)【例6-1】編程式事務(wù)實(shí)例分析。運(yùn)行結(jié)果:謝謝觀看主講人:石云延遲符修改申請(qǐng)?jiān)O(shè)計(jì)Spring的數(shù)據(jù)庫開發(fā)與事務(wù)修改申請(qǐng)?jiān)O(shè)計(jì)
修改申請(qǐng)的主要功能是用戶在申請(qǐng)沒有審批之前,可以修改申請(qǐng)內(nèi)容。本任務(wù)實(shí)施的重點(diǎn)是事務(wù)的處理,即在修改時(shí)增加事務(wù)管理。本任務(wù)使用編程式事務(wù)管理,實(shí)現(xiàn)方式:使用TransactionManager實(shí)現(xiàn)編程事務(wù);使用TransactionTemplate類實(shí)現(xiàn)編程事務(wù)。使用TransactionManager實(shí)現(xiàn)編程事務(wù)修改申請(qǐng)DAO實(shí)現(xiàn)類,增加DataSource、DataSourceTransactionManager、DefaultTransactionDefinition屬性的定義,在修改申請(qǐng)代碼中增加事務(wù)處理。修改申請(qǐng)的代碼如下所示。classApplyDAOimplementsIApplyDAO{ @Autowired privateJdbcTemplatejdbcTemplate; @Autowired privateDataSourcedataSource; @Autowired privateDataSourceTransactionManagertransactionManager; privateDefaultTransactionDefinitiondef;使用TransactionManager實(shí)現(xiàn)編程事務(wù)publicbooleanupdateApply(Applyapply){ //事務(wù)管理對(duì)象 transactionManager=newDataSourceTransactionManager(dataSource); //事務(wù)定義 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); ……//設(shè)置applyContet、applyDate、applyId參數(shù) returnps;}});使用TransactionManager實(shí)現(xiàn)編程事務(wù)intj=jdbcTemplate.update(newPreparedStatementCreator(){ publicPreparedStatementcreatePreparedStatement(Connectioncon) throwsSQLException{ //故意設(shè)置update為updat Stringsql="updattb_applicationsettitle=?,applyContent=?,applyDate=?whereapplyId=?"; PreparedStatementps=con.prepareStatement(sql); ps.setString(1,title); ps.setString(1,title); ……//設(shè)置applyContet、applyDate、applyId參數(shù) returnps;}}); transactionMmit(status);//事務(wù)提交 }catch(DataAccessExceptione){ transactionManager.rollback(status);//事務(wù)回滾}……}使用TransactionTemplate類實(shí)現(xiàn)編程事務(wù)使用TransactionTemplate類實(shí)現(xiàn)編程事務(wù)首先創(chuàng)建TransactionTemplate對(duì)象,然后設(shè)置事務(wù)定義,調(diào)用execute()方法實(shí)現(xiàn)事務(wù)管理。修改的申請(qǐng)的代碼如下所示。//修改申請(qǐng):使用TransactionTemplate管理事務(wù)publicbooleanupdateApply(Applyapply){ finalintapplyId=apply.getApplyId(); finalStringtitle=apply.getTitle(); finalStringapplyContent=apply.getApplyContent(); finalStringapplyDate=apply.getApplyDate();transactionManager=newDataSourceTransactionManager(dataSource);//事務(wù)管理對(duì)象TransactionTemplatetransactionTemplate=newTransactionTemplate(transactionManager); transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
使用TransactionTemplate類實(shí)現(xiàn)編程事務(wù)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設(shè)置applyContent、applyDate、applyId參數(shù)?returnps;}});??使用TransactionTemplate類實(shí)現(xiàn)編程事務(wù)intj=jdbcTemplate.update(newPreparedStatementCreator(){?publicPreparedStatementcreatePreparedStatement(Connectioncon)?throwsSQLException{?Stringsql="updattb_applicationsettitle=?,applyContent=?,applyDate=?whereapplyId=?";?PreparedStatementps=con.prepareStatement(sql);?ps.setString(1,title);?**……**?//ps設(shè)置applyContent、applyDate、applyId參數(shù)
?returnps;}});}});?returntrue;}謝謝觀看主講人:石云延遲符基于Spring注解方式的事務(wù)管理配置Spring的數(shù)據(jù)庫開發(fā)與事務(wù)Spring的聲明式事務(wù)
底層建立在AOP基礎(chǔ)上。本質(zhì)是對(duì)方法前后進(jìn)行攔截,然后在目標(biāo)方法開始之前創(chuàng)建或者加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。Spring的聲明式事務(wù)
聲明式事務(wù),有以下優(yōu)點(diǎn)。不需要通過編程的方式管理事務(wù),不需要在業(yè)務(wù)邏輯代碼中摻雜事務(wù)管理的代碼。事務(wù)管理是一個(gè)典型的橫切邏輯。AOP為聲明式事務(wù)提供了簡單而強(qiáng)大的支持。只需在配置文件中做相關(guān)的事務(wù)規(guī)則聲明(或通過等價(jià)的基于標(biāo)注的方式),便可以將事務(wù)規(guī)則應(yīng)用到業(yè)務(wù)邏輯中。Spring的聲明式事務(wù)1.基于TransactionInter的聲明式事務(wù)管理Spring提供了TransactionInterceptor類來實(shí)施聲明式事務(wù)管理功能。Spring的聲明式事務(wù)<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的聲明式事務(wù)指定事務(wù)屬性的取值的規(guī)則傳播行為[,隔離級(jí)別][,只讀屬性][,超時(shí)屬性][不影響提交的異常][,導(dǎo)致回滾的異常]傳播行為必須設(shè)置,取值必須以“PROPAGATION_”開頭,具體包括:PROPAGATION_MANDATORYPROPAGATION_NESTEDPROPAGATION_NEVERPROPAGATION_NOT_SUPPORTEDPROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_SUPPORTS隔離級(jí)別的取值必須以“ISOLATION_”開頭,具體包括:ISOLATION_DEFAULTISOLATION_READ_COMMITTEDISOLATION_READ_UNCOMMITTEDISOLATION_REPEATABLE_READISOLATION_SERIALIZABLESpring的聲明式事務(wù)示例1:<propertyname="*Service">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20,+AbcException,+DefException,-HijException</property>針對(duì)所有方法名以Service結(jié)尾的方法,使用PROPAGATION_REQUIRED事務(wù)傳播行為,事務(wù)的隔離級(jí)別是ISOLATION_READ_COMMITTED,超時(shí)時(shí)間為20秒,當(dāng)事務(wù)拋出AbcException或者DefException類型的異常,則仍然提交,當(dāng)拋出HijException類型的異常時(shí)必須回滾事務(wù)。這里沒有指定“readOnly”,表示事務(wù)不是只讀的。Spring的聲明式事務(wù)示例2:<propertyname="test">PROPAGATION_REQUIRED,readOnly</property>針對(duì)所有方法名為test的方法,使用PROPAGATION_REQUIRED事務(wù)傳播行為,并且該事務(wù)是只讀的。除此之外,其他的屬性均使用默認(rèn)值。比如,隔離級(jí)別和超時(shí)時(shí)間使用底層事務(wù)性資源的默認(rèn)值,并且當(dāng)發(fā)生未檢查異常,則回滾事務(wù),發(fā)生已檢查異常則仍提交事務(wù)。Spring的聲明式事務(wù)【例6-2】Spring支持聲明式事務(wù)實(shí)例。配置文件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的聲明式事務(wù)<beanid="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource"/><!--聲明式事務(wù)--><beanid="userInfoDao"class="cn.js.ccit.dao.UserInfoDAO"> <propertyname="dataSource"> <refbean="dataSource"/> </property> <propertyname="template"> <refbean="jdbcTemplate"/> </property></bean>
【例6-2】Spring支持聲明式事務(wù)實(shí)例。配置文件spring.xml的代碼如下:Spring的聲明式事務(wù)<!--代理--><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的聲明式事務(wù)2.基于<tx>命名空間的聲明式事務(wù)管理Spring3引入了<tx>命名空間,結(jié)合使用<aop>命名空間,帶給開發(fā)人員配置聲明式事務(wù)的全新體驗(yàn),配置變得更加簡單和靈活。另外,得益于<aop>命名空間的切點(diǎn)表達(dá)式支持,聲明式事務(wù)也變得更加強(qiáng)大。Spring的聲明式事務(wù)基于<tx>的事務(wù)管理示例配置文件如下所示:<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的聲明式事務(wù)如果默認(rèn)的事務(wù)屬性就能滿足要求,簡化后的基于<tx>的事務(wù)管理示例配置文件,如下所示:<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注解方式的事務(wù)管理配置Spring5為事務(wù)管理提供了@Transactional注解,通過為@Transactional指定不同的參數(shù),以滿足不同的事務(wù)管理需求?;赟pring注解方式的事務(wù)管理配置參數(shù)名稱功能描述readOnly該屬性用于設(shè)置當(dāng)前事務(wù)是否為只讀事務(wù),設(shè)置為true表示只讀,false則表示可讀寫,默認(rèn)值為false。rollbackFor該屬性用于設(shè)置需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。rollbackForClassName該屬性用于設(shè)置需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。noRollbackFor該屬性用于設(shè)置不需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),不進(jìn)行事務(wù)回滾。noRollbackForClassName該屬性用于設(shè)置不需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí),不進(jìn)行事務(wù)回滾。propagation該屬性用于設(shè)置事務(wù)的傳播
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 司機(jī)擔(dān)保協(xié)議合同
- 零售連鎖店經(jīng)營模式創(chuàng)新與數(shù)字化升級(jí)解決方案
- 園林綠化工程設(shè)計(jì)合同
- 匯流箱施工方案
- 委托物業(yè)管理電梯協(xié)議書
- 解決方案優(yōu)化提案書
- 個(gè)人民間借貸合同書
- 咨詢服務(wù)委托合同協(xié)議書
- 外墻保溫吊籃施工方案
- 特色廊架施工方案
- 手機(jī)攝影教程全套課件
- 2025屆寧夏銀川一中高三上學(xué)期第五次月考英語試題及答案
- 2025年皖西衛(wèi)生職業(yè)學(xué)院單招職業(yè)適應(yīng)性測試題庫完整
- 空調(diào)原理培訓(xùn)課件
- 2024年國網(wǎng)陜西省電力有限公司招聘考試真題
- 2025年云南省公安廳招聘文職人員18人歷年高頻重點(diǎn)模擬試卷提升(共500題附帶答案詳解)
- 健康教育學(xué)(全套課件)
- 光伏工程施工組織設(shè)計(jì)
- 體育運(yùn)動(dòng)中的交流與合作 課件 2024-2025學(xué)年人教版(2024)初中體育與健康七年級(jí)全一冊
- DB53∕T 1269-2024 改性磷石膏用于礦山廢棄地生態(tài)修復(fù)回填技術(shù)規(guī)范
- 二年級(jí)下冊口算題大全(全冊可直接打印)
評(píng)論
0/150
提交評(píng)論