您的位置:首页 > 编程语言 > Java开发

【超全必看】Spring框架基础入门学习总结笔记(附搭建过程及代码)【下】

2020-01-11 12:51 579 查看

JDBCemplate

概述

它是 spring 框架中提供的一个对象,是对原始 JDBC API 对象的简单封装。
spring 框架为我们提供了很多的操作模板类。

  • 操作关系型数据的:
    JdbcTemplate
    HibernateTemplate
  • 操作 nosql 数据库的:
    RedisTemplate
  • 操作消息队列的:
    JmsTemplate

环境搭建

在pom.xml中导入相关依赖

<!-- 导入mysql的jar包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- 导入context的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- 导入测试单元的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- 导入JDBC的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- 导入事务控制的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

基本使用

仍然使用前2篇文章的account表和Account类
测试类:

public class JDBCdemo1 {

public static void main(String[] args) {
//准备数据源:spring的内置数据源
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///test?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("sjh2019");

JdbcTemplate jdbcTemplate = new JdbcTemplate();
//设置数据源
jdbcTemplate.setDataSource(dataSource);
jdbcTemplate.execute("insert into account(name,money) values('eee',3000)");
}
}

运行后,查询数据库,数据被成功插入:

使用IOC简化操作

bean.xml中的配置:

<!-- 配置数据源 -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 连接数据库的信息 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="sjh2019"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource1"/>
</bean>

测试类

public class JDBCdemo1 {

public  static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) ac.getBean("jdbcTemplate");
jdbcTemplate.execute("insert into account(name,money) values('eee',3000)");
}
}

使用Jdbctemplate实现单表CRUD

增删改一般用

update
方法,查询用
query
,查询一行一列用
queryForObject

public  static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) ac.getBean("jdbcTemplate");
//保存
jdbcTemplate.update("insert into account(name,money) values(?,?)","eee",3000);
//更新
jdbcTemplate.update("update account set name=?,money=? where id=?","test",4000,5);
//删除
jdbcTemplate.update("delete from account where id=?",5);
//查询所有
List<Account> acounts = jdbcTemplate.query("select * from acount", new BeanPropertyRowMapper<>(Account.class));
//查询一个
List<Account> accounts = jdbcTemplate.query("select * from acount where id =?", new BeanPropertyRowMapper<>(Account.class), 1);
System.out.println(accounts.get(0));
//查询一行一列,不使用groupby
Integer count = jdbcTemplate.queryForObject("select count(*) from account where money > ?", Integer.class, 2000);
System.out.println(count);
}

JDBCTemplate在dao中的使用

持久层接口

//账户持久层接口
public interface IAccountDao {

//查询一个
Account findAccountById(Integer id);

//更新
void updateAccount(Account account);

//根据名称查找唯一一个账户
Account findAccountByName(String name);
}

持久层实现类

//账户持久层实现类
public class AccountDaoImpl implements IAccountDao {

private JdbcTemplate jdbcTemplate;

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public Account findAccountById(Integer id) {
List<Account> accounts = jdbcTemplate.query("select * from account where id =?", new BeanPropertyRowMapper<>(Account.class), id);
return accounts.isEmpty()?null:accounts.get(0);
}

public void updateAccount(Account account) {
jdbcTemplate.update("update account set name=?,money = ? where id=  ? ",account.getName(),account.getMoney(),account.getId());
}

@Override
public Account findAccountByName(String name) {
List<Account> accounts = jdbcTemplate.query("select * from account where name =?", new BeanPropertyRowMapper<>(Account.class), name);
if(accounts.isEmpty())
return null;
if(accounts.size()>1)
throw new RuntimeException("结果集不唯一");
return accounts.get(0);
}
}

xml配置

<?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: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/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="accountDao" class="dao.impl.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

<!-- 配置数据源 -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 连接数据库的信息 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="sjh2019"/>
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource1"/>
</bean></beans>

测试类

public class DaoTest {

public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
IAccountDao accountDao = ac.getBean("accountDao",IAccountDao.class);

Account accountById = accountDao.findAccountById(1);
System.out.println(accountById);

accountById.setMoney(2000f);
accountDao.updateAccount(accountById);
System.out.println(accountDao.findAccountById(1));

Account accountByName = accountDao.findAccountByName("范闲");
System.out.println(accountByName);

}
}

结果:

Account{id=1, name=‘aaa’, money=1000.0}
Account{id=1, name=‘aaa’, money=2000.0}
Account{id=4, name=‘范闲’, money=5000.0}

另一种编写dao的方式
JdbcDaoSupport 是 spring 框架为我们提供的一个类,该类中定义了一个 JdbcTemplate 对象,我们可以直接获取使用,但是要想创建该对象,需要为其提供一个数据源。
让之前的实现类继承JdbcDaoSupport类,使用继承的方法获取jdbctemplate对象。

//账户持久层实现类
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

public Account findAccountById(Integer id) {
List<Account> accounts = getJdbcTemplate().query("select * from account where id =?", new BeanPropertyRowMapper<>(Account.class), id);
return accounts.isEmpty()?null:accounts.get(0);
}

