Spring:整合jdbc、aop事務

spring整合JDBC

spring提供了很多模板整合Dao技術


spring中提供了一個可以操作數據庫的對象.對象封裝了jdbc技術.

JDBCTemplate => JDBC模板對象:

與DBUtils中的QueryRunner非常相似.


步驟

導包:4+2+2+2

4(基本)+2(日誌)

junit4類庫:spring-test-4.2.4.RELEASE、spring-aop-4.2.4.RELEASE

c3p0連接池:com.springsource.com.mchange.v2.c3p0-0.9.1.2

JDBC驅動:mysql-connector-java-5.1.7-bin

spring-jdbc:spring-jdbc-4.2.4.RELEASE

spring-tx事務:spring-tx-4.2.4.RELEASE


準備數據庫


書寫Dao:創建Dao接口,裏面有增刪改查方法、再創建一個DaoImpl實現方法


增刪改


查詢單個對象


查詢值類型


查詢list集合類型




spring配置


依賴關係


src下的:db.properties


src下:創建applicationContext.xml






<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd ">

<!-- 指定spring讀取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties"  />

<!-- 1.將連接池放入spring容器 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
	<property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property>
	<property name="driverClass" value="${jdbc.driverClass}" ></property>
	<property name="user" value="${jdbc.user}" ></property>
	<property name="password" value="${jdbc.password}" ></property>
</bean>


<!-- 2.將JDBCTemplate放入spring容器 -->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>

<!-- 3.將UserDao放入spring容器 -->
<bean name="userDao" class="cn.itcast.a_jdbctemplate.UserDaoImpl" >
	<!-- <property name="jt" ref="jdbcTemplate" ></property> -->
	<property name="dataSource" ref="dataSource" ></property>
</bean>
	

</beans>

測試




package cn.itcast.a_jdbctemplate;

import java.beans.PropertyVetoException;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import cn.itcast.bean.User;

//演示JDBC模板
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
		@Resource(name="userDao")
	private UserDao ud;
	
	@Test
	public void fun1() throws Exception{
		
		//0 準備連接池
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setDriverClass("com.mysql.jdbc.Driver");
		dataSource.setJdbcUrl("jdbc:mysql:///hibernate_32");
		dataSource.setUser("root");
		dataSource.setPassword("1234");
		//1 創建JDBC模板對象
		JdbcTemplate jt = new JdbcTemplate();
		jt.setDataSource(dataSource);
		//2 書寫sql,並執行
		String sql = "insert into t_user values(null,'rose') ";
		jt.update(sql);
		
	}
	
	@Test
	public void fun2() throws Exception{
		User u = new User();
		u.setName("tom");
		ud.save(u);
	}
	@Test
	public void fun3() throws Exception{
		User u = new User();
		u.setId(2);
		u.setName("jack");
		ud.update(u);
		
	}
	
	@Test
	public void fun4() throws Exception{
		ud.delete(2);
	}
	
	@Test
	public void fun5() throws Exception{
		System.out.println(ud.getTotalCount());
	}
	
	@Test
	public void fun6() throws Exception{
		System.out.println(ud.getById(1));
	}
	
	@Test
	public void fun7() throws Exception{
		System.out.println(ud.getAll());
	}
	
}



進階內容

JDBCDaoSupport






讀取外部的Properties配置

注意加前綴





Spring:aop事務

事務

事務特性:acid

事務併發問題:髒讀、不可重讀、幻讀

事務的隔離級別:1 讀未提交、2 讀已提交、4 可重複讀、8 串行化


spring封裝了事務管理代碼

事務操作:打開事務、提交事務、回滾事務

事務操作對象


因爲在不同平臺,操作事務的代碼各不相同.spring提供了一個接口

 PlatformTransactionManager 接口

JDBC: DataSourceTransactionManager

 Hibernate:HibernateTransitionmanager

 注意:在spring中玩事務管理.最爲核心的對象就是TransactionManager對象


spring管理事務的屬性介紹

事務的隔離級別:1 讀未提交、2 讀已提交、4 可重複讀、8 串行化

是否只讀:true 只讀、false 可操作


事務的傳播行爲




spring管理事務方式

編碼式

1.將核心事務管理器配置到spring容器


2.配置TransactionTemplate模板


3.將事務模板注入Service



4.在Service中調用模板


xml配置(aop)

1.導包

aop

aspect

aop聯盟

weaving織入包

2.導入新的約束(tx)


beans: 最基本
context:讀取properties配置
aop:配置aop
tx:配置事務通知


