Spring入门笔记(三)之JdbcTemplate和事务管理

  Craig Walls所著《Spring实战》一书里说,Spring的两大关键字:DI(依赖注入),AOP(面向切面编程)。在之前的两篇博客里,我们已经学习了spring的核心,DI和AOP。大头我们已经学完了,这篇博客主要是介绍剩下的一些知识点,如JdbcTemplate和事务管理等。

JdbcTemplate

  • spring 提供用于操作JDBC工具类,类似:DBUtils。
  • 依赖 连接池DataSource (数据源)

1.1环境搭建

创建表(我这里使用的是MySql)

USE test;
CREATE TABLE t_user(
  id INT PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR(50),
  PASSWORD VARCHAR(32)
);

INSERT INTO t_user(username,PASSWORD) VALUES('jack','1234');
INSERT INTO t_user(username,PASSWORD) VALUES('rose','5678');

导入Jar包


1.2使用API

public class TestApi {
	public static void main(String[] args) {
		//1 创建数据源(连接池) dbcp
				BasicDataSource dataSource = new BasicDataSource();
				// * 基本4项
				dataSource.setDriverClassName("com.mysql.jdbc.Driver");
				dataSource.setUrl("jdbc:mysql://localhost:3306/test");
				dataSource.setUsername("root");
				dataSource.setPassword("root");
				
				
				//2  创建模板
				JdbcTemplate jdbcTemplate = new JdbcTemplate();
				jdbcTemplate.setDataSource(dataSource);
				
				
				//3 通过api操作
				jdbcTemplate.update("insert into t_user(username,password) values(?,?);", "tom","998");
				
			}
	}


dao类:

public class UserDao {

	//JDBC模板将有spring注入
	private JdbcTemplate jdbcTemplate;
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
		this.jdbcTemplate = jdbcTemplate;
	}
	public void update(User user){
		String sql = "update t_user set username=?,password=? where id=?";
		Object[] args = {user.getUsername(),user.getPassword(),user.getId()};
		jdbcTemplate.update(sql,args);
	}
}



1.3配置DBCP示例:

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       					   http://www.springframework.org/schema/beans/spring-beans.xsd
       					   http://www.springframework.org/schema/aop 
       					   http://www.springframework.org/schema/aop/spring-aop.xsd
       					   http://www.springframework.org/schema/context 
       					   http://www.springframework.org/schema/context/spring-context.xsd">
	
	<!-- 创建数据源 -->
	<bean id="dataSourceId" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
		<property name="username" value="root"></property>
		<property name="password" value="root"></property>
	</bean>
	<!-- 创建模板 ,需要注入数据源-->
	<bean id="jdbcTemplateId" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSourceId"></property>
	</bean>
	
	<!-- 配置dao -->
	<bean id="userDaoId" class="com.spring.dbcp.UserDao">
		<property name="jdbcTemplate" ref="jdbcTemplateId"></property>
	</bean>
</beans>

1.4 C3P0配置示例

<!-- 创建数据源 c3p0-->
	<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/<span style="font-family:SimSun;">test</span>"></property>
		<property name="user" value="root"></property>
		<property name="password" value="1234"></property>
	</bean>

1.5使用JdbcDaoSupport

   为了简化dao类,每次注入JdbcTemplate,我们可以继承JdbcDaoSupport,替代set方法。

public class UserDao extends JdbcDaoSupport{
	
	public void update(User user){
		String sql = "update t_user set username=?,password=? where id=?";
		Object[] args = {user.getUsername(),user.getPassword(),user.getId()};
		this.getJdbcTemplate().update(sql,args);
	}
}

<!-- 配置dao 
		* dao 继承 JdbcDaoSupport,之后只需要注入数据源,底层将自动创建模板
	-->
	<bean id="userDaoId" class="com.spring.jdbcSupport.UserDao">
		<property name="dataSource" ref="dataSourceId"></property>
	</bean>

源码分析:



1.6配置Properties

properties文件:

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/<span style="font-family:SimSun;">test</span>
jdbc.user=root
jdbc.password=1234

Spring配置文件

<!-- 加载配置文件 
		"classpath:"前缀表示 src下
		在配置文件之后通过  ${key} 获得内容
	-->
	<context:property-placeholder location="classpath:com/spring/properties/jdbcInfo.properties"/>
	
	<!-- 创建数据源 c3p0-->
	<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="user" value="${jdbc.user}"></property>
		<property name="password"  value="${jdbc.password}"></property>
	</bean>

2.事务管理

