【Spring MVC】如何运用应用分层思想实现简单图书管理系统前后端交互工作

embedded/2025/2/1 0:30:21/

前言

🌟🌟本期讲解关于SpringMVC的编程思想之应用分层~~~

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

🔥 你的点赞就是小编不断更新的最大动力                                       

🎆那么废话不多说直接开整吧~~

  

目录

📚️1.图书管理系统

1.1交互接口

1.2后端代码实现

1.对象属性的初始化

2.实现用户登录

3.实现图书获取

4.postman进行测试

1.3前端代码实现

📚️2.应用分层

2.1介绍

1.什么是应用分层

2.为什么要分层

3.如何分层(三层架构)

4.MVC 和三层架构的区别和联系 

2.2代码重构

1.建立各个功能的包

2.Dao数据层

3.Service业务逻辑层

4.Controller表现层

2.3应用分层的好处

📚️3.总结


 

📚️1.图书管理系统

和之前的几次登录的前后端交互的思路是基本一致的,通过规定前后端交互的接口的实现,我们这里要明白,这个过程的重要意义;

1.1交互接口

登录接口

如下所示:

[URL]
POST /user/login
[请求参数]
name=admin&password=admin
[响应]
true //账号密码验证成功
false//账号密码验证失败

图书列表展示

如下所示:

[URL]
POST /book/getList
[ 请求参数 ]
[ 响应 ]
返回图书列表
[
{
"id": 1,
"bookName": " 活着 ",
"author": " 余华 ",
"count": 270,
"price": 20,
"publish": " 北京⽂艺出版社 ",
"status": 1,
"statusCN": " 可借阅 "
},
...
]

 

1.2后端代码实现

1.对象属性的初始化

可以看到此时由于存在大量的是数据,所以我们需要把这些属性放在一个对象中,达到统一管理的目的;不可能直接在后端响应的参数中直接通过参数定义来进行操作;

代码如下所示:

public class BookInfo {//图书IDprivate Integer id;//书名private String bookName;//作者private String author;//数量private Integer count;//定价private BigDecimal price;//出版社private String publish;//状态 0-⽆效 1-允许借阅 2-不允许借阅private Integer status;private String statusCN;

解释:

这里小编没有定义构造函数,get与set方法,是因为:小编在上期讲解过,我们添加了lombok包中的Data的注解,所以这里进行了反编译(编译器生成代码的一种工具包),所以帮我们编写了get 与set方法;

2.实现用户登录

和之前的案例的样式基本是一致的,URL路由映射,判断拿到的参数是否符合要求,并进行对应的逻辑处理,返回对应的类型的值

代码如下所示:

@RequestMapping("/user")
@RestController
public class UserController {@RequestMapping("/login")public boolean login(String userName, String password, HttpSession session){if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){return false;}if("admin".equals(userName) && "admin".equals(password)){return true;}return false;}
}

解释:

第一个if判断,拿到的参数是否是为空的,如果为空那么就返回false,反之进入下一个判断;

第二个if判断,这里的文本是否是我们规定的文本(这一步就是判断密码用户是否正确)(这里写死了!)

3.实现图书获取

由于没有连接数据库,所以这里小编将进行mock的数据方式,进行数据的模拟,方便我们通过postman进行测试

代码如下所示:

