一、启动类
package com.springlearning.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan({"com.springlearning"})
@Import(DBConfiguration.class)
@PropertySource("classpath:application.yml")
public class SpringConfiguration {
}
二、Datasource配置类
public class DBConfiguration {
@Value("${driverClassName}")
private String driverClassName;
@Value("${url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean("dataSource")
public DataSource getDataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
三、Dao类
@Repository
public class AccountDaoImpl implements IAccountDao {
@Autowired
ConnectionUtils connectionUtils;
//保存
public void saveAccount(Account account){
PreparedStatement pstmt = null;
String saveSql = "insert into accounts(id, name, money) value(?,?,?)";
try {
pstmt = connectionUtils.getConnection().prepareStatement(saveSql);
pstmt.setInt(1, account.getId());
pstmt.setString(2, account.getName());
pstmt.setFloat(3, account.getMoney());
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
//删除
public void deleteAccount(int id){
PreparedStatement pstmt = null;
String deleteSql = "delete from accounts where id = ?";
try {
pstmt = connectionUtils.getConnection().prepareStatement(deleteSql);
pstmt.setInt(1, id);
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
//更新
public void updateAccount(Account account){
PreparedStatement pstmt = null;
String updateSql = "update accounts set money = ? where id = ?";
try {
pstmt = connectionUtils.getConnection().prepareStatement(updateSql);
pstmt.setFloat(1, account.getMoney());
pstmt.setInt(2, account.getId());
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
//查询多个
public List<Account> searchAccounts(float money){
PreparedStatement pstmt = null;
ResultSet rs = null;
List<Account> accountList = new ArrayList<Account>();
String serchAccountsSql = "select * from accounts where money > ?";
RowMapper<Account> rowMapper = new BeanPropertyRowMapper<Account>(Account.class);
try {
pstmt = connectionUtils.getConnection().prepareStatement(serchAccountsSql);
pstmt.setFloat(1, money);
rs = pstmt.executeQuery();
while(rs.next()){
Account account = new Account();
account.setId(rs.getInt(1));
account.setName(rs.getString(2));
account.setMoney(rs.getFloat(3));
accountList.add(account);
}
} catch (SQLException e) {
e.printStackTrace();
}
return accountList;
}
//查询一个
public Account searchAccountByName(String name){
PreparedStatement pstmt = null;
ResultSet rs = null;
Account account = new Account();
String searchAccountByName = "select * from accounts where name = ?";
try {
pstmt = connectionUtils.getConnection().prepareStatement(searchAccountByName);
pstmt.setString(1, name);
rs = pstmt.executeQuery();
if(rs.next()){
account.setId(rs.getInt(1));
account.setName(rs.getString(2));
account.setMoney(rs.getFloat(3));
}
} catch (SQLException e) {
e.printStackTrace();
}
return account;
}
//查询一行或一列
public Integer serchCount(float money){
PreparedStatement pstmt = null;
int count = 0;
String searchCount = "select count(*) from accounts where money > ?";
try {
pstmt = connectionUtils.getConnection().prepareStatement(searchCount);
pstmt.setFloat(1, money);
ResultSet rs = pstmt.executeQuery();
if(rs.next()){
count = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return count;
}
public void transfer(String sourceName, String targetName, float money){
Account source = searchAccountByName(sourceName);
Account target = searchAccountByName(targetName);
source.setMoney(source.getMoney() - money);
target.setMoney(target.getMoney() + money);
updateAccount(source);
int i = 1/0;
updateAccount(target);
}
}
四、Service实现类
@Service
public class AccountServiceImpl implements IAccountService {
@Autowired
IAccountDao accountDao;
public void saveAccount(Account account) throws SQLException {
accountDao.saveAccount(account);
}
public void deleteAccount(int id) throws SQLException {
accountDao.deleteAccount(id);
}
public void updateAccount(Account account) throws SQLException {
accountDao.updateAccount(account);
}
public List<Account> searchAccounts(float money) throws SQLException {
return accountDao.searchAccounts(money);
}
public Account searchAccountByName(String name) throws SQLException {
return accountDao.searchAccountByName(name);
}
public Integer serchCount(float money) throws SQLException {
return accountDao.serchCount(money);
}
public void transfer(String sourceName, String targetName, float money) throws SQLException {
accountDao.transfer(sourceName, targetName, money);
}
}
五、Connection
@Component
public class ConnectionUtils{
ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
@Autowired
DataSource dataSource;
public Connection getConnection() {
Connection conn = tl.get();
if (conn == null) {
try {
conn = dataSource.getConnection();
tl.set(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
return conn;
}
public void remove() {
//将connection移除,此时connection已经被关掉如果不从线程中移除connection,那么下次就会拿到带有无效connection的线程
tl.remove();
}
}
六、代理类
package com.springlearning.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.sql.SQLException;
@Component
@Aspect
//相当于
@EnableAspectJAutoProxy
public class TransactionManager {
@Pointcut("execution(* *.*.*.*.AccountServiceImpl.*(..))")
public void pt1(){}
@Autowired
ConnectionUtils connectionUtils;
// @Before("pt1()")
public void begainTransaction() {
System.out.println("begainTransaction");
try {
connectionUtils.getConnection().setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
// @AfterReturning("pt1()")
public void commitTransaction() {
System.out.println("commitTransaction");
try {
connectionUtils.getConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
// @AfterThrowing("pt1()")
public void rollback() {
System.out.println("rollback");
try {
connectionUtils.getConnection().rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
// @After("pt1()")
public void close() {
try {
System.out.println("close connection");
connectionUtils.getConnection().close();
connectionUtils.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Around("pt1()")
public Object aroundTransaction(ProceedingJoinPoint joinPoint){
Object rtValue = null;
Object[] args = joinPoint.getArgs();
try {
begainTransaction();
rtValue = joinPoint.proceed(args);
commitTransaction();
} catch (Throwable throwable) {
throwable.printStackTrace();
rollback();
}finally {
close();
}
return rtValue;
}
}
package com.springlearning;
import com.springlearning.config.SpringConfiguration;
import com.springlearning.entity.Account;
import com.springlearning.service.IAccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.sql.SQLException;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class TestAccount {
@Autowired
IAccountService accountService;
@Test
public void testTransfer() throws SQLException {
accountService.transfer("one", "two", 100);
}
@Test
public void testSaveAccount() throws SQLException {
Account account = new Account();
account.setId(5);
account.setName("five");
account.setMoney(1000f);
accountService.saveAccount(account);
}
@Test
public void testDeleteAccount() throws SQLException {
accountService.deleteAccount(5);
}
@Test
public void updateAccount() throws SQLException {
Account account = new Account();
account.setId(1);
account.setMoney(1000);
accountService.updateAccount(account);
}
@Test
public void searchAccounts() throws SQLException {
List<Account> accountList = accountService.searchAccounts(100f);
for (Account account : accountList) {
System.out.println(account.toString());
}
System.out.println(accountList.size());
}
@Test
public void searchAccountByName() throws SQLException {
System.out.println(accountService.searchAccountByName("one").toString());
}
@Test
public void serchCount() throws SQLException {
System.out.println(accountService.serchCount(100f));
}
}