2.1回顾事务

  • 事务:一组业务操作ABCD,要么全部成功,要么全部不成功。
  • 特性:ACID

   原子性:整体

            一致性:完成

            隔离性:并发

            持久性:结果

  • 隔离问题:

     脏读:一个事务读到另一个事务没有提交的数据

  不可重复读:一个事务读到另一个事务已提交的数据(update

  虚读(幻读):一个事务读到另一个事务已提交的数据(insert

  • 隔离级别:

   read uncommitted:读未提交。存在3个问题

   read committed:读已提交。解决脏读,存在2个问题

   repeatable read:可重复读。解决:脏读、不可重复读,存在1个问题。

   serializable :串行化。都解决,单事务。


  • mysql 事务操作--简单,示例描述:
ABCD 一个事务
Connection conn = null;
try{
  //1 获得连接
  conn = ...;
  //2 开启事务
  conn.setAutoCommit(false);
  A
  B
  C
  D
  //3 提交事务
  conn.commit();
} catche(){
  //4 回滚事务
  conn.rollback();
}


  •  mysql 事务操作--Savepoint  示例描述:
需求:AB(必须),CD(可选) 
Connection conn = null;
Savepoint savepoint = null;  //保存点,记录操作的当前位置,之后可以回滚到指定的位置。(可以回滚一部分)
try{
  //1 获得连接
  conn = ...;
  //2 开启事务
  conn.setAutoCommit(false);
  A
  B
  savepoint = conn.setSavepoint();
  C
  D
  //3 提交事务
  conn.commit();
} catche(){
  if(savepoint != null){   //CD异常
     // 回滚到CD之前
     conn.rollback(savepoint);
     // 提交AB
     conn.commit();
  } else{   //AB异常
     // 回滚AB
     conn.rollback();
  }
}

2.2事务管理介绍

导入Jar包:

transaction  -->  tx


在开始具体实现之前,我们必须先了解三个顶级接口



  • PlatformTransactionManager  平台事务管理器,spring要管理事务,必须使用事务管理器

   进行事务配置时,必须配置事务管理器

  • TransactionDefinition:事务详情(事务定义、事务属性),spring用于确定事务具体详情,

   例如:隔离级别、是否只读、超时时间

   进行事务配置时,必须配置详情spring将配置项封装到该对象实例。

  • TransactionStatus:事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。

   spring底层根据状态进行相应操作。


2.2.1 PlatformTransactionManager事务管理器

  • 导入jar包:需要时平台事务管理器的实现类


  • 常见的事务管理器

   DataSourceTransactionManagerjdbc开发时事务管理器,采用JdbcTemplate

   HibernateTransactionManager,hibernate开发时事务管理器,整合hibernate


  •  api详解

    TransactionStatus getTransaction(TransactionDefinition definition),事务管理器 通过“事务详情”,获得“事务状态”,从而管理事务。

    void commit(TransactionStatus status)  根据状态提交

    void rollback(TransactionStatus status) 根据状态回滚


2.2.2 TransactionStatus(了解即可)



2.2.3 TransactionDefinition


  • 传播行为:在两个业务之间如何共享事务。

PROPAGATION_REQUIRED , required , 必须  【默认值】

           支持当前事务,A如果有事务,B将使用该事务。

           如果A没有事务,B将创建一个新的事务。

PROPAGATION_SUPPORTS ,supports ,支持

          支持当前事务,A如果有事务,B将使用该事务。

           如果A没有事务,B将以非事务执行。

PROPAGATION_MANDATORY,mandatory ,强制

          支持当前事务,A如果有事务,B将使用该事务。

          如果A没有事务,B将抛异常。

PROPAGATION_REQUIRES_NEW , requires_new ,必须新的

         如果A有事务,将A的事务挂起,B创建一个新的事务

         如果A没有事务,B创建一个新的事务

PROPAGATION_NOT_SUPPORTED ,not_supported ,不支持

       如果A有事务,将A的事务挂起,B将以非事务执行

       如果A没有事务,B将以非事务执行

PROPAGATION_NEVER ,never,从不

      如果A有事务,B将抛异常

      如果A没有事务,B将以非事务执行

PROPAGATION_NESTED ,nested ,嵌套

  A和B底层采用保存点机制,形成嵌套事务。


掌握:PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED

 

案例;转账案例(晚些再贴上来)


  学习到这里,Spring的知识点你已经基本掌握了,具体Spring和一些其他框架的整合,我会专门写一篇博客。这个系列的三篇Spring博客都很基础,而且是基于3.2的。然而Spring Boot,Spring家族中一个新的令人兴奋的项目。Spring致力于简化JAVA开发,而Spring Boot致力于让Spring本身更加简单!后期我应该会写关于SpringBoot的博客,有兴趣的朋友我们,我们可以共同学习,共同探讨。

  现在,你仅仅是一个Spring的user距离真正的developer还有很长的距离。Spring的源码是你必须去深究的。就像《Spring实战》的最后作者说道,你的Spring之路才刚刚开始。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值