public void updateAccount(Account account) {
getJdbcTemplate().update("update account set name=?,money = ? where id=  ? ",account.getName(),account.getMoney(),account.getId());
}

@Override
public Account findAccountByName(String name) {
List<Account> accounts = getJdbcTemplate().query("select * from account where name =?", new BeanPropertyRowMapper<>(Account.class), name);
if(accounts.isEmpty())
return null;
if(accounts.size()>1)
throw new RuntimeException("结果集不唯一");
return accounts.get(0);
}
}

xml的对应配置
只需配置并注入数据源即可。

<!-- 配置账户持久层 -->
<bean id="accountDao" class="dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource1"/>
</bean>

<!-- 配置数据源 -->
<bean id="dataSource1" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 连接数据库的信息 -->
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="sjh2019"/>
</bean>

基于XML实现事务控制

在上一篇中,我们通过动态代理实现了事务控制和aop,现在通过xml配置aop的方式实现事务控制。

在事务控制类中加入一个环绕通知的方法,删除之前的工厂类和代理类

public Object around(ProceedingJoinPoint point){
Object val;
try{
beginTran();
System.out.println("开始事务");
val=point.proceed(point.getArgs());
commit();
System.out.println("提交事务");
return val;
}catch (Throwable e){
rollback();
throw new RuntimeException(e);
}finally {
release();
System.out.println("释放连接");
}
}

在bean.xml中配置

<aop:config>
<aop:aspect id="aop" ref="transactionManager">
<aop:around method="around" pointcut="execution(* *..AccountServiceImpl.*(..))"/>
</aop:aspect>
</aop:config>

删除之前工厂类和代理类的配置,完整的bean.xml

<?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: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/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">

<!--把对象的创建交给spring -->
<bean id="accountService" class="service.impl.AccountServiceImpl">
<!-- 注入dao对象 -->
<property name="accountDao" ref="accountDao"/>
</bean>

<!-- 配置dao -->
<bean id="accountDao" class="dao.impl.AccountDaoImpl">
<!-- 注入queryrunner -->
<property name="queryRunner" ref="query"/>
<!-- 注入工具类 -->
<property name="connectionUtils" ref="connectionUtils"/>
</bean>

<!-- 配置query runner 使用多例-->
<bean id="query" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
</bean>

<!--  配置connection工具类 -->
<bean id="connectionUtils" class="utils.ConnectionUtils">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 连接数据库的信息 -->
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///test?serverTimezone=UTC"/>
<property name="user" value="root"/>
<property name="password" value="sjh2019"/>
</bean>

<!-- 配置事务管理器 -->
<bean id="transactionManager" class="utils.TransactionManager">
<!-- 注入工具类 -->
<property name="connectionUtils" ref="connectionUtils"/>
</bean>

<aop:config>
<aop:aspect id="aop" ref="transactionManager">
<aop:around method="around" pointcut="execution(* *..AccountServiceImpl.*(..))"/>
</aop:aspect>
</aop:config>
</beans>

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class AccountTest {

@Autowired
IAccountService accountService;

@Test
public void findAll(){
List<Account> accounts = accountService.findAll();
accounts.forEach(System.out::println);
}

@Test
public void transfer(){
accountService.transfer("aaa","bbb", (float) 100);
}
}

执行测试方法后,出现异常,但事务回滚成功,并未出现问题。

基于XML的声明式事务

环境准备和测试

<?xml version="1.0" encoding="UTF-8"?>
<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.sjh</groupId>
<artifactId>spring01</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<packaging>jar</packaging>

<dependencies>
<!-- 导入mysql的jar包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<!-- 导入context的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- 导入测试单元的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!-- 导入JDBC的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

<!-- 导入事务控制的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>

</dependencies>

</project>

持久层接口和实现类

/**
* 账户的持久层接口
*/
public interface IAccountDao {

/**
* 根据Id查询账户
* @param accountId
* @return
*/
Account findAccountById(Integer accountId);

/**
* 根据名称查询账户
* @param accountName
* @return
*/
Account findAccountByName(String accountName);

/**
* 更新账户
* @param account
*/
void updateAccount(Account account);
}
/**
* 账户的持久层实现类
*/
public class AccountDaoImpl extends JdbcDaoSupport implements IAccountDao {

@Override
public Account findAccountById(Integer accountId) {
List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
return accounts.isEmpty()?null:accounts.get(0);
}

@Override
public Account findAccountByName(String accountName) {
List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
if(accounts.isEmpty()){
return null;
}
if(accounts.size()>1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}

@Override
public void updateAccount(Account account) {
super.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
}
}

业务层接口和实现类

public interface IAccountService {

//根据Id查询账户
Account findAccountById(Integer accountId);

//转账
void transfer(String sourceName,String targetName,Float money);
}
public class AccountServiceImpl implements IAccountService {
private IAccountDao accountDao;

public void setAccountDao(IAccountDao accountDao) {
this.accountDao = accountDao;
}

@Override
public Account findAccountById(Integer accountId) {
return accountDao.findAccountById(accountId);
}

@Override
public void transfer(String sourceName, String targetName, Float money) {
//查询出转出和转入账户
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
//更改账户金额
source.setMoney(source.getMoney()-money);
target.setMoney(target.getMoney()+money);
//更新账户
accountDao.updateAccount(source);
accountDao.updateAccount(target);
}
}

bean.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- 配置账户的业务层-->
<bean id="accountService" class="service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>

<!-- 配置账户的持久层-->
<bean id="accountDao" class="dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
</bean>
</beans>

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class JDBCTest {
@Autowired
private IAccountService accountService;
@Test
public void test(){
accountService.transfer("aaa","bbb",100f);
}
}

进行测试
初始状态:

执行测试方法后,结果正常

但此时由于没有事务控制,如果转账代码中加入异常代码,会出现问题

此时再次执行,转出账户金额减少,但转入账户金额并未增加

进行事务XML配置

第一步:配置事务管理器

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

第二步:配置事务的通知引用事务管理器

<!-- 事务的配置 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
</tx:advice>

第三步:配置事务的属性

