其他分享
首页 > 其他分享> > 4-1-3 Spring基础-Spring JDBC与事务管理

4-1-3 Spring基础-Spring JDBC与事务管理

作者:互联网

Spring JDBC是什么

Spring JDBC是Spring生态用于处理关系型数据库的模块

Spring JDBC对JDBC API进行封装,极大简化开发工作量

JdbcTemplate是Spring JDBC核心类,提供CRUD方法

Spring JDBC与MyBatis

MyBatis是ORM框架,适合中小企业完成敏捷开发.封装程度高,执行效率比较低.

Spring JDBC只对JDBC进行了简单封装,可以结合实际情况进行二次封装.

Spring JDBC执行效率比MyBatis执行效率高

Spring JDBC的使用步骤

Maven工程引入依赖spring-jdbc

applicationContext.xml配置DataSource数据源

在Dao注入JdbcTemplate对象,实现数据CRUD

 Demo

pom.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>com.mingm.spring</groupId>
 8     <artifactId>jdbc</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10     <dependencies>
11         <dependency>
12             <groupId>org.springframework</groupId>
13             <artifactId>spring-context</artifactId>
14             <version>5.2.6.RELEASE</version>
15         </dependency>
16         <dependency>
17             <groupId>org.springframework</groupId>
18             <artifactId>spring-jdbc</artifactId>
19             <version>5.2.6.RELEASE</version>
20         </dependency>
21         <dependency>
22             <groupId>mysql</groupId>
23             <artifactId>mysql-connector-java</artifactId>
24             <version>8.0.16</version>
25         </dependency>
26 
27         <dependency>
28             <groupId>junit</groupId>
29             <artifactId>junit</artifactId>
30             <version>4.12</version>
31         </dependency>
32         <dependency>
33             <groupId>org.springframework</groupId>
34             <artifactId>spring-test</artifactId>
35             <version>5.2.6.RELEASE</version>
36         </dependency>
37 
38         <!--logback日志组件,Spring框架默认集成-->
39         <dependency>
40             <groupId>ch.qos.logback</groupId>
41             <artifactId>logback-classic</artifactId>
42             <version>1.2.3</version>
43         </dependency>
44 
45     </dependencies>
46 
47 </project>

applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         https://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context
 8         https://www.springframework.org/schema/context/spring-context.xsd">
 9     <!-- 数据源 -->
10     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
11         <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
12         <property name="url"
13                   value="jdbc:mysql://localhost:3306/mingm?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
14         <property name="username" value="root"/>
15         <property name="password" value="123456"/>
16     </bean>
17     <!--JdbcTemplate提供数据CRUD的API-->
18     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
19         <property name="dataSource" ref="dataSource"/>
20     </bean>
21 
22     <bean id="employeeDao" class="com.mingm.spring.jdbc.dao.EmployeeDao">
23         <!--为Dao注入JdbcTemplate对象-->
24         <property name="jdbcTemplate" ref="jdbcTemplate"/>
25     </bean>
26 
27 </beans>
Employee.java(实体类)
 1 package com.mingm.spring.jdbc.entity;
 2 
 3 import java.util.Date;
 4 
 5 public class Employee {
 6     private Integer eno;
 7     private String ename;
 8     private Float salary;
 9     private String dname;
10     private Date hiredate;
11 
12     public Integer getEno() {
13         return eno;
14     }
15 
16     public void setEno(Integer eno) {
17         this.eno = eno;
18     }
19 
20     public String getEname() {
21         return ename;
22     }
23 
24     public void setEname(String ename) {
25         this.ename = ename;
26     }
27 
28     public Float getSalary() {
29         return salary;
30     }
31 
32     public void setSalary(Float salary) {
33         this.salary = salary;
34     }
35 
36     public String getDname() {
37         return dname;
38     }
39 
40     public void setDname(String dname) {
41         this.dname = dname;
42     }
43 
44     public Date getHiredate() {
45         return hiredate;
46     }
47 
48     public void setHiredate(Date hiredate) {
49         this.hiredate = hiredate;
50     }
51 
52     @Override
53     public String toString() {
54         return "Employee{" +
55                 "eno=" + eno +
56                 ", ename='" + ename + '\'' +
57                 ", salary=" + salary +
58                 ", dname='" + dname + '\'' +
59                 ", hiredate=" + hiredate +
60                 '}';
61     }
62 }
EmployeeDao.java
 1 package com.mingm.spring.jdbc.dao;
 2 
 3 import com.mingm.spring.jdbc.entity.Employee;
 4 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 5 import org.springframework.jdbc.core.JdbcTemplate;
 6 
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 public class EmployeeDao {
11     private JdbcTemplate jdbcTemplate;
12 
13     public Employee findById(Integer eno){
14         String sql = "select * from employee where eno = ?";
15         //查询单条数据
16         Employee employee = jdbcTemplate.queryForObject(sql, new Object[]{eno}, new BeanPropertyRowMapper<Employee>(Employee.class));
17         return employee;
18     }
19 
20     public JdbcTemplate getJdbcTemplate() {
21         return jdbcTemplate;
22     }
23 
24     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
25         this.jdbcTemplate = jdbcTemplate;
26     }
27 }