3.配置通知


4.配置將通知織入目標



註解配置(aop)

1.導包

aop

aspect

aop聯盟

weaving織入包

2.導入新的約束(tx)


beans: 最基本
context:讀取properties配置
aop:配置aop
tx:配置事務通知


3.開啓註解管理事務


4.使用註解





<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">

<!-- 指定spring讀取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties"  />

<!-- 事務核心管理器,封裝了所有事務操作. 依賴於連接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 事務模板對象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
	<property name="transactionManager" ref="transactionManager" ></property>
</bean>

<!-- 配置事務通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager" >
	<tx:attributes>
		<!-- 以方法爲單位,指定方法應用什麼事務屬性
			isolation:隔離級別
			propagation:傳播行爲
			read-only:是否只讀
		 -->
		<tx:method name="save*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="persist*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="modify*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="delete*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="remove*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
		<tx:method name="get*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
		<tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true" />
		<tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" />
	</tx:attributes>
</tx:advice>


<!-- 配置織入 -->
<aop:config  >
	<!-- 配置切點表達式 -->
	<aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="txPc"/>
	<!-- 配置切面 : 通知+切點
		 	advice-ref:通知的名稱
		 	pointcut-ref:切點的名稱
	 -->
	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPc" />
</aop:config>


<!-- 1.將連接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
	<property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property>
	<property name="driverClass" value="${jdbc.driverClass}" ></property>
	<property name="user" value="${jdbc.user}" ></property>
	<property name="password" value="${jdbc.password}" ></property>
</bean>



<!-- 2.Dao-->
<bean name="accountDao" class="cn.itcast.dao.AccountDaoImpl" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 3.Service-->
<bean name="accountService" class="cn.itcast.service.AccountServiceImpl" >
	<property name="ad" ref="accountDao" ></property>
	<property name="tt" ref="transactionTemplate" ></property>
</bean>  

</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">

<!-- 指定spring讀取db.properties配置 -->
<context:property-placeholder location="classpath:db.properties"  />

<!-- 事務核心管理器,封裝了所有事務操作. 依賴於連接池 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 事務模板對象 -->
<bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" >
	<property name="transactionManager" ref="transactionManager" ></property>
</bean>

<!-- 開啓使用註解管理aop事務 -->
<tx:annotation-driven/>

<!-- 1.將連接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
	<property name="jdbcUrl" value="${jdbc.jdbcUrl}" ></property>
	<property name="driverClass" value="${jdbc.driverClass}" ></property>
	<property name="user" value="${jdbc.user}" ></property>
	<property name="password" value="${jdbc.password}" ></property>
</bean>



<!-- 2.Dao-->
<bean name="accountDao" class="cn.itcast.dao.AccountDaoImpl" >
	<property name="dataSource" ref="dataSource" ></property>
</bean>
<!-- 3.Service-->
<bean name="accountService" class="cn.itcast.service.AccountServiceImpl" >
	<property name="ad" ref="accountDao" ></property>
	<property name="tt" ref="transactionTemplate" ></property>
</bean>  

</beans>

package cn.itcast.dao;

import org.springframework.jdbc.core.support.JdbcDaoSupport;

public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao  {

	@Override
	public void increaseMoney(Integer id, Double money) {
		
		getJdbcTemplate().update("update t_account set money = money+? where id = ? ", money,id);
		
	}

	@Override
	public void decreaseMoney(Integer id, Double money) {

		getJdbcTemplate().update("update t_account set money = money-? where id = ? ", money,id);
	}

}



package cn.itcast.service;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import cn.itcast.dao.AccountDao;

@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=true)
public class AccountServiceImpl implements AccountService {

	private AccountDao ad ;
	private TransactionTemplate tt;
	
	@Override
	@Transactional(isolation=Isolation.REPEATABLE_READ,propagation=Propagation.REQUIRED,readOnly=false)
	public void transfer(final Integer from,final Integer to,final Double money) {
				//減錢
				ad.decreaseMoney(from, money);
				int i = 1/0;
				//加錢
				ad.increaseMoney(to, money);
	}

/*	@Override
	public void transfer(final Integer from,final Integer to,final Double money) {
		
		tt.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				//減錢
				ad.decreaseMoney(from, money);
				int i = 1/0;
				//加錢
				ad.increaseMoney(to, money);
			}
		});
		
		
	}
*/
	public void setAd(AccountDao ad) {
		this.ad = ad;
	}

	public void setTt(TransactionTemplate tt) {
		this.tt = tt;
	}
	
	

}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章