首页 > 其他分享 >简易记事本项目开发(SSM框架)

简易记事本项目开发(SSM框架)

时间:2024-10-31 20:51:41浏览次数:5  
标签:return String int void SSM 简易 user public 记事本

一、项目需求分析

开发一个基于 SSM 框架的简易记事本项目,主要功能包括:

  1. 用户注册
  2. 用户登录与退出
  3. 事件分类的增删改查管理
  4. 事件管理的增删改查管理

二、项目环境搭建

1. 创建 Maven Web 项目
  • 使用 IDEA  创建 Maven Web 工程,设置打包方式为 war
  • 添加 SSM 框架依赖到 pom.xml 文件中:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>notepad</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Spring Framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.9</version>
        </dependency>

        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>

        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>

        <!-- Servlet API -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <!-- JUnit for Testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

2. 配置 Spring、SpringMVC 和 MyBatis 

Spring 配置文件 (applicationContext.xml): 配置数据源、事务管理、扫描包等。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
        <!-- 数据源配置 -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/notebook?useSSL=false" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>

        <!-- MyBatis 配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:mapper/*.xml" />
</bean>

        <!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<tx:annotation-driven/>
</beans>

SpringMVC 配置文件 (spring-mvc.xml): 配置视图解析器、处理器映射器等。 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />

        <!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>

        <!-- 静态资源访问 -->
<mvc:resources mapping="/static/**" location="/static/" />
</beans>

web.xml 文件: 配置 Spring 容器和 SpringMVC 的 DispatcherServlet。 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 配置 Spring MVC 的 DispatcherServlet -->
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 指定 Spring MVC 配置文件的位置 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 映射 DispatcherServlet -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 其他配置,例如 Spring ContextLoaderListener 等 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>

三、数据库设计

1. 数据库表设计

  • 用户表 (users)

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    name VARCHAR(50),
    password VARCHAR(100) NOT NULL,
    age INT,
    phone VARCHAR(15),
    email VARCHAR(50),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

 事件分类表 (categories)

CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,
    category_name VARCHAR(50) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

事件表 (events)

CREATE TABLE events (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,
    category_id INT,
    title VARCHAR(100),
    content TEXT,
    start_date DATE,
    end_date DATE,
    level ENUM('重要', '紧急', '一般') DEFAULT '重要',
    status ENUM('已完成', '未完成', '作废') DEFAULT '未完成',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (category_id) REFERENCES categories(id)
);

四、功能模块实现 

1. 用户注册功能

  • Controller 类 (UserController.java)

@Controller
@RequestMapping("/user")
public class UserController {
    
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String showRegisterForm() {
        return "register";
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String register(User user, Model model) {
        boolean isRegistered = userService.register(user);
        if (isRegistered) {
            return "redirect:/user/login";
        } else {
            model.addAttribute("error", "注册失败,用户名已存在");
            return "register";
        }
    }
}

 

Service 类 (UserService.java): 

public interface UserService {
    boolean register(User user);
}

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean register(User user) {
        User existingUser = userMapper.findByUsername(user.getUsername());
        if (existingUser == null) {
            userMapper.save(user);
            return true;
        }
        return false;
    }
}

 Mapper 类 (UserMapper.java)

public interface UserMapper {
    User findByUsername(String username);
    void save(User user);
}

Mapper XML (UserMapper.xml): 

<mapper namespace="UserMapper">
    <select id="findByUsername" resultType="User">
        SELECT * FROM users WHERE username = #{username}
    </select>
    <insert id="save" parameterType="User">
        INSERT INTO users (username, name, password, age, phone, email)
        VALUES (#{username}, #{name}, #{password}, #{age}, #{phone}, #{email});
    </insert>
</mapper>

2. 用户登录与退出

Controller 部分(放到UserController)

// 用户退出
    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate(); // 清除 session
        return "redirect:/login"; // 跳转到登录页面
    }

登录界面:

<form action="${pageContext.request.contextPath}/user/login" method="post">
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username">
    <label for="password">密码:</label>
    <input type="password" id="password" name="password">
    <input type="submit" value="登录">
</form>
<p style="color:red;">${error}</p>

service和mapper逻辑与上面一致

3. 事件分类管理 

controller:

@Controller
@RequestMapping("/category")
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    // 查询分类列表
    @GetMapping("/list")
    public String list(Model model, HttpSession session) {
        User user = (User) session.getAttribute("user");
        List<Category> categories = categoryService.findCategoriesByUserId(user.getId());
        model.addAttribute("categories", categories);
        return "category-list"; // 显示分类列表
    }

    // 新增分类
    @PostMapping("/add")
    public String addCategory(@RequestParam("categoryName") String categoryName, HttpSession session, Model model) {
        User user = (User) session.getAttribute("user");
        if (categoryService.isCategoryNameUnique(categoryName, user.getId())) {
            categoryService.addCategory(new Category(categoryName, user.getId()));
            return "redirect:/category/list";
        } else {
            model.addAttribute("error", "分类名称已存在");
            return "category-add";
        }
    }

    // 修改分类
    @PostMapping("/update")
    public String updateCategory(@RequestParam("categoryId") int categoryId,
                                 @RequestParam("categoryName") String categoryName, HttpSession session, Model model) {
        User user = (User) session.getAttribute("user");
        if (categoryService.isCategoryNameUnique(categoryName, user.getId())) {
            categoryService.updateCategory(categoryId, categoryName);
            return "redirect:/category/list";
        } else {
            model.addAttribute("error", "分类名称已存在");
            return "category-edit";
        }
    }

    // 删除分类
    @GetMapping("/delete/{categoryId}")
    public String deleteCategory(@PathVariable("categoryId") int categoryId, HttpSession session, Model model) {
        User user = (User) session.getAttribute("user");
        if (categoryService.canDeleteCategory(categoryId)) {
            categoryService.deleteCategory(categoryId);
        } else {
            model.addAttribute("error", "该分类下有事件,无法删除");
        }
        return "redirect:/category/list";
    }
}

 

Service 部分

@Service
public class CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    public List<Category> findCategoriesByUserId(int userId) {
        return categoryMapper.findByUserId(userId);
    }

    public boolean isCategoryNameUnique(String categoryName, int userId) {
        return categoryMapper.findByNameAndUserId(categoryName, userId) == null;
    }

    public void addCategory(Category category) {
        categoryMapper.insertCategory(category);
    }

    public void updateCategory(int categoryId, String categoryName) {
        categoryMapper.updateCategory(categoryId, categoryName);
    }

    public boolean canDeleteCategory(int categoryId) {
        return categoryMapper.countEventsByCategoryId(categoryId) == 0;
    }

    public void deleteCategory(int categoryId) {
        categoryMapper.deleteCategory(categoryId);
    }
}

mapper部分:

@Mapper
public interface CategoryMapper {

    List<Category> findByUserId(@Param("userId") int userId);

    Category findByNameAndUserId(@Param("categoryName") String categoryName, @Param("userId") int userId);

    void insertCategory(Category category);

    void updateCategory(@Param("categoryId") int categoryId, @Param("categoryName") String categoryName);

    int countEventsByCategoryId(@Param("categoryId") int categoryId);

    void deleteCategory(@Param("categoryId") int categoryId);
}

xml逻辑一致

4. 事件管理

Controller 部分

@Controller
@RequestMapping("/event")
public class EventController {

    @Autowired
    private EventService eventService;

    // 查询事件列表
    @GetMapping("/list")
    public String listEvents(Model model, HttpSession session) {
        User user = (User) session.getAttribute("user");
        List<Event> events = eventService.findEventsByUserId(user.getId());
        model.addAttribute("events", events);
        return "event-list"; // 事件列表页面
    }

    // 新增事件
    @PostMapping("/add")
    public String addEvent(@ModelAttribute Event event, HttpSession session) {
        User user = (User) session.getAttribute("user");
        event.setUserId(user.getId());
        eventService.addEvent(event);
        return "redirect:/event/list";
    }

    // 修改事件
    @PostMapping("/update")
    public String updateEvent(@ModelAttribute Event event, HttpSession session) {
        User user = (User) session.getAttribute("user");
        event.setUserId(user.getId());
        eventService.updateEvent(event);
        return "redirect:/event/list";
    }

    // 删除事件
    @GetMapping("/delete/{eventId}")
    public String deleteEvent(@PathVariable("eventId") int eventId) {
        eventService.deleteEvent(eventId);
        return "redirect:/event/list";
    }
}

 

service部分:

@Service
public class EventService {

    @Autowired
    private EventMapper eventMapper;

    public List<Event> findEventsByUserId(int userId) {
        return eventMapper.findByUserId(userId);
    }

    public void addEvent(Event event) {
        eventMapper.insertEvent(event);
    }

    public void updateEvent(Event event) {
        eventMapper.updateEvent(event);
    }

    public void deleteEvent(int eventId) {
        eventMapper.deleteEvent(eventId);
    }
}

mapper部分:

@Mapper
public interface EventMapper {

    List<Event> findByUserId(@Param("userId") int userId);

    void insertEvent(Event event);

    void updateEvent(Event event);

    void deleteEvent(@Param("eventId") int eventId);
}

实体类:

user:

package org.example.pojo;

public class User {
    private int id;           // 用户ID
    private String username;   // 用户名
    private String password;   // 密码
    private String name;       // 姓名
    private int age;           // 年龄
    private String phone;      // 手机号
    private String email;      // 邮箱

    // 构造函数
    public User() {}

    public User(String username, String password, String name, int age, String phone, String email) {
        this.username = username;
        this.password = password;
        this.name = name;
        this.age = age;
        this.phone = phone;
        this.email = email;
    }

    // Getter 和 Setter 方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{id=" + id + ", username='" + username + '\'' + ", name='" + name + '\'' + ", age=" + age +
                ", phone='" + phone + '\'' + ", email='" + email + '\'' + '}';
    }
}

Event:

package org.example.pojo;

import java.sql.Date;

public class Event {
    private int id;              // 事件ID
    private String title;         // 事件标题
    private Date startDate;       // 事件开始日期
    private Date endDate;         // 事件截止日期
    private String content;       // 事件内容
    private String level;         // 事件级别(重要、紧急、一般)
    private String status;        // 事件状态(已完成、未完成、作废)
    private int categoryId;       // 事件分类ID
    private int userId;           // 用户ID(关联用户)

    // 构造函数
    public Event() {}

    public Event(String title, Date startDate, Date endDate, String content, String level, String status, int categoryId, int userId) {
        this.title = title;
        this.startDate = startDate;
        this.endDate = endDate;
        this.content = content;
        this.level = level;
        this.status = status;
        this.categoryId = categoryId;
        this.userId = userId;
    }

    // Getter 和 Setter 方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getLevel() {
        return level;
    }

    public void setLevel(String level) {
        this.level = level;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(int categoryId) {
        this.categoryId = categoryId;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    @Override
    public String toString() {
        return "Event{id=" + id + ", title='" + title + '\'' + ", startDate=" + startDate +
                ", endDate=" + endDate + ", content='" + content + '\'' + ", level='" + level + '\'' +
                ", status='" + status + '\'' + ", categoryId=" + categoryId + ", userId=" + userId + '}';
    }
}

 Category:

package org.example.pojo;

public class Category {
    private int id;             // 分类ID
    private String categoryName; // 分类名称
    private int userId;          // 用户ID(关联用户)

    // 构造函数
    public Category() {}

    public Category(String categoryName, int userId) {
        this.categoryName = categoryName;
        this.userId = userId;
    }

    // Getter 和 Setter 方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    @Override
    public String toString() {
        return "Category{id=" + id + ", categoryName='" + categoryName + '\'' + ", userId=" + userId + '}';
    }
}

五、前端页面设计 (前端界面都是GPT生成的,不保证美观)

1. 用户注册页面(register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Registration</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <h2 class="text-center mt-4">User Registration</h2>
    <form action="register" method="post">
        <div class="form-group">
            <label for="username">Username:</label>
            <input type="text" class="form-control" id="username" name="username" required>
        </div>
        <div class="form-group">
            <label for="name">Full Name:</label>
            <input type="text" class="form-control" id="name" name="name" required>
        </div>
        <div class="form-group">
            <label for="password">Password:</label>
            <input type="password" class="form-control" id="password" name="password" required minlength="6">
        </div>
        <div class="form-group">
            <label for="age">Age:</label>
            <input type="number" class="form-control" id="age" name="age" required>
        </div>
        <div class="form-group">
            <label for="phone">Phone:</label>
            <input type="text" class="form-control" id="phone" name="phone" required>
        </div>
        <div class="form-group">
            <label for="email">Email:</label>
            <input type="email" class="form-control" id="email" name="email" required>
        </div>
        <button type="submit" class="btn btn-primary btn-block">Register</button>
    </form>
</div>
</body>
</html>

用户登录页面(login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>User Login</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <h2 class="text-center mt-4">User Login</h2>
    <form action="login" method="post">
        <div class="form-group">
            <label for="username">Username:</label>
            <input type="text" class="form-control" id="username" name="username" required>
        </div>
        <div class="form-group">
            <label for="password">Password:</label>
            <input type="password" class="form-control" id="password" name="password" required>
        </div>
        <button type="submit" class="btn btn-primary btn-block">Login</button>
    </form>
</div>
</body>
</html>

管理后台主页(dashboard.jsp) 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dashboard</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <h2 class="text-center mt-4">Welcome, ${user.name}</h2>
    <div class="d-flex justify-content-between">
        <a href="categoryList" class="btn btn-info">Category Management</a>
        <a href="eventList" class="btn btn-info">Event Management</a>
        <a href="logout" class="btn btn-danger">Logout</a>
    </div>
</div>
</body>
</html>

分类管理页面(categoryList.jsp) 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Category Management</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <h2 class="text-center mt-4">Category Management</h2>
    <a href="addCategory" class="btn btn-success mb-3">Add New Category</a>
    <table class="table table-striped">
        <thead>
        <tr>
            <th>Category ID</th>
            <th>Category Name</th>
            <th>Actions</th>
        </tr>
        </thead>
        <tbody>
        <!-- Category list here -->
        <c:forEach var="category" items="${categoryList}">
            <tr>
                <td>${category.id}</td>
                <td>${category.categoryName}</td>
                <td>
                    <a href="editCategory?id=${category.id}" class="btn btn-warning">Edit</a>
                    <a href="deleteCategory?id=${category.id}" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</a>
                </td>
            </tr>
        </c:forEach>
        </tbody>
    </table>
</div>
</body>
</html>

事件管理页面(eventList.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event Management</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <style>
        .important { background-color: #f8d7da; } /* 红色 */
        .urgent { background-color: #fff3cd; }    /* 黄色 */
        .normal { background-color: #d4edda; }    /* 绿色 */
    </style>
</head>
<body>
<div class="container">
    <h2 class="text-center mt-4">Event Management</h2>
    <a href="addEvent" class="btn btn-success mb-3">Add New Event</a>
    <form class="form-inline mb-3">
        <input type="text" name="title" class="form-control mr-2" placeholder="Search by title">
        <select name="categoryId" class="form-control mr-2">
            <option value="">All Categories</option>
            <!-- Loop through categories -->
            <c:forEach var="category" items="${categoryList}">
                <option value="${category.id}">${category.categoryName}</option>
            </c:forEach>
        </select>
        <select name="level" class="form-control mr-2">
            <option value="">All Levels</option>
            <option value="important">Important</option>
            <option value="urgent">Urgent</option>
            <option value="normal">Normal</option>
        </select>
        <button type="submit" class="btn btn-primary">Search</button>
    </form>
    <table class="table table-striped">
        <thead>
        <tr>
            <th>Event ID</th>
            <th>Title</th>
            <th>Category</th>
            <th>Start Date</th>
            <th>End Date</th>
            <th>Level</th>
            <th>Status</th>
            <th>Actions</th>
        </tr>
        </thead>
        <tbody>
        <!-- Event list -->
        <c:forEach var="event" items="${eventList}">
            <tr class="${event.level}">
                <td>${event.id}</td>
                <td>${event.title}</td>
                <td>${event.categoryName}</td>
                <td>${event.startDate}</td>
                <td>${event.endDate}</td>
                <td>${event.level}</td>
                <td>${event.status}</td>
                <td>
                    <a href="editEvent?id=${event.id}" class="btn btn-warning">Edit</a>
                    <a href="deleteEvent?id=${event.id}" class="btn btn-danger" onclick="return confirm('Are you sure?')">Delete</a>
                </td>
            </tr>
        </c:forEach>
        </tbody>
    </table>
</div>
</body>
</html>

添加/修改事件页面(addOrEditEvent.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Add/Edit Event</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
    <h2 class="text-center mt-4">${event == null ? 'Add' : 'Edit'} Event</h2>
    <form action="${event == null ? 'addEvent' : 'updateEvent'}" method="post">
        <input type="hidden" name="id" value="${event != null ? event.id : ''}">
        <div class="form-group">
            <label for="title">Title:</label>
            <input type="text" class="form-control" id="title" name="title" value="${event != null ? event.title : ''}" required>
        </div>
        <div class="form-group">
            <label for="categoryId">Category:</label>
            <select id="categoryId" name="categoryId" class="form-control" required>
                <c:forEach var="category" items="${categoryList}">
                    <option value="${category.id}" ${event != null && category.id == event.categoryId ? 'selected' : ''}>${category.categoryName}</option>
                </c:forEach>
            </select>
        </div>
        <div class="form-group">
            <label for="startDate">Start Date:</label>
            <input type="date" class="form-control" id="startDate" name="startDate" value="${event != null ? event.startDate : ''}" required>
        </div>
        <div class="form-group">
            <label for="endDate">End Date:</label>
            <input type="date" class="form-control" id="endDate" name="endDate" value="${event != null ? event.endDate : ''}" required>
        </div>
        <div class="form-group">
            <label for="level">Level:</label>
            <select id="level" name="level" class="form-control" required>
                <option value="important" ${event != null && event.level == 'important' ? 'selected' : ''}>Important</option>
                <option value="urgent" ${event != null && event.level == 'urgent' ? 'selected' : ''}>Urgent</option>
                <option value="normal" ${event != null && event.level == 'normal' ? 'selected' : ''}>Normal</option>
            </select>
        </div>
        <div class="form-group">
            <label for="status">Status:</label>
            <select id="status" name="status" class="form-control" required>
                <option value="completed" ${event != null && event.status == 'completed' ? 'selected' : ''}>Completed</option>
                <option value="pending" ${event != null && event.status == 'pending' ? 'selected' : ''}>Pending</option>
                <option value="cancelled" ${event != null && event.status == 'cancelled' ? 'selected' : ''}>Cancelled</option>
            </select>
        </div>
        <div class="form-group">
            <label for="content">Content:</label>
            <textarea id="content" name="content" class="form-control" rows="4" required>${event != null ? event.content : ''}</textarea>
        </div>
        <button type="submit" class="btn btn-primary btn-block">${event == null ? 'Add' : 'Update'} Event</button>
    </form>
</div>
</body>
</html>

六、测试类编写:

在pom中单独加入数据库模拟的依赖:

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>

UserServiceTest.java:

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class UserServiceTest {

    private Connection connection;
    private UserService userService;

    @Before
    public void setUp() throws Exception {
        // 设置数据库连接
        Class.forName("com.mysql.cj.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/your_database", "username", "password");
        userService = new UserService(connection); // 传入连接
    }

    @After
    public void tearDown() throws Exception {
        // 清理测试数据
        PreparedStatement stmt = connection.prepareStatement("DELETE FROM users WHERE username = ?");
        stmt.setString(1, "testUser");
        stmt.executeUpdate();
        stmt.close();
        connection.close();
    }

    @Test
    public void testRegisterUser() throws Exception {
        User user = new User("testUser", "Test User", "password123", 25, "1234567890", "[email protected]");
        boolean result = userService.register(user);
        assertTrue(result); // 注册应该成功

        // 验证用户是否存在于数据库中
        PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE username = ?");
        stmt.setString(1, "testUser");
        ResultSet rs = stmt.executeQuery();
        assertTrue(rs.next()); // 用户应该存在
        assertEquals("Test User", rs.getString("name")); // 验证用户姓名
        rs.close();
        stmt.close();
    }

    @Test
    public void testLoginUser() throws Exception {
        User user = new User("testUser", "Test User", "password123", 25, "1234567890", "[email protected]");
        userService.register(user); // 先注册用户

        User loggedInUser = userService.login("testUser", "password123");
        assertNotNull(loggedInUser); // 用户登录应该成功
        assertEquals("Test User", loggedInUser.getName()); // 验证用户名
    }

    @Test
    public void testLoginUser_Failed() throws Exception {
        User user = new User("testUser", "Test User", "password123", 25, "1234567890", "[email protected]");
        userService.register(user); // 先注册用户

        User loggedInUser = userService.login("testUser", "wrongPassword");
        assertNull(loggedInUser); // 用户登录失败
    }
}

分类管理测试: 

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class CategoryServiceTest {

    private Connection connection;
    private CategoryService categoryService;

    @Before
    public void setUp() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/your_database", "username", "password");
        categoryService = new CategoryService(connection); // 传入连接
    }

    @After
    public void tearDown() throws Exception {
        // 清理测试数据
        PreparedStatement stmt = connection.prepareStatement("DELETE FROM categories WHERE name = ?");
        stmt.setString(1, "Work");
        stmt.executeUpdate();
        stmt.close();
        connection.close();
    }

    @Test
    public void testAddCategory() throws Exception {
        Category category = new Category("Work");
        boolean result = categoryService.addCategory(category);
        assertTrue(result); // 添加类别应该成功

        // 验证类别是否存在于数据库中
        PreparedStatement stmt = connection.prepareStatement("SELECT * FROM categories WHERE name = ?");
        stmt.setString(1, "Work");
        ResultSet rs = stmt.executeQuery();
        assertTrue(rs.next()); // 类别应该存在
        assertEquals("Work", rs.getString("name")); // 验证类别名称
        rs.close();
        stmt.close();
    }

    @Test
    public void testDeleteCategory() throws Exception {
        Category category = new Category("Work");
        categoryService.addCategory(category); // 先添加类别

        boolean result = categoryService.deleteCategory("Work");
        assertTrue(result); // 删除类别应该成功
    }
}

事件管理:

import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class EventServiceTest {

    private Connection connection;
    private EventService eventService;

    @Before
    public void setUp() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/your_database", "username", "password");
        eventService = new EventService(connection); // 传入连接
    }

    @After
    public void tearDown() throws Exception {
        // 清理测试数据
        PreparedStatement stmt = connection.prepareStatement("DELETE FROM events WHERE title = ?");
        stmt.setString(1, "Meeting");
        stmt.executeUpdate();
        stmt.close();
        connection.close();
    }

    @Test
    public void testAddEvent() throws Exception {
        Event event = new Event("Meeting", "Work", "2024-10-31", "2024-11-01", "Important meeting", "important", "pending");
        boolean result = eventService.addEvent(event);
        assertTrue(result); // 添加事件应该成功

        // 验证事件是否存在于数据库中
        PreparedStatement stmt = connection.prepareStatement("SELECT * FROM events WHERE title = ?");
        stmt.setString(1, "Meeting");
        ResultSet rs = stmt.executeQuery();
        assertTrue(rs.next()); // 事件应该存在
        assertEquals("Important meeting", rs.getString("content")); // 验证事件内容
        rs.close();
        stmt.close();
    }

    @Test
    public void testDeleteEvent() throws Exception {
        Event event = new Event("Meeting", "Work", "2024-10-31", "2024-11-01", "Important meeting", "important", "pending");
        eventService.addEvent(event); // 先添加事件

        boolean result = eventService.deleteEvent("Meeting");
        assertTrue(result); // 删除事件应该成功
    }
}

标签:return,String,int,void,SSM,简易,user,public,记事本
From: https://blog.csdn.net/m0_73302939/article/details/143396632

相关文章

  • SSM 框架重要知识点解析
    在JavaWeb开发领域,SSM框架(Spring+SpringMVC+MyBatis)是一套备受青睐的轻量级企业级开发框架组合,它为我们提供了高效、便捷且可维护的开发方式。接下来,让我们深入探讨一下SSM框架中的重要知识点。一、Spring框架核心要点1.IOC(控制反转)与DI(依赖注入)概念解析I......
  • 基础设施:简易调试器
    之前总文章写作太卡了,写了快4万字,卡的我随便打个字都有延迟,索性直接开个贴把这一块补上,就跟github项目的branch分支一样,等我把这些分支弄好后再拼到总文章里面去。1.8.4.1解析命令我们先来查看一下readline的manual手册。manreadline接着,我们再来查看一下strtok手册。......
  • 基于SpringBoot+MySQL+SSM+Vue.js的交友系统(附论文)
    获取见最下方名片信息获取见最下方名片信息获取见最下方名片信息演示视频基于SpringBoot+MySQL+SSM+Vue.js的交友系统(附论文)技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoo......
  • 基于SpringBoot+MySQL+SSM+Vue.js的宠物猫售卖管理
    获取见最下方名片获取见最下方名片获取见最下方名片演示视频基于SpringBoot+MySQL+SSM+Vue.js的宠物猫售卖管理技术描述开发工具:Idea/Eclipse数据库:MySQLJar包仓库:Maven前端框架:Vue/ElementUI后端框架:Spring+SpringMVC+Mybatis+SpringBoot文字描述基......
  • 基于SSM的中文学习系统(有报告)。Javaee项目。ssm项目。
    演示视频:基于SSM的中文学习系统(有报告)。Javaee项目。ssm项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringMvc+Mybatis+Jsp+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。系统设计思想一个成功的......
  • windows11快速打开软件,快速打开记事本
    前言本次分享为:通过'运行'打开常用程序在运行上输入对应程序名称,达到快速打开软件的目的下面请看演示本次案例以常用程序NotePad(记事本)为例目录前言演示找到记事本文件夹(路径)常用目录查找方式非常用查找方式创建快捷方式创建文件夹打开系统变量测试演示找到记......
  • 基于SSM学生竞赛模拟系统的设计
    管理员账户功能包括:系统首页,个人中心,用户管理,公告信息管理,试题管理,论坛交流,试卷管理,系统管理前台账号功能包括:系统首页,个人中心,公告信息,论坛交流,试卷,校园资讯开发系统:Windows架构模式:SSMJDK版本:JavaJDK1.8开发工具:IDEA(推荐)数据库版本:mysql5.7数据库可视化工具:navic......
  • 免费送源码:Java+ssm+Springboot Springboot小型仪器公司生产管理系统 计算机毕业设计
    摘要本论文主要论述了如何使用java语言开发一个Springboot小型仪器公司生产管理系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述小型仪器公司生产管理系统的当前背景以及系统开发的目的,后续章节将严格按......
  • 免费送源码:Java+ssm+MySQL+Ajax ssm第二课堂管理系统 计算机毕业设计原创定制
    摘要随着互联网的高速发展,教育进入了信息化时代,促使了多种混合式教学模式的出现。第二课堂管理系统是这一时期新型混合式教学模式的代表,它的出现改变了传统教学模式,将知识传递置于课前,将学习知识的主动性交给学生,促使学生的素质全面发展。第二课堂管理系统以“以学生为......
  • 【SSM详细教程】-16-SSM整合超详细讲解
     精品专题:01.《C语言从不挂科到高绩点》课程详细笔记https://blog.csdn.net/yueyehuguang/category_12753294.html?spm=1001.2014.3001.548202.《SpringBoot详细教程》课程详细笔记https://blog.csdn.net/yueyehuguang/category_12789841.html?spm=1001.2014.3001.54820......