基于 JAVASSM(Java + Spring + Spring MVC + MyBatis)框架开发一个九宫格日志系统

基于 JAVASSM(Java + Spring + Spring MVC + MyBatis)框架开发一个九宫格日志系统
在这里插入图片描述

步骤一:需求分析

明确系统需要实现的功能,比如:

  • 用户注册和登录
  • 添加日志(包含标题、内容、图片)
  • 查看日志列表
  • 查看单个日志的详细信息
  • 九宫格展示日志图片

步骤二:设计数据库

使用 MySQL 数据库存储系统数据。设计数据库表结构如下:

用户表(users)
  • id (INT, 主键, 自增)
  • username (VARCHAR)
  • password (VARCHAR)
  • email (VARCHAR)
  • phone (VARCHAR)
日志表(logs)
  • id (INT, 主键, 自增)
  • user_id (INT, 外键)
  • title (VARCHAR)
  • content (TEXT)
  • created_at (DATETIME)
日志图片表(log_images)
  • id (INT, 主键, 自增)
  • log_id (INT, 外键)
  • image_url (VARCHAR)

步骤三:选择开发工具

使用 IntelliJ IDEA 或 Eclipse 作为开发环境。

步骤四:搭建项目结构

  1. 创建 Maven 项目。
  2. 添加必要的依赖项(Spring、Spring MVC、MyBatis、MySQL 驱动等)。

步骤五:配置文件

