Spring 配置連接池丶JdbcTemplate丶事務

1. 配置數據庫連接池

1.1 配置Spring的內置的連接池

<!-- 配置Spring的內置的連接池 -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://localhost:3306/test04"/>
	<property name="username" value="root"/>
	<property name="password" value="root"/>
</bean> 

1.2 配置DBCP連接池

  • 導入DBCP的jar包
    在這裏插入圖片描述
    在這裏插入圖片描述
<!-- 配置DBCP連接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://localhost:3306/test04"/>
	<property name="username" value="root"/>
	<property name="password" value="root"/>
</bean> 

1.3 配置C3P0連接池

  • 導入C3P0的jar包
    在這裏插入圖片描述
<!-- 配置C3P0連接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="com.mysql.jdbc.Driver"/>
	<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test04"/>
	<property name="user" value="root"/>
	<property name="password" value="root"/>
</bean> 

1.4 使用屬性文件存儲數據庫信息

  • 在屬性文件jdbc.properties中配置數據庫信息
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test04
jdbc.username=root
jdbc.password=root
  • 引入屬性文件並配置連接池
<!-- 通過context標籤引入屬性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- 配置C3P0連接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
	<property name="driverClass" value="${jdbc.driverClass}"/>
	<property name="jdbcUrl" value="${jdbc.url}"/>
	<property name="user" value="${jdbc.username}"/>
	<property name="password" value="${jdbc.password}"/>
</bean>

2. JdbcTemplate

2.1 配置Spring的JDBC模版實例

<!-- 此處省略連接池配置,具體參考上面代碼 -->

<!-- 配置Spring的JDBC的模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
	<property name="dataSource" ref="dataSource" />
</bean>

2.2 使用的JdbcTemplate的增刪改操作

//讀取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//根據bean標籤的id屬性值查找實例
JdbcTemplate jdbcTemplate= ac.getBean("jdbcTemplate",JdbcTemplate.class);

//update方法執行的是增刪改方法
jdbcTemplate.update("insert into Account values (null,?,?)","田七",1000);
jdbcTemplate.update("update Account set money=? where id=?",800,1);
jdbcTemplate.update("delete from Account  where id=?",11);

2.3 查詢返回單個值

//讀取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//根據bean標籤的id屬性值查找實例
JdbcTemplate jdbcTemplate= ac.getBean("jdbcTemplate",JdbcTemplate.class);

String name=jdbcTemplate.queryForObject("select name from Account where id=?", String.class,1);
System.out.println(name);

Long count=jdbcTemplate.queryForObject("select count(*) from Account ", Long.class);
System.out.println(count);

2.4 查詢返回封裝成對象的數據

@Test
public void test3(){
	//讀取spring配置文件
	ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
	//根據bean標籤的id屬性值查找實例
	JdbcTemplate jdbcTemplate= ac.getBean("jdbcTemplate",JdbcTemplate.class);
	
	//查詢返回單行數據並封裝成對象
	Account account=jdbcTemplate.queryForObject("select * from Account where id=?", new AccountRowMapper(),1);
	System.out.println(account);
	
	//查詢多行數據並封裝成對象集合
	List<Account> list=jdbcTemplate.query("select * from Account", new AccountRowMapper());
	for (Account a : list) {
		System.out.println(a);
	}
}

//對返回結果封裝成對象
class AccountRowMapper implements RowMapper<Account>{

	@Override
	public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
		Account account=new Account();
		account.setId(rs.getInt("id"));
		account.setName(rs.getString("name"));
		account.setMoney(rs.getDouble("money"));
		return account;
	}
	
}

3.Spring聲明式事務(AOP)