Spring JDBC常用方法

 1 package com.mingm.spring.jdbc.dao;
 2 
 3 import com.mingm.spring.jdbc.entity.Employee;
 4 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 5 import org.springframework.jdbc.core.JdbcTemplate;
 6 
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 public class EmployeeDao {
11     private JdbcTemplate jdbcTemplate;
12 
13     public Employee findById(Integer eno){
14         String sql = "select * from employee where eno = ?";
15         //查询单条数据
16         Employee employee = jdbcTemplate.queryForObject(sql, new Object[]{eno}, new BeanPropertyRowMapper<Employee>(Employee.class));
17         return employee;
18     }
19 
20     public List<Employee> findByDname(String dname){
21         String sql = "select * from employee where dname = ?";
22         //查询复合数据
23         List<Employee> list = jdbcTemplate.query(sql, new Object[]{dname}, new BeanPropertyRowMapper<Employee>(Employee.class));
24         return list;
25     }
26 
27     public List<Map<String, Object>> findMapByDname(String dname){
28         String sql = "select eno as empno , salary as s from employee where dname = ?";
29         //将查询结果作为Map进行封装
30         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{dname});
31         return maps;
32     }
33 
34     public void insert(Employee employee){
35         String sql = "insert into employee(eno,ename,salary,dname,hiredate) values(?,?,?,?,?)";
36         //利用update方法实现数据写入操作
37         jdbcTemplate.update(sql,new Object[]{
38            employee.getEno() , employee.getEname(),employee.getSalary(),employee.getDname() , employee.getHiredate()
39         });
40     }
41 
42     public int update(Employee employee){
43         String sql = "UPDATE employee SET ename = ?, salary = ?, dname = ?, hiredate = ? WHERE eno = ?";
44         int count = jdbcTemplate.update(sql, new Object[]{employee.getEname(), employee.getSalary(), employee.getDname(), employee.getHiredate(), employee.getEno()});
45         return count;
46     }
47 
48     public int delete(Integer eno){
49         String sql = "delete from employee where eno = ?";
50         return jdbcTemplate.update(sql, new Object[]{eno});
51     }
52 
53 
54     public JdbcTemplate getJdbcTemplate() {
55         return jdbcTemplate;
56     }
57 
58     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
59         this.jdbcTemplate = jdbcTemplate;
60     }
61 }

Spring编程式事务

Spring JDBC通过TransactionManager事务管理器实现事务控制

事务管理器提供commit/rollback方法进行事务提交与回滚

applicationContext.xml加入事务管理器

1     <bean id="employeeService" class="com.mingm.spring.jdbc.service.EmployeeService">
2         <property name="employeeDao" ref="employeeDao"/>
3         <property name="transactionManager" ref="transactionManager"/>
4     </bean>
5     <!--事务管理器-->
6     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
7         <property name="dataSource" ref="dataSource"></property>
8     </bean>

 

 1 package com.mingm.spring.jdbc.service;
 2 
 3 import com.mingm.spring.jdbc.dao.EmployeeDao;
 4 import com.mingm.spring.jdbc.entity.Employee;
 5 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
 6 import org.springframework.transaction.TransactionDefinition;
 7 import org.springframework.transaction.TransactionStatus;
 8 import org.springframework.transaction.support.DefaultTransactionDefinition;
 9 
