这是我的表结构:
DROP TABLE IF EXISTS `animalphotos`;
CREATE TABLE `animalphotos` (
`photo_id` int NOT NULL AUTO_INCREMENT COMMENT ' 照片ID',
`animal_id` int NULL DEFAULT NULL COMMENT ' 所属动物ID',
`photo_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图片路径或URL',
PRIMARY KEY (`photo_id`) USING BTREE,
INDEX `animal_id`(`animal_id` ASC) USING BTREE,
CONSTRAINT `animalphotos_ibfk_1` FOREIGN KEY (`animal_id`) REFERENCES `animals` (`animal_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for animals
-- ----------------------------
DROP TABLE IF EXISTS `animals`;
CREATE TABLE `animals` (
`animal_id` int NOT NULL AUTO_INCREMENT COMMENT '动物唯一标识',
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '名称',
`species` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT ' 种类',
`gender` enum('雄','雌') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT ' 性别',
`age` int NULL DEFAULT NULL COMMENT ' 年龄',
`user_id` int NULL DEFAULT NULL COMMENT ' 关联饲养者/管理者(Users.user_id)',
`zone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '动物位置',
PRIMARY KEY (`animal_id`) USING BTREE,
INDEX `caretaker_id`(`user_id` ASC) USING BTREE,
INDEX `species_id`(`species` ASC) USING BTREE,
CONSTRAINT `animals_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for animaltraits
-- ----------------------------
DROP TABLE IF EXISTS `animaltraits`;
CREATE TABLE `animaltraits` (
`trait_id` int NOT NULL AUTO_INCREMENT COMMENT ' 特征ID',
`animal_id` int NULL DEFAULT NULL COMMENT '动物ID(Animals)',
`nature` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '性格 ',
`favourite` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT ' 喜好描述',
PRIMARY KEY (`trait_id`) USING BTREE,
INDEX `animal_id`(`animal_id` ASC) USING BTREE,
CONSTRAINT `animaltraits_ibfk_1` FOREIGN KEY (`animal_id`) REFERENCES `animals` (`animal_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`user_id` int NOT NULL AUTO_INCREMENT COMMENT ' 用户唯一标识',
`username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户名',
`password` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '密码(加密)',
`role` enum('游客','饲养者','管理员') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT ' 角色:游客/饲养者/管理员',
`status` enum('在线','离线') CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '用户状态(是否在线)',
PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
这是我的实体类:
// User 类
public class User {
private int user_id;
private String username;
private String password;
private String role;
private String status;
private List<Animals> animals; // 用户与动物是一对多关系
// getter 和 setter 方法
}
// Animals 类
public class Animals {
private int animal_id;
private String name;
private String gender; // 雄/雌
private Integer age;
private String species;
private String zone;
private User user; // 动物与用户是一对多关系(反向关联)
private List<AnimalPhoto> animalPhotos; // 动物与照片是一对多关系
// getter 和 setter 方法
}
// AnimalPhoto 类
public class AnimalPhoto {
private int photo_id;
private Animals animal; // 照片与动物是一对多关系(反向关联)
private String photo_url;
// getter 和 setter 方法
}
// AnimalTrait 类
public class AnimalTrait {
private int trait_id;
private Animals animal; // 特征与动物是一对一关系(反向关联)
private String nature; // 性格
private String favourite; // 喜好描述
// getter 和 setter 方法
}
用户 (users) 与动物 (animals) 之间是一对多关系。
动物 (animals) 与照片 (animalphotos) 之间是一对多关系。
动物 (animals) 与特征 (animaltraits) 之间是一对一关系。
这是我登录注册代码:
package com.cxy.Controller;
import com.cxy.Pojo.User;
import com.cxy.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.*;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class UserController {
@Autowired
private UserService userService;
// 显示登录页面
@GetMapping("/login")
public String loginPage(@RequestParam(value = "error", required = false) String error, Model model) {
if (error != null) {
model.addAttribute("error", true);
}
return "/login/login.jsp"; // 返回登录页面
}
// 处理登录请求
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password, HttpSession session, Model model) {
User user = userService.login(username, password);
if (user != null) {
// 更新数据库中的在线状态
userService.updateUserStatus(user.getUserId(), "在线");
// 将用户信息存入 session
session.setAttribute("user", user);
session.setAttribute("username", user.getUsername()); // 存储用户名
session.setAttribute("role", user.getRole()); // 存储角色
session.setAttribute("status", "在线"); // 存储状态
session.setAttribute("loginTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 登录时间
return "redirect:/index.jsp"; // 登录成功,跳转到主页
}
// 登录失败,返回登录页面并传递错误信息
model.addAttribute("loginError", "用户名或密码错误,请重新尝试。");
return "login/login.jsp";
}
// 显示注册页面
@GetMapping("/register")
public String registerPage() {
return "/login/register.jsp"; // 返回注册页面
}
// 处理注册请求
@PostMapping("/register")
public String register(User user, Model model) {
if (userService.register(user)) {
return "/login/login.jsp"; // 注册成功,跳转到登录页面
}
model.addAttribute("registerError", "用户名已存在"); // 用户名已存在
return "/login/register.jsp"; // 注册失败,返回注册页面
}
// 处理退出登录
@GetMapping("/logout")
public String logout(HttpSession session) {
User user = (User) session.getAttribute("user");
if (user != null) {
userService.updateUserStatus(user.getUserId(), "离线");
}
session.invalidate(); // 清除session
return "redirect:/login/login.jsp"; // 返回登录页面
}
}
这是我实现登录注册的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cxy.Mapper.UserMapper">
<!-- 查询用户 -->
<select id="findByUsername" resultType="com.cxy.Pojo.User">
SELECT * FROM users WHERE username = #{username}
</select>
<!-- 插入新用户 -->
<insert id="insertUser" parameterType="com.cxy.Pojo.User">
INSERT INTO users (username, password, role)
VALUES (#{username}, #{password}, #{role})
</insert>
<!-- 更新在线状态 -->
<update id="updateStatus">
UPDATE users SET status = #{status} WHERE user_id = #{user_id}
</update>
</mapper>
application-dao.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:context="http://www.springframework.org/schema/context"
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">
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.cxy.Mapper"/>
</bean>
</beans>
application-service.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:context="http://www.springframework.org/schema/context"
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">
<!-- 配置组件扫描 -->
<context:component-scan base-package="com.cxy.Service"/>
</beans>
spring-mvc.xml:<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.cxy.Controller"/>
<mvc:annotation-driven/>
<mvc:resources mapping="/css/**" location="/css/" />
</beans>
web.xml:<?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">
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring DispatcherServlet -->
<servlet>
<servlet-name>Dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<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>
<!-- 配置 Spring DispatcherServlet 映射 -->
<servlet-mapping>
<servlet-name>Dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.Date" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<title>动物园数字档案管理系统</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/index.css">
</head>
<body>
<!-- 顶部导航栏 -->
<header>
<div class="logo">
<img src="<%= request.getContextPath() %>/images/zoo-logo.png" alt="Zoo Logo">
</div>
<nav>
<ul>
<li><a href="${pageContext.request.contextPath}/index.jsp">首页</a></li>
<li><a href="${pageContext.request.contextPath}/animal.jsp">动物信息</a></li>
<li><a href="${pageContext.request.contextPath}/activities.jsp">活动预约</a></li>
<li><a href="${pageContext.request.contextPath}/forum.jsp">用户交流</a></li>
<%
String username = (String) session.getAttribute("username");
String userRole = (String) session.getAttribute("role");
String userStatus = (String) session.getAttribute("status");
if ("饲养者".equals(userRole)) {
out.println("<li><a href='" + request.getContextPath() + "/animal/list'>我的动物</a></li>");
} else if ("管理员".equals(userRole)) {
out.println("<li><a href='" + request.getContextPath() + "/animal/list'>所有动物</a></li>");
}
if (username == null) {
out.println("<li><a href='" + request.getContextPath() + "/login/login.jsp'>登录/注册</a></li>");
} else {
out.println("<li><a href='" + request.getContextPath() + "/logout'>退出登录</a></li>");
out.println("<li><span>登录时间: " + session.getAttribute("loginTime") + "</span></li>");
}
%>
</ul>
</nav>
</header>
<!-- 主要内容 -->
<div class="content">
<%
if ("游客".equals(userRole)) {
%>
<div class="animal-search">
<h2>探索动物世界</h2>
<input type="text" placeholder="搜索动物...">
<button onclick="window.location.href='${pageContext.request.contextPath}/activities.jsp'">立即预约活动</button>
</div>
<%
} else if ("饲养者".equals(userRole)) {
%>
<div class="manage-animals">
<h2>饲养者面板</h2>
<p>欢迎,<%= username %>!您当前状态:<%= userStatus %></p>
</div>
<%
} else if ("管理员".equals(userRole)) {
%>
<div class="admin-panel">
<h2>管理员面板</h2>
<p>欢迎,<%= username %>!您当前状态:<%= userStatus %></p>
</div>
<%
} else {
%>
<div class="welcome-message">
<h2>欢迎来到动物园数字档案管理系统</h2>
<p>请登录或注册以获取更多功能。</p>
<button onclick="window.location.href='${pageContext.request.contextPath}/login/login.jsp'">登录/注册</button>
</div>
<%
}
%>
</div>
<!-- 底部信息栏 -->
<footer>
<div class="footer-content">
<p>©2023 动物园数字档案管理系统</p>
<p>联系我们:info@zoodatabase.com</p>
</div>
</footer>
</body>
</html>
add_animal.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<title>添加动物 - 动物园数字档案管理系统</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/animal_form.css">
</head>
<body>
<jsp:include page="/header.jsp"/>
<div class="container">
<h1>添加新动物</h1>
<form action="${pageContext.request.contextPath}/animal/add" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="name">动物名称:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="species">种类:</label>
<input type="text" id="species" name="species" required>
</div>
<div class="form-group">
<label for="gender">性别:</label>
<select id="gender" name="gender" required>
<option value="">请选择</option>
<option value="雄">雄</option>
<option value="雌">雌</option>
</select>
</div>
<div class="form-group">
<label for="age">年龄:</label>
<input type="number" id="age" name="age" min="0" required>
</div>
<div class="form-group">
<label for="zone">位置:</label>
<input type="text" id="zone" name="zone" required>
</div>
<div class="form-group">
<label for="photo_url">上传照片:</label>
<input type="file" id="photo_url" name="photo_url" multiple>
</div>
<div class="form-group">
<label for="nature">性格:</label>
<input type="text" id="nature" name="nature" required>
</div>
<div class="form-group">
<label for="favourite">喜好描述:</label>
<textarea id="favourite" name="favourite"></textarea>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">添加动物</button>
<a href="${pageContext.request.contextPath}/animal/list" class="btn btn-secondary">取消</a>
</div>
</form>
</div>
注意:查询查的是动物完整的信息(包括图片),添加也要添加动物完整的信息,可以对数据库插入动物图片。这需要对表进行关联。
请根据我的配置和我给出的添加动物页面add_aniaml.jsp,用javaee的ssm整合框架实现饲养者和管理者对动物的增删改查,,以及写出对应的jsp页面:在/animal/目录内,并修改index页面。包括(controller接口,mapper接口,service,serviceimpl和Mapper新配置)。其中饲养者登录时:显示我的动物导航栏,点击进入页面只能对自己添加的动物进行修改数据和删除,也可以在该页面添加新的动物。而管理者登录时:显示所有动物导航栏,点击进入页面,可以对全部动物信息增删改。饲养者和管理者可以对动物所有信息进行写入。