第一步:定义一个简单实现转账功能页面index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
<title>银行账户转账</title>
</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>
第二步:定义AccountTransferServlet类
package com.huhu.bank.web.servlet;
import com.huhu.bank.exceptions.MoneyNotEnoughException;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
/**
* 在不使用MVC架构模式,完成银行账户转账
*/
@WebServlet("/transfer")
public class AccountTransferServlet extends HttpServlet {
@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"));
PrintWriter out = response.getWriter();
//1.转账之前需要判断转账金额是否足够
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/mvc";
String user="root";
String password="2337144";
con=DriverManager.getConnection(url,user,password);
//获取预编译的数据库操作对象
String sql1="select * from t_act where actno=?";
ps=con.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 (Exception e){
//e.printStackTrace();
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 (con!=null){
try {
con.close();
}catch (SQLException e){
throw new RuntimeException(e);
}
}
}
}
}
第三步:转账过程遇到异常处理
public class MoneyNotEnoughException extends Exception {
public MoneyNotEnoughException() {}
public MoneyNotEnoughException(String msg) {
super(msg);
}
}
第四步:实现转账功能
//开始转账
//act001账户减去10000
//act002账户加上10000
String sql2="update t_act set balance=balance-? where actno=?";
ps2=con.prepareStatement(sql2);
ps2.setDouble(1,money);
ps2.setString(2,fromActno);
int count=ps2.executeUpdate();
String sql3="update t_act set balance=balance+? where actno=?";
ps3=con.prepareStatement(sql3);
ps3.setDouble(1,money);
ps3.setString(2,toActno);
count+=ps3.executeUpdate();
if (count!=2){
throw new AppException("App异常,请联系管理员!");
}
public class AppException extends Exception {
public AppException(String msg) {
super(msg);
}
public AppException() {
}
}
第五步:完善一下事务提交功能
package com.huhu.bank.web.servlet;
import com.huhu.bank.exceptions.AppException;
import com.huhu.bank.exceptions.MoneyNotEnoughException;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
/**
* 在不使用MVC架构模式,完成银行账户转账
*/
@WebServlet("/transfer")
public class AccountTransferServlet extends HttpServlet {
@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"));
PrintWriter out = response.getWriter();
//1.转账之前需要判断转账金额是否足够
Connection con=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="2337144";
con=DriverManager.getConnection(url,user,password);
//手动开启事务
con.setAutoCommit(false);
//获取预编译的数据库操作对象
String sql1="select * from t_act where actno=?";
ps=con.prepareStatement(sql1);
ps.setString(1,fromActno);
//执行sql语句,返回结果集
rs=ps.executeQuery();
//处理结果集
if (rs.next()){
double balance=rs.getDouble("balance");
if (balance<money){
//余额不足(使用异常处理机制)
throw new MoneyNotEnoughException("对不起,余额不足!");
}
//开始转账
//act001账户减去10000
//act002账户加上10000
String sql2="update t_act set balance=balance-? where actno=?";
ps2=con.prepareStatement(sql2);
ps2.setDouble(1,money);
ps2.setString(2,fromActno);
int count=ps2.executeUpdate();
String sql3="update t_act set balance=balance+? where actno=?";
ps3=con.prepareStatement(sql3);
ps3.setDouble(1,money);
ps3.setString(2,toActno);
count+=ps3.executeUpdate();
if (count!=2){
throw new AppException("App异常,请联系管理员!");
}
con.commit();
//转账成功
out.print("转账成功!");
}
}catch (Exception e){
//e.printStackTrace();
//保险起见,出现异常就出现回滚
try{
if (con!=null){
con.rollback();
}
}catch (SQLException ex){
throw new RuntimeException(ex);
}
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 (con!=null){
try {
con.close();
}catch (SQLException e){
throw new RuntimeException(e);
}
}
}
}
}
总结缺陷:
1.代码复用性太差(没有进行职能分工,没有独立组件概念,所以没有办法进行代码复用,代码和代码之间耦合度太高,扩展性太差)
2.耦合度高,导致代码很难扩展
3.操作数据库代码和业务逻辑混合在一起,容易出错。