10 import java.util.Date;
11 
12 public class EmployeeService {
13     private EmployeeDao employeeDao;
14     private DataSourceTransactionManager transactionManager;
15 
16     public void batchImport(){
17         //定义了事务默认的标准配置
18         TransactionDefinition definition = new DefaultTransactionDefinition();
19         //开始一个事务,返回事务状态,事务状态说明当前事务的执行阶段
20         TransactionStatus status = transactionManager.getTransaction(definition);
21         try {
22             for (int i = 1; i <= 10; i++) {
23                 /*if (i == 3) {
24                     throw new RuntimeException("意料之外的异常");
25                 }*/
26                 Employee employee = new Employee();
27                 employee.setEno(8000 + i);
28                 employee.setEname("员工" + i);
29                 employee.setSalary(4000f);
30                 employee.setDname("市场部");
31                 employee.setHiredate(new Date());
32                 employeeDao.insert(employee);
33             }
34             //提交事务
35             transactionManager.commit(status);
36         }catch (RuntimeException e){
37             //回滚事务
38             transactionManager.rollback(status);
39             throw e;
40         }
41 
42     }
43     public EmployeeDao getEmployeeDao() {
44         return employeeDao;
45     }
46 
47     public void setEmployeeDao(EmployeeDao employeeDao) {
48         this.employeeDao = employeeDao;
49     }
50 
51     public DataSourceTransactionManager getTransactionManager() {
52         return transactionManager;
53     }
54 
55     public void setTransactionManager(DataSourceTransactionManager transactionManager) {
56         this.transactionManager = transactionManager;
57     }
58 }

Spring声明式事务

声明式事务是指在不修改源码情况下通过配置形式自动实现事务控制,声明式事务本质就是AOP环绕通知

当目标方法执行成功时,自动提交事务

当目标方法抛出运行时异常时,自动事务回滚

配置过程

1.配置TransactionManager事务管理器

2.配置事务通知和事务属性

3.为事务通知绑定PointCut切点

demo

pom.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>com.mingm.spring</groupId>
 8     <artifactId>jdbc</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10     <dependencies>
11         <dependency>
12             <groupId>org.springframework</groupId>
13             <artifactId>spring-context</artifactId>
14             <version>5.2.6.RELEASE</version>
15         </dependency>
16         <dependency>
17             <groupId>org.springframework</groupId>
18             <artifactId>spring-jdbc</artifactId>
19             <version>5.2.6.RELEASE</version>
20         </dependency>
21         <dependency>
22             <groupId>mysql</groupId>
23             <artifactId>mysql-connector-java</artifactId>
24             <version>8.0.16</version>
25         </dependency>
26 
27         <dependency>
28             <groupId>junit</groupId>
29             <artifactId>junit</artifactId>
30             <version>4.12</version>
31         </dependency>
32         <dependency>
33             <groupId>org.springframework</groupId>
34             <artifactId>spring-test</artifactId>
35             <version>5.2.6.RELEASE</version>
36         </dependency>
37 
38         <!--logback日志组件,Spring框架默认集成-->
39         <dependency>
40             <groupId>ch.qos.logback</groupId>
41             <artifactId>logback-classic</artifactId>
42             <version>1.2.3</version>
43         </dependency>
44         <dependency>
45             <groupId>org.aspectj</groupId>
46             <artifactId>aspectjweaver</artifactId>
47             <version>1.9.5</version>
48         </dependency>
49     </dependencies>
50 
51 </project>

applicationContext.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:tx="http://www.springframework.org/schema/tx"
 6        xmlns:aop="http://www.springframework.org/schema/aop"
 7        xsi:schemaLocation="http://www.springframework.org/schema/beans
 8         https://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/context