@RequestMapping("/book")
@RestController
public class BookController {@RequestMapping("/getList")public List<BookInfo> getList(){//获取数据List<BookInfo> books = mockData();//处理⻚⾯展⽰for (BookInfo book:books){if (book.getStatus()==1){book.setStatusCN("可借阅");}else {book.setStatusCN("不可借阅");}}return books;}public List<BookInfo> mockData() {List<BookInfo> books = new ArrayList<>();for (int i = 0; i < 5; i++) {BookInfo book = new BookInfo();book.setId(i);book.setBookName("书籍" + i);book.setAuthor("作者" + i);book.setCount(i * 5 + 3);book.setPrice(new BigDecimal(new Random().nextInt(100)));book.setPublish("出版社" + i);book.setStatus(1);books.add(book);}return books;}
}

解释:

这里的数据模拟,大家可以简单看看,具体的数据逻辑处理就是在判断书籍的借出的状态,当这里的状态是1的时候就是不可借阅的状态,反之如果是2,就是可以借阅的状态;

4.postman进行测试

此时我们用户登录的测试,输入正确的userName与password参数进行测试:

此时的返回的值就是true,说明我们的代码是没有问题的;

1.3前端代码实现

由于小编不是专业的前端程序员,所以小编主要讲解一下前端的核心代码即可:

<script>function login() {$.ajax({url:"user/login",type:"post",data:{userName:$("#userName").val(),password:$("#password").val()},success: function (result) {if(result){location.href="/book_list.html"}else {alert("用户名或密码错误")}}})}

解释:

这里主要是通过URL进行传递参数的地址,Ajax方法实现这里的要求,拿到这里的username与password,传递给后端服务器,,拿到返回值,进行对应事务的处理;

getBookList();function getBookList() {$.ajax({type: "get",url: "/book/getList",success: function (result) {console.log(result);if (result != null) {var finalHtml = "";for (var book of result) {finalHtml += '<tr>';finalHtml += '<td><input type="checkbox" name="selectBook"value="' + book.id + '" id="selectBook" class="book-select"></td>';finalHtml += '<td>' + book.id + '</td>';finalHtml += '<td>' + book.bookName + '</td>';finalHtml += '<td>' + book.author + '</td>';finalHtml += '<td>' + book.count + '</td>';finalHtml += '<td>' + book.price + '</td>';finalHtml += '<td>' + book.publish + '</td>';finalHtml += '<td>' + book.statusCN + '</td>';finalHtml += '<td><div class="op">';finalHtml += '<a href="book_update.html?bookId=' + book.id+ '">修改</a>';finalHtml += '<a href="javascript:void(0)"onclick="deleteBook(' + book.id + ')">删除</a>';finalHtml += '</div></td>';finalHtml += "</tr>";}$("tbody").html(finalHtml);}}});}

解释:

本段代码主要是负责,拿到后端数据对象中的数据,通过循环遍历,然后拿到每一个对象后,进行每个属性的拼接;

成果展示:

点击登录后:

注意:

1.这里的数据是小编进行模拟的数据,是没有实际意义的

2.这里的前端代码是小编这里自己的模版,需要的uu可以私信小编哦~~~

📚️2.应用分层

通过上⾯的练习, 我们学习了Spring MVC简单功能的开发, 但是我们也发现了⼀些问题
⽬前我们程序的代码有点"杂乱", 然⽽当前只是"⼀点点功能"的开发. 如果我们把整个项⽬功能完成呢?

代码会更加的"杂乱⽆章"(⽂件乱, 代码内容乱)

2.1介绍

阿⾥开发⼿册中, 关于⼯程结构部分, 定义了常⻅⼯程的应⽤分层结构:

但是这个仅供参考即可;

1.什么是应用分层

应⽤分层 是⼀种软件开发设计思想, 它将应⽤程序分成N个层次, 这N个层次分别负责各⾃的职责, 多个层次之间协同提供完整的功能. 根据项⽬的复杂度, 把项⽬分成三层, 四层或者更多层.

常⻅的MVC设计模式, 就是应⽤分层的⼀种具体体现. 

2.为什么要分层

 ⼤量的代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发⽽动全⾝等问题

总结就是:“高内聚,低耦合”;

3.如何分层(三层架构)

Model(模型), View(视图)和Controller(控制器)三个层次,也就是将⽤⼾视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层构。

如下图所示:

可以看到这是一个标准的MVC架构思想

由于现在的前后端分离的原因:

所以对于Java后端开发者, ⼜有了⼀种新的分层架构: 把整体架构分为表现层、业务逻辑层和数据层. 这种分层⽅式也称之为"三层架构".

1. 表现层: 就是展⽰数据结果和接受⽤⼾指令的,是最靠近⽤⼾的⼀层;
2. 业务逻辑层: 负责处理业务逻辑, ⾥⾯有复杂业务的具体实现;
3. 数据层: 负责存储和管理与应⽤程序相关的数据 

按照上⾯的层次划分, Spring MVC 站在后端开发⼈员的⻆度上, 也进⾏了⽀持, 把上⾯的代码划分为三个部分:

• Controller:控制层。接收前端发送的请求,对请求进⾏处理,并响应数据。 •
• Service:业务逻辑层。处理具体的业务逻辑。
• Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查

4.MVC 和三层架构的区别和联系 

MVC模式:强调数据和视图分离, 将数据展⽰和数据处理分开, 通过控制器对两者进⾏组合.
三层架构:强调不同维度数据处理的⾼内聚和低耦合, 将交互界⾯, 业务处理和数据库操作的逻辑分开.⻆度不同也就谈不上互相替代了,在⽇常的开发中可以经常看到两种共存的情况

但是两者的目的:都是"解耦,分层,代码复⽤"(高内聚,低耦合)

2.2代码重构

此时我们实现分层应用的思想实现上述代码的改进:

1.建立各个功能的包

此时就对应了三层架构的思想模式;

这里多了一个包就是实体类,用model来进行存储;

2.Dao数据层

此时就是负责拿到每个数据的存储:

public class BookDao {public List<BookInfo> mockData(){List<BookInfo> books=new ArrayList<>();for (int i = 0; i < 5; i++) {BookInfo book = new BookInfo();book.setId(i);book.setBookName("书籍" + i);book.setAuthor("作者" + i);book.setCount(i * 5 + 3);book.setPrice(new BigDecimal(new Random().nextInt(100)));book.setPublish("出版社" + i);book.setStatus(1);books.add(book);}return books;}
}

将这里的模拟mock数据进行存储在列表里; 

3.Service业务逻辑层

这里就是进行业务逻辑处理,这里要处理的数据就是判断这本书的状态,判断为1还是为2;

代码如下:

public class BookService {public List<BookInfo> getBookList(){BookDao bookDao=new BookDao();List<BookInfo> books=bookDao.mockData();for (BookInfo book : books) {if (book.getStatus() == 1) {book.setStatusCN("可借阅");} else {book.setStatusCN("不可借阅");}}return books;}

解释:

这里要注意,这里的数据是从哪里来的,很明显是从模拟数据包这类里来的,所以要先创建一个对象,拿到这里面的数据,然后进行相应的数据逻辑处理;

4.Controller表现层

