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

基于 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.Driver

mybatis.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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://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 {
    @Autowired
    private 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 {
    @Autowired
    private 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 {
    @Autowired
    private 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 {
    @Autowired
    private 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.kler.cn/a/383226.html

相关文章:

  • Doris Tablet 损坏如何应对?能恢复数据吗?
  • Zerotier + VSCode远程连接实验室的服务器、Xshell连接远程服务器
  • 详解磁盘IO、网络IO、零拷贝IO、BIO、NIO、AIO、IO多路复用(select、poll、epoll)
  • Rust: offset祼指针操作
  • 个人笔记:ORM数据库框架EFCore使用示例,运行通过,附源码
  • Linux文件目录 --- 移动和改名命令MV、强制移动、试探性移动过、按时间移动
  • Kotlin函数由易到难
  • sqlserver使用bak文件恢复数据库
  • 解密 C# 中的迭代器与 yield:高效管理序列的艺术
  • 阿里云文本内容安全处理
  • Vue3中实现原生CSS完成圆形按钮点击粒子效果和定点旋转动画
  • 云联网:打造多云互联新生态,助力企业数字化转型
  • DICOM标准:重要概念——多种传输语法、私有数据元素标签、唯一标识符(UID)等详解
  • 梧桐数据库与GBase建表方式比较
  • 【机器学习】连续属性离散化与sklearn.preprocessing.KBinsDiscretizer
  • 非[I,P]结构的生成矩阵如何巧妙计算校验矩阵
  • 题目练习之二叉树那些事儿(续集)
  • Linux入门之vim
  • 深度学习常用开源数据集介绍【持续更新】
  • 《华为工作法》读书摘记
  • 【Git】Liunx环境下Git的使用:“克隆,提交,推送“
  • Sat-NeRF论文笔记和复现问题处理
  • 小游戏开发,出现了降本增效的技术?
  • 安装acondana3, Conda command not found
  • python项目实战---使用图形化界面下载音乐
  • 离线部署k8s1.21.2集群教程