浪漫编码:手把手教你实现校园表白墙功能

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 浪漫编码:手把手教你实现校园表白墙功能

表白墙

前面的案例中,我们写了表白墙,但是⼀旦服务器重启,数据仍然会丢失.

要想数据不丢失,需要把数据存储在数据库中.接下来咱们借助MyBatis来实现数据的操作


数据准备

DROP TABLE IF EXISTS message_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;

ONUPDATEnow():当数据发生更新操作时,自动把该列的值设置为now(),

now()可以替换成其他获取时间的标识符,⽐如:CURRENT_TIMESTAMP(),LOCALTIME()等MySQL<5.6.5

  1. 只有TIMESTAMP⽀持自动更新
  2. ⼀个表只能有⼀列设置自动更新
  3. 不允许同时存在两个列,其中⼀列设置了DEFAULTCURRENT_TIMESTAMP,]
  4. TIMESTAMP和DATETIME都⽀持自动更新,且可以有多列

引入MyBatis和MySQL驱动依赖

修改pom文件

<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>3.0.3</version>
</dependency>
<dependency>
  <groupId>com.mysql</groupId>
  <artifactId>mysql-connector-j</artifactId>
  <scope>runtime</scope>
</dependency>

或者使用插件EditStarters来引入依赖

配置MySQL账号密码

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

编写后端代码

import lombok.Data;
@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;
}

MessageInfoMapper

import com.example.demo.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 {
  @Select("select `id`, `from`, `to`, `message` from message_info where delete_flag=0")
  List<MessageInfo> queryAll();
  
  @Insert("insert into message_info (`from`,`to`, `message`) values(#{from},#{to},#{message})")
  Integer addMessage(MessageInfo messageInfo);
}

MessageInfoService

import com.example.demo.mapper.MessageInfoMapper;
import com.example.demo.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 List<MessageInfo> queryAll() {
    return messageInfoMapper.queryAll();
  }
  
  public Integer addMessage(MessageInfo messageInfo) {
    return messageInfoMapper.addMessage(messageInfo);
  }
}

MessageController

import com.example.demo.model.MessageInfo;
import com.example.demo.service.MessageInfoService;
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
public class MessageController {
    @Autowired
    private MessageInfoService messageInfoService;
    /**
     * 获取留言列表
     * @return
     */
    @RequestMapping("/getList")
    public List<MessageInfo> getList() {
        return messageInfoService.queryAll();
    }
    /**
     * 发表留言
     * @param messageInfo
     * @return
     */
    @RequestMapping("/publish")
    public boolean publish(MessageInfo messageInfo) {
        System.out.println(messageInfo);
        if (StringUtils.hasLength(messageInfo.getFrom())
                && StringUtils.hasLength(messageInfo.getTo())
                && StringUtils.hasLength(messageInfo.getMessage())) {
            messageInfoService.addMessage(messageInfo);
            return true;
        }
        return false;
    }
}


测试代码

部署程序,验证服务器是否能正确响应:http://127.0.0.1:8080/messagewall.html

输入留言信息,点击提交,发现页面列表显示新的数据,并且数据库中也添加了⼀条记录.

重启服务,页面显示不变.

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
存储 数据可视化 Serverless
使用蒙特卡罗模拟的投资组合优化
在金融市场中,优化投资组合对于实现风险与回报之间的预期平衡至关重要。蒙特卡罗模拟提供了一个强大的工具来评估不同的资产配置策略及其在不确定市场条件下的潜在结果。
935 1
|
监控 项目管理
软件工程IT项目管理复习之 十二:项目采购管理
软件工程IT项目管理复习之 十二:项目采购管理
471 0
|
SQL 存储 关系型数据库
IDEA中居然有碾压Navicat的数据库管理工具
【8月更文挑战第12天】IDEA中居然有碾压Navicat的数据库管理工具
754 3
IDEA中居然有碾压Navicat的数据库管理工具
|
移动开发 监控 网络协议
每个端侧产品都需要的用户体验监控
ARMS RUM 是阿里云应用实时监控服务(ARMS)下的用户体验监控(RUM)产品,覆盖 Web/H5、各类平台小程序、Android、iOS、Flutter、ReactNative、Windows、macOS 等平台框架。接入 SDK 后会主动采集端侧页面性能、资源加载、API 调用、异常崩溃、卡顿、用户操作、系统信息等数据,还支持事件、日志、异常等数据按需自定义上报以满足业务数据分析需求,提供全面的性能分析、异常分析、产品分析、会话分析能力,帮助快速跟踪定位问题原因,提升产品用户使用体验。
927 106
|
存储 人工智能 数据可视化
拍汉服照,自动调色超厉害的软件是什么?摄影师 2025 新春必备!
在汉服制作与租赁行业蓬勃发展的背景下,2025蛇年新春为摄影师带来了更多机遇。高质量的摄影作品至关重要,合适的自动调色和团队协作软件能极大提升效率。推荐6款软件助力摄影师:板栗看板提供清晰流程管理和实时沟通;Luminar智能调色一键打造古风;Capture One精准色彩管理还原汉服本色;Darktable开源免费且功能强大;On1 Photo RAW综合功能强大并引入AI技术;Polarr移动端便捷调色。这些工具将帮助摄影师在新春期间大放异彩,同时确保团队协作顺畅高效。
427 1
|
监控 数据可视化 JavaScript
Total.js Flow
Total.js Flow
352 61
|
安全 Go C语言
Go常量的定义和使用const,const特性“隐式重复前一个表达式”,以及iota枚举常量的使用
这篇文章介绍了Go语言中使用`const`定义常量的方法,包括常量的特性“隐式重复前一个表达式”,以及如何使用`iota`实现枚举常量的功能。
|
数据采集 数据可视化 数据管理
【企业实践】台州银行携手瓴羊Dataphin共建数据平台,打造小微金融治理新标杆
台州银行数据治理项目携手瓴羊Dataphin,荣获中国信息通信研究院评为“2023年铸基计划高质量数字化转型典型优秀案例”、数字化研究机构沙丘社区选为“2024中国数据资产管理最佳实践案例”双重认可。
962 4
【企业实践】台州银行携手瓴羊Dataphin共建数据平台,打造小微金融治理新标杆
|
传感器
【经典案例】STM32F407使用HAL库配置I2C详解
STM32F407是一个强大的微控制器,广泛应用于嵌入式系统中。在许多应用中,我们需要使用I2C总线来与传感器、EEPROM、显示屏等外设进行通信。本文将详细介绍如何使用STM32 HAL库来配置和使用I2C接口。
2470 2
|
Linux 知识图谱 Docker
知识图谱(Knowledge Graph)- Neo4j 5.10.0 Docker 安装
知识图谱(Knowledge Graph)- Neo4j 5.10.0 Docker 安装
459 0