 这里就是负责数据的获取,从前端拿到数据,并返回处理过后的数据:

这里的数据的获取就是如下的:

@RequestMapping("/book")
@RestController
public class BookController {@RequestMapping("/getList")public List<BookInfo> getList() {//获取数据BookService bookService = new BookService();List<BookInfo> books = bookService.getBookList();//处理⻚⾯展⽰return books;}
}

解释:

这里就是拿到业务逻辑处理过后的数据,所以要拿到这个对应的对象,然后返回给前端,实现数据的交互

这里的用户也是没有变动的,小编就不在进行演示了;

2.3应用分层的好处

• 降低层与层之间的依赖, 结构更加的明确, 利于各层逻辑的复⽤
• 开发⼈员可以只关注整个结构中的其中某⼀层, 极⼤地降低了维护成本和维护时间
• 可以很容易的⽤新的实现来替换原有层次的实现
• 有利于标准化

📚️3.总结

小编本期主要讲解了关于图书管理系统简单登录,和模拟数据的展示,重点讲解了关于应用分层的概念,以及优点和如何实现,并通过应用分层的思想改进了后端代码;

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                 😊😊  期待你的关注~~~


http://www.ppmy.cn/embedded/158486.html

相关文章

Redis复制

一、Redis复制&#xff1a; 1.为了解决分布式中单点故障问题&#xff0c;通常会把数据复制多个副本部署到其他机器上来解决故障恢复和负载均衡等需求。 2.建立复制 参与复制的redis实例划分为主节点&#xff08;master&#xff09;和从节点&#xff08;slave&#xff09;,每个从…

electron打包客户端在rk3588上支持h265硬解

目录 前言 chromium是如何支持h265硬解 electron/chromium第一次编译 electron/chromium第二次编译 前言 我们的客户端程序是用electron打包的前端程序&#xff0c;其在rk3588主机上的linux环境运行。之前使用客户端查看h264编码的视频直播是没有问题的&#xff0c;但视频源…

Linux实操篇-文件目录类>/>>/echo/head/tail/ln/history

目录 传送门前言一、>、 >>概念二、>、 >>实战1. **>&#xff08;输出重定向&#xff09;**2. **>>&#xff08;追加输出&#xff09;****区别总结&#xff1a;** 三、echo、head、tail概念四、echo、head、tail实战1. **echo****用法**&#xff1a…

58.界面参数传递给Command C#例子 WPF例子

界面参数的传递&#xff0c;界面参数是如何从前台传送到后台的。 param 参数是从界面传递到命令的。这个过程通常涉及以下几个步骤&#xff1a; 数据绑定&#xff1a;界面元素&#xff08;如按钮&#xff09;的 Command 属性绑定到视图模型中的 RelayCommand 实例。同时&#x…

新鲜速递:DeepSeek-R1开源大模型本地部署实战—Ollama + MaxKB 搭建RAG检索增强生成应用

在AI技术快速发展的今天&#xff0c;开源大模型的本地化部署正在成为开发者们的热门实践方向。最火的莫过于吊打OpenAI过亿成本的纯国产DeepSeek开源大模型&#xff0c;就在刚刚&#xff0c;凭一己之力让英伟达大跌18%&#xff0c;纳斯达克大跌3.7%&#xff0c;足足是给中国AI产…

基于java线程池和EasyExcel实现异步导出

基于java线程池和EasyExcel实现异步导出 1.controller层 GetMapping("export") public void exportExcel(HttpServletResponse response) throws IOException, InterruptedException {exportService.exportExcel(response); }2. service public void exportExcel(H…

机试题——最小矩阵宽度

题目描述 给定一个矩阵&#xff0c;包含 N * M 个整数&#xff0c;和一个包含 K 个整数的数组。 现在要求在这个矩阵中找一个宽度最小的子矩阵&#xff0c;要求子矩阵包含数组中所有的整数。 输入描述 第一行输入两个正整数 N&#xff0c;M&#xff0c;表示矩阵大小。 接下…

zookeeper-3.8.3-基于ACL的访问控制

ZooKeeper基于ACL的访问控制 ZooKeeper 用ACL控制对znode的访问&#xff0c;类似UNIX文件权限&#xff0c;但无znode所有者概念&#xff0c;ACL指定ID及对应权限&#xff0c;且仅作用于特定znode&#xff0c;不递归。 ZooKeeper支持可插拔认证方案&#xff0c;ID格式为scheme…