0
点赞
收藏
分享

微信扫一扫

不适用MVC架构模式完成银行账户转账

1. 程序编写 63-64

代码在com.powernode.bank.web.servlet

AccountTransferServlet

package com.powernode.bank.web.servlet;

import com.powernode.bank.exceptions.AppException;
import com.powernode.bank.exceptions.MoneyNotEnoughException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.sql.*;

//这是一个转账的servlet   63
//在不使用mvc架构的模式下,完成银行账户的转账
//分析这个程序有那些问题
/**
 * 在不使用MVC架构模式的前提下,完成银行账户转账。
 * 分析这个程序存在哪些问题?
 *  缺点1> 代码的复用性太差。(代码的重用性太差)
 *  导致缺点1的原因?
 *      因为没有进行“职能分工”,没有独立组件的概念,所以没有办法进行代码复用。代码和代码之间的耦合度太高,扩展力太差。
 *  缺点2> 耦合度高,导致了代码很难扩展。
 *  缺点3> 操作数据库的代码和业务逻辑混杂在一起,很容易出错。编写代码的时候很容易出错,无法专注业务逻辑的编写。
 *
 * 分析以下AccountTransferServlet他都负责了什么?
 * 1> 负责了数据接收
 * 2> 负责了核心的业务处理
 * 3> 负责了数据库表中数据的CRUD操作(Create【增】 Retrieve【查】 Update【改】 Delete【删】)
 * 4> 负责了页面的数据展示
 * ....
 */
@WebServlet("/transfer")
public class AccountTransferServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //获取响应流对象(就是输出到浏览器页面上)
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        //获取转账相关信息
        String fromActno = request.getParameter("fromActno");
        String toActno = request.getParameter("toActno");
        double money = Double.parseDouble(request.getParameter("money"));
        //连接数据库,编写业务逻辑代码,进行转账操作
        // 1. 转账之前要判断转出账户的余额是否充足
        Connection conn = null;
        PreparedStatement ps = null;
        PreparedStatement ps2 = null;
        PreparedStatement ps3 = null;
        ResultSet rs = null;
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取链接
            String url = "jdbc:mysql://localhost:3306/mvc";
            String user = "root";
            String password = "lzl";
            conn = DriverManager.getConnection(url, user, password);

            //开启事务,(不在自动提交,改为手动提交,业务完成后在提交)   64
            conn.setAutoCommit(false);

            //获取预编译的数据库操作对象
            String sql1 = "select balance from t_act where actno = ?";
            ps = conn.prepareStatement(sql1);
            //给问号赋值
            ps.setString(1,fromActno);
            //执行sql语句,返回结果集
            rs = ps.executeQuery();
            //处理结果集
            if(rs.next()){
                double balance = rs.getDouble("balance");
                if(balance<money){
                    //余额不足(使用异常处理机制)
                    throw new MoneyNotEnoughException("对不起,余额不足");
                }

                //程序能走到这里,一定是余额充足,(因为程序在此之前一旦遇到异常就会被catch捕获)
                //开始转账
                // 开始转账
                // act001账户减去10000
                String sql2 = "update t_act set balance = balance - ? where actno = ?";
                ps2 = conn.prepareStatement(sql2);
                ps2.setDouble(1,money);
                ps2.setString(2,fromActno);
                int count = ps2.executeUpdate();

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

                // act002账户加上10000
                String sql3 = "update t_act set balance = balance + ? where actno = ?";
                ps3 = conn.prepareStatement(sql3);
                ps3.setDouble(1, money);
                ps3.setString(2, toActno);

                //累计受影响条数
                count += ps3.executeUpdate();

                if(count !=2){
                    throw new AppException("app异常,请联系管理员");
                }

                //手动提交事务   64
                conn.commit();
                //转账成功
                out.print("转账成功!");

            }
        } catch (Exception e) {
            //保险起见,回滚事务
            try {
                if(conn!=null){
                    conn.rollback();//事务的回滚   64
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            //异常处理,发生异常后你怎么办
            //e.printStackTrace();
            //下面解释这个e.getMessage(),异常的调用,
            // 首先因为 throw new MoneyNotEnoughException("对不起,yue不足");创建了一个我们自己
            //的异常类对象(并且是调用有参构造)在我们的有参构造中的super(msg);(这个msg就是接受了)
            //"对不起,余额不足"这句话,然后经过一系列传递后,这句话最终传到了异常的这个方法,从而被我们调用
            /*
            * public String getMessage() {
                 return detailMessage;
              }
            * */
            out.print(e.getMessage());


        }finally {
            //释放资源
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {

                    throw new RuntimeException(e);
                }
            }
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {

                    throw new RuntimeException(e);
                }
            }
            if(ps2!=null){
                try {
                    ps2.close();
                } catch (SQLException e) {

                    throw new RuntimeException(e);
                }
            }
            if(ps3!=null){
                try {
                    ps3.close();
                } catch (SQLException e) {

                    throw new RuntimeException(e);
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {

                    throw new RuntimeException(e);
                }
            }
        }
    }
}

异常类com.powernode.bank.exceptions

AppException

package com.powernode.bank.exceptions;

//app异常类  63
public class AppException extends Exception{
    public AppException() {
    }

    public AppException(String msg) {
        super(msg);
    }
}

MoneyNotEnoughException

package com.powernode.bank.exceptions;

//钱不足异常类  63
public class MoneyNotEnoughException extends Exception{
    //以下是两个构造器
    //无参构造器
    public MoneyNotEnoughException() {
    }
    //有参构造器
    public MoneyNotEnoughException(String msg) {
        super(msg);
    }
}

转账页面index.jsp

<%--银行转账页面   63--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>转账页面</title>
    <base href="${pageContext.request.scheme}://${pageContext.request.serverName}
:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
  </head>
  <body>
  <form action="transfer" method="post">
    转出账户:<input type="text" name="fromActno"><br>
    转入账户:<input type="text" name="toActno"><br>
    转账金额:<input type="text" name="money"><br>
    <input type="submit" value="转账"/>
  </form>
  </body>
</html>

2. 程序存在的问题 64

2.1 分析以下AccountTransferServlet他都负责了什么?64

1> 负责了数据接收

2> 负责了核心的业务处理

3> 负责了数据库表中数据的CRUD操作(Create【增】 Retrieve【查】 Update【改】 Delete【删】)

4> 负责了页面的数据展示

....

2.2 分析这个程序存在哪些问题?64

缺点1> 代码的复用性太差。(代码的重用性太差)

导致缺点1的原因?

因为没有进行“职能分工”,没有独立组件的概念,所以没有办法进行代码复用。代码和代码之间的耦合度太高,扩展力太差。

缺点2> 耦合度高,导致了代码很难扩展。

缺点3> 操作数据库的代码和业务逻辑混杂在一起,很容易出错。编写代码的时候很容易出错,无法专注业务逻辑的编写。

举报

相关推荐

0 条评论