10         https://www.springframework.org/schema/context/spring-context.xsd
11         http://www.springframework.org/schema/tx
12         https://www.springframework.org/schema/tx/spring-tx.xsd
13         http://www.springframework.org/schema/aop
14         https://www.springframework.org/schema/aop/spring-aop.xsd">
15     <!-- 数据源 -->
16     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
17         <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
18         <property name="url"
19                   value="jdbc:mysql://localhost:3306/mingm?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
20         <property name="username" value="root"/>
21         <property name="password" value="root"/>
22     </bean>
23     <!--JdbcTemplate提供数据CRUD的API-->
24     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
25         <property name="dataSource" ref="dataSource"/>
26     </bean>
27 
28     <bean id="employeeDao" class="com.mingm.spring.jdbc.dao.EmployeeDao">
29         <!--为Dao注入JdbcTemplate对象-->
30         <property name="jdbcTemplate" ref="jdbcTemplate"/>
31     </bean>
32 
33     <bean id="employeeService" class="com.mingm.spring.jdbc.service.EmployeeService">
34         <property name="employeeDao" ref="employeeDao"/>
35         <property name="batchService" ref="batchService"/>
36     </bean>
37 
38     <bean id="batchService" class="com.mingm.spring.jdbc.service.BatchService">
39         <property name="employeeDao" ref="employeeDao"/>
40     </bean>
41 
42     <!-- 1.事务管理器,用于创建事务/提交/回滚 -->
43     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
44         <property name="dataSource" ref="dataSource"/>
45     </bean>
46 
47     <!--2.事务通知配置,决定哪些方法使用事务,哪些方法不使用事务 -->
48     <tx:advice id="txAdvice" transaction-manager="transactionManager">
49         <tx:attributes>
50             <!-- 目标方法名为batchImport时,启用声明式事务,成功提交,运行时异常回滚 -->
51             <tx:method name="batchImport" propagation="REQUIRED"/>
52             <tx:method name="batch*" propagation="REQUIRED"/>
53             <!-- 设置所有findXXX方法不需要使用事务 -->
54             <tx:method name="find*" propagation="NOT_SUPPORTED" read-only="true"/>
55             <tx:method name="get*" propagation="NOT_SUPPORTED" read-only="true"/>
56 
57             <tx:method name="importJob1" propagation="REQUIRES_NEW"/>
58             <tx:method name="importJob2" propagation="REQUIRES_NEW"/>
59             <tx:method name="*" propagation="REQUIRED"/>
60         </tx:attributes>
61     </tx:advice>
62 
63     <!--3. 定义声明式事务的作用范围-->
64     <aop:config>
65         <aop:pointcut id="pointcut" expression="execution(* com.mingm..*Service.*(..))"/>
66         <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
67     </aop:config>
68 </beans>

事务传播行为

事务传播类型 说明 场景
PROPAGATION_REQUIRED(默认) 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,就加入到这个事务中,这是最常见的选择 大多数保证同时提交,同时失败回滚的场景
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起 在一个事务中下多个子事务不需要保证同时成功提交,失败回滚.,只需要保证子事务.多见于批量操作
PROPAGATION_NOT_SUPPORTED 以非事务方式执行,如果当前存在事务,就将当前事务挂起 大多数查询操作
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行 不常见
PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常 不常见
PROPAGATION_NEVER 以非事务的方式运行,如果当前存在事务,则抛出异常 不常见
PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行.如果当前没有事务,则执行有PROPAGATION_REQUIRED类似操作 不常见

注解配置声明式事务

applicationContext.xml

<!-- 启用注解形式声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

EmployService.java

 1 package com.mingm.spring.jdbc.service;
 2 
 3 import com.mingm.spring.jdbc.dao.EmployeeDao;
 4 import com.mingm.spring.jdbc.entity.Employee;
 5 import org.springframework.stereotype.Service;
 6 import org.springframework.transaction.annotation.Propagation;
 7 import org.springframework.transaction.annotation.Transactional;
 8 
 9 import javax.annotation.Resource;
10 import java.util.Date;
11 @Service
12 //声明式事务核心注解
13 //放在类上,将声明式事务配置应用于当前类所有方法,默认事务传播为 REQUIRED
14 @Transactional
15 public class EmployeeService {
16     @Resource
17     private EmployeeDao employeeDao;
18     @Resource
19     private BatchService batchService;
20 
21     @Transactional(propagation = Propagation.NOT_SUPPORTED , readOnly = true)
22     public Employee findById(Integer eno){
23         return employeeDao.findById(eno);
24     }
25 
26     public void batchImport() {
27         for (int i = 1; i <= 10; i++) {
28             if(i==3){
29                 throw new RuntimeException("意料之外的异常");
30             }
31             Employee employee = new Employee();
32             employee.setEno(8000 + i);
33             employee.setEname("员工" + i);
34             employee.setSalary(4000f);
35             employee.setDname("市场部");
36             employee.setHiredate(new Date());
37             employeeDao.insert(employee);
38         }
39     }
40 
41     public void startImportJob(){
42         batchService.importJob1();
43         if(1==1){
44             throw new RuntimeException("意料之外的异常");
45         }
46         batchService.importJob2();
47         System.out.println("批量导入成功");
48     }
49 
50     public EmployeeDao getEmployeeDao() {
51         return employeeDao;
52     }
53 
54     public void setEmployeeDao(EmployeeDao employeeDao) {
55         this.employeeDao = employeeDao;
56     }
57 
58     public BatchService getBatchService() {
59         return batchService;
60     }
61 
62     public void setBatchService(BatchService batchService) {
63         this.batchService = batchService;
64     }
65 }

 

标签:事务管理,事务,JDBC,Spring,eno,jdbc,employee,import,public
来源: https://www.cnblogs.com/mingmingn/p/14018160.html