  • read-only:是否是只读事务。默认 false,不只读。只有查询方法才能设置true。
  • isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
  • propagation:指定事务的传播行为,默认required,表示一定有事务,增删改方法的选择。查询方法可用supports。
  • timeout:指定超时时间。默认值为:-1。永不超时。
  • rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。没有默认值,任何异常都回滚。
  • no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时,事务回滚。没有默认值,任何异常都回滚。
<!--在 tx:advice 标签内部 配置事务的属性 -->
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>

第四步:配置 AOP 切入点表达式

<!-- 配置 aop -->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut expression="execution(* *..impl.*.*(..))" id="pt1"/>
</aop:config>

第五步:配置切入点表达式和事务通知的对应关系

<!-- 在 aop:config 标签内部:建立事务的通知和切入点表达式的关系 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/>

完整配置

<?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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- 配置账户的业务层-->
<bean id="accountService" class="service.impl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>

<!-- 配置账户的持久层-->
<bean id="accountDao" class="dao.impl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="sjh2019"/>
</bean>

<!--配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<!-- 配置事务通知 -->
<tx:advice id="transactionInterceptor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<!-- 下面的优先级更高 -->
<tx:method name="find*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>

<!-- 配置aop -->
<aop:config>
<!-- 配置切入点表达式 -->
<aop:pointcut id="pt" expression="execution(* *..impl.*.*(..))"/>
<!-- 建立切入点表达式和事务通知的关系 -->
<aop:advisor advice-ref="transactionInterceptor" pointcut-ref="pt"/>
</aop:config>

</beans>

此时再次运行测试类

事务控制是成功的

基于注解的声明式事务
项目整体结构

持久层配置

@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

@Autowired
private JdbcTemplate jdbcTemplate;

@Override
public Account findAccountById(Integer accountId) {
List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
return accounts.isEmpty()?null:accounts.get(0);
}

@Override
public Account findAccountByName(String accountName) {
List<Account> accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
if(accounts.isEmpty()){
return null;
}
if(accounts.size()>1){
throw new RuntimeException("结果集不唯一");
}
return accounts.get(0);
}

@Override
public void updateAccount(Account account) {
jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());
}
}

业务层配置

@Service("accountService")
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class AccountServiceImpl implements IAccountService {
@Autowired
private IAccountDao accountDao;

@Override
public Account findAccountById(Integer accountId) {
return accountDao.findAccountById(accountId);
}

@Override
@Transactional(propagation = Propagation.REQUIRED)
public void transfer(String sourceName, String targetName, Float money) {
//查询出转出和转入账户
Account source = accountDao.findAccountByName(sourceName);
Account target = accountDao.findAccountByName(targetName);
//更改账户金额
source.setMoney(source.getMoney()-money);
target.setMoney(target.getMoney()+money);
//更新账户
accountDao.updateAccount(source);
//模拟错误
int i=1/0;
accountDao.updateAccount(target);
}
}

jdbc配置
propertis文件

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///test?serverTimezone=UTC
user=root
password=sjh2019
public class JdbcConfig {
@Value("${driver}")
private String driver;
@Value("${url}")
private String url;
@Value("${user}")
private String user;
@Value("${password}")
private String password;

@Bean("jdbcTemplate")
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}

@Bean("dataSource")
public DataSource createDataSource (){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}

}

事务控制

//事务配置相关类
public class TransactionConfig {

@Bean("transactionManager")
public PlatformTransactionManager getTransactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}

主配置

@Configuration//配置类,相当于bean.xml
@ComponentScan(basePackages={"service","dao"})//要扫描的包
@Import({JdbcConfig.class,TransactionConfig.class})//读取的配置类
@PropertySource("jdbc.properties")//读取的配置资源
@EnableTransactionManagement//开启spring事务注解支持
public class SpringConfig {
}

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)//引入主配值文件
public class JDBCTest {
@Autowired
private IAccountService accountService;

@Test
public void test(){
accountService.transfer("aaa","bbb",100f);
}
}

运行结果:可成功控制事务

  • 点赞 1
  • 收藏
  • 分享
  • 文章举报
西安陈萍萍 发布了41 篇原创文章 · 获赞 118 · 访问量 1万+ 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: