MVC架构模式实现银行转账

 MVC架构模式

 对Model进一步细化

 Controller+View等于Web层/表现层 

 第一步:定义Account类

package com.huhu.bank.mvc;

/**
 * 账户实体类,封装账户信息
 */
public class Account {
    //一般属性不建议设计为基本数据类型,建议使用包装类,防止null带来问题
    private Long id;
    private String actno;
    private Double balance;

    public Account(Long id, String actno, Double balance) {
        this.id = id;
        this.actno = actno;
        this.balance = balance;
    }

    public Account() {
    }

    @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;
    }
}

第二步:定义Dao层

package com.huhu.bank.mvc;

import com.huhu.bank.utils.DBUtil;

import java.sql.*;
import java.util.*;

/**
 * 负责Account数据的增删改查
 * DAO数据访问对象
 * 只负责数据库的CRUD,没有任何业务逻辑在里面
 */
public class AccountDao {
    public int insert(Account act) {
        Connection con = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            con = DBUtil.getConnection();
            String sql = "insert into t_act(actno,balance) values(?,?)";
            ps = con.prepareStatement(sql);
            ps.setString(1, act.getActno());
            ps.setDouble(2, act.getBalance());
            count = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(con, ps, null);
        }
        return count;
    }

    public int deleteById(String id) {
        Connection con = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            con = DBUtil.getConnection();
            String sql = "delete from t_act where id=?";
            ps = con.prepareStatement(sql);
            ps.setString(1, id);
            count = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(con, ps, null);
        }
        return count;
    }

    public int update(Account act) {
        Connection con = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            con = DBUtil.getConnection();
            String sql = "update t_act set balance=?,actno=? where id=? ";
            ps = con.prepareStatement(sql);
            ps.setDouble(1, act.getBalance());
            ps.setString(2, act.getActno());
            ps.setLong(3, act.getId());
            count = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(con, ps, null);
        }
        return count;
    }

    public Account selectByActno(String actno) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        Account act = null;
        try {
            con = DBUtil.getConnection();
            String sql = "select id,actno,balance from t_act where actno=?";
            ps = con.prepareStatement(sql);
            ps.setString(1, actno);
            rs = ps.executeQuery();
            if (rs.next()) {
                Long id = rs.getLong("id");
                double balance = rs.getDouble("balance");
                //将结果集封装成对象
                act = new Account();
                act.setId(id);
                act.setActno(actno);
                act.setBalance(balance);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(con, ps, null);
        }
        return act;
    }

    public List<Account> selectAll() {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<Account> list = new ArrayList<>();
        try {
            con = DBUtil.getConnection();
            String sql = "select id,actno,balance from t_act";
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                //取出数据
                Long id = rs.getLong("id");
                String actno = rs.getString("actno");
                double balance = rs.getDouble("balance");
                //封装对象
                Account account = new Account();
                account.setId(id);
                account.setActno(actno);
                account.setBalance(balance);
                //加到List集合
                list.add(account);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(con, ps, null);
        }
        return list;
    }
}

第三步:定义业务层

package com.huhu.bank.mvc;

import com.huhu.bank.exceptions.AppException;
import com.huhu.bank.exceptions.MoneyNotEnoughException;

public class AccountService {

    private AccountDao accountDao=new AccountDao();

    /**
     * 完成转账业务逻辑
     *
     * @param fromActno
     * @param toActno
     * @param money
     */
    public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException, AppException {
        //查询余额是否充足
        Account fromAct = accountDao.selectByActno(fromActno);
        if (fromAct.getBalance() < money) {
            throw new MoneyNotEnoughException("对不起,余额不足!");
        }
        //余额充足
        Account toAct = accountDao.selectByActno(toActno);
        fromAct.setBalance(fromAct.getBalance() - money);
        toAct.setBalance(toAct.getBalance() + money);
        //更新数据库中余额
        int count = accountDao.update(fromAct);
        count += accountDao.update(toAct);
        if (count!=2){
            throw new AppException("账户转账异常!!!");
        }
    }
}

第四步:定义表现层 

package com.huhu.bank.mvc;

import com.huhu.bank.exceptions.MoneyNotEnoughException;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;

/**
 * 账户小程序
 * 司令官。负责调度其他组件完成任务
 */
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet {

    private AccountService accountService = new AccountService();

    @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"));
        //调用业务方法处理业务(调用model处理业务)

        try {
            accountService.transfer(fromActno, toActno, money);
            //转账成功
            //展示处理结果(调用view作页面展示)
            response.sendRedirect(request.getContextPath() + "/success.jsp");
        } catch (MoneyNotEnoughException e) {
            //余额不足
            //展示处理结果(调用view作页面展示)
            response.sendRedirect(request.getContextPath() + "/moneyNotEnough.jsp");
        } catch (Exception e) {
            //转账失败
            //展示处理结果(调用view作页面展示)
            response.sendRedirect(request.getContextPath() + "/error.jsp");
        }


    }
}

工具类

package com.huhu.bank.utils;
import java.sql.*;
import java.util.*;
import static java.util.ResourceBundle.*;

/**
 * JDBC工具类封装
 */
public class DBUtil {

    private static ResourceBundle bundle = getBundle("resources/jdbc");
    private static String driver = bundle.getString("driver");
    private static String url = bundle.getString("url");
    private static String user = bundle.getString("user");
    private static String password = bundle.getString("password");

    /**
     * 私有构造方法
     * 不让创建对象,因为工具类中方法都是静态的,不需要创建对象
     * 为了防止创建对象,因此将方法私有化
     */
    private DBUtil() {}

    //DBUtil类加载注册驱动
    static {
        try {
            Class.forName(driver);
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
    }

    /**
     * 这里没有使用数据库连接池,直接创建连接对象
     * @return 连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        Connection con=DriverManager.getConnection(url,user,password);
        return con;
    }

    /**
     * 关闭资源
     * @param con 连接对象
     * @param stmt 数据库操作对象
     * @param rs 结果集对象
     */
    public static void close(Connection con,Statement stmt,ResultSet rs){
        if (rs!=null){
            try {
                rs.close();
            }catch (SQLException e){
                throw new RuntimeException(e);
            }
        }
        if (stmt!=null){
            try {
                stmt.close();
            }catch (SQLException e){
                throw new RuntimeException(e);
            }
        }
        if (con!=null){
            try {
                con.close();
            }catch (SQLException e){
                throw new RuntimeException(e);
            }
        }
    }
}

事务银行转账优化篇 

工具类

private static ThreadLocal<Connection> local=new ThreadLocal<>();
    /**
     * 这里没有使用数据库连接池,直接创建连接对象
     * @return 连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        Connection con = local.get();
        if (con==null){
            con=DriverManager.getConnection(url,user,password);
            local.set(con);
        }
        return con;
    }
        if (con!=null){
            try {
                con.close();
                //根本原因:Tomcat支持线程池的,一个人使用过t1线程,不移除的话可能会被其他人使用
                local.remove();
            }catch (SQLException e){
                throw new RuntimeException(e);
            }
        }

 Service层类

package com.huhu.bank.mvc;

import com.huhu.bank.exceptions.AppException;
import com.huhu.bank.exceptions.MoneyNotEnoughException;
import com.huhu.bank.utils.DBUtil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class AccountService {

    private AccountDao accountDao=new AccountDao();

    /**
     * 完成转账业务逻辑
     *
     * @param fromActno
     * @param toActno
     * @param money
     */
    public void transfer(String fromActno, String toActno, double money) throws MoneyNotEnoughException, AppException {
        //Service层控制事务
        try(Connection con= DBUtil.getConnection()){
            System.out.println(con);
            con.setAutoCommit(false);
            //查询余额是否充足
            Account fromAct = accountDao.selectByActno(fromActno);
            if (fromAct.getBalance() < money) {
                throw new MoneyNotEnoughException("对不起,余额不足!");
            }
            //余额充足
            Account toAct = accountDao.selectByActno(toActno);
            fromAct.setBalance(fromAct.getBalance() - money);
            toAct.setBalance(toAct.getBalance() + money);
            //更新数据库中余额
            int count = accountDao.update(fromAct);
            count += accountDao.update(toAct);

            //模拟异常
            String s=null;
            s.toString();

            if (count!=2){
                throw new AppException("账户转账异常!!!");
            }
            con.commit();
        }catch (SQLException e){
            throw new AppException("账户转账异常!!!");
        }

    }
}

Dao类 

package com.huhu.bank.mvc;

import com.huhu.bank.utils.DBUtil;

import java.sql.*;
import java.util.*;

/**
 * 负责Account数据的增删改查
 * DAO数据访问对象
 * 只负责数据库的CRUD,没有任何业务逻辑在里面
 */
public class AccountDao {
    public int insert(Account act) {
        PreparedStatement ps = null;
        int count = 0;
        try {
            Connection con = DBUtil.getConnection();
            String sql = "insert into t_act(actno,balance) values(?,?)";
            ps = con.prepareStatement(sql);
            ps.setString(1, act.getActno());
            ps.setDouble(2, act.getBalance());
            count = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(null, ps, null);
        }
        return count;
    }

    public int deleteById(String id) {
        PreparedStatement ps = null;
        int count = 0;
        try {
            Connection con = DBUtil.getConnection();
            String sql = "delete from t_act where id=?";
            ps = con.prepareStatement(sql);
            ps.setString(1, id);
            count = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(null, ps, null);
        }
        return count;
    }

    public int update(Account act) {
        PreparedStatement ps = null;
        int count = 0;
        try {
            Connection con = DBUtil.getConnection();
            String sql = "update t_act set balance=?,actno=? where id=? ";
            ps = con.prepareStatement(sql);
            ps.setDouble(1, act.getBalance());
            ps.setString(2, act.getActno());
            ps.setLong(3, act.getId());
            count = ps.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(null, ps, null);
        }
        return count;
    }

    public Account selectByActno(String actno) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Account act = null;
        try {
            Connection con = DBUtil.getConnection();
            String sql = "select id,actno,balance from t_act where actno=?";
            ps = con.prepareStatement(sql);
            ps.setString(1, actno);
            rs = ps.executeQuery();
            if (rs.next()) {
                Long id = rs.getLong("id");
                double balance = rs.getDouble("balance");
                //将结果集封装成对象
                act = new Account();
                act.setId(id);
                act.setActno(actno);
                act.setBalance(balance);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(null, ps, rs);
        }
        return act;
    }

    public List<Account> selectAll() {
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<Account> list = new ArrayList<>();
        try {
            Connection con = DBUtil.getConnection();
            String sql = "select id,actno,balance from t_act";
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                //取出数据
                Long id = rs.getLong("id");
                String actno = rs.getString("actno");
                double balance = rs.getDouble("balance");
                //封装对象
                Account account = new Account();
                account.setId(id);
                account.setActno(actno);
                account.setBalance(balance);
                //加到List集合
                list.add(account);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBUtil.close(null, ps, rs);
        }
        return list;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值