(银行转账)spring框架+jdbc+事务+Junit练习

完整项目的压缩包在我的资源里

第一步 创建表:

create table account(
id int PRIMARY KEY auto_increment,
name varchar(20) not null,
money double not null);
insert into account VALUES(null,"zhou",2000);
insert into account values(null,"li",2000);

第二步 创建Account类

package cn.sdut.po;

 

public class Account {

int id;

String name;

double money;

public Account() {

super();

}

public Account(int id, String name, double money) {

super();

this.id = id;

this.name = name;

this.money = money;

}

public int getId() {

return id;

}

public void setId(int 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 + "]";

}

}

 

第三步 创建DAO层接口及实现类,并进行测试

package cn.sdut.dao;

 

package cn.sdut.dao;

 

import java.util.List;

 

import cn.sdut.po.Account;

 

public interface AccountDao {

public int add(Account account);

public int del(int id);

public int update(Account account);

public Account getById(int id);

public List<Account> getAll();

public int update(String name,double change);

}

 

package cn.sdut.dao.impl;

 

import java.util.List;

 

import org.springframework.dao.EmptyResultDataAccessException;

import org.springframework.jdbc.core.BeanPropertyRowMapper;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

 

import cn.sdut.dao.AccountDao;

import cn.sdut.po.Account;

 

public class AccountDaoImpl implements AccountDao{

JdbcTemplate template;

public void setTemplate(JdbcTemplate template) {

this.template = template;

}

 

 

@Override

public int add(Account account) {

    String sql="insert into account values(null,?,?)";   

return  template.update(sql,account.getName(),account.getMoney());

}

 

@Override

public int del(int id) {

 String sql="delete from account where id=?";   

return  template.update(sql,id);

}

 

@Override

public int update(Account account) {

 String sql="update account set name=?,money=? where id=?";   

return  template.update(sql,account.getName(),account.getMoney(),account.getId());

}

 

@Override

public Account getById(int id) {

Account ac=null;

String sql="select * from account where id=?";

RowMapper mapper=(RowMapper) new BeanPropertyRowMapper<Account>(Account.class);

try{ ac=(Account)template.queryForObject(sql,mapper,id);}

catch (EmptyResultDataAccessException e) {    

}

finally{

return ac;

}

}

 

@Override

public List<Account> getAll() {

String sql="select * from account";

RowMapper mapper=(RowMapper) new BeanPropertyRowMapper<Account>(Account.class);

List<Account> accountList=template.query(sql,mapper);

return accountList;

}

 

 

@Override

public int update(String name, double change) {

 String sql="update account set money=money+? where name=?";   

 return template.update(sql,change,name);

}

}

 

测试:

package cn.sdut.dao.impl;

 

import java.util.List;

 

import org.junit.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import cn.sdut.dao.AccountDao;

import cn.sdut.po.Account;

 

public class AccountDaoImplTest {

ClassPathXmlApplicationContext context=

new ClassPathXmlApplicationContext("applicationContext.xml");

AccountDao accountDao = (AccountDao)context.getBean("accountDao");

 

@Test

public void testAdd() {

Account ac=new Account(0,"SDUT",1000);

int r=accountDao.add(ac);

System.out.println(r);

}

 

@Test

public void testDel() {

int r=accountDao.del(1001);

System.out.println(r);

}

 

@Test

public void testUpdateAccount() {

Account ac=new Account(1002,"LILI",1000);

int r=accountDao.update(ac);

System.out.println(r);

}

 

@Test

public void testGetById() {

Account account = accountDao.getById(1002);

System.out.println(account);

}

 

@Test

public void testGetAll() {

List<Account> list = accountDao.getAll();

System.out.println(list);

}

 

@Test

public void testUpdateStringDouble() {

int r1=accountDao.update("wang", -1000);

int r2=accountDao.update("abcd", 1000);

System.out.println(r1*r2);

}

 

}

 

 

 

第四步 创建Service层接口及其实现类,并进行测试

package cn.sdut.service;

 

public interface BankService {

public boolean transfer(String out,String in,double change);

}

 

package cn.sdut.service.impl;

 

import org.springframework.transaction.annotation.Transactional;

 

import cn.sdut.dao.AccountDao;

import cn.sdut.service.BankService;

 

public class BankServiceImpl implements BankService {

AccountDao accoutDao;

public void setAccoutDao(AccountDao accoutDao) {

this.accoutDao = accoutDao;

}

@Transactional(noRollbackFor=java.lang.ArithmeticException.class)

@Override

public boolean transfer(String out, String in, double change) {

int r1=accoutDao.update(out,change*(-1));

int r2=accoutDao.update(in,change);

return r1*r2>0?true:false;

}

}

 

