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

表白墙案例

一、前言

学习了mybatis之后,为了及时巩固知识,做一个小项目先练练手。

二、过程

1.MessageInfo(实体类model)
描述实体类MessageInfo的定义,包括字段、注解及用途。
package com.example.demo.model; 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; }
-解释package com.example.demo.model;
这个java代码放在哪个包(文件夹)下面,需要导入包(文件夹)路径,程序才能找到这个java程序。

-解释import lombok.Data;

导入lombok的@Data注解,可自动生成getter,setter,toString,equals,hasCode,避免手动生成,简化代码。

-解释import java.util.Date;

导入日期类型,用于存更新时间,创建时间。

-解释@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;//留言更新时间
}

2.MessageInfoMapper

(说明数据访问层MessageInfoMapper的实现,如接口方法或 SQL 映射配置。)

package com.example.demo.mapper; 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); }
--解释package com.example.demo.mapper;

同上,mapper是MessageInfoMapper.java程序所在的包,导入mapper,编译器才能找到这个java程序

--解释import com.example.demo.model.MessageInfo;

因为mapper要从数据库中查找数据,查找的数据放到了我们自定义的数据类型MessageInfo里面,要查找数据就要先导入MessageInfo

--解释

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

导入用来写sql语句的mybatis注解(@Insert,@Mapper,@Select在后面写sql语句会用到)

-解释 import java.util.List;

导入List列表,用来返回多条留言

-解释@Mapper

告诉SpringBoot这是一共操作数据库的Mapper接口

-解释

public interface MessageInfoMapper {

}

定义接口MessageInfoMapper,用这个接口来专门操作message_info这个数据库表

-解释

public interface MessageInfoMapper {
@Select("select `id`, `from`, `to`, `message` from message_info where delete_flag=0")
List<MessageInfo> queryAll();

select `id`, `from`, `to`, `message` from message_info where delete_flag=0是sql语句,作用是从message_info中查找所有没有被删除的留言

@Select作用是执行查询语句

方法:List<MessageInfo> queryAll();

List<MessageInfo>是返回值,用于返回多条留言

queryAll是方法名,意思是查询所有

-解释

@Insert("insert into message_info (`from`,`to`, `message`) values(#{from},#{to},#{message})")
Integer addMessage(MessageInfo messageInfo);

insert into message_info (`from`,`to`, `message`) values(#{from},#{to},#{message})

是插入的sql语句, (`from`,`to`, `message`)三个字段

#{from},#{to},#{message}是具体要存的值。

具体的值来自MessageInfo对象,MyBatis会自动从MessageInfo中取值

那问题来了,MessageInfo的值从哪里来呢?来自Controller!

前端页面输入-->Controller-->Service-->Mapper-->数据库

例:你在前端写

--数据传到后端,变成:

MessageInfo.setFrom("小明");

MessageInfo.setTo("小红");

MessageInfo.setMessage("我喜欢你");

--数据传到Mapper,变成:

#{from}=小明;

#{to}=小红;

#{message}=我喜欢你;

--数据传到数据库,变成:

insert into ('from','to','message') messags_info values(‘小明’,‘小红’,‘我喜欢你’);

MessageInfoService

介绍业务逻辑层MessageInfoService的核心功能,如方法逻辑或事务处理。

package com.example.demo.service; 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); } }

-解释package com.example.demo.service;

这个MessageInfoService.java类在service包里

-解释

import com.example.demo.mapper.MessageInfoMapper;
import com.example.demo.model.MessageInfo;

因为用来Mapper和MessageInfo,所以必须导入这两个类

-解释

import org.springframework.beans.factory.annotation.Autowired;

导入@Autowired这个自动装配注解

import org.springframework.stereotype.Service;

导入@Service这个注解

业务逻辑层,Spring启动时会自动创建这个类的对象,放到容器里,方便Spring统一管理

-解释

import java.util.List;

导入List,用List来装多条留言数据

-解释

public class MessageInfoService {
}
定义公开的业务类,专门处理留言相关的业务逻辑

-解释@Autowired
private MessageInfoMapper messageInfoMapper;

