Spring使用Spring框架开发银行项目与事务实现相关详解-----Spring框架

什么是事务?
在一个业务流程中,通常需要多条DML语句联合执行才能完成,因此这多条DML语句必须同时成功或者同时失败,这样才能保证数据的安全
多条DML语句要么同时成功,要么同时失败,这叫做事务
事务(Transaction)TX
四个处理过程
第一步:开启事务
第二步:执行核心业务代码
第三步:提交事务(如果没有出现异常)Commit transaction
第四步:回滚事务(如果出现异常)rollback transaction
四大特性
原子性(最小的单位)
一致性(事务要求要么同时成功,要么同时失败)
隔离性(事务事务之间要互不干扰)
持久性(持久性是事务结束的标志)
AOP的实际案例(编程式处理方案/事务),Spring底层对事务的支持底层还是AOP二次封装
什么是事务?
在一个业务流程中,通常需要多条DML语句联合执行才能完成,因此这多条DML语句必须同时成功或者同时失败,这样才能保证数据的安全
多条DML语句要么同时成功,要么同时失败,这叫做事务
事务(Transaction)TX
四个处理过程
第一步:开启事务
第二步:执行核心业务代码
第三步:提交事务(如果没有出现异常)Commit transaction
第四步:回滚事务(如果出现异常)rollback transaction
四大特性
原子性(最小的单位)
一致性(事务要求要么同时成功,要么同时失败)
隔离性(事务事务之间要互不干扰)
持久性(持久性是事务结束的标志)
AOP的实际案例(编程式处理方案/事务),Spring底层对事务的支持底层还是AOP二次封装
<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <loggers>
        <!--日志级别,由低到高-->
        <!--ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF-->
        <root level="DEBUG">
            <appender-ref ref="spring6log"/>
        </root>
    </loggers>
    <appenders>
        <!--输出日志到控制台-->
        <console name="spring6log" target="SYSTEM_OUT">
            <!--控制输出的日志格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
        </console>
    </appenders>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <loggers>
        <!--日志级别,由低到高-->
        <!--ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF-->
        <root level="DEBUG">
            <appender-ref ref="spring6log"/>
        </root>
    </loggers>
    <appenders>
        <!--输出日志到控制台-->
        <console name="spring6log" target="SYSTEM_OUT">
            <!--控制输出的日志格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
        </console>
    </appenders>
</configuration>
<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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:component-scan base-package="com.powernode.bank"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <aop:config proxy-target-class="true"></aop:config>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:13306/spring6"></property>
        <property name="username" value="root"></property>
        <property name="password" value="abc123"></property>
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--    配置事务管理器-->
    <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--    事务注解驱动器开启,采用注解的方式去控制事务-->
    <tx:annotation-driven transaction-manager="tx"></tx:annotation-driven>
</beans>
<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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:component-scan base-package="com.powernode.bank"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <aop:config proxy-target-class="true"></aop:config>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:13306/spring6"></property>
        <property name="username" value="root"></property>
        <property name="password" value="abc123"></property>
    </bean>
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
<!--    配置事务管理器-->
    <bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--    事务注解驱动器开启,采用注解的方式去控制事务-->
    <tx:annotation-driven transaction-manager="tx"></tx:annotation-driven>
</beans>
package com.powernode.bank.test;

import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.impl.AccountServiceImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTXTest
{
    private static final Logger logger = LoggerFactory.getLogger(SpringTXTest.class);
    @Test
    public void TestSpringTX()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        AccountServiceImpl accountServiceImpl = context.getBean("accountServiceImpl", AccountServiceImpl.class);
        try
        {
            accountServiceImpl.transfer("act-001","act-002",10000);
            logger.info("转账成功");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    @Test
    public void TestPropagation()//测试事务的传播行为
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        //获取的是一号Service对象
        AccountServiceImpl accountServiceImpl = context.getBean("accountServiceImpl", AccountServiceImpl.class);
        Account account = new Account("act-003",1000);
        accountServiceImpl.save(account);
    }
}
package com.powernode.bank.test;

