spring基于纯注解的声明式事务控制

副配置类文件:JdbcConfig

package com.itheima.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

/**
* @Author: lijiahao
* @Description:和连接数据库相关的配置类
* @Data: Create in 20:49 2020/2/9
* @Modified By:
*/
public class JdbcConfig {

@Value("${jdbc.driver}")
private String driver;

@Value("${jdbc.url}")
private String url;

@Value("${jdbc.username}")
private String username;

@Value("${jdbc.password}")
private String password;

/**
* @Author Lijiahao
* @Description 创建JdbcTemplate对象
* @Date 20:52 2020/2/9
* @Param [dataSource]
* @return org.springframework.jdbc.core.JdbcTemplate
**/
@Bean(name="jdbcTemplate")
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}

/**
* @Author Lijiahao
* @Description 创建数据源对象
* @Date 20:55 2020/2/9
* @Param []
* @return javax.sql.DataSource
**/
@Bean(name="dataSource")
public DataSource createDataSource(){
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}

主配置类文件:SpringConfiguration
package com.itheima.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resources;

/**
* @Author: lijiahao
* @Description: Spring的配置类,相当于bean.xml
* @Data: Create in 20:46 2020/2/9
* @Modified By:
*/
@Configuration//用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@ComponentScan("com.itheima")//开启注解扫描
@Import({JdbcConfig.class,TransactionConfig.class})//导入副配置文件的字节码文件
@PropertySource("jdbcConfig.properties")//加载jdbcproperties配置文件的资源
@EnableTransactionManagement//开启注解事务的支持
public class SpringConfiguration {
}

副配置类文件:TransactionConfig
package com.itheima.config;

import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

/**
* @Author: lijiahao
* @Description:和事务相关的配置类
* @Data: Create in 21:04 2020/2/9
* @Modified By:
*/
public class TransactionConfig {

/**
* @Author Lijiahao
* @Description 用于创建事务管理器对象
* @Date 21:08 2020/2/9
* @Param [dataSource]
* @return org.springframework.transaction.PlatformTransactionManager
**/
@Bean(name="transactionManager")//存入ioc容器
public PlatformTransactionManager createTransactionManager(DataSource dataSource){
return new DataSourceTransactionManager(dataSource);
}
}

资源文件:jdbcConfig.properties
jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/eesy?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false
jdbc.username = root
jdbc.password = 123456

测试类:
package com.itheima.test;

import com.itheima.config.SpringConfiguration;
import com.itheima.domain.Account;
import com.itheima.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

/**
* @Author: lijiahao
* @Description: 使用junit测试配置
* @Data: Create in 0:59 2020/2/6
* @Modified By:
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= SpringConfiguration.class)
public class AccountServiceTest {
@Autowired
private IAccountService as;

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

service接口
package com.itheima.service;

import com.itheima.Dao.IAccountDao;
import com.itheima.domain.Account;

/**
* @Author: lijiahao
* @Description: 账户的业务层接口
* @Data: Create in 16:46 2020/2/9
* @Modified By:
*/
public interface IAccountService {

//根据id查询账户信息
Account findAccountById(Integer id);

//交易
void transfer(String sourceName,String targetName,Float money);
}

service实现类:
package com.itheima.service.impl;

import com.itheima.Dao.IAccountDao;
import com.itheima.domain.Account;
import com.itheima.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* @Author: lijiahao
* @Description:
* @Data: Create in 0:16 2020/2/6
* @Modified By:
*/
@Service("accountService")
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)//只读型事务的配置
public class AccountServiceImpl implements IAccountService {

@Autowired
private IAccountDao accountDao;

public Account findAccountById(Integer accountid) {
return accountDao.findAccountById(accountid);
}

//需要的是读写型事务配置
@Transactional(propagation = Propagation.REQUIRED,readOnly = false)
public void transfer(String sourceName, String targetName, Float money) {
System.out.println("trans......");
//2.1.根据名称查询转出帐户
Account source = accountDao.findAccountByName(sourceName);
//2.2.根据名称查询转入帐户
Account target = accountDao.findAccountByName(targetName);
//2.3.转出账户减钱
source.setMoney(source.getMoney()-money);
//2.4.转入帐户加钱
target.setMoney(target.getMoney()+money);
//2.5.更新转出账户
accountDao.updateAccount(source);

//int i = 1/0;

//2.6.更新转入账户
accountDao.updateAccount(target);

}
}

Dao接口:
package com.itheima.Dao;

import com.itheima.domain.Account;

/**
* @Author: lijiahao
* @Description: 帐户的持久性接口
* @Data: Create in 2:30 2020/2/9
* @Modified By:
*/
public interface IAccountDao {

/**
* @Author Lijiahao
* @Description 根据id查帐户
* @Date 2:31 2020/2/9
* @Param [id]
* @return com.itheima.domain.Account
**/
Account findAccountById(Integer id);
//根据名字查帐户
Account findAccountByName(String name);
//更新帐户
void updateAccount(Account account);
}

Dao实现类:
package com.itheima.Dao.impl;

import com.itheima.Dao.IAccountDao;
import com.itheima.domain.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* @Author: lijiahao
* @Description:
* @Data: Create in 2:32 2020/2/9
* @Modified By:
*/
@Repository("accountDao")
public class AccountDaoImpl implements IAccountDao {

@Autowired
private JdbcTemplate jdbcTemplate;

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

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

public void updateAccount(Account account) {
jdbcTemplate.update("update account set name=? ,money=? where id = ?", account.getName(),account.getMoney(),account.getId());
}
}
posted @ 2020-02-09 21:24  lijiahaoAA  阅读(232)  评论(0编辑  收藏  举报