自动注入mapper,自动new一个MessageInfoMapper对象,不用手动创建

MessageInfoMapper是数据库操作的接口类型

-解释

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

这个是查询所有留言的方法,方法内部不直接写sql语句,调用mapper的查询方法,Mapper执行sql在数据库查询数据,查询结果原路返回到Controller

-解释

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

这个是增加留言的方法,同上调用mapper的查询方法查询数据。

MessageInfoController

阐述控制层MessageInfoController的接口设计,如路由、参数校验及响应格式。

package com.example.demo.controller; 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.CrossOrigin; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @RequestMapping("/message") @RestController @CrossOrigin public class MessageInfoController { @Autowired private MessageInfoService messageInfoService; /** * 获取留言列表 */ @RequestMapping("/getList") public List<MessageInfo> getList() { return messageInfoService.queryAll(); } /** * 获取发表留言 */ @PostMapping("/publish") // 必须用 PostMapping public boolean publish(@RequestBody MessageInfo messageInfo) { // 必须加 @RequestBody System.out.println("收到前端数据:" + messageInfo); if (StringUtils.hasLength(messageInfo.getFrom()) && StringUtils.hasLength(messageInfo.getTo()) && StringUtils.hasLength(messageInfo.getMessage())) { messageInfoService.addMessage(messageInfo); return true; } return false; } }
-解释 package com.example.demo.controller;

这个java文件放在Controller包里

-解释

import com.example.demo.model.MessageInfo;
import com.example.demo.service.MessageInfoService;

要使用MessageInfo数据类型和Service传数据,故要导入对应的类

-解释

import org.springframework.beans.factory.annotation.Autowired;

可以自动创建Service对象,不用自己new

-解释

import org.springframework.util.StringUtils;

导入字符串判断工具,如果留言是空的,则留言发不出去

-解释

import org.springframework.web.bind.annotation.CrossOrigin;

让前端网页可以正常访问接口,解决前后端跨域的问题

-解释

import org.springframework.web.bind.annotation.PostMapping;//指定接口必须要用Post形式提交
import org.springframework.web.bind.annotation.RequestBody;

//把前端传过来的数据自动转为java对象
import org.springframework.web.bind.annotation.RestController;

//@RestController是接口控制器告诉Spring这个被修饰的类只返回json数据,不返回页面
import org.springframework.web.bind.annotation.RequestMapping;

@ResquestMapper给接口设置访问地址

别人访问对应地址,就会跑到我这个方法里

-解释 @CrossOrigin

允许前端网页访问接口,不报跨域的错误

-解释

public class MessageInfoController {

}接口控制器,专门处理前端的留言请求

-解释 @Autowired
private MessageInfoService messageInfoService;
自动注入service,自动把service拿过来干活

-解释 @RequestMapping("/getList")

第一个接口,获取留言列表,前端需要访问则访问http://localhost:8080/message/getList

-解释

public List<MessageInfo> getList() {
return messageInfoService.queryAll();
}获取留言的方法

-解释

第二个接口,发表留言方法前端需要访问则访问 http://localhost:8080/message/publich

@PostMapping("/publish")
public boolean publish(@RequestBody 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;

Demo1Application

描述启动类Demo1Application的配置及作用,如主类注解或启动逻辑。

package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Demo1Application { public static void main(String[] args) { SpringApplication.run(Demo1Application.class, args); } }
message_sending.html

展示前端页面message_sending.html的结构,如表单设计或交互逻辑。

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>表白墙</title> <style> body { text-align: center; margin-top: 50px; } input, textarea { margin: 5px; padding: 8px; width: 200px; } #list { margin-top: 30px; width: 500px; margin-left: auto; margin-right: auto; text-align: left; } .msg { border: 1px solid #ccc; padding: 10px; margin: 5px; border-radius: 5px; } </style> </head> <body> <h1>💌 表白墙</h1> <div> <input type="text" id="from" placeholder="我是谁"> <br> <input type="text" id="to" placeholder="我想对谁说"> <br> <textarea id="message" rows="3" placeholder="我想说..."></textarea> <br> <button onclick="sendMsg()">提交表白</button> </div> <h2>留言列表</h2> <div id="list"></div> <script> // 页面加载时自动获取留言 window.onload = getList(); // 获取所有留言 function getList() { fetch("http://localhost:8080/message/getList") .then(response => response.json()) .then(data => { let html = ""; for (let msg of data) { html += ` <div class="msg"> <strong>${msg.from}</strong> 对 <strong>${msg.to}</strong> 说:<br> ${msg.message} </div> `; } document.getElementById("list").innerHTML = html; }) } // 提交留言 function sendMsg() { let from = document.getElementById("from").value; let to = document.getElementById("to").value; let message = document.getElementById("message").value; let data = { from: from, to: to, message: message }; fetch("http://localhost:8080/message/publish", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }).then(res => { alert("发表成功!"); location.reload(); }) } </script> </body> </html>

三、结语

本项目通过 Spring Boot + MyBatis 实现了一个简易表白墙,完成了核心功能:
前端页面输入留言信息(发送者、接收者、内容);后端接收请求,通过 MyBatis 将数据存入数据库;页面加载时自动查询所有未删除留言并展示。整个项目覆盖了 “前后端交互 - 数据持久化 - 业务逻辑处理” 的完整流程,成功巩固了 MyBatis 的核心用法(注解式 SQL、Mapper 接口、参数绑定)及 Spring Boot 的组件扫描、依赖注入等基础知识点。

喜欢可以点个赞哦~

http://www.jsqmd.com/news/818231/

相关文章:

  • 深圳汽车救援公司有哪些
  • 牛肝菌哪家靠谱:此山中野生菌资质齐全 - 19120507004
  • AntiDupl.NET:智能清理重复图片,轻松释放存储空间的终极指南
  • 自动完成(Autocomplete)
  • 显卡驱动彻底清理指南:Display Driver Uninstaller完全使用教程
  • 对比直接购买与使用Taotoken Token Plan套餐的实际成本节省体会
  • Claude Code 状态恢复机制全解析:自动压缩后文件、技能、计划与 Agent 上下文如何不断片?
  • 保姆级避坑指南:在PVE 7.4上完美安装Windows 11专业版(解决TPM、驱动、磁盘识别问题)
  • 野生菌哪家靠谱:此山中野生菌行业标杆 - 17329971652
  • 通过Taotoken的用量看板与账单追溯功能清晰掌握API成本
  • Zotero元数据格式化终极指南:如何让文献管理告别混乱,实现专业自动化
  • 为什么90%的SaaS团队在2026年Q1紧急切换TTS供应商?——深度拆解语音延迟突增、情感断层、声纹漂移三大致命缺陷
  • GroundingDINO配置文件深度解析:SwinT与SwinB架构的技术决策指南
  • GD32F4xx定时器1配置详解:从APB时钟树到1ms中断的保姆级代码
  • 2026阿里腾讯同日财报:AI投入致利润承压,“进水”“出水”谁能笑到最后?
  • 传输对象模式
  • 荔枝菌哪家靠谱:此山中野生菌保质保真 - 13724980961
  • Unity C#入门:委托Delegate的基础定义与调用
  • 《武林外传十年之约》手游:最新下载官网入口,新区开荒冲榜攻略,开服快速霸服细节技巧!
  • 从IService到ServiceImpl:解锁Mybatis-Plus服务层封装的最佳实践
  • C#命名空间指南:概念、用法与实践
  • 25岁入行AI,30岁实现年薪80w:我的5步成长法
  • 学习率调度全解析:Warmup + Cosine Decay + 1Cycle,为什么你的模型训不好
  • BallonTranslator:3分钟搞定漫画翻译的终极AI工具,完全免费开源!
  • 磁力链接转种子文件:3步实现永久资源保存的专业解决方案
  • svg 查看器 一个在线查看svg图片的网站
  • 大模型概念扫盲(万字长文 建议收藏)
  • OpenHuman:一个让你在几分钟内拥有 AI 超级智能的开源项目
  • 2026 年 5 月股权纠纷律师权威榜单:专业破局,守护企业与股东核心权益 - 外贸老黄
  • 汽车制造的质量革命:5个AR检测落地案例深度解析