【学习笔记】手写 Tomcat 五

目录

一、优化 Servlet

创建一个抽象类

继承抽象类

二、三层架构 

业务逻辑层

数据访问层

1. 在 Dao 层操作数据库

2. 调用 Dao 层,实现业务逻辑功能

3. 调用 Service 层,响应数据

测试

三、数据库连接池

1. 手写数据库连接池

2. 创建数据库连接池的类

3. 初始化连接池

4. 在 Dao 层获取数据库连接

5. 归还数据库连接

作业

1. 3w1h的方式,了解单例模式

2. 了解其他连接池


一、优化 Servlet

昨天,我们把响应动态资源的功能放到了 Servlet,一个 Servlet 就是一个功能

当 Servlet 多了之后,我们会发现,每个 Servlet 里都有 service 方法,那有什么方法可以简化呢?

这里就可以使用 Java 的三大特性之一 继承

创建一个抽象类

定义普通的 service 方法,和 doGet , doPost 抽象方法

继承抽象类

在每个 Servlet 中继承这个抽象类,然后就可以删除 service 方法了

二、三层架构 

我们把功能都写在了 Servlet,这样有几个缺点,一是不够低耦合 高内聚,二是不方便协同开发等

我们可以使用三层架构来解决这个问题

三层架构是一种设计思想,分为表示层业务逻辑层数据访问层

表示层 Servlet:负责处理用户的请求和响应用户需要的数据

业务逻辑层 Service:负责业务上逻辑的处理,也是表示层和数据层之间的桥梁,

数据访问层 Dao:操作数据库,进行增删改查,并将结果传给业务逻辑层

三层架构区分层次的目的是为了 “高内聚,低耦合”。开发人员分工更明确

业务逻辑层

创建 UserService 接口,用于专门处理用户相关的业务逻辑,比如用户登录,注册,修改密码等

创建接口的实现类,在实现类里实现业务相关逻辑

为什么要创建接口,再创建实现类去实现接口呢?直接创建类,在类里实现业务逻辑不行吗?

当然可以,不过面向接口有很多优点。比如解耦,当实现类需要改变,不会影响 Servlet 层。还有规范化等优点

数据访问层

创建 UserDao 接口,并创建实现类,和业务逻辑层同理

在接口定义抽象方法

1. 在 Dao 层操作数据库

在实现类实现接口,并把 Servlet 层的关于数据库操作的代码放到实现类里

package com.shao.Dao.Impl;import com.shao.Dao.UserDao;
import com.shao.Utils.DBConnectUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;public class UserDaoImpl implements UserDao {@Overridepublic int Login(String account, String password) {Connection connection = null;PreparedStatement pstmt = null;ResultSet resultSet = null;int result = 0;try {// 3. 获取数据库连接connection = DBConnectUtil.getConnection();// 4. 获取可执行对象String SQL = "select count(*) from train.users where account = ? and password = ?";pstmt = connection.prepareStatement(SQL);// 设置占位符的值pstmt.setString(1, account);pstmt.setString(2, password);// 5. 执行sql语句,获取结果集resultSet = pstmt.executeQuery();// 6. 结果处理if (resultSet.next() && resultSet.getInt(1) > 0) {// 表示可以查询到数据result = 1;}} catch (Exception e) {e.printStackTrace();} finally {// 7. 释放资源DBConnectUtil.releaseSource(connection, pstmt, resultSet);}// 返回结果给业务逻辑层return result;}
}

2. 调用 Dao 层,实现业务逻辑功能

在 Service 层调用 Dao 层,并实现业务逻辑功能

package com.shao.Service.Impl;import com.shao.Dao.Impl.UserDaoImpl;
import com.shao.Dao.UserDao;
import com.shao.Service.UserService;
import com.shao.Utils.responseDTO;public class UserServiceImpl implements UserService {// 创建一个UserDao的实现类对象private UserDao userDao = new UserDaoImpl();@Overridepublic responseDTO Login(String account, String password) {// 调用UserDao的Login方法int login = userDao.Login(account, password);// 判断是否登录成功if (login == 1) {return new responseDTO(200, null, "登录成功");} else {return new responseDTO(201, null, "账号或密码错误");}}
}

3. 调用 Service 层,响应数据

在 Servlet 层调用 Service 层,然后把业务逻辑层返回的数据响应到客户端

package com.shao.Servlet;import com.alibaba.fastjson2.JSON;
import com.shao.Service.Impl.UserServiceImpl;
import com.shao.Service.UserService;
import com.shao.Utils.responseDTO;
import com.shao.net.HttpRequest;
import com.shao.net.HttpResponse;public class LoginServlet extends BaseServlet {responseDTO responseDTO = null;public void doGet(HttpRequest request, HttpResponse response) {// 获取请求参数String account = request.getRequestBodyParams().get("account");String pwd = request.getRequestBodyParams().get("password");// 调用 Service 层的Login方法UserService userService = new UserServiceImpl();responseDTO = userService.Login(account, pwd);// 响应数据response.send(JSON.toJSONBytes(responseDTO));}public void doPost(HttpRequest request, HttpResponse response) {responseDTO = new responseDTO(400, null, "不支持POST提交方法");response.send(JSON.toJSONBytes(responseDTO));}
}

测试

三、数据库连接池

在测试的时候,我们可能会发现,第一次登录的时候,数据响应会比较慢,第二次之后就比较快了

这是因为第一次登录需要与数据库进行连接,第二次访问时,数据库已经准备好了,所以比较快

而且,当用户很多时,发起一次请求就需要建立一个数据库连接,不用了就断开连接,这样比较消耗资源,也比较耗时

那如何解决这个问题呢?

解决方案是使用数据库连接池,在系统空闲的时候,创建好数据库连接,当用户发起请求后就从连接池取出一条连接使用,当用完了再把连接放到连接池中,这样就节约了资源,也提升了效率

数据库连接池可以使用市面上的,比如Druid,Apache DBCP 等

1. 手写数据库连接池

这里我们手写一个简单的数据库连接池

在设计数据库连接池之前,我们需要确定,这个连接池一个就可以了,所以连接池的类就只能有一个实例(对象),这就可以用到单例设计模式。使用哪种方式创建单例模式,如果使用饿汉式,需要提前加载好连接池

2. 创建数据库连接池的类

package com.shao.Utils;import java.sql.Connection;
import java.util.LinkedList;public class DBConnectPool {// 定义一个双向链表,存放连接private static final LinkedList<Connection> connectionPool = new LinkedList<>();// 连接池最大连接数private static final int maxSize = 10;// 定义一个成员变量,存储单例对象private static DBConnectPool dbConPool;// 静态代码块,在类加载时,就会执行代码块,且只执行一次// 调用工具类获取连接,然后添加到连接池中static {for (int i = 0; i < maxSize; i++) {Connection connection = DBConnectUtil.getConnection();if (connection != null) {connectionPool.add(connection);}}}// 私有构造方法,防止外部实例化private DBConnectPool() {}// 对外提供一个接口,用于获取DBConnectPool对象public static DBConnectPool getInstance() {synchronized (DBConnectPool.class) {if (dbConPool == null) {dbConPool = new DBConnectPool();}return dbConPool;}}// 获取连接public Connection getConnection() {// 从连接池删除一个连接,然后把连接返回// 以同步的方法获取连接,保证线程安全synchronized (DBConnectPool.class) {Connection poll = connectionPool.poll();return poll;}}// 释放连接public void releaseConnection(Connection connection) {if (connection == null) {return;}//把连接放回连接池synchronized (DBConnectPool.class) {connectionPool.add(connection);}}
}

3. 初始化连接池

用饿汉式创建连接池,所以需要在启动 Tomcat 的时候就加载好连接池

4. 在 Dao 层获取数据库连接

5. 归还数据库连接

在数据库连接工具类的释放资源的方法中可以删掉释放数据库连接的参数,改为使用连接池的归还连接的方法

作业

1. 3w1h的方式,了解单例模式

2. 了解其他连接池

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148188.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

2024年9月19日---关于ES6(2)

五 异步编程 5.1 回调函数 5.1.1 概念 回调函数(callback function)&#xff0c;当一个函数作为参数传入另一个参数中&#xff0c;并且它不会立即执行&#xff0c;只有当满足一定条件后该函数才可以执行&#xff0c;这种函数就称为回调函数。 你可以将其理解为 回头再调用的…

GNU编译器(GCC):编译的4个过程及.elf、.list、.map文件功能说明

0 参考资料 GNU-LD-v2.30-中文手册.pdf GNU linker.pdf1 前言 一个完整的编译工具链应该包含以下4个部分&#xff1a; &#xff08;1&#xff09;编译器 &#xff08;2&#xff09;汇编器 &#xff08;3&#xff09;链接器 &#xff08;4&#xff09;lib库 在GNU工具链中&…

开源 AI 智能名片 S2B2C 商城小程序与营销工具的快速迭代

摘要&#xff1a;本文以开源 AI 智能名片 S2B2C 商城小程序为研究对象&#xff0c;探讨在营销工具快速迭代的背景下&#xff0c;该小程序如何借鉴以拼多多为代表的“小程序拼团”、以蘑菇街为代表的“小程序直播”、以花点时间为代表的“小程序按月订花”等经典案例&#xff0c…

数据集-目标检测系列-摩托车检测数据集 motorcycle >> DataBall

数据集-目标检测系列-摩托车检测数据集 motorcycle >> DataBall 数据集-目标检测系列-摩托车&#xff08;motorcycle&#xff09;检测数据集 数据量&#xff1a;1W 想要进一步了解&#xff0c;请联系 DataBall。 DataBall 助力快速掌握数据集的信息和使用方式&#xf…

《论软件架构建模技术与应用》写作框架,软考高级系统架构设计师

论文真题 软件架构风格是描述一类特定应用领域中系统组织方式的惯用模式&#xff0c;反映了领域中诸多系统所共有的结构特征和语义特征&#xff0c;并指导如何将各个模块和子系统有效组织成一个完整的系统。分层架构是一种常见的软件架构风格&#xff0c;能够有效简化设计&…

Python语法进阶之路

一、Python基础 1.1 注释 定义和作用 对代码解释说明&#xff0c;增强可读性 单行注释 # 多行注释 """ 这是一个多行注释 """ 1.2 变量及变量类型 定义和作用 计算机目的是计算&#xff0c;编程是为了更方便计算&#xff0c;计算对象就是…

论前端框架的对比和选择 依据 前端框架的误区

前端框架的对比和选择依据 在前端开发中&#xff0c;有多种框架可供选择&#xff0c;以下是一些常见前端框架的对比和选择依据&#xff1a; 一、Vue.js 特点&#xff1a; 渐进式框架&#xff0c;灵活度高&#xff0c;可以逐步引入到项目中。学习曲线相对较平缓&#xff0c;容…

Attention is All You Need精读

原文开头&#xff0c;不是搬运 dog。All attention is all you need Abstract 摘要 这篇文章的内容源于基于编码器-解码器架构的RNN模型&#xff0c;在其他人的工作中&#xff0c;我们可以发现注意力机制对于提升编码器-解码器架构模型的性能很重要。这篇文章提出了一个比较简…

SpringBoot 更改启动图标

每次springboot开启时&#xff0c;开会显示spring的图标&#xff0c;这个图标是可以修改的。 一、原始的图标样式 二、修改图标样式 https://patorjk.com/software/taag/#pdisplay&fGraffiti&thttps://patorjk.com/software/taag/#pdisplay&fGraffiti&t 在…

MMROTATE 1.X特征图可视化(绘制Heat Map)

本文参考MMYOLO官方的特征图可视化教程&#xff0c;对MMROTATE相关算法进行特征图可视化 1. 新建featmap_vis_demo.py文件 在mmrotate项目文件夹下新建 featmap_vis_demo.py &#xff1a; # Copyright (c) OpenMMLab. All rights reserved. import argparse import os from t…

“吉林一号”宽幅02B系列卫星

离轴四反光学成像系统 1.光学系统参数&#xff1a; 焦距&#xff1a;77.5mm&#xff1b; F/#&#xff1a;7.4&#xff1b; 视场&#xff1a;≥56゜&#xff1b; 光谱范围&#xff1a;400nm&#xff5e;1000nm。 2.说明&#xff1a; 光学系统采用离轴全反射式结构&#xff0c;整…

CIM平台应用的一些思考

今天中午看了一些书&#xff0c;讲致幻剂在疾病治疗的一些作用。致幻剂包括毒蘑菇等这类东西&#xff0c;有精神疾病或其他心里疾病的患者在吸食或注射&#xff08;专业医生的指导下&#xff09;会忘记或减轻身体的痛苦&#xff0c;忘记死亡&#xff0c;相信永生&#xff0c;治…

VMWare虚拟机安装CentOS-7-x86_64-DVD-1611操作系统

VMWare虚拟机安装CentOS7操作系统 1、虚拟机准备打开VMware单机创建新的虚拟机典型与自定义安装选择虚拟机硬件兼容性选择安装程序光盘映射文件(iso)选择客户机操作系统命名虚拟机处理器配置内存配置网络连接类型I/O类型选择磁盘类型选择磁盘指定磁盘的最大磁盘大小磁盘名称我们…

高中数学:立体几何-平面的定义与公理

文章目录 一、平面定义及画法1、定义2、表示方法 二、公理1、公理12、公理23、公理3 一、平面定义及画法 1、定义 平面是向四周无限延展的。 2、表示方法 我们常用矩形的直观图&#xff0c;即平行四边形表示平面&#xff0e; 我们常用希腊字母α&#xff0c;β&#xff0c…

八. 实战:CUDA-BEVFusion部署分析-coordTrans Precomputation

目录 前言0. 简述1. 案例运行2. coordTrans3. Precomputation总结下载链接参考 前言 自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第八章—实战&#xff1a;CUDA-BEVFusion部署分…

『正版软件』XYplorer 专业的 Windows 文件管理工具软件

在数字化时代&#xff0c;我们每天都在与各种文件打交道。无论是工作文档、个人照片还是多媒体资料&#xff0c;管理这些文件的效率直接关系到我们的工作效率和生活体验。今天&#xff0c;我要向大家推荐一款功能强大、操作简便的文件管理软件 —— XYplorer。 XYplorer&#x…

【小bug】使用 RestTemplate 工具从 JSON 数据反序列化为 Java 对象时报类型转换异常

起因&#xff1a;今天编写一个请求时需要通过RestTemplate调用外部接口&#xff0c;获取一些信息&#xff0c;但是在获取了外部接口响应内容后&#xff0c;使用强制转换发现报了类型转换异常。之前也遇到过&#xff0c;但是没记录下来&#xff0c;今天又查了一遍……干脆记录一…

【hot100-java】【搜索旋转排序数组】

R8-二分查找篇 等等&#xff0c;不是&#xff1f;O(logn)&#xff1f;那岂不是一次遍历数组都超时了hh. 二分查找分类 class Solution {public int search(int[] nums, int target) {if (numsnull||nums.length0){return -1;}int start0;int endnums.length-1;int mid;while …

以太坊客户端Geth的介绍与搭建

一、以太坊客户端 1.介绍 以太坊客户端是指用于连接、交互和参与以太坊区块链网络的软件。以太坊客户端允许用户执行各种操作&#xff0c;如发送交易、挖矿、部署智能合约、同步区块链数据等。 2.功能 区块链同步&#xff1a;客户端会下载并验证以太坊区块链的所有区块&…

windows 出现身份验证错误,要求的函数不受支持

现象环境&#xff1a; win10 mstsc内网远程server2016&#xff0c;出现错误代码&#xff1a; 远程桌面连接出现身份验证错误。要求的函数不受支持。这可能是由于CredSSP加密数据库修正 出现身份验证错误 原因&#xff1a; 系统更新&#xff0c;微软系统补丁的更新将 Cred…