四、spring的JDBC模板和事务管理

Spring的JDBC模板

Spring是JavaEE开发的一站式框架,对各种持久化技术都提供了简单的模板

ORM持久化技术 模板类
JDBC org.springframework.jdbc.core.JdbcTemplate
Hibernate5.0 org.springframework.orm.hibernate5.HibernateTemplate
IBatis(MyBatis) org.springframework.orm.ibatis.SqlMapClientTemplate
JPA org.springfrmaework.orm.jpa.JpaTemplate

JDBC模板的基本使用

  1. 引入jar
    • Spring项目的6个基础开发包
    • 数据库驱动包
    • Spring的JDBC模板的jar包
  2. 测试
    • 编写测试类
      public class TestDemo {
      
      	@Test
      	public void demo() {
      		//创建连接池
      		DriverManagerDataSource dataSource = new DriverManagerDataSource();
      		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      		dataSource.setUrl("jdbc:mysql:///test");
      		dataSource.setUsername("root");
      		dataSource.setPassword("root");
      		
      		//创建jdbc模板
      		JdbcTemplate template = new JdbcTemplate(dataSource);
      		List<Map<String,Object>> list = template.queryForList("select * from user");
      		for (Map<String, Object> map : list) {
      			Set<String> keySet = map.keySet();
      			Iterator<String> iterator = keySet.iterator();
      			while (iterator.hasNext()) {
      				String key = iterator.next();
      				System.out.println(key+" : "+map.get(key));
      			}
      		}
      	}
      }
    • 测试结果
      id : 1
      name : test
      password : 0
      id : 2
      name : wxf
      password : 1
      id : 3
      name : admin
      password : 123

Spring管理模板和连接池

  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: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/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd"> 
            <!-- 管理数据库连接池 -->    
    	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="url" value="jdbc:mysql:///test"></property>
    		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    		<property name="username" value="root"></property>
    		<property name="password" value="root"></property>
    	</bean>        
            
    	<!-- 管理JDBC模板 -->
    	<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
    		<property name="dataSource" ref="dataSource"/>
    	</bean>
    </beans>
  2. 测试方法
    @Test
    public void demo2() {
    	
    	ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    	JdbcTemplate template = (JdbcTemplate) context.getBean("template");
    	
    	List<Map<String,Object>> list = template.queryForList("select * from user");
    	for (Map<String, Object> map : list) {
    		Set<String> keySet = map.keySet();
    		Iterator<String> iterator = keySet.iterator();
    		while (iterator.hasNext()) {
    			String key = iterator.next();
    			System.out.println(key+" : "+map.get(key));
    		}
    	}
    }

Spring中使用开源数据库连接池

DBCP的使用

  1. 引入jar包
    • com.springsource.org.apache.commons.pool-1.5.3.jar
    • com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar  
  2. Spring配置连接池
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    	<property name="url" value="jdbc:mysql:///test"></property>
    	<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    	<property name="username" value="root"></property>
    	<property name="password" value="root"></property>
    </bean>

C3P0的使用

  1. 引入jar包
    • com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
  2. Spring配置连接池
    <!-- 管理c3p0数据库连接池 --> 
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    	<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
    	<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    	<property name="user" value="root"></property>
    	<property name="password" value="root"></property>
    </bean>

抽取连接池属性配置值到Properties文件 

  1. 定义一个properties文件:jdbc.properties
    jdbc.url=jdbc:mysql:///test
    jdbc.driverClassName=com.mysql.jdbc.Driver
    jdbc.username=root
    jdbc.password=root
  2. Spring引入jdbc.properties文件
    • 第一种:使用<bean>标签
      <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      	<property name="location" value="classpath:jdbc.properties"/>
      </bean>
    • 第二种:使用<context:property-placeholder>标签
      <context:property-placeholder location="classpath:jdbc.properties" />
       
  3. Spring配置文件使用jdbc.properties的属性值
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    	<property name="url" value="${jdbc.url}"></property>
    	<property name="driverClassName" value="${jdbc.driverClassName}"></property>
    	<property name="username" value="${jdbc.username}"></property>
    	<property name="password" value="${jdbc.password}"></property>
    </bean>

Spring的事务管理

常用API

PlatformTransactionManager

  • Spring的事务基础结构的中心接口,常用实现类
    • DataSourceTransactionManager:使用JDBC管理事务
    • HibernateTransactionManager:使用Hibernate管理事务    

TransactionDefinition

  • Spring的事务定义,用于定义事务相关的信息。例如,隔离级别、传播行为、是否只读、超时信息等  

TransactionStatus

  • 用于记录事务管理的过程中,事务的状态信息  

Spring进行事务管理时,PlatformTransactionManager根据TransactionDefinition进行事务的管理,这个过程中会产生各种状态,将这些状态记录到TransactionStatus中

传播行为

基本认识

事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法的时事务如何传播

主要用来解决业务层方法(每个业务层方法有自己的事务)相互调用的问题

7种传播行为

class TestServiceImpl01 {
	...
	public void A() {
		testDao1.test1();
		testDao2.test2();
	}
}

class TestServiceImpl02 {
	...
	public void B() {
		new TestServiceImpl01().A();//A操作
		testDao3.test3();//B操作
		testDao4.test4();//B操作
	}
}

  

分类 传播行为类型 说明

多个操作在同一个事务中

(A、B操作在一个事务中)

PROPAGATION_REQUIRED 默认值,如果A中有事务,使用A中的事务;如果A中没有事务,创建一个新的事务,将操作(A、B)包含进来
PROPAGATION_SUPPORTS 如果A中有事务,使用A中的事务;如果A中没有事务,就不使用事务
PROPAGATION_MANDATORY 如果A中有事务,使用A中的事务;如果A中没有事务,就抛出异常

多个操作不在同一个事务中

(A、B操作不在一个事务中)

PROPAGATION_REQUIRES_NEW 如果A中有事务,将A的事务挂起,新建一个事务,只将自身操作(B)包含进来
PROPAGATION_NOT_SUPPORTED 如果A中有事务,将A的事务挂起,不使用事务
PROPAGATION_NEVER 如果A中有事务,抛出异常
嵌套式事务 PROPAGATION_NESTED

如果A中有事务,执行A事务,执行完成后设置一个保存点;再执行B中的操作,如果没有异常,执行通过;如果有异常

可以回滚到最初始位置(A操作前),也可以回滚到A操作后设置的保存点位置

基本使用

案例要求:

  账户之间相互转账,一方转出的同时另一方必须转入才行

实现一:不使用事务

  1. 创建service层、dao层的接口和实现类
    • dao层
      • 接口
      • 实现类  
    • service层 
      • 接口
      • 实现类   
  2. Spring管理service和dao的实现类
  3. 测试

编程式、声明式事务管理

猜你喜欢

转载自www.cnblogs.com/qf123/p/10268139.html
今日推荐