import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.impl.AccountServiceImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTXTest
{
    private static final Logger logger = LoggerFactory.getLogger(SpringTXTest.class);
    @Test
    public void TestSpringTX()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        AccountServiceImpl accountServiceImpl = context.getBean("accountServiceImpl", AccountServiceImpl.class);
        try
        {
            accountServiceImpl.transfer("act-001","act-002",10000);
            logger.info("转账成功");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    @Test
    public void TestPropagation()//测试事务的传播行为
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        //获取的是一号Service对象
        AccountServiceImpl accountServiceImpl = context.getBean("accountServiceImpl", AccountServiceImpl.class);
        Account account = new Account("act-003",1000);
        accountServiceImpl.save(account);
    }
}
package com.powernode.bank;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ComponentScan({"com.powernode.bank"})
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Spring6Config
{
    //Spring对事务的支持,实现事务的两种方式
    //编程式事务:通过编写代码来实现事务的管理
    //声明式事务:基于注解和XML配置方式
    //Spring对事务的管理底层实现是基于AOP实现的,采用了AOP的方式进行封装
    //DataSourceTransactionManager:支持jdbcTemplate,Mybatis,Hibernate
    //JtaTransactionManager:支持分布式事务管理
}
package com.powernode.bank;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ComponentScan({"com.powernode.bank"})
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Spring6Config
{
    //Spring对事务的支持,实现事务的两种方式
    //编程式事务:通过编写代码来实现事务的管理
    //声明式事务:基于注解和XML配置方式
    //Spring对事务的管理底层实现是基于AOP实现的,采用了AOP的方式进行封装
    //DataSourceTransactionManager:支持jdbcTemplate,Mybatis,Hibernate
    //JtaTransactionManager:支持分布式事务管理
}
package com.powernode.bank.service;

import com.powernode.bank.pojo.Account;
import org.springframework.stereotype.Service;

@Service
public interface AccountService//业务接口
{

    //从这个账户转出,转到另外一个账户,金额是
    void transfer(String Actno,String toActno,double money);
    void save(Account account);//保存账户信息
    void withdraw();
}
package com.powernode.bank.service;

import com.powernode.bank.pojo.Account;
import org.springframework.stereotype.Service;

@Service
public interface AccountService//业务接口
{

    //从这个账户转出,转到另外一个账户,金额是
    void transfer(String Actno,String toActno,double money);
    void save(Account account);//保存账户信息
    void withdraw();
}
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service("accountService2")
public class AccountServiceImpl2 implements AccountService
{
    @Resource(name = "accountDao")
    private AccountDao accountDao;
    @Override
    public void transfer(String Actno, String toActno, double money)
    {

    }
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void save(Account account)
    {
        accountDao.insert(account);
        //异常
        String s = null;
        s.toString();
        //大括号没结束,事务没结束
        //事务没结束就得回滚
        //后续可能还有其他的DML操作,这个大括号内也许还有其他DML语句的
        //回滚了,数据是安全的
    }

    @Override
    public void withdraw()
    {

    }
}
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service("accountService2")
public class AccountServiceImpl2 implements AccountService
{
    @Resource(name = "accountDao")
    private AccountDao accountDao;
    @Override
    public void transfer(String Actno, String toActno, double money)
    {

    }
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void save(Account account)
    {
        accountDao.insert(account);
        //异常
        String s = null;
        s.toString();
        //大括号没结束,事务没结束
        //事务没结束就得回滚
        //后续可能还有其他的DML操作,这个大括号内也许还有其他DML语句的
        //回滚了,数据是安全的
    }

    @Override
    public void withdraw()
    {

    }
}
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
//写在类上所有的方法都应用事务
public class AccountServiceImpl implements AccountService
{
    @Resource(name = "accountDao")
    private AccountDao accountDao;
    @Resource(name = "accountService2")
    private AccountServiceImpl2 accountServiceImpl2;
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    //数据库三大读问题
    //脏读:读取到还没有提交到数据库的数据,叫做脏读(读到内存里面没有commit的数据)
    //不可重复读:在同一个事务中,第一次和第二次读到的数据不一样(在同一个事务中读到的数据前后不一致)
    //幻读:读到的数据是假的(只要A事务和B事务在同时进行时,永远都会幻读)
    //脑子里想象的数据和真实数据不一样,就是幻读,只要多个事务并发,一定会幻读
    //多个事务并发一定会幻读
    //读未提交:会读内存中的数据,不可重复读,因为事务并发会导致事务中读到的信息前后不一致,导致幻读
    //读提交:不会读内存中的数据,仅读取数据库commit了的数据,仍然会因为事务并发读到前后不一致的信息,导致幻读
    //可重复读:不会读内存中的数据,仅读取commit数据,在事务未结束前,数据库读取到的缓存信息始终不变,但是会导致幻读(因为其他事务已经修改了数据库信息)
    //序列化:事务必须排队执行,不支持并发,解决了幻读问题
    public void transfer(String Actno, String toActno, double money)
    {
        //开启事务
        //需要控制事务,因为在这个方法中要完成所有的转账业务
        //查询转出账户余额是否充足
        Account account = accountDao.selectByAccountNo(Actno);
        if(account.getBalance() < money)
        {
            throw new RuntimeException("余额不足");
        }
        Account toAccount = accountDao.selectByAccountNo(toActno);
        account.setBalance(account.getBalance() - money);
        toAccount.setBalance(toAccount.getBalance() + money);
        int update = accountDao.update(account);
        //模拟异常信息导致中断业务
//        String s = null;
//        s.toString();
        update = update + accountDao.update(toAccount);
        //提交事务
        //遇到异常回滚事务
        if(update != 2)
        {
            throw new RuntimeException("转账失败,请联系银行");
        }
        withdraw();
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void save(Account account)
    {
        //这里有一个保存操作
        //调Dao的保存
        accountDao.insert(account);//保存act-003
        //创建账户对象
        Account ac = new Account("act-004",1000);
        //如果这里不捕捉,一号事务内也无法执行完毕,也会回滚数据
        //因为他们两个是完全不同事务
        try
        {
            accountServiceImpl2.save(ac);//保存act-003
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        //继续往后执行一号的事务
        //应该是3号提交了,4号没能保存
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void withdraw()
    {
        //Propagation.REQUIRED如果原先有事务,就调用原事务,如果没有就创建一个新事务(同一个事务)
        //Propagation.SUPPORTS支持当前事务,有就执行,没有就没有(原事务)
        //Propagation.MANDATORY(强制性的)有就加入当前事务,没有就抛出异常信息(原事务)
        //Propagation.REQUIRES_NEW不管调用处是否有业务,只要调用,就创建一个新业务,并把老业务挂起(新事务)
        //Propagation.NOT_SUPPORTED以非事务方式运行,如果有事务存在,挂起当前事务(无事务)
        //Propagation.NEVER以非事务方式运行,如果有事务存在,抛出异常(无事务)
        //Propagation.NESTED如果当前有事务存在运行中,则该方法运行在一个嵌套式事务中,被嵌套的事务可以独立外层事务进行提交或回滚
        //没有事务就视为required一样(两个事务并行)
    }
}
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
//写在类上所有的方法都应用事务
public class AccountServiceImpl implements AccountService
{
    @Resource(name = "accountDao")
    private AccountDao accountDao;
    @Resource(name = "accountService2")
    private AccountServiceImpl2 accountServiceImpl2;
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED)
    //数据库三大读问题
    //脏读:读取到还没有提交到数据库的数据,叫做脏读(读到内存里面没有commit的数据)
    //不可重复读:在同一个事务中,第一次和第二次读到的数据不一样(在同一个事务中读到的数据前后不一致)
    //幻读:读到的数据是假的(只要A事务和B事务在同时进行时,永远都会幻读)
    //脑子里想象的数据和真实数据不一样,就是幻读,只要多个事务并发,一定会幻读
    //多个事务并发一定会幻读
    //读未提交:会读内存中的数据,不可重复读,因为事务并发会导致事务中读到的信息前后不一致,导致幻读
    //读提交:不会读内存中的数据,仅读取数据库commit了的数据,仍然会因为事务并发读到前后不一致的信息,导致幻读
    //可重复读:不会读内存中的数据,仅读取commit数据,在事务未结束前,数据库读取到的缓存信息始终不变,但是会导致幻读(因为其他事务已经修改了数据库信息)
    //序列化:事务必须排队执行,不支持并发,解决了幻读问题
    public void transfer(String Actno, String toActno, double money)
    {
        //开启事务
        //需要控制事务,因为在这个方法中要完成所有的转账业务
        //查询转出账户余额是否充足
        Account account = accountDao.selectByAccountNo(Actno);
        if(account.getBalance() < money)
        {
            throw new RuntimeException("余额不足");
        }
        Account toAccount = accountDao.selectByAccountNo(toActno);
        account.setBalance(account.getBalance() - money);
        toAccount.setBalance(toAccount.getBalance() + money);
        int update = accountDao.update(account);
        //模拟异常信息导致中断业务
//        String s = null;
//        s.toString();
        update = update + accountDao.update(toAccount);
        //提交事务
        //遇到异常回滚事务
        if(update != 2)
        {
            throw new RuntimeException("转账失败,请联系银行");
        }
        withdraw();
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void save(Account account)
    {
        //这里有一个保存操作
        //调Dao的保存
        accountDao.insert(account);//保存act-003
        //创建账户对象
        Account ac = new Account("act-004",1000);
        //如果这里不捕捉,一号事务内也无法执行完毕,也会回滚数据
        //因为他们两个是完全不同事务
        try
        {
            accountServiceImpl2.save(ac);//保存act-003
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        //继续往后执行一号的事务
        //应该是3号提交了,4号没能保存
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void withdraw()
    {
        //Propagation.REQUIRED如果原先有事务,就调用原事务,如果没有就创建一个新事务(同一个事务)
        //Propagation.SUPPORTS支持当前事务,有就执行,没有就没有(原事务)
        //Propagation.MANDATORY(强制性的)有就加入当前事务,没有就抛出异常信息(原事务)
        //Propagation.REQUIRES_NEW不管调用处是否有业务,只要调用,就创建一个新业务,并把老业务挂起(新事务)
        //Propagation.NOT_SUPPORTED以非事务方式运行,如果有事务存在,挂起当前事务(无事务)
        //Propagation.NEVER以非事务方式运行,如果有事务存在,抛出异常(无事务)
        //Propagation.NESTED如果当前有事务存在运行中,则该方法运行在一个嵌套式事务中,被嵌套的事务可以独立外层事务进行提交或回滚
        //没有事务就视为required一样(两个事务并行)
    }
}
package com.powernode.bank.dao;

import com.powernode.bank.pojo.Account;

public interface AccountDao
{
    //专门负责账户的CRUD操作,只执行SQL语句
    //只负责增删改查
    //通过账号ID查询账户信息
    Account selectByAccountNo(String actno);
    //更新账户信息
    int update(Account account);
    int insert(Account account);
}
package com.powernode.bank.dao;

import com.powernode.bank.pojo.Account;

public interface AccountDao
{
    //专门负责账户的CRUD操作,只执行SQL语句
    //只负责增删改查
    //通过账号ID查询账户信息
    Account selectByAccountNo(String actno);
    //更新账户信息
    int update(Account account);
    int insert(Account account);
}
package com.powernode.bank.pojo;

public class Account
{
    private String actno;
    private double balance;

    @Override
    public String toString() {
        return "Account{" +
                "actno='" + actno + '\'' +
                ", balance=" + balance +
                '}';
    }

    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Account(String actno, double balance) {
        this.actno = actno;
        this.balance = balance;
    }

    public Account() {
    }
}
package com.powernode.bank.pojo;

public class Account
{
    private String actno;
    private double balance;

    @Override
    public String toString() {
        return "Account{" +
                "actno='" + actno + '\'' +
                ", balance=" + balance +
                '}';
    }

    public String getActno() {
        return actno;
    }

    public void setActno(String actno) {
        this.actno = actno;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Account(String actno, double balance) {
        this.actno = actno;
        this.balance = balance;
    }

    public Account() {
    }
}
package com.powernode.bank.dao.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao
{
    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Override
    public Account selectByAccountNo(String actno)
    {
        String sql = "select actno,balance from t_act where actno = ?";
        Account account = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Account.class),actno);
        return account;
    }

    @Override
    public int update(Account account)
    {
        String sql = "update t_act set balance = ? where actno = ?";
        int update = jdbcTemplate.update(sql, account.getBalance(), account.getActno());
        return update;
    }

    @Override
    public int insert(Account account)
    {
        String sql = "insert into t_act(actno,balance) values(?,?)";
        int update = jdbcTemplate.update(sql, account.getActno(), account.getBalance());
        return update;
    }
}
package com.powernode.bank.dao.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao
{
    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Override
    public Account selectByAccountNo(String actno)
    {
        String sql = "select actno,balance from t_act where actno = ?";
        Account account = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Account.class),actno);
        return account;
    }

    @Override
    public int update(Account account)
    {
        String sql = "update t_act set balance = ? where actno = ?";
        int update = jdbcTemplate.update(sql, account.getBalance(), account.getActno());
        return update;
    }

    @Override
    public int insert(Account account)
    {
        String sql = "insert into t_act(actno,balance) values(?,?)";
        int update = jdbcTemplate.update(sql, account.getActno(), account.getBalance());
        return update;
    }
}
CREATE DATABASE spring6;
USE spring6
CREATE TABLE t_act(actno VARCHAR(100) PRIMARY KEY NOT NULL,balance DOUBLE);
INSERT INTO t_act(actno,balance) VALUE('act-001',50000);
INSERT INTO t_act(actno,balance) VALUE('act-002',0);
SELECT * FROM t_act;
UPDATE t_act SET balance = 50000 WHERE actno = 'act-001';
UPDATE t_act SET balance = 0 WHERE actno = 'act-002';
DELETE FROM t_act WHERE actno = 'act-003';
DELETE FROM t_act WHERE actno = 'act-004';

 CREATE DATABASE spring6;
USE spring6
CREATE TABLE t_act(actno VARCHAR(100) PRIMARY KEY NOT NULL,balance DOUBLE);
INSERT INTO t_act(actno,balance) VALUE('act-001',50000);
INSERT INTO t_act(actno,balance) VALUE('act-002',0);
SELECT * FROM t_act;
UPDATE t_act SET balance = 50000 WHERE actno = 'act-001';
UPDATE t_act SET balance = 0 WHERE actno = 'act-002';
DELETE FROM t_act WHERE actno = 'act-003';
DELETE FROM t_act WHERE actno = 'act-004';

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值