参照:https://blog.csdn.net/chuangxin/article/details/80921704
试验代码:https://download.csdn.net/download/u010476739/11518163
试验目的:
- spring-jdbc使用方法
- spring-jdbc事务实现编程式事务管理的两种方法:
1:transactionManager+JDBCTemplate
2:transactionTemplate - spring-jdbc事务实现声明式事务管理的两种方法
1:xml,在spring配置文件中配置好切点和事务通知
2:注解,在spring配置文件中启动事务驱动注解,在事务方法上添加@Transactional
试验环境:
- win10家庭版64位
- postgresql10
- springframework 4.2.4.release
一、试验jdbc操作和编程式事务的两种书写方式
1.1 准备数据库demo新建表Student
CREATE TABLE Student(
ID SERIAL PRIMARY Key,
NAME VARCHAR(20) NOT NULL,
AGE INT NOT NULL
);
1.2 pom文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jackletter</groupId>
<artifactId>spring-jdbc-tran1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>this is name</name>
<description>this is desc</description>
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
<postgresql.version>42.2.6</postgresql.version>
</properties>
<dependencies>
<!-- Spring Core -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Context -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
</project>
1.3 sping配置文件(applicationContext.xml)
<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"
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">
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName"
value="org.postgresql.Driver" />
<property name="url"
value="jdbc:postgresql://localhost:5432/demo" />
<property name="username" value="postgres" />
<property name="password" value="123456" />
<property name="initialSize" value="5" />
</bean>
<bean id="JDBCTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg>
<ref bean="dataSource" />
</constructor-arg>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="transactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
<context:component-scan
base-package="com.jackletter" />
</beans>
其实从这个上面可以看出spring-jdbc关于事务的主要对象
1.4 java代码
Student.java:
package com.jackletter.entity;
public class Student {
private Integer age;
private String name;
private Integer id;
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
}
StudentMapper.java:
package bean;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.jackletter.entity.Student;
public class StudentMapper implements RowMapper<Student> {
public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
return student;
}
}
StudentDAO.java:
package com.jackletter.dao;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.jackletter.entity.Student;
import bean.StudentMapper;
@Component
public class StudentDAO {
@Resource
private JdbcTemplate jdbcTemplateObject;
@Resource
private PlatformTransactionManager transactionManager;
@Resource
private TransactionTemplate transactionTemplate;
public void create(String name, Integer age) {
String SQL = "insert into Student (name, age) values (?, ?)";
jdbcTemplateObject.update(SQL, name, age);
System.out.println("Created Record Name = " + name + " Age = " + age);
return;
}
public Student getStudent(Integer id) {
String SQL = "select * from Student where id = ?";
Student student = jdbcTemplateObject.queryForObject(SQL, new Object[] { id }, new StudentMapper());
return student;
}
public List<Student> listStudents() {
String SQL = "select * from Student";
List<Student> students = jdbcTemplateObject.query(SQL, new StudentMapper());
return students;
}
public void delete(Integer id) {
String SQL = "delete from Student where id = ?";
jdbcTemplateObject.update(SQL, id);
System.out.println("Deleted Record with ID = " + id);
return;
}
public void update(Integer id, Integer age) {
String SQL = "update Student set age = ? where id = ?";
jdbcTemplateObject.update(SQL, age, id);
System.out.println("Updated Record with ID = " + id);
return;
}
public void opTX() {
DefaultTransactionDefinition define = new DefaultTransactionDefinition();
TransactionStatus status = transactionManager.getTransaction(define);
System.out.println("withTX start...");
try {
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", "20");
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", "哈哈");
transactionManager.commit(status);
} catch (Exception ex) {
transactionManager.rollback(status);
System.out.println(ex);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void opTXTemplate() {
transactionTemplate.execute(new TransactionCallback() {
@Override
public Object doInTransaction(TransactionStatus status) {
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", "20");
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", "哈哈");
return null;
}
});
}
}
App.java:
package com.jackletter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jackletter.dao.StudentDAO;
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentDAO studentDao = (StudentDAO) context.getBean(StudentDAO.class);
// 測試jdbc普通的增刪 改查
// System.out.println("------Records Creation--------");
// studentDao.create("Zara", 11);
// studentDao.create("Nuha", 2);
// studentDao.create("Ayan", 15);
//
// System.out.println("------Listing Multiple Records--------");
// List<Student> students = studentDao.listStudents();
// for (Student record : students) {
// System.out.print("ID : " + record.getId());
// System.out.print(", Name : " + record.getName());
// System.out.println(", Age : " + record.getAge());
// }
//
// System.out.println("----Updating Record with ID = 2 -----");
// studentDao.update(2, 20);
//
// System.out.println("----Listing Record with ID = 2 -----");
// Student student = studentDao.getStudent(2);
// System.out.print("ID : " + student.getId());
// System.out.print(", Name : " + student.getName());
// System.out.println(", Age : " + student.getAge());
//studentDao.opTX();
studentDao.opTXTemplate();
}
}
1.5 直接运行查看数据库的数据和控制台输出即可
二、试验spring-jdbc声明式事务的xml方式
2.1 环境
- 数据库采用上个试验的
- pom文件增加aspectj依赖
- spring配置文件中增加aop配置(事务的切点、通知),删除transactionTemplate内容(用不到)
- 精简StudentDao.java代码、App代码
2.2 改变了的文件
pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jackletter</groupId>
<artifactId>spring-jdbc-tran2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>this is name</name>
<description>this is desc</description>
<properties>
<spring.version>4.2.4.RELEASE</spring.version>
<postgresql.version>42.2.6</postgresql.version>
</properties>
<dependencies>
<!-- Spring Core -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Context -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${postgresql.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
</dependencies>
</project>
applicationContext.xml:
<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">
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName"
value="org.postgresql.Driver" />
<property name="url"
value="jdbc:postgresql://localhost:5432/demo" />
<property name="username" value="postgres" />
<property name="password" value="123456" />
<property name="initialSize" value="5" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="JDBCTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg>
<ref bean="dataSource" />
</constructor-arg>
</bean>
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="Transaction*"></tx:method>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pt"
expression="execution(* com.jackletter.dao.*.*(..))"></aop:pointcut>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"></aop:advisor>
</aop:config>
<context:component-scan
base-package="com.jackletter" />
</beans>
StudentDao:
package com.jackletter.dao;
import javax.annotation.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class StudentDAO {
@Resource
private JdbcTemplate jdbcTemplateObject;
public void TransactionOp() {
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", 20);
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", "哈哈");
}
}
App.java:
package com.jackletter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.jackletter.dao.StudentDAO;
public class App {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
StudentDAO studentDao = (StudentDAO) context.getBean(StudentDAO.class);
studentDao.TransactionOp();
}
}
2.3 直接运行后观察控制台输出和数据库的数据变化
三、试验spring-jdbc声明式事务的注解方式
3.1 环境
- 数据库使用上个试验的
- pom文件不变
- spring配置文件删除上个试验的通知、切点配置,增加事务的注解驱动
- StudentDao代码修改为使用注解方式使用事务
3.2 改变了的文件
application.xml:
<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">
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName"
value="org.postgresql.Driver" />
<property name="url"
value="jdbc:postgresql://localhost:5432/demo" />
<property name="username" value="postgres" />
<property name="password" value="123456" />
<property name="initialSize" value="5" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="JDBCTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg>
<ref bean="dataSource" />
</constructor-arg>
</bean>
<tx:annotation-driven
transaction-manager="transactionManager" />
<context:component-scan
base-package="com.jackletter" />
</beans>
StudentDao.java:
package com.jackletter.dao;
import javax.annotation.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class StudentDAO {
@Resource
private JdbcTemplate jdbcTemplateObject;
@Transactional
public void TransactionOp() {
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", 20);
jdbcTemplateObject.update("insert into Student(NAME,AGE) values(?,?)", "测试事务", "哈哈");
}
}