- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
@ 。
多读书,书中有,你对生活,困难所解不开的答案
比如:《杀死一只是更鸟》中提到的
对应我们:我们努力中考,高考,升本,考研,每天都在努力学习,但是某天突然想到万一没有考上的话,那现在的努力又有什么意义呢?
答案:在《杀死一只是更鸟》里有这样一段话:
> 勇敢是,当你还未开始,你就知道自己会输,可你依然要去做,而且无论如何都要把它坚持到底,你很少能赢,但有时也会。努力的这个过程本身就是有意义,能够获得理想的结果当然很好,但如果失败了也没关系。因为你的勇敢,从未辜负你的青春,而黎明的光亮,总有一刻,会照亮穿梭于黑暗之中的自己。况且,你还不一定会输呢。
MVC开始是存在于桌面程序中的,M是指业务模型,V是指 用户界面 ,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批 统计数据 可以分别用 柱状图 、 饼图 来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。 [1-2] 。
模型-视图-控制器( MVC )是[Xerox PARC]( https://baike.baidu.com/item/Xerox PARC/10693263?fromModule=lemma_inlink)在二十世纪八十年代为 编程语言 Smalltalk-80发明的一种 软件设计模式 ,已被广泛使用。后来被推荐为 Oracle 旗下Sun公司[Java EE]( https://baike.baidu.com/item/Java EE/2180381?fromModule=lemma_inlink)平台的设计模式,并且受到越来越多的使用 ColdFusion 和 PHP 的开发者的欢迎。模型-视图-控制器模式是一个有用的 工具箱 ,它有很多好处,但也有一些缺点.
MVC(Model View Controller) 是软件工程中的一种软件架构模式,它把软件系统分为 模型 、 视图 和 控制器 三个基本部分。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.
MVC 主要的核心就是:分层:希望专人干专事,各司其职,职能分工要明确,这样可以让代码耦合度降低,扩展力增强,组件的可复用性增强 .
MVC 从字面意思我们就可以看到:是分为了三层的,M(Mode 模型),V(View 视图),C(Controller 控制器) 。
M即model模型 :是指 模型表示 业务规则 。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与 数据格式 无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的 重复性 .
V即View视图 :是指用户看到并与之交互的界面。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操作的方式.
C即controller控制器 :是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据.
M(Model :数据/业务) V (View :视图/展示) C (Controller : 控制层) 。
C(是核心,是控制器,是司令官) 。
M(处理业务/处理数据的一个秘书) 。
V(负责页面展示的一个秘书) 。
MVC(一个司令官,调度两个秘书,去做这件事),仅仅只做事务上的调度,而不做其他的操作 。
优点:
缺点:
三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为: 界面层[表示层](User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer).
区分层次的目的即为了“高内聚低耦合” 的思想 。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构.
三层架构每层之间的逻辑关系:
三层架构的优点 。
三层架构的缺点:
MVC的也可以被说成是 MVC三层架构,说白了,它们其实都是一个东西,只是在一些细节上有稍微的不同,大致设计思想都是一样的:“高内聚,低耦合”.
其实,无论是MVC还是三层架构,都是一种规范,都是奔着" 高内聚,低耦合 "的思想来设计的。三层中的UI和Servlet来分别对应MVC中的View和Controller,业务逻辑层是来 组合 数据访问层的原子性功能的.
如下我们,实现一个用户账户转账操作的一个案例:
准备工作:创建表,创建数据 。
CREATE DATABASE mvc;
USE mvc;
SHOW TABLES;
CREATE TABLE t_act (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
actno VARCHAR(255) NOT NULL,
balance DECIMAL(10,2)
);
INSERT INTO t_act(actno,balance)
VALUES('act001',50000.00),('act002',0.00);
SELECT *
FROM t_act;
javaBean :Account 封装数据 。
账户实体类,封装账户信息的 。
package com.RainbowSea.bank.mvc;
import java.io.Serializable;
import java.util.Objects;
/**
* 账户实体类,封装账户信息的
* 一般是一张表一个。
* pojo 对象
* 有的人也会把这种专门封装数据的对象,称为:"bean对象" (javabean对象,咖啡豆)
* 有的人也会把这种专门封装数据的对象,称为领域模型对象,domain对象
* 不同的程序员不同的习惯。
*/
public class Account implements Serializable { // 这种普通的简单的对象被成为pojo对象
// 注意我们这里定义的数据类型,使用引用数据类型
// 因为我们数据库中可能存在 null 值,而基本数据类型是不可以存储 null值的
private Long id = null; // id
private String actno; // 账号
private Double balance; // 余额
// 反序列化
private static final long serialVersionUID = 1L;
public Account() {
}
public Account(Long id, String actno, Double balance) {
this.id = id;
this.actno = actno;
this.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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Account)) return false;
Account account = (Account) o;
return Objects.equals(getId(), account.getId()) && Objects.equals(getActno(), account.getActno()) && Objects.equals(getBalance(), account.getBalance());
}
@Override
public int hashCode() {
return Objects.hash(getId(), getActno(), getBalance());
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", actno='" + actno + '\'' +
", balance=" + balance +
'}';
}
}
DB连接数据库的工具:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mvc
user=root
password=MySQL
package com.RainbowSea.bank.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class DBUtil {
// resourceBundle 只能读取到 properties 后缀的文件,注意不要加文件后缀名
private static ResourceBundle resourceBundle = ResourceBundle.getBundle("resources/jdbc");
private static String driver = resourceBundle.getString("driver");
private static String url = resourceBundle.getString("url");
private static String user = resourceBundle.getString("user");
private static String password = resourceBundle.getString("password");
// DBUtil 类加载注册驱动
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 将构造器私有化,不让创建对象,因为工具类中的方法都是静态的,不需要创建对象
// 为了防止创建对象,故将构造方法私有化
private DBUtil() {
}
/**
* 这里没有使用数据库连接池,直接创建连接对象
*/
public static Connection getConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return connection;
}
/**
* 资源的关闭
* 最后使用的最先关闭,逐个关闭,防止存在没有关闭的
*/
public static void close(Connection connection , PreparedStatement preparedStatement, ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (preparedStatement!=null) {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
对应Account数据表的DAO操作工具类 。
AccountDao 是负责Account 数据的增上改查 。
什么是DAO ?
为什么叫做 AccountDao 呢?
主要定义如下:增删改查方法() 。
int insert() ;
int deleteByActno();
int update() ;
Account selectByActno();
List<Account> selectAll();
package com.RainbowSea.bank.mvc;
import com.RainbowSea.bank.utils.DBUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
/**
* AccountDao 是负责Account 数据的增上改查
* <p>
* 1. 什么是DAO ?
* Data Access Object (数据访问对象)
* 2. DAO实际上是一种设计模式,属于 JavaEE的设计模式之一,不是 23种设计模式
* 3.DAO只负责数据库表的CRUD ,没有任何业务逻辑在里面
* 4.没有任何业务逻辑,只负责表中数据增上改查的对象,有一个特俗的称谓:DAO对象
* 5. 为什么叫做 AccountDao 呢?
* 这是因为DAO是专门处理t_act 这张表的
* 如果处理t_act 表的话,可以叫做:UserDao
* 如果处理t-student表的话,可以叫做 StudentDao
* <p>
* int insert() ;
* int deleteByActno();
* int update() ;
* Account selectByActno();
* List<Account> selectAll();
*/
public class AccountDao {
/**
* 插入数据
*
* @param account
* @return
*/
public int insert(Account account) {
Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = null;
int count = 0;
try {
String sql = "insert into t_act(actno,balance) values(?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, account.getActno());
preparedStatement.setDouble(2, account.getBalance());
count = preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtil.close(connection, preparedStatement, null);
}
return count;
}
/**
* 通过Id删除数据
*
* @param id
* @return
*/
public int deleteById(String id) {
Connection connection = DBUtil.getConnection();
int count = 0;
PreparedStatement preparedStatement = null;
try {
String sql = "delete from t_act where id = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, id);
count = preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtil.close(connection, preparedStatement, null);
}
return count;
}
/**
* 更新数据
*
* @param account
* @return
*/
public int update(Account account) {
Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = null;
int count = 0;
try {
String sql = "update t_act set balance = ?, actno = ? where id = ?";
preparedStatement = connection.prepareStatement(sql);
//注意设置的 set类型要保持一致。
preparedStatement.setDouble(1, account.getBalance());
preparedStatement.setString(2, account.getActno());
preparedStatement.setLong(3, account.getId());
count = preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtil.close(connection, preparedStatement, null);
}
return count;
}
/**
* 通过 actno 查找账户信息
*
* @param actno
* @return
*/
public Account selectByActno(String actno) {
Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
Account account = new Account();
try {
String sql = "select id,actno,balance from t_act where actno = ?";
preparedStatement = connection.prepareStatement(sql);
//注意设置的 set类型要保持一致。
preparedStatement.setString(1, actno);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
Long id = resultSet.getLong("id");
Double balance = resultSet.getDouble("balance");
// 将结果集封装到java 对象中
account.setActno(actno);
account.setId(id);
account.setBalance(balance);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtil.close(connection, preparedStatement, resultSet);
}
return account;
}
/**
* 查询所有的账户信息
*
* @return
*/
public List<Account> selectAll() {
Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<Account> list = null;
try {
String sql = "select id,actno,balance from t_act";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
String actno = resultSet.getString("actno");
Long id = resultSet.getLong("id");
Double balance = resultSet.getDouble("balance");
// 将结果集封装到java 对象中
Account account = new Account(id,actno,balance);
// 添加到List集合当中
list.add(account);
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtil.close(connection, preparedStatement, resultSet);
}
return list;
}
}
对指定的数据表的数据进行service 业务逻辑处理操作:
service 翻译为:业务.
package com.RainbowSea.bank.mvc;
/**
* service 翻译为:业务。
* AccountService 专门处理Account业务的一个类
* 在该类中应该编写纯业务代码。(只专注域业务处理,不写别的,不和其他代码混合在一块)
* 只希望专注业务,能够将业务完美实现,少量bug.
* <p>
* 业务类一般起名:XXXService,XXXBiz...
*/
public class AccountService {
// 这里的方法起名,一定要体现出,你要处理的是什么业务:
// 我们要提供一个能够实现转账的业务的方法(一个业务对应一个方法)
// 比如:UserService StudentService OrderService
// 处理Account 转账业务的增删改查的Dao
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.RainbowSea.bank.mvc;
/**
* 余额不足异常
*/
public class AppException extends Exception{
public AppException() {
}
public AppException(String msg) {
super(msg);
}
}
package com.RainbowSea.bank.mvc;
/**
* 余额不足异常
*/
public class MoneyNotEnoughException extends Exception{
public MoneyNotEnoughException() {
}
public MoneyNotEnoughException(String msg) {
super(msg);
}
}
仅仅负责调度 M业务处理层,V视图显示层,而不做其他操作.
package com.RainbowSea.bank.mvc;
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;
/**
* 账户小程序
* AccountServlet 是一个司令官,他负责调度其他组件来完成任务。
*
*/
@WebServlet("/transfer")
public class AccountServlet extends HttpServlet { // AccountServlet 作为一个 Controller 司令官
@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处理业务,其中是对应数据表的 CRUD操作)
AccountService accountService = new AccountService();
try {
accountService.transfer(fromActno,toActno,money);
// 执行到这里说明,成功了,
// 展示处理结束(调度 View 做页面展示)
response.sendRedirect(request.getContextPath()+"/success.jsp");
} catch (MoneyNotEnoughException e) {
// 执行到种类,说明失败了,(余额不足
// 展示处理结束(调度 View 做页面展示)
response.sendRedirect(request.getContextPath()+"/error.jsp");
} catch (AppException e) {
// 执行到种类,说明失败了,转账异常
// 展示处理结束(调度 View 做页面展示)
response.sendRedirect(request.getContextPath()+"/error.jsp");
}
// 页面的展示 (调度View做页面展示)
}
}
index.jsp 转账页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>银行账号转账</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/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>
success转账成功的页面显示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>转账成功</title>
</head>
<body>
<h3>转账成功</h3>
</body>
</html>
error 转账失败的页面显示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>转账失败</title>
</head>
<body>
<h3>转账失败</h3>
</body>
</html>
虽然上述:代码成功实现的了用户转账的操作,但是并没有进行事务的处理.
如下是运用 TreadLocal 进行事务的处理:🔜🔜🔜 https://blog.csdn.net/weixin_61635597/article/details/130728394?csdn_share_tail 。
MVC 从字面意思我们就可以看到:是分为了三层的,M(Mode 模型),V(View 视图),C(Controller 控制器) 。
M(Model :数据/业务) V (View :视图/展示) C (Controller : 控制层) 。
C(是核心,是控制器,是司令官) 。
M(处理业务/处理数据的一个秘书) 。
V(负责页面展示的一个秘书) 。
MVC(一个司令官,调度两个秘书,去做这件事),仅仅只做事务上的调度,而不做其他的操作 。
三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为: 界面层[表示层](User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer).
无论是MVC还是三层架构,都是一种规范,都是奔着" 高内聚,低耦合 "的思想 。
⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 感谢如下博主的分享: ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 。
【1】 https://blog.csdn.net/weixin_43232955/article/details/104963392?ops_request_misc 。
【2】 https://blog.csdn.net/weixin_42694511/article/details/120690083?ops_request_misc 。
限于自身水平,其中存在的错误,希望大家,给予指教,韩信点兵——多多益善,谢谢大家,江湖再见,后会有期!!! 。
最后此篇关于MVC三层架构案例详细讲解的文章就讲到这里了,如果你想了解更多关于MVC三层架构案例详细讲解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
是否可以简化在裸机上运行的这条链: 具有随时间变化的副本数的 StatefulSet 服务 使用 proxy-next-upstream: "error http_502 timeout invali
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我需要为应用程序制定架构。它专为销售产品而设计。 系统每天将接受大约 30-40k 的新产品。它将导致在表 product 中创建新记录。 系统应保留价格历史记录。用户应该能够看到产品 A 的价格在去
我需要一些帮助来理解 PHP 的内部工作原理。 还记得,在过去,我们曾经写过 TSR(Terminate and stay resident)例程(pre-windows 时代)吗?一旦该程序被执行,
1.Nginx 基础架构 nginx 启动后以 daemon 形式在后台运行,后台进程包含一个 master 进程和多个 worker 进程。如下图所示: master与
.NET Core:架构、特性和优势详解 在软件开发领域,保持领先地位至关重要。随着技术以指数级的速度发展,开发人员不断寻求高效、可扩展且多功能的解决方案来应对现代挑战。.NET Core 就是这样
本文深入探讨了Kubernetes(K8s)的关键方面,包括其架构、容器编排、网络与存储管理、安全与合规、高可用性、灾难恢复以及监控与日志系统。 关注【TechLeadCloud】,
我知道 CNN 的工作原理,包括每一层的用途(Dropout、Pooling 等)。但是,在为新数据集设计 CNN 时,我不知道要使用多少个 Conv-Relu-Pool 层,在最终获得输出之前我应该
在基于 REST 的架构中,资源和方法之间有什么区别。有吗? 最佳答案 资源是您的应用程序定义的东西;它们与物体非常相似。方法是 HTTP 动词之一,例如 GET、POST、PUT、DELETE。它们
我想用 oneOf仅在 xyType 的值上不同的模式属性(property)。我想要其中两个:一个是 xyType设置为 "1"第二个在哪里xyType是 任何其他值 .这可以使用 json 模式完
寻求 PHP 架构师的建议! 我对 PHP 不是很熟悉,但已经接管了一个用该语言编写的大型分析包的维护工作。该架构旨在将报告的数据读取到大型键/值数组中,这些数组通过各种解析模块传递,以提取每个模块已
这些存在吗? 多年来,我一直是大型强类型面向对象语言(Java 和 C#)的奴隶,并且是 Martin Fowler 及其同类的信徒。 Javascript,由于它的松散类型和函数性质,似乎不适合我习
我已经阅读了 Manning 的 Big Data Lambda Architecture ( http://www.manning.com/marz/BD_meap_ch01.pdf ),但仍然无法
在过去的几年里,我做了相当多的 iOS 开发,所以我非常熟悉 iOS 架构和应用程序设计(一切都是一个 ViewController,您可以将其推送、弹出或粘贴到选项卡栏中)。我最近开始探索正确的 M
我有以下应用程序,我在其中循环一些数据并显示它。 {{thing.title}} {{thing.description}}
昨天我和我的伙伴讨论了我正在开发的这个电子购物网站的架构。请注意,我为此使用 ASP.NET。他非常惊讶地发现我没有将添加到购物车的项目保留在 ArrayList 或其他通用列表中,而是使用 LINQ
我正在使用在 tridion 蓝图层次结构中处于较低位置的出版物。从蓝图中较高级别的出版物继承的一些内容和模式不适合我的出版物,并且永远不会被我的出版物使用。 我将跟进添加这些项目的内部团队,并尝试说
我目前已经在 Cassandra 中设计了一个架构,但我想知道是否有更好的方法来做事情。基本上,问题在于大多数(如果不是全部)读取都是动态的。我构建了一个分段系统作为应用程序服务,读取动态自定义查询(
我正在按照 documentation 中给出的 icingaweb UI v 2.0 布局执行在服务器上设置 icinga 的步骤。 。我成功进入设置页面,该页面要求您输入 token ,然后按照步
我必须保存来自不同社交媒体的用户的不同个人资料。例如用户可能有 1 个 Facebook 和 2 个 Twitter 个人资料。如果我保存每个配置文件它作为新文档插入不同的集合中,例如 faceboo
我是一名优秀的程序员,十分优秀!