乌兰察布网站建设湖南监理建设协会网站
- 作者: 五速梦信息网
- 时间: 2026年04月20日 07:15
当前位置: 首页 > news >正文
乌兰察布网站建设,湖南监理建设协会网站,科技有限公司是什么性质,100万一300万企业所得税JdbcTemplate概述
JdbcTemplate是spring框架中提供的一个对象#xff0c;是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如#xff1a;操作关系型数据的JdbcTemplate和#xff0c;操作nosql数据库的RedisTemplate#xff0c;操作消息…JdbcTemplate概述
JdbcTemplate是spring框架中提供的一个对象是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。例如操作关系型数据的JdbcTemplate和操作nosql数据库的RedisTemplate操作消息队列的JmsTemplate等等。 按如下项目结构准备 maven jar项目即可 导入依赖 dependencies!–spring核心容器包–dependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion5.3.5/version/dependency!–spring切面包–dependencygroupIdorg.springframework/groupIdartifactIdspring-aspects/artifactIdversion5.3.5/version/dependency!–aop联盟包–dependencygroupIdaopalliance/groupIdartifactIdaopalliance/artifactIdversion1.0/version/dependency!–德鲁伊连接池–dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.1.10/version/dependency!–mysql驱动–dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.22/version/dependency!–springJDBC包–dependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion5.3.5/version/dependency!–spring事务控制包–dependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion5.3.5/version/dependency!–spring orm 映射依赖–dependencygroupIdorg.springframework/groupIdartifactIdspring-orm/artifactIdversion5.3.5/version/dependency!–Apache Commons日志包–dependencygroupIdcommons-logging/groupIdartifactIdcommons-logging/artifactIdversion1.2/version/dependency!–Junit单元测试–dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.1/versionscopetest/scope/dependency!–lombok –dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.12/versionscopeprovided/scope/dependency/dependencies准备JDBC.properties
jdbc_usernameroot
jdbc_passwordroot
jdbc_drivercom.mysql.cj.jdbc.Driver
jdbc_urljdbc:mysql://127.0.0.1:3306/mydb?useSSLfalseuseUnicodetruecharacterEncodingUTF-8serverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue准备applicationContext.xml
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:chttp://www.springframework.org/schema/cxmlns:utilhttp://www.springframework.org/schema/utilxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd
!–spring 注解扫描–context:component-scan base-packagecom.msb/!–读取jdbc配置文件–context:property-placeholder locationclasspath:jdbc.properties/!–配置德鲁伊连接池–bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty nameusername value\({jdbc_username}/propertyproperty namepassword value\){jdbc_password}/propertyproperty nameurl value\({jdbc_url}/propertyproperty namedriverClassName value\){jdbc_driver}/property/bean!–配置JDBCTemplate对象,并向里面注入DataSource–bean idjdbcTemplate classorg.springframework.jdbc.core.JdbcTemplate!–通过set方法注入连接池–property namedataSource refdataSource/property/bean
/beans单个数据操作 准备实体类
package com.msb.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;AllArgsConstructor
NoArgsConstructor
Data
public class Emp implements Serializable{private Integer empno;private String ename;private String job;private Integer mgr;private Date hiredate;private Double sal;private Double comm;private Integer deptno;
}准备service层接口和实现类
package com.msb.service;
import com.msb.pojo.Emp;
import java.util.List;public interface EmpService {int findEmpCount();Emp findByEmpno(int empno);ListEmp findByDeptno(int deptno);int addEmp(Emp emp);int updateEmp(Emp emp);int deleteEmp( int empno);
}package com.msb.service.impl;
import com.msb.dao.EmpDao;
import com.msb.pojo.Emp;
import com.msb.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;Service
public class EmpServiceImpl implements EmpService {Autowiredprivate EmpDao empDao;Overridepublic int findEmpCount() {return empDao.findEmpCount();}Overridepublic Emp findByEmpno(int empno) {return empDao.findByEmpno( empno);}Overridepublic ListEmp findByDeptno(int deptno) {return empDao.findByDeptno( deptno);}Overridepublic int addEmp(Emp emp) {return empDao.addEmp(emp);}Overridepublic int updateEmp(Emp emp) {return empDao.updateEmp(emp);}Overridepublic int deleteEmp(int empno) {return empDao.deleteEmp(empno);}
}准备dao层接口和实现类
package com.msb.dao;
import com.msb.pojo.Emp;
import java.util.List;public interface EmpDao {int findEmpCount();Emp findByEmpno(int empno);ListEmp findByDeptno(int deptno);int addEmp(Emp emp);int updateEmp(Emp emp);int deleteEmp(int empno);
}package com.msb.dao.impl;
import com.msb.dao.EmpDao;
import com.msb.pojo.Emp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;Repository
public class EmpDaoImpl implements EmpDao {Autowiredprivate JdbcTemplate jdbcTemplate;Overridepublic int findEmpCount() {/查询员工个数 queryForObject 两个参数* 1 SQL语句* 2 返回值类型** /Integer empCount jdbcTemplate.queryForObject(select count(1) from emp, Integer.class);return empCount;}Overridepublic Emp findByEmpno(int empno) {/** 查询单个员工对象 queryForObject三个参数* 1 SQL语句* 2 RowMapper接口的实现类对象,用于执行返回的结果用哪个类来进行封装 ,实现类为BeanPropertyRowMapper* 3 SQL语句中需要的参数 (可变参数)* */BeanPropertyRowMapperEmp rowMapper new BeanPropertyRowMapper(Emp.class);Emp emp jdbcTemplate.queryForObject(select * from emp where empno ?, rowMapper, empno);return emp;}Overridepublic ListEmp findByDeptno(int deptno) {/** 查询单个员工对象* query三个参数* 1 SQL语句* 2 RowMapper接口的实现类对象,用于执行返回的结果用哪个类来进行封装 ,实现类为BeanPropertyRowMapper* 3 SQL语句中需要的参数 (可变参数)* */BeanPropertyRowMapperEmp rowMapper new BeanPropertyRowMapper(Emp.class);ListEmp emps jdbcTemplate.query(select * from emp where deptno ?, rowMapper, deptno);return emps;}Overridepublic int addEmp(Emp emp) {/增删改 统统用update方法 两个参数* 1 SQL语句* 2 SQL语句需要的参数 (可变参数)** */String sql insert into emp values(DEFAULT ,?,?,?,?,?,?,?);Object[] args {emp.getEname(),emp.getJob(),emp.getMgr(),emp.getHiredate(),emp.getSal(),emp.getComm(),emp.getDeptno()};return jdbcTemplate.update(sql,args);}Overridepublic int updateEmp(Emp emp) {String sql update emp set ename ? , job ?, mgr? , hiredate ?, sal?, comm?, deptno ? where empno ?;Object[] args {emp.getEname(),emp.getJob(),emp.getMgr(),emp.getHiredate(),emp.getSal(),emp.getComm(),emp.getDeptno(),emp.getEmpno()};return jdbcTemplate.update(sql,args);}Overridepublic int deleteEmp(int empno) {String sql delete from emp where empno ?;return jdbcTemplate.update(sql, empno);}
}测试代码
package com.msb.test;
import com.msb.pojo.Emp;
import com.msb.service.EmpService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Date;
import java.util.List;public class Test1 {Testpublic void testEmpService(){ApplicationContext contextnew ClassPathXmlApplicationContext(applicationContext.xml);EmpService empService context.getBean(EmpService.class);// 查询员工个数/int empCount empService.findEmpCount();System.out.println(empCount);/// 根据员工编号查询员工对象/* Emp byEmpno empService.findByEmpno(7521);System.out.println(byEmpno);*//根据部门编号查询多个员工对象集合//ListEmp emps empService.findByDeptno(20);emps.forEach(System.out::println);//增加员工信息//int rows empService.addEmp(new Emp(null, TOM, SALESMAN, 7521, new Date(), 2000.0, 100.0, 10));System.out.println(rows);//根据员工编号修改员工信息//int rows empService.updateEmp(new Emp(7939, JERRY, MANAGER, 7839, new Date(), 3000.0, 0.0, 20));System.out.println(rows);//根据员工编号删除员工信息//int rows empService.deleteEmp(7939);System.out.println(rows);/}
}批量操作 1 批量增加 2 批量修改 3 批量删除
实体类
package com.msb.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;AllArgsConstructor
NoArgsConstructor
Data
public class Dept implements Serializable {private Integer deptno;private String dname;private String loc;
}
DeptService
package com.msb.service;
import com.msb.pojo.Dept;
import java.util.List;public interface DeptService {int[] deptBatchAdd(ListDept depts);int[] deptBatchUpdate(ListDept depts);int[] deptBatchDelete(ListInteger deptnos);
}package com.msb.service.impl;
import com.msb.dao.DeptDao;
import com.msb.pojo.Dept;
import com.msb.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;Service
public class DeptServiceImpl implements DeptService {Autowiredprivate DeptDao deptDao;Overridepublic int[] deptBatchAdd(ListDept depts) {return deptDao.deptBatchAdd(depts);}Overridepublic int[] deptBatchUpdate(ListDept depts) {return deptDao.deptBatchUpdate(depts);}Overridepublic int[] deptBatchDelete(ListInteger deptnos) {return deptDao.deptBatchDelete(deptnos);}
}DeptDao
package com.msb.dao;
import com.msb.pojo.Dept;
import java.util.List;public interface DeptDao {int[] deptBatchAdd(ListDept depts);int[] deptBatchUpdate(ListDept depts);int[] deptBatchDelete(ListInteger deptnos);
}package com.msb.dao.impl;
import com.msb.dao.DeptDao;
import com.msb.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import java.util.LinkedList;
import java.util.List;Repository
public class DeptDaoImpl implements DeptDao {Autowiredprivate JdbcTemplate jdbcTemplate;Overridepublic int[] deptBatchAdd(ListDept depts) {String sql insert into dept values(DEFAULT,?,?);ListObject[] args new LinkedList();for (Dept dept : depts) {Object[] arg {dept.getDname(),dept.getLoc()};args.add(arg);}return jdbcTemplate.batchUpdate(sql, args);}Overridepublic int[] deptBatchUpdate(ListDept depts) {String sql update dept set dname ? ,loc ? where deptno?;ListObject[] args new LinkedList();for (Dept dept : depts) {Object[] arg {dept.getDname(),dept.getLoc(),dept.getDeptno()};args.add(arg);}return jdbcTemplate.batchUpdate(sql, args);}Overridepublic int[] deptBatchDelete(ListInteger deptnos) {String sql delete from dept where deptno ?;ListObject[] args new LinkedList();for (Integer deptno : deptnos) {Object[] arg {deptno};args.add(arg);}return jdbcTemplate.batchUpdate(sql, args);}
}
测试
package com.msb.test;
import com.msb.pojo.Dept;
import com.msb.service.DeptService;
import com.msb.service.EmpService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class Test2 {Testpublic void testBatchAdd(){ApplicationContext contextnew ClassPathXmlApplicationContext(applicationContext.xml);DeptService deptService context.getBean(DeptService.class);ListDept depts new ArrayList();for (int i 0; i 10; i) {depts.add(new Dept(null,namei,loci));}int[] ints deptService.deptBatchAdd(depts);System.out.println(Arrays.toString(ints));}Testpublic void testBatchUpdate(){ApplicationContext contextnew ClassPathXmlApplicationContext(applicationContext.xml);DeptService deptService context.getBean(DeptService.class);ListDept depts new ArrayList();for (int i 51; i 60; i) {depts.add(new Dept(i,newname,newLoc));}int[] ints deptService.deptBatchUpdate(depts);System.out.println(Arrays.toString(ints));}Testpublic void testBatchDelete(){ApplicationContext contextnew ClassPathXmlApplicationContext(applicationContext.xml);DeptService deptService context.getBean(DeptService.class);ListInteger deptnos new ArrayList();for (int i 51; i 69; i) {deptnos.add(i);}int[] ints deptService.deptBatchDelete(deptnos);System.out.println(Arrays.toString(ints));}
}事务
1.事务的概念
事务Transaction指的是一个操作序列该操作序列中的多个操作要么都做要么都不做是一个不可分割的工作单位是数据库环境中的逻辑工作单位由DBMS中的事务管理子系统负责事务的处理。
目前常用的存储引擎有InnoDBMySQL5.5以后默认的存储引擎和MyISAMMySQL5.5之前默认的存储引擎其中InnoDB支持事务处理机制而MyISAM不支持。
2.事务的特性
事务处理可以确保除非事务性序列内的所有操作都成功完成否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的序列可以简化错误恢复并使应用程序更加可靠。
但并不是所有的操作序列都可以称为事务这是因为一个操作序列要成为事务必须满足事务的原子性Atomicity、一致性Consistency、隔离性Isolation和持久性Durability。这四个特性简称为ACID特性。
原子性
原子是自然界最小的颗粒具有不可再分的特性。事务中的所有操作可以看做一个原子事务是应用中不可再分的最小的逻辑执行体。
使用事务对数据进行修改的操作序列要么全部执行要么全不执行。通常某个事务中的操作都具有共同的目标并且是相互依赖的。如果数据库系统只执行这些操作中的一部分则可能会破坏事务的总体目标而原子性消除了系统只处理部分操作的可能性。
2)一致性
一致性是指事务执行的结果必须使数据库从一个一致性状态变到另一个一致性状态。当数据库中只包含事务成功提交的结果时数据库处于一致性状态。一致性是通过原子性来保证的。
例如在转账时只有保证转出和转入的金额一致才能构成事务。也就是说事务发生前和发生后数据的总额依然匹配。
隔离性
隔离性是指各个事务的执行互不干扰任意一个事务的内部操作对其他并发的事务都是隔离的。也就是说并发执行的事务之间既不能看到对方的中间状态也不能相互影响。
例如在转账时只有当A账户中的转出和B账户中转入操作都执行成功后才能看到A账户中的金额减少以及B账户中的金额增多。并且其他的事务对于转账操作的事务是不能产生任何影响的。
4)持久性
持久性指事务一旦提交对数据所做的任何改变都要记录到永久存储器中通常是保存进物理数据库即使数据库出现故障提交的数据也应该能够恢复。但如果是由于外部原因导致的数据库故障如硬盘被损坏那么之前提交的数据则有可能会丢失。
3.事务的并发问题
脏读Dirty read
当一个事务正在访问数据并且对数据进行了修改而这种修改还没有提交到数据库中这时另外一个事务也访问了这个数据然后使用了这个数据。因为这个数据是还没有提交的数据那么另外一个事务读到的这个数据是“脏数据”依据“脏数据”所做的操作可能是不正确的。 不可重复读
Unrepeatableread: 指在一个事务内多次读同一数据。在这个事务还没有结束时另一个事务也访问该数据。那么在第一个事务中的两次读数据之间由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况因此称为不可重复读。 幻读
Phantom read: 幻读与不可重复读类似。它发生在一个事务T1读取了几行数据接着另一个并发事务T2插入了一些数据时。在随后的查询中第一个事务T1就会发现多了一些原本不存在的记录就好像发生了幻觉一样所以称为幻读。 不可重复度和幻读区别
不可重复读的重点是修改幻读的重点在于新增或者删除。
解决不可重复读的问题只需锁住满足条件的行解决幻读需要锁表
例1同样的条件, 你读取过的数据, 再次读取出来发现值不一样了 事务1中的A先生读取自己的工资为 1000的操作还没完成事务2中的B先生就修改了A的工资为2000导 致A再读自己的工资时工资变为 2000这就是不可重复读。
例2同样的条件, 第1次和第2次读出来的记录数不一样 假某工资单表中工资大于3000的有4人事务1读取了所有工资大于3000的人共查到4条记录这时事务2又插入了一条工资大于3000的记录事务1再次读取时查到的记录就变为了5条这样就导致了幻读
4.事务的隔离级别
事务的隔离级别用于决定如何控制并发用户读写数据的操作。数据库是允许多用户并发访问的如果多个用户同时开启事务并对同一数据进行读写操作的话有可能会出现脏读、不可重复读和幻读问题所以MySQL中提供了四种隔离级别来解决上述问题。
事务的隔离级别从低到高依次为READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ以及SERIALIZABLE隔离级别越低越能支持高并发的数据库操作。 spring中可以使用如下方式实现事务的控制
1 编程式(不推荐)
2 声明式(掌握)
1)注解(简单,必会)
2)XML配置(繁琐,了解)
demo搭建 通过张三给李四转账案例演示事务的控制 1 数据库中准备表格 applicationContext.xml jdbc.properties 如上边项目配置 项目中准备实体类
package com.msb.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;AllArgsConstructor
NoArgsConstructor
Data
public class Account implements Serializable {private Integer id;private String name;private Integer money;
}准备DAO层,创建一个根据id修改money的方法
package com.msb.dao;public interface AccountDao {int transMoney(int id,int money);
}package com.msb.dao.impl;
import com.msb.dao.AccountDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;Repository
public class AccountDaoImpl implements AccountDao {Autowiredprivate JdbcTemplate jdbcTemplate;Overridepublic int transMoney(int id, int money) {String sql update account set money money ? where id ?;return jdbcTemplate.update(sql,money,id);}
}准备Service,创建一个转账的业务方法
package com.msb.service;public interface AccountService {int transMoney(int from ,int to,int money);
}package com.msb.service.impl;
import com.msb.dao.AccountDao;
import com.msb.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;Service
public class AccountServiceImpl implements AccountService {Autowiredprivate AccountDao accountDao;Overridepublic int transMoney(int from, int to, int money) {int rows0;rowsaccountDao.transMoney(from, 0 - money); rowsaccountDao.transMoney(to, money); return rows;}
}测试代码,测试转账
package com.msb.test;
import com.msb.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestTx {Test()public void testTransaction(){ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);AccountService accountService context.getBean(AccountService.class);int rows accountService.transMoney(1, 2, 100);System.out.println(rows);}}基于注解方式实现
Spring声明式事务的实现方式,底层就是AOP,AOP的底层就是动态代理
Spring事务管理相关的API
事务管理器接口: PlatformTransactionManager 针对不同的框架,提供了不同的实现类 注解方式实现事务控制 在applicationContext.xml配置事务相关的配置
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:chttp://www.springframework.org/schema/cxmlns:utilhttp://www.springframework.org/schema/utilxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
!–spring 注解扫描–context:component-scan base-packagecom.msb/!–读取jdbc配置文件–context:property-placeholder locationclasspath:jdbc.properties/!–配置德鲁伊连接池–bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty nameusername value\({jdbc_username}/propertyproperty namepassword value\){jdbc_password}/propertyproperty nameurl value\({jdbc_url}/propertyproperty namedriverClassName value\){jdbc_driver}/property/bean!–配置JDBCTemplate对象,并向里面注入DataSource–bean idjdbcTemplate classorg.springframework.jdbc.core.JdbcTemplate!–通过set方法注入连接池–property namedataSource refdataSource/property/bean!–配置一个事务管理器–bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager!–将数据源注入事务管理器–property namedataSource refdataSource/property/bean!–开启事务注解–tx:annotation-driven transaction-managertransactionManager/
/beans在Service层中添加事务的注解
package com.msb.service.impl;
import com.msb.dao.AccountDao;
import com.msb.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;Service
//Transactional //加在类上,代表类中的所有方法都添加了事务控制
public class AccountServiceImpl implements AccountService {Autowiredprivate AccountDao accountDao;OverrideTransactional// 放在方法上,就是仅仅对当前方法增加了事务控制public int transMoney(int from, int to, int money) {int rows0;rowsaccountDao.transMoney(from, 0 - money);int i 1⁄0;rowsaccountDao.transMoney(to, money);return rows;}
}
再次测试,就算是service方法运行出现异常,自动会回滚,如果没有,那么自动提交
Transactional 注解的一些参数和参数的含义 Transactional(propagation Propagation.REQUIRED,isolation Isolation.READ_UNCOMMITTED,readOnly true,rollbackFor ClassCastException.class,noRollbackFor NullPointerException.class,timeout 10)
Target({ElementType.TYPE, ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
Inherited
Documented
public interface Transactional {AliasFor(transactionManager)String value() default ;AliasFor(value)String transactionManager() default ;String[] label() default {};Propagation propagation() default Propagation.REQUIRED;Isolation isolation() default Isolation.DEFAULT;int timeout() default -1;String timeoutString() default ;boolean readOnly() default false;Class? extends Throwable[] rollbackFor() default {};String[] rollbackForClassName() default {};Class? extends Throwable[] noRollbackFor() default {};String[] noRollbackForClassName() default {};
}propagation 事务的传播行为(面试) 多事务方法之间调用,事务是如何管理的 如果service层 add方法调用了 addDept和addEmp两个方法
PROPAGATION_REQUIRED 如果add方法有事务,那么addDept和addEmp就加入到add方法里的事务 如果add方法没有事务,那么就新建一个事务,将addDept和addEmp加入到这个新的事务中
PROPAGATION_REQUIRES_NEW 无论add是否有事务,都建立一个新的事务,所有的方法都加入到新的事务中,add原来的事务就不用了
isolation 事务的隔离级别 DEFAULT 默认 这是一个PlatfromTransactionManager默认的隔离级别使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。 MySQL默认REPEATABLE_READ Oracle默认READ_COMMITTED READ_UNCOMMITTED 读未提交 这是事务最低的隔离级别它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读不可重复读和幻像读。 READ_COMMITTED 读已提交 保证一个事务修改的数据提交后才能被另外一个事务读取另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现但是可能会出现不可重复读和幻像读。 REPEATABLE_READ 可重复读 这种事务隔离级别可以防止脏读、不可重复读但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外还保证了不可重复读。 SERIALIZABLE串行化 这是花费最高代价但是最可靠的事务隔离级别事务被处理为顺序执行。除了防止脏读、不可重复读外还避免了幻像读。
timeout 超时时间 事务一定要在多长时间之内提交,如果不提交就会回滚
readOnly 只读事务 事务是否只能读取数据库的数据,如果为true,则不允许进行增删改
rollbackFor 指定发生回滚的异常 当方法发生哪些异常时才会回滚
noRollbackFor 指定不发生回滚的异常 当方法发生哪些异常时,不会回滚
事务的xml配置
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:phttp://www.springframework.org/schema/pxmlns:chttp://www.springframework.org/schema/cxmlns:utilhttp://www.springframework.org/schema/utilxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd
context:component-scan base-packagecom.msb/!–读取jdbc配置文件–context:property-placeholder locationclasspath:jdbc.properties/!–配置德鲁伊连接池–bean iddataSource classcom.alibaba.druid.pool.DruidDataSourceproperty nameusername value\({jdbc_username}/propertyproperty namepassword value\){jdbc_password}/propertyproperty nameurl value\({jdbc_url}/propertyproperty namedriverClassName value\){jdbc_driver}/property/bean!–配置JDBCTemplate对象,并向里面注入DataSource–bean idjdbcTemplate classorg.springframework.jdbc.core.JdbcTemplate!–通过set方法注入连接池–property namedataSource refdataSource/property/bean!–配置一个事务管理器–bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager!–将数据源注入事务管理器–property namedataSource refdataSource/property/bean!–配置通知–tx:advice idtxAdvice!–配置事务参数–tx:attributestx:method nametransMoney isolationDEFAULT propagationREQUIRED//tx:attributes/tx:advice!–配置AOP–aop:config!–配置切入点–aop:pointcut idpt expressionexecution(* com.msb.service.AccountService.transMoney(..))/!–配置切面–aop:advisor advice-reftxAdvice pointcut-refpt/aop:advisor/aop:config
/beans创建零配置文件事务(配置类配置)
package com.msb.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;Configuration // 配置类标志注解
ComponentScan(basePackages com.msb) // spring包扫描
PropertySource(classpath:jdbc.properties) // 读取属性配置文件
EnableTransactionManagement // 开启事务注解
public class SpringConfig {Value(\({jdbc_driver})private String driver;Value(\){jdbc_url})private String url;Value(\({jdbc_username})private String username;Value(\){jdbc_password})private String password;/创建数据库连接池/Beanpublic DruidDataSource getDruidDataSource(){DruidDataSource dataSourcenew DruidDataSource();dataSource.setDriverClassName(driver);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);return dataSource;}no/创建JdbcTemplate对象/Beanpublic JdbcTemplate getJdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplatenew JdbcTemplate();jdbcTemplate.setDataSource(dataSource);return jdbcTemplate;}/创建事务管理器/Beanpublic PlatformTransactionManager getPlatformTransactionManager(DataSource dataSource){DataSourceTransactionManager transactionManager new DataSourceTransactionManager();transactionManager.setDataSource(dataSource);return transactionManager;}
}测试代码 Test()public void testTransaction3(){ApplicationContext context new AnnotationConfigApplicationContext(SpringConfig.class);AccountService accountService context.getBean(AccountService.class);int rows accountService.transMoney(1, 2, 100);System.out.println(rows);}附Spring测试组件
spring5框架自带了通用的日志封装,也可以整合自己的日志 1)spring移除了 LOG4jConfigListener,官方建议使用log4j2 2)spring5整合log4j2 导入log4j2依赖 !–log4j2 依赖–!–dependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-core/artifactIdversion2.14.0/version/dependency–!–slf4-impl 包含了log4j2 依赖 引入它即可–dependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-slf4j-impl/artifactIdversion2.14.0/versionscopetest/scope/dependency在resources目录下准备log4j2.xml的配置文件
?xml version1.0 encodingUTF-8?
Configuration statusDEBUGAppendersConsole nameConsole targetSYSTEM_OUTPatternLayout pattern%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n //Console/AppendersLoggersRoot leveldebugAppenderRef refConsole //Root/Loggers
/Configurationspring5关于测试工具的支持
整合junit4 依赖的jar !–Junit4单元测试–dependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.13.1/versionscopetest/scope/dependency!–spring test测试支持包–dependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion5.3.5/versionscopetest/scope/dependency测试代码编写方式
//省略了加载容器配置文件代码编写
package com.msb.test;
import com.msb.config.SpringConfig;
import com.msb.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;RunWith(SpringJUnit4ClassRunner.class)// 指定测试支持类
ContextConfiguration(classpath:applicationContext.xml)// 指定核心配置文件位置
public class Test2 {Autowired // 注入要获取的beanprivate AccountService accountService;Test()public void testTransaction(){int rows accountService.transMoney(1, 2, 100);System.out.println(rows);}
}整合junit5
依赖的jar !–junit5单元测试–dependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter-api/artifactIdversion5.7.0/versionscopetest/scope/dependency测试代码编写方式
package com.msb.test;
import com.msb.service.AccountService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;/使用ExtentWith和ContextConfiguration注解/
/ExtendWith(SpringExtension.class)
ContextConfiguration(classpath:applicationContext.xml)/
// 使用复合注解代替前两个注解
SpringJUnitConfig(locations classpath:applicationContext.xml)
public class Test3 {Autowired // 注入要获取的beanprivate AccountService accountService;Testpublic void testTransaction(){int rows accountService.transMoney(1, 2, 100);System.out.println(rows);}
}
- 上一篇: 乌海品牌网站建设seo查询站长
- 下一篇: 乌兰察布做网站的公司高清短视频素材库无水印
相关文章
-
乌海品牌网站建设seo查询站长
乌海品牌网站建设seo查询站长
- 技术栈
- 2026年04月20日
-
乌尔禾区做网站哪里好论坛门户网站建设运营费用
乌尔禾区做网站哪里好论坛门户网站建设运营费用
- 技术栈
- 2026年04月20日
-
卧龙区网站建设wordpress 阿里云 漏洞
卧龙区网站建设wordpress 阿里云 漏洞
- 技术栈
- 2026年04月20日
-
乌兰察布做网站的公司高清短视频素材库无水印
乌兰察布做网站的公司高清短视频素材库无水印
- 技术栈
- 2026年04月20日
-
乌兰浩特网站开发公司网站制作服务
乌兰浩特网站开发公司网站制作服务
- 技术栈
- 2026年04月20日
-
乌云网是个什么网站东莞市手机网站建设
乌云网是个什么网站东莞市手机网站建设
- 技术栈
- 2026年04月20日
