当前位置: 首页 > news >正文

【JavaEE初阶】Servlet (三)MessageWall

在我们之前博客中写到的留言墙页面,有很严重的问题:(留言墙博客)

  1. 如果刷新页面/关闭页面重开,之前输入的消息就不见了.
  2. 如果一个机器上输入了数据,第二个机器上是看不到的.

针对以上问题,我们的解决思如如下:
让服务器来存储用户提交的数据,由服务器保存.
当有新的浏览器打开页面的时候,从服务器获取数据.

此时服务器就可以用来存档和读档.

设计程序:
写web程序,务必要重点考虑前后端如何交互,约定好前后端交互的数据格式.
设计前后端交互接口: 1.请求是什么样 2. 响应是什么样 3.浏览器什么时候发送这个请求 4. 浏览器按照什么格式来解析

在我们的留言墙程序中,以下环节涉及到前后端交互:

  1. 点击提交,浏览器把表白墙信息发送到服务器这里
  2. 页面加载,浏览器从服务器获取到表白信息.
  1. 点击提交,浏览器把表白墙信息发送到服务器这里
    请求:
    POST/message
    按照json格式:
{from:"i",to:"you",message:"hello"
}

响应:
HTTP/1.1 200 OK

  1. 页面加载,浏览器从服务器获取到表白信息.
    请求:
    GET/message
    响应:
    HTTP/1.1 200 OK
    body部分:
[{from:"i",to:"you",message:"hello"}{from:"i",to:"you",message:"hello"}
]

此处约定的目的是为了前端代码和后端代码能够对应上.约定的方式可以有很多种.
通过约定,我们可以写出后端代码为:

import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;class Message{public String from;public String to;public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {private List<Message> messageList = new ArrayList<>();ObjectMapper objectMapper = new ObjectMapper();//    向服务器提交数据@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//读取body中的内容,解析成 Message 对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//保存messageList.add(message);//设置状态码resp.setStatus(200);}//    从服务器获取数据@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//显示告诉浏览器,数据是 json 格式,字符集是 utf8resp.setContentType("application/json;charset=utf8");//通过 writeValue 将 messageList(java对象) 转成 json 格式并将其写入 resp 中//objectMapper.writeValue(resp.getWriter(),messageList);//把java对象转成json字符串String jsonResp = objectMapper.writeValueAsString(messageList);System.out.println("jsonResp: "+jsonResp);//把这个字符串写回到响应 body 中resp.getWriter().write(jsonResp);}
}

通过Postman 构造POST请求,使用json语法编辑body部分,点击两次发送,再通过GET获取得到响应如下:
在这里插入图片描述
存档:
其次,我们再看前端代码:在前端代码中使用ajax发送一个post请求.
在这里插入图片描述
通过fiddler得到:
在这里插入图片描述
通过dopost 执行:
在这里插入图片描述
通过resp.setStatus(200);回到回调函数:
在这里插入图片描述
读档:根据ajax创建GET响应:
在这里插入图片描述
打开fiddler可以看到:
在这里插入图片描述
GET请求触发doGet方法:
在这里插入图片描述
我们可以得到完整的前端代码(包含撤销功能):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>MessageBoard</title><style>*{/* 消除浏览器的默认样式 */margin: 0;padding: 0;/* 保证盒子不会撑大 */box-sizing: border-box;/* background-color: rgba(255, 192, 203, 0.436); */}.container{width: 600px;margin: 20px auto;}h1 {text-align: center;}p {text-align: center;color: #666;margin: 20px 0;}.row {/* 开启弹性布局 */display: flex;height: 40px;/* 水平方向居中 */justify-content: center;/* 垂直方向居中 */align-items: center;}.row span {width: 80px;}.row input {width: 200px;height: 30px;}.row button {width: 280px;height: 30px;color: white;background-color: orange;/* 去掉边框 */border: none;border-radius: 5px;}/* 点击的时候有个反馈 */.row button:active {background-color: grey;}</style>
</head>
<body><div class="container"><h1>留言板</h1><p>输入内容后点击提交,信息会显示到下方表格中</p><div class="row"><span>谁:</span><input type="text"></div><div class="row"><span>对谁:</span><input type="text"></div><div class="row"><span>说:</span><input type="text"></div><div class="row"><button id="submit">提交</button></div><div class="row"><button id="revert">撤销</button></div></div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script><script>//实现提交操作,点击提交,就能够吧用户输入的内容提交到页面上显示//点击时,获取到三个输入框的文本内容//创建一个新的div.rom把内容构造到这个div中即可.let containerDiv = document.querySelector('.container');let inputs = document.querySelectorAll('input');let button = document.querySelector('#submit');button.onclick = function(){//1.获取到三个输入框的内容let from = inputs[0].value;let to = inputs[1].value;let msg = inputs[2].value;if(from == '' || to == '' || msg == ''){return;}//2.构造新的divlet rowDiv = document.createElement('div');rowDiv.className = 'row message';rowDiv.innerHTML = from +" 对 "+to+' 说 : '+msg;containerDiv.appendChild(rowDiv);//3.清空输入聊天框for(let input of inputs){input.value = '';}//4. [新增] 给服务器发起post请求,把上述数据提交到服务器//定义一个js对象let body = {from:from,to:to,message:msg};//将对象转成json字符串strBody = JSON.stringify(body);$.ajax({type:'post',url:'message',data:strBody,contentType:"application/json; charset=utf-8",success:function(body){console.log("发布成功.");}});}let revertButton = document.querySelector('#revert');revertButton.onclick = function(){//删除最后一条消息//选中所有的row,找出最后一个row,然后删除let rows = document.querySelectorAll('.message');if (rows == null || rows.length == 0) {return;}containerDiv.removeChild(rows[rows.length - 1]);//[新增]删除$.ajax({type: 'delete',url: 'message',success: function(body){// 1.先选中父元素ConversationDiv,然后删除所有子元素let ConversationDiv = document.querySelector('.Conversation');while(ConversationDiv.firstChild){ConversationDiv.removeChild(ConversationDiv.firstChild)}for(let message of body){// 2.对响应数据内容进行页面显示,对每一个message元素构造一个divlet resultDiv = document.createElement('div');resultDiv.className = 'row message result';resultDiv.innerHTML = message.from + ' 对: ' + message.to + ' 说: ' + message.message;ConversationDiv.appendChild(resultDiv);}}})}//[新增]在页面加载的时候,发送GET请求,从服务器获取到数据并添加到页面中$.ajax({type:'get',url:'message',success:function(body){let containerDiv = document.querySelector('.container');for(let message of body){let rowDiv = document.createElement('div');rowDiv.className ='row message';rowDiv.innerHTML = message.from +' 对 '+ message.to +' 说 : ' + message.message;containerDiv.appendChild(rowDiv);}}});</script>
</body>
</html>

在这里插入图片描述
刷新页面后数据也不会消失.
但是以上重启服务器后数据就消失了,所以我们可以把数据写入数据库中进行长久的保存.
C:\Users\xxxflower>mysql -uroot -p
Enter password: ****
create table message(from varchar(20),to varchar(20),message varchar(1024));
注意,由于from和to都是sql中的关键字,所以需要使用`.
创建表:
在这里插入图片描述
完整的后端代码:
MessageServlet.java:

import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;class Message{public String from;public String to;public String message;
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {//private List<Message> messageList = new ArrayList<>();private ObjectMapper objectMapper = new ObjectMapper();//    向服务器提交数据@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//读取body中的内容,解析成 Message 对象Message message = objectMapper.readValue(req.getInputStream(),Message.class);//保存save(message);//messageList.add(message);//设置状态码resp.setStatus(200);}//    从服务器获取数据@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//显示告诉浏览器,数据是 json 格式,字符集是 utf8resp.setContentType("application/json;charset=utf-8");//通过 writeValue 将 messageList(java对象) 转成 json 格式并将其写入 resp 中//objectMapper.writeValue(resp.getWriter(),messageList);//把java对象转成json字符串List<Message> messageList = load();String jsonResp = objectMapper.writeValueAsString(messageList);System.out.println("jsonResp: " + jsonResp);//把这个字符串写回到响应 body 中resp.getWriter().write(jsonResp);}//使用jdbc 往数据库里面存消息private void save(Message message) {//JDBCConnection connection = null;PreparedStatement statement = null;try {//1.建立连接connection = DBUtil.getConnection();//2.构造sql语句String sql = "insert into message values(?, ?, ?)";statement = connection.prepareStatement(sql);statement.setString(1,message.from);statement.setString(2,message.to);statement.setString(3,message.message);//3.执行sqlstatement.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);}finally {//4.关闭连接DBUtil.close(connection,statement,null);}}//从数据库取所有消息private List<Message> load(){List<Message> messageList = new ArrayList<>();Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {//1.与数据库建立连接connection = DBUtil.getConnection();//2.构造sqlString sql = "select * from message";statement = connection.prepareStatement(sql);//3.执行sqlresultSet = statement.executeQuery();//4.遍历集合while (resultSet.next()){Message message = new Message();message.from = resultSet.getString("from");message.to = resultSet.getString("to");message.message = resultSet.getString("message");messageList.add(message);}} catch (SQLException e) {e.printStackTrace();}finally {//5.释放资源 断开连接DBUtil.close(connection,statement,resultSet);}return messageList;}@Overrideprotected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json; charset=utf-8");// 从数据库获取所有表白信息// 1.获取最后一份表白信息,并从数据库删除List<Message> messageList = load();if(messageList.size() == 0){return;}Message messageEnd = messageList.get(messageList.size()-1);int count = delete(messageEnd);if(count == 1){System.out.println("留言信息删除成功");}else {System.out.println("留言信息删除失败");}// 2.获取删除最后一条信息后的 全部表白信息,并写回到浏览器messageList = load();objectMapper.writeValue(resp.getOutputStream(), messageList);}private int delete(Message message) {Connection connection = null;PreparedStatement preparedStatement = null;int count = 0;try {// 1.获取连接connection = DBUtil.getConnection();// 2.编写sqlString sql = "delete from message where `from` = ? and `to` = ? and message = ?";// 3.获取预编译对象,进行预编译preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, message.from);preparedStatement.setString(2, message.to);preparedStatement.setString(3, message.message);// 4.执行sql语句count = preparedStatement.executeUpdate();// 5.处理结果} catch (SQLException throwables) {throwables.printStackTrace();} finally {DBUtil.close(connection, preparedStatement, null);}return count;}
}

DBUtil:

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;//这个类用于封装数据库连接过程
//此处把 DBUtil 作为一个工具类,提供 static 方法供其他代码使用
public class DBUtil {//静态成员跟随类对象,类对象在整个进程中只有唯一一份//静态成员相当于也是唯一的实例(单例模式,饿汉模式)private static DataSource dataSource = new MysqlDataSource();//使用静态代码块针对 DataDource 进行初始化操作static {((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/javaee?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("0828");}//建立连接public static Connection getConnection() throws SQLException {return dataSource.getConnection();}//断开连接 释放资源public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}

最终实现效果:
请添加图片描述

相关文章:

【JavaEE初阶】Servlet (三)MessageWall

在我们之前博客中写到的留言墙页面,有很严重的问题:(留言墙博客) 如果刷新页面/关闭页面重开,之前输入的消息就不见了.如果一个机器上输入了数据,第二个机器上是看不到的. 针对以上问题,我们的解决思如如下: 让服务器来存储用户提交的数据,由服务器保存. 当有新的浏览器打开页…...

D. Make It Round

在Berlandia发生了通货膨胀&#xff0c;所以商店需要改变商品的价格。 商品n的当前价格已经给出。允许将该商品的价格提高k倍&#xff0c;1≤k≤m&#xff0c;k为整数。输出商品的最圆的可能的新价格。也就是在最后有最大数量的零的那个。 例如&#xff0c;数字481000比数字1…...

Python网站页面开发HTML总结

Python网站页面开发HTML总结 一、HTML基础语法 1.HTML是什么&#xff1f; ●HTML是HyperText Mark-up Language的首字母简写&#xff0c;即超文本标记语言。 ●HTML不是一种编程语言&#xff0c;而是一种标记语言。 ●超文本指的是超链接&#xff0c;标记指的是标签&#xf…...

[个人笔记] vCenter设置时区和NTP同步

VMware虚拟化 - 运维篇 第三章 vCenter设置时区和NTP同步 VMware虚拟化 - 运维篇系列文章回顾vCenter设置时区和NTP同步&#xff08;附加&#xff09;ESXi设置alias参考链接 系列文章回顾 第一章 vCenter给虚机添加RDM磁盘 第二章 vCenter回收活跃虚拟机的剩余可用空间 vCente…...

(原创)Flutter与Native通信的方式:EventChannel和BasicMessageChannel

前言 上一篇博客主要介绍了MethodChannel的使用方式 Flutter与Native通信的方式&#xff1a;MethodChannel 这篇博客接着讲另外两种通信方式 EventChannel和BasicMessageChannel EventChannel用于从native向flutter发送通知事件&#xff0c;例如flutter通过其监听Android的重…...

【解决】el-tree报Cannot read property ‘getCheckedKeys‘ of undefined

如果你报错 Cannot read property getCheckedKeys of undefined 或者 Cannot read property getCheckedNodes of undefined 只要在你的在<el-tree>上加个这个&#xff0c;就可以了 ref"tree"...

车载软件架构 —— 信息安全与基础软件

车载软件架构 —— 信息安全与基础软件 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕…...

C\C++内存管理

目录 1.C/C内存分布2.C语言中动态内存管理方式3.C中动态内存管理3.1new/delete内置类型3.2new和delete操作自定义类型 4.operator new与operator delete函数4.2重载operator new与operator delete&#xff08;了解&#xff09; 5.new和delete的实现原理5.1内置类型5.2 自定义类…...

会议室预约系统-检验是否被预约核心SQL

会议室预约时&#xff0c;判断能否被预约&#xff0c;即查询是否已经有预约记录&#xff0c;存在不能被预约。 s,e&#xff1b;表示已经预约的开始结束时间&#xff1b; ns,ne&#xff0c;表示表单提交的预约时间&#xff1b; 只需要(ns,ne)与(s,e)区间没有交集&#xff0c;可…...

C++11类模板

类模板是用来生成类的蓝图&#xff0c;与函数模板的不同之处是&#xff0c;编译器不能为类模板推断模板参数类型。 所以我们在使用类的时候要带上<>并且指定类型如下 vector<int> v; // 需要带上<int> 哦定义类模板 如下&#xff0c;和函数模板差不多都是…...

SpiderFlow爬虫平台(爬虫学习)

申明 作为自己学习的记录,方面后期查阅 官网 SpiderFlow官网 简介 spider-flow 是一个爬虫平台&#xff0c;以图形化方式定义爬虫流程&#xff0c;无需代码即可实现一个爬虫 是使用springboot开发的项目,后端代码直接运行即可使用...

Rime输入法配置

Rime输入法在我电脑上&#xff0c;删了装&#xff0c;装了删&#xff0c;已经反复好几次了。就像是Vim&#xff0c;用它的时候&#xff0c;感觉各种配置太麻烦&#xff0c;想要的功能不知道怎么实现。转用其它编辑器的时候&#xff0c;却又念着它的快捷键和可定制性&#xff0c…...

R语言学习笔记--列表list、数据框

列表 1-列表 列表可以包含不同类型的对象&#xff0c;也就是说&#xff0c;列表不是将某些具体的值组织起来&#xff0c;而是组织R对象。列表将数据组织在一个一维集合中。 列表非常好用&#xff0c;因为它可以装任何类型的对象&#xff0c;不要求数据之间是同质的。 创建列…...

电磁波定义、特性以及信道相关知识

文章目录 前言一、电磁波的定义、特性、波谱1、电磁波的特性2、电磁波谱的划分及用途 二、地球大气层的结构三、电磁波的传播方式1、地波&#xff08;ground-wave&#xff09;2、天波&#xff08;sky-wave&#xff09;3、视线传播&#xff08;line-of-sight&#xff09;①、相关…...

TCP KeepAlive与HTTP Keep-Alive

TCP KeepAlive与HTTP Keep-Alive TCP KeepAliveHTTP Keep-AliveTCP服务器怎么检测客户端断开连接 TCP KeepAlive TCP连接建立之后&#xff0c;如果应用程序或者上层协议一直不发送数据&#xff0c;或者隔很长时间才发送一次数据&#xff0c;那么TCP需要判断是应用程序掉线了还…...

SkyWalking链路追踪-Agent (代理人)

基础概念&#xff1a; SkyWalking链路追踪代理&#xff08;SkyWalking Tracing Agent&#xff09;是一种用于收集和传输链路追踪数据的工具。它与应用程序一起部署&#xff0c;并通过自动或手动方式来收集关于应用程序中的请求路径和操作的信息。该代理将收集到的数据发送到Sky…...

多线程案例 | 单例模式、阻塞队列、定时器、线程池

多线程案例 1、案例一&#xff1a;线程安全的单例模式 单例模式 单例模式是设计模式的一种 什么是设计模式&#xff1f; 设计模式好比象棋中的 “棋谱”&#xff0c;红方当头炮&#xff0c;黑方马来跳&#xff0c;针对红方的一些走法&#xff0c;黑方应招的时候有一些固定的…...

C++文件操作

1.写文件 //文件操作 #include<fstream> int main() {//写文件//路径 -- 此路径没有就生成给文件 string filePath R"(E:\项目\test.txt)";//打开文件 ios::app在后面追加内容 啥也不跟是覆盖写入ofstream fout(filePath, ios::app);//检查是否打开成功if (…...

overleaf(latex) 公式过大,需要调小字体,同时公式编号字体不变的方法

提问&#xff1a;用latex编辑的双列排版的论文中&#xff0c;如果一个包含矩阵的公式中&#xff0c;矩阵过大&#xff0c;导致超出列的范围&#xff0c;一般该如何调整呢&#xff1f; 回答&#xff1a;如果你在LaTeX中的双列排版中遇到了一个矩阵过大而导致超出列范围的问题&a…...

flink采用thrift读取tablets一个天坑

原先的配置 [INFO] StarRocksSourceBeReader [open Scan params.mem_limit 8589934592 B] [INFO] StarRocksSourceBeReader [open Scan params.query-timeout-s 600 s] [INFO] StarRocksSourceBeReader [open Scan params.keep-alive-min 100 min] [INFO] StarRocksSourceBeRea…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...