测试:

package cn.sdut.service.impl;

 

import org.junit.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

import cn.sdut.service.BankService;

 

public class BankServiceImplTest {

ClassPathXmlApplicationContext context=

new ClassPathXmlApplicationContext("applicationContext.xml");

BankService bankService= (BankService)context.getBean("bankService");

@Test

public void testTransfer() {

boolean flag=bankService.transfer("LILI", "SDUT", 500);

System.out.println(flag);

}

 

} 

 

 

 

第五步 配置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:p="http://www.springframework.org/schema/p"

xmlns:tx="http://www.springframework.org/schema/tx"

xmlns:aop="http://www.springframework.org/schema/aop"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">

 

   <bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

   <property name="driverClassName" value="com.mysql.jdbc.Driver"/>

   <property name="url" value="jdbc:mysql://localhost:3306/test" />

   <property name="username" value="root"/>

   <property name="password" value="root" />

   </bean>

   <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">

       <property name="dataSource" ref="ds"/>

   </bean>

   <bean id="accountDao" class="cn.sdut.dao.impl.AccountDaoImpl">

   <property name="template" ref="template"/>

   </bean>

   <bean id="bankService" class="cn.sdut.service.impl.BankServiceImpl">

   <property name="accoutDao" ref="accountDao"/>

   </bean>

   

   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <property name="dataSource" ref="ds"/>

   </bean>

   

   <tx:annotation-driven />

   

  <!--  <tx:advice id="myTx" transaction-manager="transactionManager">

      <tx:attributes>

       <tx:method name="transfer"

        isolation="DEFAULT" propagation="REQUIRED"

        no-rollback-for="java.lang.ArithmeticException"

        />

      </tx:attributes>

   </tx:advice>

   

   <aop:config>

      <aop:advisor

      advice-ref="myTx"

      pointcut="execution(* transfer(..))"/>

   </aop:config> -->

   

   

</beans>


  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
假设一个银行系统,其中有两个账户,分别是A和B。现在需要进行一笔转账操作,将A账户中的100元转到B账户中。 以下是使用Spring事务来处理这个转账操作的例子: 1. 创建一个AccountService类,用于封装转账操作。 ```java @Service public class AccountService { @Autowired private AccountDao accountDao; @Transactional public void transfer(String fromAccount, String toAccount, double amount) { Account from = accountDao.getAccount(fromAccount); Account to = accountDao.getAccount(toAccount); from.setBalance(from.getBalance() - amount); to.setBalance(to.getBalance() + amount); accountDao.updateAccount(from); accountDao.updateAccount(to); } } ``` 2. 创建一个AccountDao类,用于操作数据库中的账户信息。 ```java @Repository public class AccountDao { @Autowired private JdbcTemplate jdbcTemplate; public Account getAccount(String accountNumber) { return jdbcTemplate.queryForObject("SELECT * FROM accounts WHERE account_number=?", new Object[]{accountNumber}, new AccountRowMapper()); } public void updateAccount(Account account) { jdbcTemplate.update("UPDATE accounts SET balance=? WHERE account_number=?", account.getBalance(), account.getAccountNumber()); } } ``` 3. 创建一个Account类,用于表示账户信息。 ```java public class Account { private String accountNumber; private double balance; public Account(String accountNumber, double balance) { this.accountNumber = accountNumber; this.balance = balance; } // getters and setters } ``` 4. 创建一个AccountRowMapper类,用于将数据库中的记录映射到Account对象中。 ```java public class AccountRowMapper implements RowMapper<Account> { @Override public Account mapRow(ResultSet rs, int rowNum) throws SQLException { String accountNumber = rs.getString("account_number"); double balance = rs.getDouble("balance"); return new Account(accountNumber, balance); } } ``` 5. 在Spring配置文件中开启事务管理。 ```xml <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> ``` 6. 编写一个测试类,用于验证转账操作是否正确。 ```java @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class AccountServiceTest { @Autowired private AccountService accountService; @Test public void testTransfer() { accountService.transfer("A", "B", 100); Account accountA = accountService.getAccount("A"); Account accountB = accountService.getAccount("B"); Assert.assertEquals(0.0, accountA.getBalance(), 0.01); Assert.assertEquals(100.0, accountB.getBalance(), 0.01); } } ``` 在上述例子中,我们使用了@Transactional注解来标记转账操作,表示这个操作需要在一个事务中执行。如果转账操作中的任何一步失败,整个事务都将被回滚,保证数据的一致性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿憨憨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值