3.1 Spring配置

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

	<!-- Spring配置中使用事務beans標籤需要引入
	① xmlns:tx="http://www.springframework.org/schema/tx" 
	
	② xsi:schemaLocation中添加以下兩個值
	 http://www.springframework.org/schema/tx 
	 http://www.springframework.org/schema/tx/spring-tx.xsd
	-->



	<!-- 1.通過context標籤引入數據庫連接屬性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	
	<!-- 2.配置C3P0連接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
		

	
	<!-- 3.配置事務管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>


 	<!-- 4.配置事務增強,並指定事務管理器 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!-- 定義屬性,聲明事務規則 -->
        <tx:attributes>
            <!-- name表示添加事務的方法名,支持*模式匹配 -->
            <!-- read-only設置爲true表示事務只讀,可以提高查詢功能事務的處理性能,默認值爲false -->
            <!-- 事務傳播機制propagation的默認值爲REQUIRED,表示如果存在當前事務,則支持當前事務,
                   如果不存在當前事務,則開啓一個新事務 -->
            <tx:method name="find*" read-only="true"/>
            <tx:method name="search*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="do*" propagation="REQUIRED"/>
          
            <!-- 本次例子的方法名 -->
            <tx:method name="transfer" />
        </tx:attributes>
    </tx:advice>
    
    <!-- 5.定義切面 -->
    <!-- 如果出現異常BeanNotOfRequiredTypeException需要把 proxy-target-class設置爲true -->
    <aop:config proxy-target-class="true">
        <!-- 定義事務管理器的切入點,這裏設置了業務包下的所有方法爲切入點 -->
        <aop:pointcut expression="execution(* com.service.impl.*.*(..))" id="servicePointcut"/>
        <!-- 將事務增強與切入點組合 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/>
    </aop:config>


	 <!-- 這裏不用配置JdbcTemplate實例,JdbcDaoSupport類中會自動根據dataSource進行創建實例 -->
	 <!-- 這裏注入的屬性是dataSource,而不是jdbcTemplate,因爲繼承了JdbcDaoSupport類 -->
	<bean id="accountDao" class="com.dao.impl.AccountDaoImpl">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<bean id="accountService" class="com.service.impl.AccountServiceImpl" >
		<property name="accountDao" ref="accountDao"></property>
	</bean>	
</beans>

3.2 轉賬例子

  • Dao類
package com.dao.impl;

import org.springframework.jdbc.core.support.JdbcDaoSupport;
import com.dao.AccountDao;

//只要在Spring文件中配置了dataSource實例,並且注入dataSource實例進AccountDaoImpl中,繼承JdbcDaoSupport類後就可以直接使用JdbcTemplate
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {

	//父類JdbcDaoSupport有setDataSource(),所以要注入dataSource,而jdbcTemplate父類會自動創建,所以不用注入
	
	//轉入
	@Override
	public void in(String name,double money) {
		String sql="update Account set money=money+? where name=?";
		getJdbcTemplate().update(sql,money,name);

	}

	//轉出
	@Override
	public void out(String name,double money) {
		String sql="update Account set money=money-? where name=?";
		getJdbcTemplate().update(sql,money,name);

	}

}


  • Service類
package com.service.impl;

import com.dao.AccountDao;
import com.service.AccountService;

public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	

	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}

	//轉賬操作
	@Override
	public void transfer(String from, String to, double money) {
		
		accountDao.out(from, money);
		//模擬拋出異常
//		int num=1/0;  
		accountDao.in(to, money);
		
	}

}

  • 測試類
package com.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.service.AccountService;
import com.service.impl.AccountServiceImpl;

public class TestAccount {
	@Test
	public void test(){
		//讀取spring配置文件
		ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
		//根據bean標籤的id屬性值查找實例
		AccountService accountService= ac.getBean("accountService",AccountServiceImpl.class);
		accountService.transfer("張三", "李四", 500);
	}
}

3.3 註解事務

	<!-- 1.通過context標籤引入數據庫連接屬性文件 -->
	<context:property-placeholder location="classpath:jdbc.properties"/>
	
	<!-- 2.配置C3P0連接池 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</bean>
		

	
	<!-- 3.配置事務管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>


 	<!-- 4.開啓註解事務(把原先的4和5替換了) -->
 	<!-- 如果出現異常BeanNotOfRequiredTypeException需要把 proxy-target-class設置爲true -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
//在需要添加事務的類上添加註解@Transactional
@Transactional
public class AccountServiceImpl implements AccountService {}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章