【Spring Boot】Spring Boot实现完整论坛功能示例代码

以下是一个简单的Spring Boot论坛系统示例代码:

  1. 首先是数据库设计,我们创建以下几张表:
  • user表,存储用户信息,包括id、username、password、email、create_time等字段。
  • topic表,存储帖子信息,包括id、title、content、user_id、create_time等字段。
  • comment表,存储评论信息,包括id、content、user_id、topic_id、create_time等字段。
  1. 创建实体类

2.1 User实体类:

@Entity
@Table(name = "user")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Columnprivate String username;@Columnprivate String password;@Columnprivate String email;@Column(name = "create_time")private Date createTime;// getter/setter省略
}

2.2 Topic实体类:

@Entity
@Table(name = "topic")
public class Topic {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Columnprivate String title;@Columnprivate String content;@ManyToOne@JoinColumn(name = "user_id")private User user;@Column(name = "create_time")private Date createTime;// getter/setter省略
}

2.3 Comment实体类:

@Entity
@Table(name = "comment")
public class Comment {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Columnprivate String content;@ManyToOne@JoinColumn(name = "user_id")private User user;@ManyToOne@JoinColumn(name = "topic_id")private Topic topic;@Column(name = "create_time")private Date createTime;// getter/setter省略
}
  1. 创建Repository

3.1 UserRepository:

public interface UserRepository extends JpaRepository<User, Long> {User findByUsername(String username);}

3.2 TopicRepository:

public interface TopicRepository extends JpaRepository<Topic, Long> {
}

3.3 CommentRepository:

public interface CommentRepository extends JpaRepository<Comment, Long> {
}
  1. 创建Service

4.1 UserService:

@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public boolean checkUser(User user) {User userInDb = userRepository.findByUsername(user.getUsername());if (userInDb != null && userInDb.getPassword().equals(user.getPassword())) {return true;} else {return false;}}public void saveUser(User user) {user.setCreateTime(new Date());userRepository.save(user);}public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}
}

4.2 TopicService:

@Service
public class TopicService {@Autowiredprivate TopicRepository topicRepository;public List<Topic> getAllTopics() {return topicRepository.findAll();}public Topic getTopicById(Long id) {return topicRepository.findById(id).orElse(null);}public void saveTopic(Topic topic) {topic.setCreateTime(new Date());topicRepository.save(topic);}}

4.3 CommentService:

@Service
public class CommentService {@Autowiredprivate CommentRepository commentRepository;public void saveComment(Comment comment) {comment.setCreateTime(new Date());commentRepository.save(comment);}public List<Comment> getCommentsByTopicId(Long topicId) {return commentRepository.findAllByTopicId(topicId);}
}
  1. 创建Controller

5.1 UserController:

@Controller
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/login")public String login() {return "login";}@PostMapping("/login")public String doLogin(User user, HttpSession session) {boolean result = userService.checkUser(user);if (result) {session.setAttribute("user", user);return "redirect:/";} else {return "login";}}@GetMapping("/logout")public String logout(HttpSession session) {session.removeAttribute("user");return "redirect:/";}@GetMapping("/register")public String register() {return "register";}@PostMapping("/register")public String doRegister(User user) {userService.saveUser(user);return "redirect:/login";}
}

5.2 TopicController:

@Controller
public class TopicController {@Autowiredprivate TopicService topicService;@Autowiredprivate CommentService commentService;@GetMapping("/")public String index(Model model) {List<Topic> topics = topicService.getAllTopics();model.addAttribute("topics", topics);return "index";}@GetMapping("/topic/{id}")public String topic(@PathVariable Long id, Model model) {Topic topic = topicService.getTopicById(id);List<Comment> comments = commentService.getCommentsByTopicId(id);model.addAttribute("topic", topic);model.addAttribute("comments", comments);return "topic";}@GetMapping("/new-topic")public String newTopic() {return "new-topic";}@PostMapping("/new-topic")public String doNewTopic(Topic topic, HttpSession session) {User user = (User) session.getAttribute("user");topic.setUser(user);topicService.saveTopic(topic);return "redirect:/";}}

5.3 CommentController:

 
@Controller
public class CommentController {@Autowiredprivate CommentService commentService;@PostMapping("/new-comment")public String doNewComment(Comment comment, HttpSession session) {User user = (User) session.getAttribute("user");comment.setUser(user);commentService.saveComment(comment);return "redirect:/topic/" + comment.getTopic().getId();}}

  1. 创建视图页面

