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

【Spring+MyBatis】留言墙的实现

目录

1. 添加依赖

2. 配置数据库

2.1 创建数据库与数据表

2.2 创建与数据库对应的实体类

3. 后端代码

3.1 目录结构

3.2 MessageController类

3.3 MessageService类

3.4 MessageMapper接口

4. 前端代码

5. 单元测试

5.1 后端接口测试

5.2 使用前端页面测试


在Spring专栏中,已经实现了Spring MVC版的留言墙,详见下文:

【SpringMVC】_SpringMVC实现留言墙_使用springmvc完成一个简单的留言板-CSDN博客文章浏览阅读994次,点赞24次,收藏17次。1、请求:/message/publish2、参数:使用对象MessageInfo进行存储参数:3、响应:true/false;_使用springmvc完成一个简单的留言板 https://blog.csdn.net/m0_63299495/article/details/139359758该版本的消息存储采用了List<MessageInfo>存储,每次重启服务器就会导致信息丢失。

本文基于上文,对表白墙系统进行持久化。

1. 添加依赖

在pom.xml文件中使用Alt+insert快捷键,在EditStarters中选择MyBatis与Mysql的相关依赖:

并在maven面板中进行刷新;

2. 配置数据库

2.1 创建数据库与数据表

创建数据库,名为message:

在该库下创建messgae_info数据表:

CREATE TABLE `message_info` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`from` VARCHAR ( 127 ) NOT NULL,
`to` VARCHAR ( 127 ) NOT NULL,
`message` VARCHAR ( 256 ) NOT NULL,
`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),
PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

在application.yml中进行数据库与MyBatis的相关配置:

# 端口配置
server:port: 8080
# 数据库连接配置
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/message?characterEncoding=utf8&useSSL=falseusername: rootpassword: xxxxxxdriver-class-name: com.mysql.cj.jdbc.Driver
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #配置打印MyBatis日志map-underscore-to-camel-case: true   #配置转换驼峰

2.2 创建与数据库对应的实体类

修改MessageInfo类,增加id、deleteFlag、createTime、uodateTime属性与数据表字段对应:

package com.example.springbootdemo2.controller;import lombok.Data;
import java.util.Date;@Data
public class MessageInfo {private Integer id;private String from;private String to;private String message;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

3. 后端代码

3.1 目录结构

创建controller、service、mapper、model包,并创建对应类或接口:

其中,MessageController类主要功能:

(1)参数校验;(2)调用MessageService进行业务逻辑操作;

MessageService类主要功能:

(1)调用MessageMapper接口进行数据库操作;

MessageMapper接口主要功能:

(1)执行SQL语句;

3.2 MessageController类

package com.example.springbootdemo2.controller;import com.example.springbootdemo2.model.MessageInfo;
import com.example.springbootdemo2.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;// 新增留言
@RequestMapping("/message")
@RestController
public class MessageController {@Autowiredprivate MessageService messageService;@RequestMapping("/publish")public Boolean publishMessage(MessageInfo messageInfo){// 参数校验:Controllerif(!StringUtils.hasLength(messageInfo.getFrom())|| !StringUtils.hasLength(messageInfo.getTo())|| !StringUtils.hasLength(messageInfo.getMessage())){return false;}// 添加留言:ServicemessageService.addMessage(messageInfo);return true;}// 返回所有留言信息@RequestMapping("/getMessageList")public List<MessageInfo> getMessageList(){return messageService.getMessageInfo();}
}

3.3 MessageService类

package com.example.springbootdemo2.service;import com.example.springbootdemo2.mapper.MessageMapper;
import com.example.springbootdemo2.model.MessageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class MessageService {@Autowiredprivate MessageMapper messageMapper;public void addMessage(MessageInfo messageInfo){messageMapper.insertMessage(messageInfo);}public List<MessageInfo> getMessageInfo(){return messageMapper.selectAllMessage();}
}

3.4 MessageMapper接口

package com.example.springbootdemo2.mapper;import com.example.springbootdemo2.model.MessageInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface MessageMapper {@Insert("insert into message_info(`from`,`to`,`message`) values (#{from},#{to},#{message})")void insertMessage(MessageInfo messageInfo);@Select("select* from message_info where delete_flag=0")List<MessageInfo> selectAllMessage();
}

4. 前端代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>留言板</title><style>.container {width: 350px;height: 300px;margin: 0 auto;/* border: 1px black solid; */text-align: center;}.grey {color: grey;}.container .row {width: 350px;height: 40px;display: flex;justify-content: space-between;align-items: center;}.container .row input {width: 260px;height: 30px;}#submit {width: 350px;height: 40px;background-color: orange;color: white;border: none;margin: 10px;border-radius: 5px;font-size: 20px;}</style>
</head><body>
<div class="container"><h1>留言板</h1><p class="grey">输入后点击提交, 会将信息显示下方空白处</p><div class="row"><span>谁:</span> <input type="text" name="" id="from"></div><div class="row"><span>对谁:</span> <input type="text" name="" id="to"></div><div class="row"><span>说什么:</span> <input type="text" name="" id="say"></div><input type="button" value="提交" id="submit" onclick="submit()"><!-- <div>A 对 B 说: hello</div> -->
</div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>// 页面加载时,请求后端获取留言列表(代码位置不限)$.ajax({url:"/message/getMessageList",type:"get",success:function(messages){// 参数为后端返回结果(变量名任意)for(var m of messages){// 拼接留言// 拼接节点的HTML,直接将HTML添加到container中var divE = "<div>" + m.from + "对" + m.to + "说:" + m.message + "</div>";// 把节点添加到页面上$(".container").append(divE);}}})function submit() {//1. 获取留言的内容var from = $('#from').val();var to = $('#to').val();var say = $('#say').val();if (from == '' || to == '' || say == '') {return;}// 提交留言$.ajax({url: "/message/publish",type: "post",data: {"from": from,"to": to,"message": say},success: function (result) {if (result) {// 留言添加成功//2. 拼接节点的HTML,直接将HTML添加到container中// document.createElement('div');var divE = "<div>" + from + "对" + to + "说:" + say + "</div>";//3. 把节点添加到页面上$(".container").append(divE);//4. 清空输入框的值$('#from').val("");$('#to').val("");$('#say').val("");} else {// 留言添加失败alert("留言发布失败")}}})}</script>
</body></html>

5. 单元测试

5.1 后端接口测试

(可以使用postman或Chrome)

可以在服务器日志中查看到相关信息:

需在数据库中进行是否成功的验证:

5.2 使用前端页面测试

可以在服务器日志中查看到相关信息:

需在数据库中进行是否成功的验证:

一般报错检错步骤:

(1)根据后端接口使用postman或Chrome构造请求,检查后端代码是否有错;

若后端接口访问无错误则说明错误出现在前端或前后端交互;

(2)若使用Chrome,则按F12看浏览器是否报错,根据报错信息定位错误代码;

若无错误则需检查请求是否发往后端,可以在后端服务器对应方法处打印日志(使用slf4j),若前端进行操作后,后端服务器处没有执行改行日志的代码,则说明前后端交互处出现错误;

(3)若后端、前后端交互、前端均没有出现问题,可以进行清除前端与后端缓存;

相关文章:

【Spring+MyBatis】留言墙的实现

目录 1. 添加依赖 2. 配置数据库 2.1 创建数据库与数据表 2.2 创建与数据库对应的实体类 3. 后端代码 3.1 目录结构 3.2 MessageController类 3.3 MessageService类 3.4 MessageMapper接口 4. 前端代码 5. 单元测试 5.1 后端接口测试 5.2 使用前端页面测试 在Spri…...

让编程变成一种享受-明基RD320U显示器

引言 作为一名有着多年JAVA开发经验的从业者&#xff0c;在工作过程中&#xff0c;显示器的重要性不言而喻。它不仅是我们与代码交互的窗口&#xff0c;更是影响工作效率和体验的关键因素。在多年的编程生涯中&#xff0c;我遇到过各种各样的问题。比如&#xff0c;在进行代码…...

【嵌入式Linux应用开发基础】fork()函数

目录 一、fork 函数概述 1.1. 函数作用 1.2. 函数原型与头文件 1.3. 返回值 1.4. 核心特性 二、父子进程的区别与联系 2.1. 相同点 2.2. 不同点 三、典型应用场景 3.1. 多任务处理 3.2. 守护进程创建 3.3. 执行外部程序 3.4. 并行计算 四、fork 函数的关键注意事…...

2024 年 CSDN 博客之星年度评选:技术创作与影响力的碰撞(统计时间2025-02-17 11:06:06)

摘要&#xff1a;在技术的海洋里&#xff0c;每一位博主都像是一座独特的灯塔&#xff0c;用自己创作的光芒照亮他人前行的道路。2024 年 CSDN 博客之星年度评选活动&#xff0c;正是对这些灯塔的一次盛大检阅&#xff0c;让我们看到了众多优秀博主在技术创作领域的卓越表现以及…...

串的基本操作--数据结构

目录 一、串的基本概述 二、串的存储结构 2.1定义属性存储结构 串长有两种表示方法: 1、用一个额外的变量length来存放串的长度&#xff1b; 2、串值后面加一个不计入串长的结束标记字符“\0”&#xff0c;此时的串长为隐含值。 2.2堆的顺序存储结构 三、串的基本操…...

Unity 命令行设置运行在指定的显卡上

设置运行在指定的显卡上 -force-device-index...

Dest1ny漏洞库: 美团代付微信小程序系统任意文件读取漏洞

大家好&#xff0c;今天是Dest1ny漏洞库的专题&#xff01;&#xff01; 会时不时发送新的漏洞资讯&#xff01;&#xff01; 大家多多关注&#xff0c;多多点赞&#xff01;&#xff01;&#xff01; 0x01 产品简介 美团代付微信小程序系统是美团点评旗下的一款基于微信小程…...

设计模式:状态模式

状态机有3个要素&#xff1a;状态&#xff0c;事件&#xff0c;动作。 假如一个对象有3个状态:S1、S2、S3。影响状态的事件有3个&#xff1a;E1、E2、E3。每个状态下收到对应事件的时候&#xff0c;对象的动作为AXY。那么该对象的状态机就可以用如下表格来表示。S1收到事件E1的…...

【故障处理】- 执行命令crsctl query crs xxx一直hang

【故障处理】- 执行命令crsctl query crs xxx一直hang 一、概述二、故障处理三、解决方法 一、概述 Oracle RAC环境中&#xff0c;遇到执行crsctl query crs xxx等相关命令不返回任何结果&#xff0c;一直hang在那里。系统下执行命令ps -ef |grep crsctl query crs softwarever…...

Zabbix——监控Nginx

背景 在项目中使用Nginx之后&#xff0c;有时候我们需要知道Nginx具体的工作情况&#xff0c;这时候就需要使用zabbix进行Nginx的相关监控 这边我们有两种方法 使用普通的http请求的方式获取基本信息如果使用了Nginx Plus&#xff0c;就可以通过Nginx Plus的接口获取更多的信…...

开源工具推荐--思维导图、流程图等绘制

1. 前言 在工作中&#xff0c;经常要用到各种不同的工具&#xff0c;随着系统的升级&#xff0c;有些工具也在不断更新升级。这里收集整理一些好用的开源工具推荐&#xff0c;遵循以下一些基本原则&#xff1a;开源免费&#xff0c;商业工具的有效平替&#xff0c;轻量级&…...

【论文笔记】Transformer^2: 自适应大型语言模型

Code repo: https://github.com/SakanaAI/self-adaptive-llms 摘要 自适应大型语言模型&#xff08;LLMs&#xff09;旨在解决传统微调方法的挑战&#xff0c;这些方法通常计算密集且难以处理多样化的任务。本文介绍了Transformer&#xff08;Transformer-Squared&#xff09;…...

FFmpeg源码:av_strlcpy函数分析

一、引言 在C/C编程中经常会用到strcpy这个字符串复制函数。strcpy是C/C中的一个标准函数&#xff0c;可以把含有\0结束符的字符串复制到另一个地址空间。但是strcpy不会检查目标数组dst的大小是否足以容纳源字符串src&#xff0c;如果目标数组太小&#xff0c;将会导致缓冲区…...

Unity Shader学习6:多盏平行光+点光源 ( 逐像素 ) 前向渲染 (Built-In)

0 、分析 在前向渲染中&#xff0c;对于逐像素光源来说&#xff0c;①ForwardBase中只计算一个平行光&#xff0c;其他的光都是在FowardAdd中计算的&#xff0c;所以为了能够渲染出其他的光照&#xff0c;需要在第二个Pass中再来一遍光照计算。 而有所区别的操作是&#xff0…...

docker批量pull/save/load/tag/push镜像shell脚本

目录 注意&#xff1a; 脚本内容 执行效果 注意&#xff1a; 以下脚本为shell脚本通过docker/nerdctl进行镜像独立打包镜像的相关操作脚本内仓库信息和镜像存取路径需自行更改需自行创建images.txt并填写值&#xff0c;并且与脚本位于同级目录下 [rootmaster01 sulibao]# l…...

五十天精通硬件设计第32天-S参数

系列文章传送门 50天精通硬件设计第一天-总体规划-CSDN博客 目录 1. S参数基础 2. S参数在信号完整性中的作用 3. 单端 vs. 差分S参数 4. S参数的关键特性 5. S参数的获取与使用 6. S参数分析中的常见问题 7. 实际案例:PCIe通道分析 8. 工具推荐 总结 信号完整性中…...

6.2.4 基本的数据模型

文章目录 基本的数据模型 基本的数据模型 基本的数据模型包含层次模型&#xff0c;网状模型和关系模型。 层次模型&#xff1a;使用树型结构表示数据间联系。记录间的联系用指针实现&#xff0c;简单高效。但是只能表示1:n的联系&#xff0c;且对插入、删除的限制多。网状模型…...

DeepSeek ,银行营销会被 AIGC 颠覆吗?

AI 让银行营销更智能&#xff0c;但更重要的是“懂客户” AI 在银行营销中的应用已经不仅仅局限于文案生成&#xff0c;而是渗透到了整个营销流程。 据悉&#xff0c;中国银行已经开始利用 AI 大模型构建智能营销助手系统&#xff0c;结合知识图谱和 AI 技术&#xff0c;实现…...

第150场双周赛:好数字之和、分割正方形 Ⅰ、分割正方形 Ⅱ、最短匹配字符串

Q1、好数字之和 1、题目描述 给定一个整数数组 nums 和一个整数 k&#xff0c;如果元素 nums[i] 严格 大于下标 i - k 和 i k 处的元素&#xff08;如果这些元素存在&#xff09;&#xff0c;则该元素 nums[i] 被认为是 好 的。如果这两个下标都不存在&#xff0c;那么 nums…...

HDFS是如何存储和管理大数据

HDFS&#xff08;Hadoop Distributed File System&#xff0c;Hadoop分布式文件系统&#xff09;是专为大数据处理而设计的分布式文件系统&#xff0c;具有高吞吐量、高容错性等特点&#xff0c;适用于大规模数据存储和管理。以下是HDFS存储和管理大数据的详细机制&#xff1a;…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...