简易留言板

news2024/11/23 0:58:07

目录

前端实现

数据库的使用

创建数据表

创建项目

连接数据库

后端实现

接口定义

持久层

业务逻辑层

控制层

前端代码完善


留言板是一个常见的功能,在本篇文章中,将实现一个简易的留言板:

页面中能够显示所有留言内容,当点击发布留言后,内容会在下方空白处进行显示

前端实现

在这里,使用的是 HTML、CSS 和 JavaScript 实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简易留言板</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <style>
        .container {
            margin: 20px;
        }

        .submit {
            width: 150px;
            height: 40px;
            background-color: #ffb3a7;
            color: white;
            border: none;
            margin: 10px;
            border-radius: 5px;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>简易留言板</h1>
        <form id="messageForm">
            <label for="author">作者:</label>
            <input type="text" id="author" required><br>
            <label for="content">内容:</label><br>
            <textarea id="content" rows="4" cols="50" required></textarea><br>
            <button type="submit" class="submit">发布留言</button>
        </form>
    </div>
    
    <script>
        // 监听表单提交事件
        $('#messageForm').submit(function(event) {
            event.preventDefault(); // 阻止表单默认提交行为
            var author = $('#author').val();
            var content = $('#content').val();
            if (author && content) {
                //构造节点
                var divE = '<div>' + author + '留言:' + content;
                // 将节点添加到页面上
                $('.container').append(divE);
                // 清空表单输入框
                $('#author').val('');
                $('#content').val('');
            }else {
                alert('作者和内容不能为空!');
            }
        });
    </script>
</body>
</html>

当我们点击提交后,留言内容显示在下方空白处

当我们进行刷新时,数据就会丢失,要想数据不丢失,需要将数据存储在数据库中

数据库的使用

要想使用数据库存储数据,我们首先需要创建数据表

创建数据表

DROP TABLE IF EXISTS message_info;
CREATE TABLE `message_info` (
        `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
        `author` 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;

此时,创建出表 message_info

虽然当前实现的留言板不涉及更新和删除操作,但在这里仍然创建了字段 delete_flag、update_flag,若后续增加了相关功能,则不需要再对数据表进行修改

接下来我们使用 MyBatis 来实现数据的操作

创建项目

我们首先创建SpringBoot工程,并引入MyBatis 和 MySQL驱动依赖

连接数据库

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
    username: root
    password: 123123
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  configuration: #打印 MyBatis 日志
    map-underscore-to-camel-case: true #驼峰字段转换

连接好数据库后,我们就可以开始编写后端代码了

后端实现

我们首先创建留言对象 MessageInfo 类

package com.example.messageboard.model;

import lombok.Data;

import java.util.Date;

@Data
public class MessageInfo {
    private Integer id;
    private String author;
    private String message;
    private Integer deleteFlag;
    private Date createTime;
    private Date updateTime;
}

根据留言板的需求可看出,后端需要提供两个服务:

1. 添加留言:用户输入留言信息后,后端需要将留言信息存到数据库中

2. 显示留言:页面展示时,需要从后端获取到所有的留言信息

接口定义

添加留言

[URL]

POST /message/publish

[请求参数]

author=ppp&message=ppp

[响应]

true //添加成功

false //添加失败

显示留言

[URL]

GET /message/getList

[请求参数]

[响应]

返回留言列表

[

    {

        "id": 1,

        "author": "aa",

        "message": "aa",

        "deleteFlag": 0,

        "createTime": "2024-05-11T09:42:59.000+00:00",

        "updateTime": "2024-05-11T09:42:59.000+00:00"

    },

    {

        "id": 2,

        "author": "aa",

        "message": "aa",

        "deleteFlag": 0,

        "createTime": "2024-05-11T09:52:01.000+00:00",

        "updateTime": "2024-05-11T09:52:01.000+00:00"

    },

    {

        "id": 3,

        "author": "aa",

        "message": "aa",

        "deleteFlag": 0,

        "createTime": "2024-05-11T09:52:15.000+00:00",

        "updateTime": "2024-05-11T09:52:15.000+00:00"

    }

]

持久层

将应用程序的数据持久化到数据库中,并提供对数据库的访问操作

实现向数据库中添加留言和从数据库中查询所有留言:

package com.example.messageboard.mapper;

import com.example.messageboard.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 MessageInfoMapper {
    @Insert("insert into message_info (`author`, `message`) values (#{author}, #{message})")
    Integer addMessage(MessageInfo messageInfo);

    @Select("select `id`, `author`, `message`,`delete_flag`, `create_time`, `update_time` from message_info where delete_flag = 0")
    List<MessageInfo> queryAll();
}

业务逻辑层

处理具体的业务逻辑

由于留言板的功能简单,不需要进行其他的处理,因此,我们直接调用messageInfoMapper的方法并返回即可

package com.example.messageboard.service;

import com.example.messageboard.mapper.MessageInfoMapper;
import com.example.messageboard.model.MessageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class MessageInfoService {
    @Autowired
    private MessageInfoMapper messageInfoMapper;

    public int addMessage(MessageInfo messageInfo) {
        return messageInfoMapper.addMessage(messageInfo);
    }

    public List<MessageInfo> queryAll() {
        return messageInfoMapper.queryAll();
    }
}

控制层

接收前端发送的请求,对请求进行处理,并响应数据

添加留言:进行参数校验,校验通过后添加留言 

查询留言:返回留言列表

package com.example.messageboard.controller;

import com.example.messageboard.model.MessageInfo;
import com.example.messageboard.service.MessageInfoService;
import lombok.extern.slf4j.Slf4j;
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.List;

@RequestMapping("/message")
@RestController
@Slf4j
public class MessageInfoController {
    @Autowired
    private MessageInfoService messageInfoService;

    /**
     * 发布留言
     * @param messageInfo
     * @return
     */
    @RequestMapping("/publish")
    public boolean publish(MessageInfo messageInfo){
        log.info("接收到参数messageInfo: {}", messageInfo);
        //参数校验
        if(!StringUtils.hasLength(messageInfo.getAuthor()) 
                || !StringUtils.hasLength(messageInfo.getMessage())){
            return false;
        }
        int result = messageInfoService.addMessage(messageInfo);
        if(result > 0){
            return true;
        }
        return false;
    }

    /**
     * 获取留言列表
     * @return
     */
    @RequestMapping("/getList")
    public List<MessageInfo> getList(){
        return messageInfoService.queryAll();
    }
}

后端代码编写完成后,我们运行程序,并进行测试:

我们首先测试添加留言:

分别测试 添加成功、未输入昵称、未输入留言三种情况下的添加:

结果正确

我们再测试显示留言:

结果正确 

接下来,我们来完善客户端代码

前端代码完善

    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简易留言板</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <style>
        .container {
            margin: 20px;
        }

        .submit {
            width: 150px;
            height: 40px;
            background-color: #ffb3a7;
            color: white;
            border: none;
            margin: 10px;
            border-radius: 5px;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>简易留言板</h1>
        <form id="messageForm">
            <label for="author">作者:</label>
            <input type="text" id="author" required><br>
            <label for="content">内容:</label><br>
            <textarea id="content" rows="4" cols="50" required></textarea><br>
            <button type="submit" class="submit">发布留言</button>
        </form>
    </div>
    
    <script>
        //获取留言
        $.ajax({
            url: '/message/getList',
            method: 'GET',
            success: function(messageInfos) {
                // console.log(messageInfos);
                var divE = "";
                for(var message of messageInfos){
                    divE += '<div>' + message.author + '留言:' + message.message;
                }
                $('.container').append(divE);
                
            },
            error: function(error) {
                console.error('获取留言列表时发生错误:', error);
            }
        });

        // 监听表单提交事件
        $('#messageForm').submit(function(event) {
            event.preventDefault(); // 阻止表单默认提交行为
            var author = $('#author').val();
            var content = $('#content').val();
            if (author && content) {
                // 发送 AJAX 请求保存留言
                $.ajax({
                    url: '/message/publish',
                    method: 'POST',
                    data: { author: author, message: content },
                    success: function(result) {
                        console.log(result);
                        //构造节点
                        var divE = '<div>' + author + '留言:' + content;
                        // 将节点添加到页面上
                        $('.container').append(divE);
                        // 清空表单输入框
                        $('#author').val('');
                        $('#content').val('');

                    },
                    error: function(error) {
                        console.error('保存留言时发生错误:', error);
                    }
                });
            } else {
                alert('作者和内容不能为空!');
            }
        });
    </script>
</body>
</html>

最后,我们进行测试:

所有留言信息成功显示,且新添加的留言信息也在下方成功显示 

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

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

相关文章

刷代码随想录有感(63):将有序数组转换为二叉搜索树(其实时二叉平衡搜索树)

题干&#xff1a; 代码&#xff1a; class Solution { public:TreeNode* traversal(vector<int>& nums, int left, int right){if(left > right)return NULL;int mid left (right - left)/2;TreeNode* NewRoot new TreeNode(nums[mid]);NewRoot->left tra…

maven mirrorOf的作用

在工作中遇到了一个问题导致依赖下载不了&#xff0c;最后发现是mirror的问题&#xff0c;决定好好去看一下mirror的配置&#xff0c;以及mirrorOf的作用&#xff0c;以前都是直接复制过来使用&#xff0c;看了之后才明白什么意思。 过程 如果你设置了镜像&#xff0c;镜像会匹…

HIVE调优MapJoin

HIVE调优MapJoin 目录 HIVE调优MapJoin 1.mapjoin &#xff08;1.2以后自动默认启动mapjoin&#xff09; 2.创建表格 3.查询建表 4.通过 explain 展示执行计划 5.Map JOIN 相关设置&#xff1a; 1.mapjoin &#xff08;1.2以后自动默认启动mapjoin&#xff09;…

SpringBoot内置插件的使用(jackson和lombok)

文章目录 引言I lombok(自动为属性生成构造器)II jacksonsee also引言 idea2021.2.2 已经捆绑安装jackson和lombok插件 I lombok(自动为属性生成构造器) Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。 https://p…

【SpringBoot】Redis Lua脚本实战指南:简单高效的构建分布式多命令原子操作、分布式锁

文章目录 一.Lua脚本1.Lua特性2.Lua优势 二.Lua语法1.注释2.变量3.数据类型&#xff1a;3.1.基本类型3.2.对象类型&#xff1a;表&#xff08;table&#xff09; 4.控制结构&#xff1a;4.1.条件语句: 使用if、else和elseif来实现条件分支。4.2.循环结构&#xff1a;Lua支持for…

大模型面试常考知识点2

文章目录 1. LLM推理attention优化技术KV CachePageAttention显存优化MHA\GQA\MQA优化技术FlashAttention优化技术稀疏Attention1. Atrous Self Attention2. Local Self Attention3. Sparse Self Attention 2. LLM数据处理关键去重多样性保证构造扩充数据充分利用数据 参考文献…

前端小程序调用 getLocation 实现地图位置功能,通过 纬度:latitude 经度: longitude 获取当前位置

1、首先登录一下 腾讯的位置服务 有账号就登录没账号就注册&#xff0c; 点击右上角的控制台点击左侧的应用管理 ---> 我的应用 ---->> 创建应用 1、创建应用 2、列表就会显示我们刚刚创建好的 key 3、点击添加 key 4、按照要求填写信息 我们用的是小程序 所以选择…

[python:django]:web框架搭建项目

文章目录 pip查看安装列表安装制定Django版本初始化django项目执行 python manage.py startapp projectName 生成app应用执行 python manage.py runserver 运行web项目配置django项目页面访问地址注意&#xff1a;再次访问地址&#xff0c;返回制定页面 pip查看安装列表 C:\Us…

通过 Java 操作 redis -- set 集合基本命令

目录 使用命令 sadd &#xff0c;smembers 使用命令 sismember 使用命令 scard 使用命令 spop 使用命令 sinter&#xff0c;sinterstore&#xff0c;sunion&#xff0c;sunionstore&#xff0c;sdiff&#xff0c;sdiffstore 关于 redis set 集合类型的相关命令推荐看Redis …

Vue3的CRUD模版(附Demo)

目录 前言模版 前言 用惯Vue2之后&#xff0c;在碰Vue3后&#xff0c;整体还是有所区别 此文主要做一个回顾总结 假设界面如下&#xff1a; 可CRUD&#xff0c;对应的新增 添加一些必选项&#xff1a; 其中数据库的设计如下&#xff1a; 模版 对应需要注意参数位置、初始…

基于遗传优化的双BP神经网络金融序列预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化的双BP神经网络金融序列预测算法matlab仿真&#xff0c;采用的双BP神经网络结构如下&#xff1a; 2.测试软件版本以及运行结果展示 MATLAB2022A版本…

[蓝桥杯]真题讲解:合并数列(双指针+贪心)

[蓝桥杯]真题讲解&#xff1a;班级活动&#xff08;贪心&#xff09; 一、视频讲解二、正解代码1、C2、python33、Java 一、视频讲解 [蓝桥杯]真题讲解&#xff1a;合并数列&#xff08;双指针贪心&#xff09; 二、正解代码 1、C #include<bits/stdc.h> #define in…

一个优秀 Maven 项目,各 Model 间最佳继承设计方案

1.单一职责原则 (Single Responsibility Principle): 每个模块应该专注于执行一个清晰且明确定义的功能&#xff0c;遵循单一职责原则&#xff0c;以降低模块的复杂性。 2.高内聚性 (High Cohesion): 模块内的组件和类应该紧密相关&#xff0c;共同实现模块的目标。高内聚性…

5 个遥遥领先的大模型 RAG 工具

想象一下拥有一种超能力&#xff0c;让你能够对任何问题或提示生成类似人类的回答&#xff0c;同时还能够利用庞大的外部知识库确保准确性和相关性。这不是科幻小说&#xff0c;这就是检索增强生成&#xff08;RAG&#xff09;的力量。 在本文中&#xff0c;我们将介绍五大遥遥…

macOS上将ffmpeg.c编译成Framework

1 前言 本文介绍下在macOS上将ffmpeg的fftools目录下的ffmpeg.c程序&#xff0c;也就是ffmpeg的命令行程序&#xff0c;编译成framework的方法。编译成.a或.dylib的方法类似。 编译环境如下&#xff1a; xcode15.3&#xff1b;ffmpeg release/6.1; 2 编译ffmpeg 首先clone我们…

Sqlite在Mybatis Plus中关于时间字段的处理

我的个人项目中&#xff0c;使用Mybatis-Plus 和 Sqlite数据库&#xff0c; 但是在存储和查询时间字段的时候&#xff0c;总是出现问题&#xff0c;记录下我解决问题的过程。 Sqlite会默认把时间字段转成时间戳存储到数据库的字段中&#xff0c;看起来不直观&#xff0c;所以我…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《考虑微电网联盟协调运行的用户侧共享储能多计费方式博弈定价方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

YOLOv8训练流程-原理解析[目标检测理论篇]

关于YOLOv8的主干网络在YOLOv8网络结构介绍-CSDN博客介绍了&#xff0c;为了更好地学习本章内容&#xff0c;建议先去看预测流程的原理分析YOLOv8原理解析[目标检测理论篇]-CSDN博客&#xff0c;再次把YOLOv8网络结构图放在这里&#xff0c;方便随时查看。 ​ 1.前言 YOLOv8训练…

geoserver SQL注入、Think PHP5 SQL注入、spring命令注入

文章目录 一、geoserver SQL注入CVE-2023-25157二、Think PHP5 SQL注入三、Spring Cloud Function SpEL表达式命令注入&#xff08;CVE-2022-22963&#xff09; 一、geoserver SQL注入CVE-2023-25157 介绍&#xff1a;GeoServer是一个开源的地理信息系统&#xff08;GIS&#…

[C/C++] -- 大数的加减法

大数加减法的问题主要产生于计算机基本数据类型的表示范围限制。通常情况下&#xff0c;计算机采用有限位数的数据类型&#xff08;如int、long&#xff09;来表示整数&#xff0c;这些数据类型的表示范围有限&#xff0c;无法表示超出范围的大整数。 例如超过了long类型的表示…