6.1 index.html:

 
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>论坛首页</title>
</head>
<body><h1>论坛首页</h1><div><a href="/new-topic">发表新帖</a></div><ul><li th:each="topic : ${topics}"><a th:href="@{'/topic/' + ${topic.id}}"><h3 th:text="${topic.title}"></h3></a><p th:text="${topic.content}"></p><p><span th:text="${topic.user.username}"></span><span th:text="${#dates.format(topic.createTime, 'yyyy-MM-dd HH:mm:ss')}"></span></p></li></ul>
</body>
</html>

6.2 topic.html:

 
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>话题详情</title>
</head>
<body><h1 th:text="${topic.title}"></h1><p th:text="${topic.content}"></p><p><span th:text="${topic.user.username}"></span><span th:text="${#dates.format(topic.createTime, 'yyyy-MM-dd HH:mm:ss')}"></span></p><hr><h2>评论</h2><ul><li th:each="comment : ${comments}"><p th:text="${comment.content}"></p><p><span th:text="${comment.user.username}"></span><span th:text="${#dates.format(comment.createTime, 'yyyy-MM-dd HH:mm:ss')}"></span></p></li></ul><hr><form action="/new-comment" method="post"><input type="hidden" name="topic.id" th:value="${topic.id}"><textarea name="content"></textarea><br><button type="submit">提交评论</button></form>
</body>
</html>

6.3 new-topic.html:

 
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>发表新帖</title>
</head>
<body><h1>发表新帖</h1><form action="/new-topic" method="post"><input type="text" name="title"><br><textarea name="content"></textarea><br><button type="submit">发布帖子</button></form>
</body>
</html>

6.4 login.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登录</title>
</head>
<body><h1>登录</h1><form action="/login" method="post"><input type="text" name="username">

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

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

相关文章

迅睿系统二开自定义函数和插件的自定义函数

全局的自定义函数&#xff1a; 全局的自定义函数文件&#xff1a;dayrui/My/Helper.php 此文件用于放网站自定义函数&#xff0c;程序会自动加载 当前站点的自定义函数文件&#xff1a;网站主目录/config/custom.php 插件的自定义函数&#xff1a; 基于App目录下的插件或模块…

辉瑞乡村振兴战略下传统村落文化旅游设计小红书中美德少许

辉瑞乡村振兴战略下传统村落文化旅游设计小红书中美德少许

你会使用druid数据库连接池吗???

1.下载架包。下载地址&#xff1a;https://note.youdao.com/ynoteshare/index.html?id61e2cc939390acc9c7e5017907e98044&typenote&_time1693296531722 2.将架包加入项目文件。 创建一个lib目录&#xff0c;将架包复制进去 右键点击lib目录&#xff0c;将其添加为库。…

前端 -- 基础 VSCode 工具生成骨架标签新增代码 解释详解

目录 文档类型声明标签 Lang 语言种类 字符集 文档类型声明标签 <!DOCTYPE> 文档类型声明&#xff0c;作用就是告诉浏览器 当前的页面是 使用哪种 HTML 版本 来显示的网页 HTML 版本也很多呀 &#xff0c;比如 &#xff1a; HTML5 ,HTML4&#xff0c;XHTML 等…

【infiniband】rdma-core中的ibmad_port结构体

ibmad_port在rdma-core\libibmad\mad_internal.h文件中定义的结构体是&#xff1a; struct ibmad_port { int port_id; /* file descriptor returned by umad_open() */ int class_agents[MAX_CLASS]; /* class2agent mapper */ int timeout, retries; …

自动化PLC工程师能否转到c#上位机开发?

成功从自动化PLC工程师转向C#上位机开发的经历可能因人而异&#xff0c;以下是一些分享的思路和建议&#xff1a;扩展编程技能&#xff1a;学习C#语言和相关的开发工具和框架&#xff0c;掌握语言的基础知识和常用的编程技巧。可以通过在线教程、培训课程、书籍等途径进行学习&…

vue3:使用:批量删除功能

场景&#xff1a;vue中使用el-table,常需要记住上一页所勾选的数据&#xff0c;批量删除操作&#xff0c;或者弹窗分页勾选&#xff0c;进行第一页勾选&#xff0c;在调后端接口选择第二页勾选其他数据。 1、element-ui 的table表格可以轻松实现多选的功能&#xff0c;只要在表…

一文速学-让神经网络不再神秘,一天速学神经网络基础-前向传播(三)

前言 思索了很久到底要不要出深度学习内容&#xff0c;毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新&#xff0c;很多坑都没有填满&#xff0c;而且现在深度学习的文章和学习课程都十分的多&#xff0c;我考虑了很久决定还是得出神经网络系列文章&#xff0c;…

构建个人博客_Obsidian_github.io_hexo

1 初衷 很早就开始分享文档&#xff0c;以技术类的为主&#xff0c;一开始是 MSN&#xff0c;博客&#xff0c;随着平台的更替&#xff0c;后来又用了 CSDN&#xff0c;知乎&#xff0c;简书…… 再后来是 Obsidian&#xff0c;飞书&#xff0c;Notion&#xff0c;常常有以下困…

vue页面转pdf后分页时文字被横向割裂

效果 预期效果 //避免分页被截断async outPutPdfFn (id, title) {const _t this;const A4_WIDTH 592.28;const A4_HEIGHT 841.89;// dom的id。let target document.getElementById(pdf);let pageHeight target.scrollWidth / A4_WIDTH * A4_HEIGHT;// 获取分割dom&#xf…

Rancher部署k8s集群

Rancher部署 Rancher是一个开源的企业级容器管理平台。通过Rancher&#xff0c;企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台。Rancher提供了在生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台。 首先所有节点部署docker 安装docker 安…

边缘计算相关概念--学习笔记

一.边缘计算概念 边缘计算将数据的处理&#xff0c;应用程序的运行甚至一些功能服务的实现&#xff0c;由网络中心下放到网络边缘的节点上&#xff0c;在网络边缘侧的智能网关上就近采集并且处理数据&#xff0c;不需要将大量未处理的数据上传到远程的大数据平台。边缘计算理论…

Windows版本Docker安装详细步骤

文章目录 下载地址安装异常处理docker desktop requires a newer wsl 下载地址 https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe 安装 双击下载的文件Docker Desktop Installer.exe进行安装 点击OK 开始安装 安装完成点击Close and restart&…

如何在vscode导入下载的插件安装包

点击vscode插件 --> 点击3个点 --> 选择从VSIX安装 点击更新报 Cannot update while running on a read-only volume. The application is on a read-only volume. Please move the application and try again. If you’re on macOS Sierra or later, you’ll need to m…

【Linux】【驱动】注册字符设备号

【Linux】【驱动】注册字符设备号 1. 绪论1 、静态分配设备号2、动态分配设备号3、注销设备号 2 实现的代码3 加载驱动程序 1. 绪论 在之前杂项设备的时候&#xff0c;设备号是固定的&#xff0c;字符设备就需要自己去申请设备号了&#xff0c; 申请设备号有两个方式&#xff…

linux 设置与命令基础(二)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、系统基本操作 二、命令类型 三、命令语法 四、命令补齐 五、命令帮助 六、系统基本操作命令 总结 前言 这是本人学习Linux的第二天&#xff0c;今天主…

dockerfile 例子(二)

Dockerfile由一行一行的命令语句组成&#xff0c;#开头的为注释行。Dockerfile文件内容分为四个部分&#xff1a;基础镜像信息、维护者信息、镜像操作指令以及容器启动执行指令。 接下来给大家列出Dockerfile中主要命令的说明。 FROM&#xff0c;指定所创建镜像的基础镜像。 …

path模块

path.resolve() 作用&#xff1a;path.resolve() 该方法将一些的 路径/路径段 解析为 绝对路径。 path.resolve总是返回一个以相对于当前的工作目录&#xff08;working directory&#xff09;的绝对路径。给定的路径序列从右到左处理&#xff0c;每个后续的 path 会被追加到前…

关于单例模式

单例模式的目的&#xff1a; 单例模式的目的和其他的设计模式的目的都是一样的&#xff0c;都是为了降低对象之间的耦合性&#xff0c;增加代码的可复用性&#xff0c;可维护性和可扩展性。 单例模式&#xff1a; 单例模式是一种常用的设计模式&#xff0c;用简单的言语说&am…

RabbitMQ的镜像队列

镜像队列 如果 RabbitMQ 集群中只有一个 Broker 节点&#xff0c;那么该节点的失效将导致整体服务的临时性不可用&#xff0c;并且也可能会导致消息的丢失。可以将所有消息都设置为持久化&#xff0c;并且对应队列的durable 属性也设置为 true &#xff0c;但是这样仍然无法…