spring事務管理,基於xml配置完成事務回滾;spring中資料庫表中欄位名和pojo中屬性名不一致時候,實現RowMapper介面手動封裝
阿新 • • 發佈:2018-11-17
宣告使用JDK8,spring5.0.7,
測試說明:
service 層 宣告介面進行轉賬,從A轉賬B ,然後對AB 進行更新操作,在事務中對find方法開啟 只讀許可權,無法進行更新操作,造成事務回滾進行測試事務;
主要測試方法:* void tranfer(Long fromId , Long toId ,Double money);
資料庫如下:
子工程結構;
pojo 實體;
package com.baidu.domain;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 9:38
*/
public class Account {
private Long id;
private String NAME;
private Double money;
// setter tostring
......
}
當資料庫表中filed 名字和實體類中屬性名不一致時候,需要手動對映table ;
實現RowMapper介面,重寫mapRow方法,手動封裝資料庫中table資料;
把account表中資料進行封裝, 封裝成Account物件;*
->如下:
package com.baidu.mapper;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 9:41
*/
public class AccountMapper implements RowMapper<Account> {
// 把表中的資料 封裝成 account 物件
@Override
public Account mapRow(ResultSet resultSet, int i) throws SQLException {
Account account = new Account();
account. setId(resultSet.getLong("id"));
account.setNAME(resultSet.getString("NAME"));
account.setMoney(resultSet.getDouble("money"));
return account;
}
}
dao 層, daoImpl 層
package com.baidu.dao;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 9:54
*/
public interface AccountDao {
// 通過id 查詢
//通過update
Account findById(Long id);
void update(Account account);
}
------------------------------------------------------------
// daoImpl 層
package com.baidu.daoImpl;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 9:57
*/
public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
// 通過id 查詢
@Override
public Account findById(Long id) {
String sql="select * from account where id=?";
Account account = null;
try {
account = this.getJdbcTemplate().queryForObject(sql, new BeanPropertyRowMapper<>(Account.class), id);
} catch (DataAccessException e) {
e.printStackTrace();
}
return account;
}
//通過id update使用者賬戶資訊
@Override
public void update(Account account) {
String sql="update account set NAME=?,money=? where id=?";
this.getJdbcTemplate().update(sql, account.getNAME(), account.getMoney(),account.getId());
}
}
service層 ,以及serviceImpl 層;
package com.baidu.service;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 10:05
*/
public interface AccountService {
// 轉賬
void transfer(Long fromId,Long toId,Double money);
/**
* 在事務屬性中定義了 find* 只讀
* @param id
* @return
*/
Account findById(Long id);
}
----------------------------------------------------------
// serviceImpl層
package com.baidu.serviceImpl;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 10:07
*/
public class AccountServiceImpl implements AccountService {
// 把dao 注入 提供setter方法
private AccountDao accountDao ;
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
@Override
public void transfer(Long fromId, Long toId, Double money) {
Account fromAccount = accountDao.findById(fromId);
Account toAccount = accountDao.findById(toId);
//進行轉賬
fromAccount.setMoney(fromAccount.getMoney()-money);
toAccount.setMoney(toAccount.getMoney()+money);
// 轉賬完成進行更新操作
accountDao.update(fromAccount);
accountDao.update(toAccount);
}
/**
* 在事務屬性中定義了 find* 只讀
* @param id
* @return
*/
@Override
public Account findById(Long id) {
Account byId = accountDao.findById(id);
// 進行update 操作,事務回滾
byId.setMoney(10.0);
accountDao.update(byId);
return byId;
}
}
applicationContext.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:tx="http://www.springframework.org/schema/tx"
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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<bean id="accountService" class="com.baidu.serviceImpl.AccountServiceImpl">
<property name="accountDao" ref="accountDao"></property>
</bean>
<bean id="accountDao" class="com.baidu.daoImpl.AccountDaoImpl">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 配置事務 transactionManager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--向事務中注入源資料-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置 事務的屬性 、find開頭的方法只讀事務,其他 -->
<tx:advice id="interceptor" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--配置事務的切面-->
<aop:config>
<!-- 設定 pointcut 表示式,並且把定義好事務屬性的應用到切入點 -->
<aop:pointcut id="pt1" expression="execution(* com.baidu.serviceImpl.AccountServiceImpl.*(..))"></aop:pointcut>
<aop:advisor advice-ref="interceptor" pointcut-ref="pt1"/>
</aop:config>
</beans>
測試;
/**
* @auther SyntacticSugar
* @data 2018/11/8 0008下午 10:24
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TxTest {
@Autowired
private AccountService accountService;
@Test
public void test01(){
accountService.transfer(1L,2L ,10.0 );
}
/**
* 在事務屬性中定義了 find* 只讀
* 進行 update 事務會 回滾
*/
@Test
public void test02(){
Account byId = accountService.findById(1L);
System.out.println(byId);
}
}
執行如下: