Mybatis实现银行转账业务的实现和ThreadLocal的机制解析-----Mybatis框架

package com.powernode.bank.web;

import com.powernode.bank.exceptions.MoneyNotEnoughException;
import com.powernode.bank.exceptions.TransferException;
import com.powernode.bank.service.AccountService;
import com.powernode.bank.service.Impl.AccountServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/transfer")
public class AccountServlet extends HttpServlet
{
    //为了让这个对象在其他方法中也可以使用,我们声明为实例变量
    private AccountService accountService = new AccountServiceImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        super.doGet(req, resp);
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //获取表单数据
        String fromActno = request.getParameter("fromActno");
        String toActno = request.getParameter("toActno");
        Double money = Double.parseDouble(request.getParameter("money"));
        try
        {
            //调用Service的转账方法完成转账(调业务层)
            accountService.transfer(fromActno,toActno,money);
            //程序走到这里就完成了转账
            response.sendRedirect(request.getContextPath() + "/Success.html");
            //调用视图层
        }
        catch (MoneyNotEnoughException e)
        {
            //调用视图层
            response.sendRedirect(request.getContextPath() + "/error1.html");
        }
        catch (TransferException e)
        {
            //调用视图层
            response.sendRedirect(request.getContextPath() + "/Error2.html");
        }
        catch(Exception e)
        {
            response.sendRedirect(request.getContextPath() + "/Error2.html");
        }
    }
}
package com.powernode.bank.web;

import com.powernode.bank.exceptions.MoneyNotEnoughException;
import com.powernode.bank.exceptions.TransferException;
import com.powernode.bank.service.AccountService;
import com.powernode.bank.service.Impl.AccountServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/transfer")
public class AccountServlet extends HttpServlet
{
    //为了让这个对象在其他方法中也可以使用,我们声明为实例变量
    private AccountService accountService = new AccountServiceImpl();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        super.doGet(req, resp);
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        //获取表单数据
        String fromActno = request.getParameter("fromActno");
        String toActno = request.getParameter("toActno");
        Double money = Double.parseDouble(request.getParameter("money"));
        try
        {
            //调用Service的转账方法完成转账(调业务层)
            accountService.transfer(fromActno,toActno,money);
            //程序走到这里就完成了转账
            response.sendRedirect(request.getContextPath() + "/Success.html");
            //调用视图层
        }
        catch (MoneyNotEnoughException e)
        {
            //调用视图层
            response.sendRedirect(request.getContextPath() + "/error1.html");
        }
        catch (TransferException e)
        {
            //调用视图层
            response.sendRedirect(request.getContextPath() + "/Error2.html");
        }
        catch(Exception e)
        {
            response.sendRedirect(request.getContextPath() + "/Error2.html");
        }
    }
}
package com.powernode.bank.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

public class SqlSessionUtil
{
    private SqlSessionUtil(){}
    private static SqlSessionFactory sqlSessionFactory;
    static
    {
        try
        {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }
    //全局的服务器级别的,一个服务器一个即可的
    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
    public static SqlSession openSession()
    {
        SqlSession sqlSession = local.get();
        if(sqlSession == null)
        {
            sqlSession = sqlSessionFactory.openSession();
            local.set(sqlSession);
        }
        return sqlSession;
    }
    public static void close(SqlSession sqlSession)
    {
        //关闭SqlSession对象
        if (sqlSession != null)
        {
            sqlSession.close();
            //从当前线程中移除SqlSession对象
            //注意一定要一处当前线程和SqlSession对象的绑定关系
            //因为Tomcat服务器支持线程池,也就是说用过的线程有概率还会使用这个线程
            //如果我们关闭了该SqlSession然后没有移除,就会导致另外的用户有概率拿到这个空的SqlSession对象(已经被关闭了)
            local.remove();
        }
    }
}
package com.powernode.bank.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

public class SqlSessionUtil
{
    private SqlSessionUtil(){}
    private static SqlSessionFactory sqlSessionFactory;
    static
    {
        try
        {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }
    //全局的服务器级别的,一个服务器一个即可的
    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();
    public static SqlSession openSession()
    {
        SqlSession sqlSession = local.get();
        if(sqlSession == null)
        {
            sqlSession = sqlSessionFactory.openSession();
            local.set(sqlSession);
        }
        return sqlSession;
    }
    public static void close(SqlSession sqlSession)
    {
        //关闭SqlSession对象
        if (sqlSession != null)
        {
            sqlSession.close();
            //从当前线程中移除SqlSession对象
            //注意一定要一处当前线程和SqlSession对象的绑定关系
            //因为Tomcat服务器支持线程池,也就是说用过的线程有概率还会使用这个线程
            //如果我们关闭了该SqlSession然后没有移除,就会导致另外的用户有概率拿到这个空的SqlSession对象(已经被关闭了)
            local.remove();
        }
    }
}
package com.powernode.bank.service;

import com.powernode.bank.exceptions.MoneyNotEnoughException;
import com.powernode.bank.exceptions.TransferException;

public interface AccountService
{
    //账户业务类
    void transfer(String from,String to,double money) throws MoneyNotEnoughException, TransferException;
}
package com.powernode.bank.service;

import com.powernode.bank.exceptions.MoneyNotEnoughException;
import com.powernode.bank.exceptions.TransferException;

public interface AccountService
{
    //账户业务类
    void transfer(String from,String to,double money) throws MoneyNotEnoughException, TransferException;
}
package com.powernode.bank.service.Impl;

import com.powernode.bank.POJO.Account;
import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.dao.Impl.AccountDaoImpl;
import com.powernode.bank.exceptions.MoneyNotEnoughException;
import com.powernode.bank.exceptions.TransferException;
import com.powernode.bank.service.AccountService;

public class AccountServiceImpl implements AccountService
{
    private AccountDao accountDao = new AccountDaoImpl();
    @Override
    //子类抛了父类也得抛异常
    public void transfer(String from, String to, double money) throws MoneyNotEnoughException, TransferException
    {
        //判断转出账户余额是否充足(需要查询语句)
        Account account = accountDao.selectByActNo(from);
        if(account.getBalance() < money)
        {
            //如果转出账户余额不足,提示用户
            throw new MoneyNotEnoughException("对不起,余额不足");
        }
        else
        {
            //如果转出账户余额充足,更新转出余额(Update)
            Account toAccount = accountDao.selectByActNo(to);
            account.setBalance(account.getBalance() - money);
            toAccount.setBalance(toAccount.getBalance() + money);
            //更新转入余额(Update)
            int count = accountDao.UpdateByActNo(account);
//            模拟异常
            String s = null;
            s.toString();
            count = count + accountDao.UpdateByActNo(toAccount);
            if(count == 2)
            {
                accountDao.Commit();
                accountDao.close();
            }
            else
            {
                accountDao.rollback();
                accountDao.close();
                throw new TransferException("转账异常,未知原因");
            }
        }
    }
}
package com.powernode.bank.service.Impl;

import com.powernode.bank.POJO.Account;
import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.dao.Impl.AccountDaoImpl;
import com.powernode.bank.exceptions.MoneyNotEnoughException;
import com.powernode.bank.exceptions.TransferException;
import com.powernode.bank.service.AccountService;

public class AccountServiceImpl implements AccountService
{
    private AccountDao accountDao = new AccountDaoImpl();
    @Override
    //子类抛了父类也得抛异常
    public void transfer(String from, String to, double money) throws MoneyNotEnoughException, TransferException
    {
        //判断转出账户余额是否充足(需要查询语句)
        Account account = accountDao.selectByActNo(from);
        if(account.getBalance() < money)
        {
            //如果转出账户余额不足,提示用户
            throw new MoneyNotEnoughException("对不起,余额不足");
        }
        else
        {
            //如果转出账户余额充足,更新转出余额(Update)
            Account toAccount = accountDao.selectByActNo(to);
            account.setBalance(account.getBalance() - money);
            toAccount.setBalance(toAccount.getBalance() + money);
            //更新转入余额(Update)
            int count = accountDao.UpdateByActNo(account);
//            模拟异常
            String s = null;
            s.toString();
            count = count + accountDao.UpdateByActNo(toAccount);
            if(count == 2)
            {
                accountDao.Commit();
                accountDao.close();
            }
            else
            {
                accountDao.rollback();
                accountDao.close();
                throw new TransferException("转账异常,未知原因");
            }
        }
    }
}
package com.powernode.bank.POJO;

public class Account
{
    //封装账户数据
    private Long id;
    private String actno;
    private Double balance;

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

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    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(Long id, String actno, Double balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }

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

public class Account
{
    //封装账户数据
    private Long id;
    private String actno;
    private Double balance;

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

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    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(Long id, String actno, Double balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }

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

public class TransferException extends Exception
{
    public TransferException(){};
    public TransferException(String msg)
    {
        super(msg);
    }
}
package com.powernode.bank.exceptions;

public class TransferException extends Exception
{
    public TransferException(){};
    public TransferException(String msg)
    {
        super(msg);
    }
}
package com.powernode.bank.exceptions;

public class MoneyNotEnoughException extends Exception
{
    public MoneyNotEnoughException(){};
    public MoneyNotEnoughException(String msg)
    {
        super(msg);
    }
}
package com.powernode.bank.exceptions;

public class MoneyNotEnoughException extends Exception
{
    public MoneyNotEnoughException(){};
    public MoneyNotEnoughException(String msg)
    {
        super(msg);
    }
}
package com.powernode.bank.dao;

import com.powernode.bank.POJO.Account;

public interface AccountDao
{
    //Dao对象中没有任何一个方法与业务挂钩
    //没有任何业务在里面
    //他们只负责进行CRUD
    //MVC三层架构就是分层职能分工
    Account selectByActNo(String actNo);
    //根据账号查询账户信息
    int UpdateByActNo(Account account);
    //根据账号更新账户信息
    void Commit();
    void close();
    void rollback();
}
package com.powernode.bank.dao;

import com.powernode.bank.POJO.Account;

public interface AccountDao
{
    //Dao对象中没有任何一个方法与业务挂钩
    //没有任何业务在里面
    //他们只负责进行CRUD
    //MVC三层架构就是分层职能分工
    Account selectByActNo(String actNo);
    //根据账号查询账户信息
    int UpdateByActNo(Account account);
    //根据账号更新账户信息
    void Commit();
    void close();
    void rollback();
}
package com.powernode.bank.dao.Impl;

import com.powernode.bank.POJO.Account;
import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

public class AccountDaoImpl implements AccountDao
{
    //必须保证事务从始至终都是同一个操作对象
    private SqlSession sqlSession = SqlSessionUtil.openSession();
    @Override
    public Account selectByActNo(String actNo)
    {
        Account account = (Account)sqlSession.selectOne("account.selectById", actNo);
        return account;
    }

    @Override
    public int UpdateByActNo(Account account)
    {
        int count = sqlSession.update("account.updateById", account);
        //事务的控制不能放到Dao层去实现
//        Commit();
        return count;
    }
    public void Commit()
    {
        sqlSession.commit();
    }
    public void close()
    {
        sqlSession.close();
    }
    public void rollback()
    {
        sqlSession.rollback();
    }
}
package com.powernode.bank.dao.Impl;

import com.powernode.bank.POJO.Account;
import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;

public class AccountDaoImpl implements AccountDao
{
    //必须保证事务从始至终都是同一个操作对象
    private SqlSession sqlSession = SqlSessionUtil.openSession();
    @Override
    public Account selectByActNo(String actNo)
    {
        Account account = (Account)sqlSession.selectOne("account.selectById", actNo);
        return account;
    }

    @Override
    public int UpdateByActNo(Account account)
    {
        int count = sqlSession.update("account.updateById", account);
        //事务的控制不能放到Dao层去实现
//        Commit();
        return count;
    }
    public void Commit()
    {
        sqlSession.commit();
    }
    public void close()
    {
        sqlSession.close();
    }
    public void rollback()
    {
        sqlSession.rollback();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值