MVC
本文為動力節點老杜web課程mvc部分筆記,以銀行轉賬專案為例
不使用MVC框架(分析存在的問題
1.搞個資料庫
CREATE TABLE `t_act` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '自然主鍵,與業務無關,自增',
`actno` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '賬號',
`balance` decimal(10,2) DEFAULT NULL COMMENT '余額',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
2.創建專案bank(不使用maven,手動配置
2.1基本流程
- 創建空project (無需序號 1. 空格)
- moudle
- 手動添加Framwork支持
- project structure
- 在dependency目錄下添加相關jar包,切不可添加在source目錄下(沒用)

- 添加tomcat服務器
- ,,,
2.2遇到的問題 Servlet包找不到(低級錯誤
-
原因
上述jar包添加程序有誤
-
措施
1.以為jdk17與tomcat9不適配,換成10仍不適配
2.在web WEB-INF中創建lib目錄,將servlet-api.jar拷過去,仍不管用

2.3 jsp檔案寫一個簡單頁面(EL運算式不熟練
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="https://www.cnblogs.com/tsangfandy/p/${pageContext.request.scheme}://${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" name="轉賬">
</form>
</body>
</html>

2.4servlet類實作轉賬功能
-
別忘了加注解 @WebServlet("/transfer")
-
從前端獲取用戶輸入的轉賬資訊
String fromActno = request.getParameter("fromActno");
String toActno = request.getParameter("toActno");
double money = Double.parseDouble(request.getParameter("money"));
-
撰寫轉賬業務邏輯代碼,連接資料庫,進行轉賬操作(JDBC那一套)
?
? 注意3:開啟事務,事務手動提交與事務回滾-------------------------------------------------
? jdbc會自動提交,開啟事務,不讓他自動提交
? 注意2:在web WEB-INF中添加mysql連接jar包

? 注意1: 轉賬之前判斷余額是否充足,不足則例外,(創建一個例外類)
//余額不足例外類
public class MoneyNotEnoughException extends Exception {
//構造方法
public MoneyNotEnoughException() {
}
public MoneyNotEnoughException(String msg) {
super(msg);
}
}
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
PreparedStatement ps2 = null; //有了新的sql陳述句
PreparedStatement ps3 = null;
try {
//注冊驅動
Class.forName("com.mysql.cj.jdbc.Driver");
//獲取連接
String url = "jdbc:mysql://localhost:3306/mvc";
String user = "root";
String password = "123456";
conn = DriverManager.getConnection(url,user,password);
//注意3
//開啟事務
//獲取預編譯的sql物件
String sql = "select id,balance from t_act where actno = ? ";
ps = conn.prepareStatement(sql);
ps.setString(1,fromActno);
//執行sql陳述句,回傳結果集
rs = ps.executeQuery();
//拿到結果集后處理結果集
//因為只有一條結果,if即可
if (rs.next()){
//取出余額
double balance = rs.getDouble("balance");
if (balance < 0){
//余額不足
throw new MoneyNotEnoughException("余額不足");
}
//程式走到這里已經說明余額充足,不必加else,因為if中如不足則exception
//下面轉賬,實作功能
//act01 - 10000
//act02 + 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();
//---------------------模擬例外--------------------------------
String sql3 = "update t_act set balance = balance + ? where actno = ? ";
ps3 = conn.prepareStatement("sql3");
ps3.setDouble(1,money);
ps3.setString(2,fromActno);
count += ps3.executeUpdate();
if (count != 2){
//轉賬失敗,再來例外
throw new AppException("App例外,請聯系管理員");
}
//提交事務(轉賬成功肯定能提交了-----------------------------
conn.commit();
//轉賬成功
out.print("轉賬成功");
}
} catch (Exception e) {
//-------------------------------事務回滾--------------------
try {
if (conn != null) { //保險起見,不等于null才回滾
conn.rollback();//只要遇到例外就回滾
}
} catch (SQLException ex) {
ex.printStackTrace();
}
//-----------------------------------------------------
//例外處理,發生上述例外后怎么做
//e.printStackTrace(); 不列印例外資訊了,搞到前端去
out.print(e.getMessage()); //getMessage可以獲取到上面寫的"余額不足"
// 因為構造方法中有參那個,呼叫父類的massage,父類中還有super繼續上調,
//直到一個private的成員變數,那么值就給他了,而getMassage恰好獲得他的值
}finally {
//釋放資源
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps2 != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps3 != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
下面分析mvc存在的問題
3.分析問題
3.1AccountTransferServlet負責什么業務(業務邏輯是什么)
- 資料接收
- 核心業務處理,轉賬業務
- 連接資料庫,CRUD
- 頁面資料展示
這個servlet負責所有的事情
3.2缺點是什么
-
代碼復用性太差,實作一個功能就要搞一個servlet,比如R,查一個資料就得寫一個servlet,可以搞一個專門查資料的方法,查詢資料時呼叫即可,
原因:沒有進行"職能分工",沒有獨立組件的概念,沒有辦法進行代碼復用,代碼之間耦合度太高,擴展力太差
-
耦合度高導致代碼很難擴展,
-
操作資料庫的代碼和業務邏輯混雜在一起,撰寫代碼時很容易出錯,無法專注業務邏輯,所以才需要分層,
MVC架構模式
1.理論基礎

C呼叫M和V
M:資料處理、業務處理
V:頁面展示
2.JDBC工具類封裝
jdbc.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mvc
user=root
password=123456
DBUtil
package bank.utils;
import java.sql.*;
import java.util.ResourceBundle;
/**
* JDBC工具類
* @author d
* @version 1.0
* @since 1.0
*/
public class DBUtil {
private static ResourceBundle bundle = ResourceBundle.getBundle("resources/jdbc");
private static String driver = bundle.getString("com.mysql.cj.jdbc.Driver");
private static String url = bundle.getString("jdbc:mysql://localhost:3306/mvc");
private static String user = bundle.getString("root");
private static String password = bundle.getString("123456");
//工具類一般搞個私有的構造方法,因為不讓創建物件,工具類中的方法都是靜態的,不需要創建物件
// 為了防止創建物件,故私有化
private DBUtil(){}
//DBUtil在類加載時注冊驅動
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 這里沒有使用資料庫連接池,直接創建的連接物件
* 每一次呼叫這個方法,都是一個新的物件
* @return 連接物件
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
/**
* 關閉資源
* @param conn 連接物件
* @param stmt 資料庫操作物件
* @param rs 結果集物件
*/
public static void close(Connection conn , Statement stmt, ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3.DAO與資料物件物體類
3.1DAO
AccountDao是負責Account資料增刪改查的
- 什么是Dao
- Data Access Object(資料訪問物件)
- Dao是一種設計模式,是j2EE的設計模式之一,不是23種設計模式
- Dao只負責資料庫的CRUD,沒有任何業務邏輯
- 沒有業務邏輯,只負責表中資料增刪改查物件,有一個特殊稱謂:DAO物件
- 為什么叫做AccountDao呢?
- 這是因為這個DAO是專門處理t_act這張表的,
- 如果處理t_user表的話,可以叫做:UserDao
- 如果處理t_student表的話,可以叫做:StudentDao
時間
2022.08.30
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/503248.html
標籤:Java
