1987WEB视界-分享互联网热点话题和事件

您现在的位置是:首页 > WEB开发 > 正文

WEB开发

MVC架构-01

1987web2024-03-25WEB开发41
MVC本文为动力节点老杜web课程mvc部分笔记,以银行转账项目为例不使用MVC框架(分析存在的问题1.搞个数据库CREATETABLE`t_act`(`i

MVC 本文为动力节点老杜web课程mvc部分笔记,以银行转账项目为例 不使用MVC框架(分析存在的问题 1.搞个数据库 CREATE TABLE `t_act` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT 自然主键,与业务无关,自增, `actn ...

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=InnoDBAUTO_INCREMENT=5DEFAULT 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"%> href="https://www.cnblogs.com/tsangfandy/p/${pageContext.request.scheme}://${pageContext.request.serverPort}${pageContext.request.contextPath}/"></span><span id="8e9e71e1-cd2c-4b81-beb6-1353c6527a22">银行账户转账</span><span id="9dd65700-c3b0-4b74-8cd7-c8c6bb2271f2"> action="transfer"method="post">转出账户: type="text"name="fromActno">转入账户: type="text"name="toActno">转账金额: type="text"name="money"> type="submit"name="转账">

2.4servlet类实现转账功能

别忘了加注解 @WebServlet("/transfer")

从前端获取用户输入的转账信息

StringfromActno=request.getParameter("fromActno");StringtoActno=request.getParameter("toActno");doublemoney=Double.parseDouble(request.getParameter("money"));

编写转账业务逻辑代码,连接数据库,进行转账操作(JDBC那一套)

​ 注意3:开启事务,事务手动提交与事务回滚-------------------------------------------------

​ jdbc会自动提交,开启事务,不让他自动提交

​ 注意2:在web WEB-INF中添加mysql连接jar包

​ 注意1: 转账之前判断余额是否充足,不足则异常,(创建一个异常类)

//余额不足异常类publicclassMoneyNotEnoughExceptionextendsException{//构造方法publicMoneyNotEnoughException(){}publicMoneyNotEnoughException(Stringmsg){super(msg);}}Connectionconn=null;PreparedStatementps=null;ResultSetrs=null;PreparedStatementps2=null;//有了新的sql语句PreparedStatementps3=null;try{//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接Stringurl="jdbc:mysql://localhost:3306/mvc";Stringuser="root";Stringpassword="123456";conn=DriverManager.getConnection(url,user,password);//注意3//开启事务//获取预编译的sql对象Stringsql="select id,balance from t_act where actno = ? ";ps=conn.prepareStatement(sql);ps.setString(1,fromActno);//执行sql语句,返回结果集rs=ps.executeQuery();//拿到结果集后处理结果集//因为只有一条结果,if即可if(rs.next()){//取出余额doublebalance=rs.getDouble("balance");if(balance<0){//余额不足thrownewMoneyNotEnoughException("余额不足");}//程序走到这里已经说明余额充足,不必加else,因为if中如不足则exception//下面转账,实现功能//act01 - 10000//act02 + 10000Stringsql2="update t_act set balance = balance - ? where actno = ? ";ps2=conn.prepareStatement("sql2");ps2.setDouble(1,money);ps2.setString(2,fromActno);intcount=ps2.executeUpdate();//执行更新,并返回更新的条数//---------------------模拟异常--------------------------------//此处模拟一个异常,此时钱转出,未转入Strings=null;//空指针异常//试验证明,出问题。引入事务s.toString();//---------------------模拟异常--------------------------------Stringsql3="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){//转账失败,再来异常thrownewAppException("App异常,请联系管理员");}//提交事务(转账成功肯定能提交了-----------------------------conn.commit();//转账成功out.print("转账成功");}}catch(Exceptione){//-------------------------------事务回滚--------------------try{if(conn!=null){//保险起见,不等于null才回滚conn.rollback();//只要遇到异常就回滚}}catch(SQLExceptionex){ex.printStackTrace();}//-----------------------------------------------------//异常处理,发生上述异常后怎么做//e.printStackTrace(); 不打印异常信息了,搞到前端去out.print(e.getMessage());//getMessage可以获取到上面写的"余额不足"// 因为构造方法中有参那个,调用父类的massage,父类中还有super继续上调,//直到一个private的成员变量,那么值就给他了,而getMassage恰好获得他的值}finally{//释放资源if(conn!=null){try{conn.close();}catch(SQLExceptione){e.printStackTrace();}}if(ps!=null){try{ps.close();}catch(SQLExceptione){e.printStackTrace();}}if(ps2!=null){try{ps.close();}catch(SQLExceptione){e.printStackTrace();}}if(ps3!=null){try{ps.close();}catch(SQLExceptione){e.printStackTrace();}}if(rs!=null){try{rs.close();}catch(SQLExceptione){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.Driverurl=jdbc:mysql://localhost:3306/mvcuser=rootpassword=123456

DBUtil

packagebank.utils;importjava.sql.*;importjava.util.ResourceBundle;/*** JDBC工具类* @author d* @version 1.0* @since 1.0*/publicclassDBUtil{privatestaticResourceBundlebundle=ResourceBundle.getBundle("resources/jdbc");privatestaticStringdriver=bundle.getString("com.mysql.cj.jdbc.Driver");privatestaticStringurl=bundle.getString("jdbc:mysql://localhost:3306/mvc");privatestaticStringuser=bundle.getString("root");privatestaticStringpassword=bundle.getString("123456");//工具类一般搞个私有的构造方法,因为不让创建对象。工具类中的方法都是静态的,不需要创建对象// 为了防止创建对象,故私有化privateDBUtil(){}//DBUtil在类加载时注册驱动static{try{Class.forName(driver);}catch(ClassNotFoundExceptione){e.printStackTrace();}}/*** 这里没有使用数据库连接池,直接创建的连接对象* 每一次调用这个方法,都是一个新的对象* @return 连接对象* @throws SQLException*/publicstaticConnectiongetConnection()throwsSQLException{Connectionconnection=DriverManager.getConnection(url,user,password);returnconnection;}/*** 关闭资源* @param conn 连接对象* @param stmt 数据库操作对象* @param rs 结果集对象*/publicstaticvoidclose(Connectionconn,Statementstmt,ResultSetrs){if(rs!=null){try{rs.close();}catch(SQLExceptione){e.printStackTrace();}}if(conn!=null){try{conn.close();}catch(SQLExceptione){e.printStackTrace();}}if(stmt!=null){try{stmt.close();}catch(SQLExceptione){e.printStackTrace();}}}}

3.DAO与数据对象实体类

3.1DAO

AccountDao是负责Account数据增删改查的

什么是DaoData Access Object(数据访问对象)Dao是一种设计模式,是j2EE的设计模式之一,不是23种设计模式Dao只负责数据库的CRUD,没有任何业务逻辑没有业务逻辑,只负责表中数据增删改查对象,有一个特殊称谓:DAO对象为什么叫做AccountDao呢?这是因为这个DAO是专门处理t_act这张表的。如果处理t_user表的话,可以叫做:UserDao如果处理t_student表的话,可以叫做:StudentDao

时间2022.08.30