application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/log_system?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Drivermybatis.mapper-locations=classpath:mapper/*.xml
spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.logsystem"/><mvc:annotation-driven/><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/"/><property name="suffix" value=".jsp"/></bean></beans>
mybatis-config.xml
<configuration><mappers><mapper resource="mapper/UserMapper.xml"/><mapper resource="mapper/LogMapper.xml"/><!-- 其他 Mapper 文件 --></mappers>
</configuration>

步骤六:编写实体类

User.java
package com.logsystem.entity;public class User {private int id;private String username;private String password;private String email;private String phone;// Getters and Setters
}
Log.java
package com.logsystem.entity;import java.util.Date;
import java.util.List;public class Log {private int id;private int userId;private String title;private String content;private Date createdAt;private List<String> images;// Getters and Setters
}

步骤七:编写 DAO 层

UserMapper.java
package com.logsystem.mapper;import com.logsystem.entity.User;
import org.apache.ibatis.annotations.*;@Mapper
public interface UserMapper {@Select("SELECT * FROM users WHERE username = #{username} AND password = #{password}")User login(@Param("username") String username, @Param("password") String password);@Insert("INSERT INTO users(username, password, email, phone) VALUES(#{username}, #{password}, #{email}, #{phone})")@Options(useGeneratedKeys = true, keyProperty = "id")void register(User user);
}
LogMapper.java
package com.logsystem.mapper;import com.logsystem.entity.Log;
import org.apache.ibatis.annotations.*;import java.util.List;@Mapper
public interface LogMapper {@Select("SELECT * FROM logs WHERE user_id = #{userId} ORDER BY created_at DESC")List<Log> getLogsByUserId(int userId);@Select("SELECT * FROM logs WHERE id = #{id}")Log getLogById(int id);@Insert("INSERT INTO logs(user_id, title, content, created_at) VALUES(#{userId}, #{title}, #{content}, NOW())")@Options(useGeneratedKeys = true, keyProperty = "id")void addLog(Log log);@Update("UPDATE logs SET title=#{title}, content=#{content} WHERE id=#{id}")void updateLog(Log log);@Delete("DELETE FROM logs WHERE id=#{id}")void deleteLog(int id);@Select("SELECT image_url FROM log_images WHERE log_id = #{logId}")List<String> getImagesByLogId(int logId);@Insert("INSERT INTO log_images(log_id, image_url) VALUES(#{logId}, #{imageUrl})")void addImageToLog(@Param("logId") int logId, @Param("imageUrl") String imageUrl);
}

步骤八:编写 Service 层

UserService.java
package com.logsystem.service;import com.logsystem.entity.User;
import com.logsystem.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public User login(String username, String password) {return userMapper.login(username, password);}public void register(User user) {userMapper.register(user);}
}
LogService.java
package com.logsystem.service;import com.logsystem.entity.Log;
import com.logsystem.mapper.LogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class LogService {@Autowiredprivate LogMapper logMapper;public List<Log> getLogsByUserId(int userId) {List<Log> logs = logMapper.getLogsByUserId(userId);for (Log log : logs) {log.setImages(logMapper.getImagesByLogId(log.getId()));}return logs;}public Log getLogById(int id) {Log log = logMapper.getLogById(id);log.setImages(logMapper.getImagesByLogId(id));return log;}public void addLog(Log log) {logMapper.addLog(log);for (String imageUrl : log.getImages()) {logMapper.addImageToLog(log.getId(), imageUrl);}}public void updateLog(Log log) {logMapper.updateLog(log);logMapper.deleteImagesByLogId(log.getId());for (String imageUrl : log.getImages()) {logMapper.addImageToLog(log.getId(), imageUrl);}}public void deleteLog(int id) {logMapper.deleteImagesByLogId(id);logMapper.deleteLog(id);}
}

步骤九:编写 Controller 层

UserController.java
package com.logsystem.controller;import com.logsystem.entity.User;
import com.logsystem.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;@Controller
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/login")public String showLoginForm() {return "login";}@PostMapping("/login")public String handleLogin(@RequestParam("username") String username, @RequestParam("password") String password, Model model) {User user = userService.login(username, password);if (user != null) {model.addAttribute("user", user);return "redirect:/logs";} else {model.addAttribute("error", "Invalid username or password");return "login";}}@GetMapping("/register")public String showRegisterForm() {return "register";}@PostMapping("/register")public String handleRegister(User user) {userService.register(user);return "redirect:/login";}
}
LogController.java
package com.logsystem.controller;import com.logsystem.entity.Log;
import com.logsystem.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;@Controller
public class LogController {@Autowiredprivate LogService logService;@GetMapping("/logs")public String showLogs(@RequestParam("userId") int userId, Model model) {List<Log> logs = logService.getLogsByUserId(userId);model.addAttribute("logs", logs);return "logs";}@GetMapping("/log/{id}")public String showLogDetails(@RequestParam("id") int id, Model model) {Log log = logService.getLogById(id);model.addAttribute("log", log);return "logDetails";}@GetMapping("/addLog")public String showAddLogForm() {return "addLog";}@PostMapping("/addLog")public String handleAddLog(@RequestParam("title") String title, @RequestParam("content") String content,@RequestParam("images") MultipartFile[] images, HttpServletRequest request) throws IOException {Log log = new Log();log.setTitle(title);log.setContent(content);log.setUserId(Integer.parseInt(request.getParameter("userId")));List<String> imageUrls = new ArrayList<>();for (MultipartFile file : images) {if (!file.isEmpty()) {String originalFilename = file.getOriginalFilename();String uploadDir = request.getServletContext().getRealPath("/uploads");File uploadFile = new File(uploadDir, originalFilename);file.transferTo(uploadFile);imageUrls.add("/uploads/" + originalFilename);}}log.setImages(imageUrls);logService.addLog(log);return "redirect:/logs?userId=" + log.getUserId();}@GetMapping("/editLog/{id}")public String showEditLogForm(@RequestParam("id") int id, Model model) {Log log = logService.getLogById(id);model.addAttribute("log", log);return "editLog";}@PostMapping("/editLog")public String handleEditLog(@RequestParam("id") int id, @RequestParam("title") String title, @RequestParam("content") String content,@RequestParam("images") MultipartFile[] images, HttpServletRequest request) throws IOException {Log log = logService.getLogById(id);log.setTitle(title);log.setContent(content);List<String> imageUrls = new ArrayList<>();for (MultipartFile file : images) {if (!file.isEmpty()) {String originalFilename = file.getOriginalFilename();String uploadDir = request.getServletContext().getRealPath("/uploads");File uploadFile = new File(uploadDir, originalFilename);file.transferTo(uploadFile);imageUrls.add("/uploads/" + originalFilename);}}log.setImages(imageUrls);logService.updateLog(log);return "redirect:/logs?userId=" + log.getUserId();}@GetMapping("/deleteLog/{id}")public String handleDeleteLog(@RequestParam("id") int id) {logService.deleteLog(id);return "redirect:/logs?userId=" + request.getParameter("userId");}
}

步骤十:前端页面

使用 JSP 创建前端页面。以下是简单的 JSP 示例:

login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Login</title>
</head>
<body>
<h2>Login</h2>
<form action="${pageContext.request.contextPath}/login" method="post">Username: <input type="text" name="username"><br>Password: <input type="password" name="password"><br><input type="submit" value="Login">
</form>
<c:if test="${not empty error}"><p style="color: red">${error}</p>
</c:if>
</body>
</html>
logs.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head><title>Logs</title><style>.grid-container {display: grid;grid-template-columns: repeat(3, 1fr);gap: 10px;}.grid-item {border: 1px solid #ccc;padding: 10px;text-align: center;}</style>
</head>
<body>
<h2>Logs</h2>
<a href="${pageContext.request.contextPath}/addLog">Add New Log</a>
<div class="grid-container"><c:forEach items="${logs}" var="log"><div class="grid-item"><h3>${log.title}</h3><p>${log.content}</p><c:forEach items="${log.images}" var="image"><img src="${image}" alt="${log.title}" width="100"></c:forEach><a href="${pageContext.request.contextPath}/log/${log.id}?userId=${log.userId}">View Details</a><a href="${pageContext.request.contextPath}/editLog/${log.id}?userId=${log.userId}">Edit</a><a href="${pageContext.request.contextPath}/deleteLog/${log.id}?userId=${log.userId}">Delete</a></div></c:forEach>
</div>
</body>
</html>

步骤十一:测试与调试

对每个功能进行详细测试,确保所有功能都能正常工作。

步骤十二:部署与发布

编译最终版本的应用程序,并准备好 WAR 文件供 Tomcat 或其他应用服务器部署。

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

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

相关文章

rom定制系列------小米8青春版定制安卓14批量线刷固件 原生系统

&#x1f49d;&#x1f49d;&#x1f49d;小米8青春版。机型代码platina。官方最终版为 12.5.1安卓10的版本。客户需要安卓14的固件以便使用他们的软件。根据测试&#xff0c;原生pixeExpe固件适配兼容性较好。为方便客户批量进行刷写。修改固件为可fast批量刷写。整合底层分区…

浅谈UI自动化

⭐️前言⭐️ 本篇文章围绕UI自动化来展开&#xff0c;主要内容包括什么是UI自动化&#xff0c;常用的UI自动化框架&#xff0c;UI自动化原理等。 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题…

blender导入的图片渲染看不见,图片预览正常,但渲染不出

在使用Blender时&#xff0c;我们经常会遇到导入图片后在预览渲染中显示&#xff0c;但在实际渲染时图片消失的问题。本文将提供详细的解决方法&#xff0c;帮助大家解决“Blender导入的图片渲染图像不显示”的问题。 问题原因 导入的图片在Blender中只是一张图&#xff0c;并…

vue--vueCLI

何为CLI ■ CLI是Command-Line Interface,俗称脚手架. ■ 使用Vue.js开发大型应用时&#xff0c;我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。&#xff08;vue 脚手架的作用&#xff09;&#xff0c; 而通过vue-cli即可&#xff1a;vue-cli 可以…

云专线优势有哪些?对接入网络有什么要求?

云专线是一种连接企业本地数据中心与云服务提供商之间的专用网络连接方式&#xff0c;具有以下优势&#xff1a; 高安全性&#xff1a;云专线提供了物理隔离的数据传输通道&#xff0c;减少了数据在公共互联网上传输时可能遭遇的安全风险。 低延迟&#xff1a;由于是直接连接&a…

Docker-- cgroups资源控制实战

上一篇&#xff1a;容器化和虚拟化 什么是cgroups&#xff1f; cgroups是Linux内核中的一项功能&#xff0c;最初由Google的工程师提出&#xff0c;后来被整合进Linux内核; 它允许用户将一系列系统任务及其子任务整合或分隔到按资源划分等级的不同组内&#xff0c;从而为系统…

算法: 链表题目练习

文章目录 链表题目练习两数相加两两交换链表中的节点重排链表合并 K 个升序链表K 个一组翻转链表 总结 链表题目练习 两数相加 坑: 两个链表都遍历完后,可能需要进位. class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode cur1 l1;ListNode…

js WebAPI黑马笔记(万字速通)

此笔记来自于黑马程序员&#xff0c;pink老师yyds 复习&#xff1a; splice() 方法用于添加或删除数组中的元素。 注意&#xff1a; 这种方法会改变原始数组。 删除数组&#xff1a; splice(起始位置&#xff0c; 删除的个数) 比如&#xff1a;1 let arr [red, green, b…

【Pikachu靶场:XSS系列】xss之过滤,xss之htmlspecialchars,xss之herf输出,xss之js输出通关啦

一、xss之过滤 <svg onloadalert("过关啦")> 二、xss之htmlspecialchars javascript:alert(123) 原理&#xff1a;输入测试文本为herf的属性值和内容值&#xff0c;所以转换思路直接变为js代码OK了 三、xss之href输出 JavaScript:alert(假客套) 原理&#x…

JS装备智能化储备管理体系优化改革

现代化的JS仓储管理方案&#xff0c;通过整合先进的RFID技术与三维模拟技术&#xff0c;为JS物流领域开创了新颖的改革浪潮。以下是对这两项尖端技术融合并用于战备物资管理的应用概述&#xff1a; 一、RFID技术在JS物资管理中的实践 RFID技术依靠无线电波实现无需直接接触的数…

缓存淘汰策略:Redis中的内存管理艺术

在现代应用架构中&#xff0c;缓存是提升性能的关键组件。 Redis&#xff0c;作为一个高性能的键值存储系统&#xff0c;因其快速的数据访问能力而被广泛使用。然而&#xff0c;由于物理内存的限制&#xff0c;Redis必须在存储空间和性能之间找到平衡&#xff0c;这就引出了缓…

AUTOSAR COM 与 LargeDataCOM 模块解析及 C++ 实现示例

AUTOSAR COM 和 LargeDataCOM 模块在功能和使用场景上有一些显著的区别。以下是它们的主要区别及具体的应用示例,最后用 C++ 源代码来解析说明。 AUTOSAR COM 模块 • 功能:主要用于处理标准大小的信号和 I-PDU(协议数据单元),提供了信号打包、解包、数据传输和接收等功能…

JavaWeb复习

在网络应用程序中有两种基本的结构&#xff0c;即C/S和B/S&#xff0c;对于c/s程序分为客户机和服务器两层&#xff0c;把应用软件按照在客户机端(通常由客户端维护困难)&#xff0c;通过网络与服务器进行相互通信。B/S结构却不用通知客户端安装某个软件&#xff0c;内容修改了…

qt获取本机IP和定位

前言&#xff1a; 在写一个天气预报模块时&#xff0c;需要一个定位功能&#xff0c;在网上翻来翻去才找着&#xff0c;放在这里留着回顾下&#xff0c;也帮下有需要的人 正文&#xff1a; 一开始我想着直接调用百度地图的API来定位&#xff0c; 然后我就想先获取本机IP的方…

python爬取旅游攻略(1)

参考网址&#xff1a; https://blog.csdn.net/m0_61981943/article/details/131262987 导入相关库&#xff0c;用get请求方式请求网页方式&#xff1a; import requests import parsel import csv import time import random url fhttps://travel.qunar.com/travelbook/list.…

Oracle OCP认证考试考点详解082系列12

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 56. 第56题&#xff1a; 题目 解析及答案&#xff1a; 关于企业管理器&#xff08;EM&#xff09;Express&#xff0c;以下哪两个陈述是…

Postgresql源码(137)执行器参数传递与使用

参考 《Postgresql源码&#xff08;127&#xff09;投影ExecProject的表达式执行分析》 0 总结速查 prepare p_04(int,int) as select b from tbl_01 where a $1 and b $2为例。 custom计划中&#xff0c;在表达式计算中使用参数的值&#xff0c;因为custom计划会带参数值&…

SPI通信详解-学习笔记

参考原文地址 SPI&#xff1a;高速、全双工&#xff0c;同步、通信总线 SPI主从模式 SPI分为主、从两种模式&#xff0c;一个SPI通讯系统需要包含一个&#xff08;且只能是一个&#xff09;主设备&#xff0c;一个或多个从设备。提供时钟的为主设备&#xff08;Master&#xff…

Day102漏洞发现-漏扫项目篇Poc开发Yaml语法插件一键生成匹配结果交互提取

知识点&#xff1a; 1、Nuclei-Poc开发-环境配置&编写流程 2、Nuclei-Poc开发-Yaml语法&匹配提取 3、Nuclei-Poc开发-BurpSuite一键生成插件 Nuclei-Poc开发-环境配置&编写流程 1、开发环境&#xff1a;VscodeYaml插件 Visual Studio Code - Code Editing. R…

Node.js 入门指南:从零开始构建全栈应用

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;node.js篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来node.js篇专栏内容:node.js-入门指南&#xff1a;从零开始构建全栈应用 前言 大家好&#xff0c;我是青山。作…