#純註解小專案:JdbcTemplate、SpEL@Transactional@PropertySource@EnableTransactionManagement#spring-tx@FDDLC
測試環境:IDEA 2020.2、MySQL 8.0.16
專案結構
pom.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>org.example</groupId> <artifactId>P040_TransferProblem_spring-tx_full_annotation</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <!--連線池--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!--單元測試--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <!--注意:spring-tx依賴aspectjweaver--> <version>5.1.8.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.8.RELEASE</version> </dependency> </dependencies> </project>
bean.xml的內容:無,純註解!
MySQL資料庫:
database:test port:3306 table:account
Account.java的內容:
package cn.liuxingchang.Domain; import java.io.Serializable; public class Account implements Serializable { private Integer id; private String name; private Double money; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; } }
AccountDao.java的內容:
package cn.liuxingchang.Dao; import cn.liuxingchang.Domain.Account; public interface AccountDao { void updateAccount(Account account); Account findAccountByName(String name); }
AccountDaoImpl.java的內容:
package cn.liuxingchang.Dao.impl; import cn.liuxingchang.Dao.AccountDao; import cn.liuxingchang.Domain.Account; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.util.List; @Repository("accountDao") public class AccountDaoImpl implements AccountDao { @Autowired private JdbcTemplate jdbcTemplate; public void updateAccount(Account account) { try { jdbcTemplate.update("update account set name = ?, money = ? where id = ?", account.getName(), account.getMoney(), account.getId()); } catch(Exception e) { throw new RuntimeException(e); } } public Account findAccountByName(String name) { try { List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<Account>(Account.class), name); if(accounts == null || accounts.size() == 0) { throw new RuntimeException("找不到目標賬戶!"); } else if(accounts.size() == 1) { return accounts.get(0); } else { throw new RuntimeException("賬戶不唯一!"); } } catch (Exception e) { throw new RuntimeException(e); } } }
AccountService.java的內容:
package cn.liuxingchang.service; public interface AccountService { void transfer(String sourceName, String targetName, Double money); }
AccountServiceImpl.java的內容:
package cn.liuxingchang.service.impl; import cn.liuxingchang.Dao.AccountDao; import cn.liuxingchang.Domain.Account; import cn.liuxingchang.service.AccountService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @Service("accountService") @Transactional(transactionManager = "transactionManager", propagation = Propagation.REQUIRED) //@Transactional可作用於類和方法上,方法上的優先順序高於類上的優先順序 public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; public void transfer(String sourceName, String targetName, Double money) { /** * 1、根據sourceName查詢souce賬戶 * 2、根據targetName查詢target賬戶 * 3、souce賬戶減錢 * 4、target賬戶加錢 * 5、更新souce賬戶 * 6、更新target賬戶 */ //進行操作 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); } }
DataSourceConfig.java的內容:
package config; import com.mchange.v2.c3p0.ComboPooledDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.PropertySource; import javax.sql.DataSource; import java.beans.PropertyVetoException; @PropertySource("jdbc.properties") public class DataSourceConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.user}") private String user; @Value("${jdbc.password}") private String password; @Bean("dataSource") public DataSource createDataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setUser(user); dataSource.setPassword(password); return dataSource; } }
JdbctemplateConfig.java的內容:
package config; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; public class JdbcTemplateConfig { @Bean("jdbcTemplate") public JdbcTemplate createJdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); } }
TransactionManagerConfig.java的內容:
package config; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; public class TransactionManagerConfig { @Bean("transactionManager") PlatformTransactionManager createTransactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } }
MainConfig.java的內容:
package config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; import org.springframework.transaction.annotation.EnableTransactionManagement; @ComponentScan("cn.liuxingchang") @EnableTransactionManagement //相當於<tx:annotation-driven>標籤 @Import({JdbcTemplateConfig.class, DataSourceConfig.class, TransactionManagerConfig.class}) public class MainConfig { }
Test.java的內容:
import cn.liuxingchang.service.AccountService; import config.MainConfig; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import javax.annotation.Resource; @SpringJUnitConfig(classes = MainConfig.class) @RunWith(SpringJUnit4ClassRunner.class) public class Test { //@Autowired @Resource(name = "accountService") private AccountService accountService; @org.junit.Test public void transferTest() { accountService.transfer("Zhao", "Qian", 1.0); } }
相關文章
- Java註解詳解「註解專案實戰」Java
- 純Swift專案-序篇Swift
- PyCharm 建立純Python專案PyCharmPython
- 詳解jdbcTemplate和namedParameterJdbcTemplateJDBC
- 快速搭建基於註解的 Dubbo 專案
- 註解專題(一)Java元註解,內建註解Java
- OfficialKaldi(一)| 關於Kaldi專案(翻譯註解)
- Java 專案現在基於註解開發Java
- 純Swift專案-JSON(Basic.frameworks)SwiftJSONFramework
- Spring JdbcTemplate之使用詳解SpringJDBC
- JdbcTemplateJDBC
- 註解式專案開發!詳細解析Java中各個註解的作用和使用方式Java
- Spring-Boot專案中配置redis註解快取SpringbootRedis快取
- vue小程式專案 pdf下載解決方案Vue
- 純html如何識別.vue檔案並搭建vue專案HTMLVue
- 爬蟲小專案爬蟲
- 飛機小專案
- springmvc小專案SpringMVC
- 小專案模組外包
- Spring的註解@Qualifier小結Spring
- 純Swift專案-Xib | StoryBoard 多人協作技巧Swift
- 第一個Mac OS X專案(純程式碼)Mac
- 學習java註解,初試啟動springboot專案JavaSpring Boot
- 抽取JDBCTemplateJDBC
- Python入門小專案-氣泡排序詳解Python排序
- Springboot專案中 如何獲取@Configuration註解標註的配置類Spring Boot
- 復旦大學工程碩士帶你純手寫mybatis(註解版)MyBatis
- 幹掉前端!3分鐘純 Java 註解搭個管理系統前端Java
- 小程式專案之填坑小記
- 考勤系統+(小專案)
- Mysql-cluster小專案MySql
- 小程式專案總結
- 初步建立小程式專案
- 小程式專案-總結
- 續專案管理小結專案管理
- 微信小程式上手專案微信小程式
- 七分設計感的純React專案MungReact
- 重構案例:將純HTML/JS專案遷移到WebpackHTMLJSWeb