mybtis <foreach>标签循环插入不能用<if>标签判空的解决办法,java中
时间: 2025-05-16 15:24:04 浏览: 71
<think>嗯,用户的问题是关于MyBatis中使用foreach标签进行循环插入时,结合if标签判空的解决方案。我需要先理解用户的具体需求和遇到的问题。
首先,用户提到在MyBatis的foreach循环插入时,无法用if标签判空。根据之前的引用内容,比如引用[1]中提到了在in查询时使用if判断list是否为空,但插入操作可能结构不同。插入通常涉及多个字段,可能每个字段都需要判空处理,而foreach循环插入可能是一个批量操作,每个记录中的某些字段可能为空,需要动态判断。
用户可能遇到的情况是,当使用foreach批量插入时,如果某个字段的值为空,希望跳过该字段或者在SQL中不插入该字段。但MyBatis的foreach标签通常用于生成多个VALUES子句,每个记录的结构需要一致,所以直接在foreach内部使用if标签可能会导致语法错误,比如逗号问题或者字段数量不一致。
例如,假设插入语句是INSERT INTO table (col1, col2) VALUES (#{item.col1}, #{item.col2}), (#{item.col1}, #{item.col2})...,如果在foreach内部的每个item中使用if判断某个字段是否为空,可能会导致某些记录的字段数量不同,从而引发SQL语法错误。
这个时候,需要找到一种方法,在批量插入时动态处理每个字段的空值,同时保证所有记录的字段结构一致。可能需要结合MyBatis的动态SQL功能,比如使用trim、where或者choose等标签,但需要确保每个记录生成的字段部分结构相同。
另外,引用[4]提到使用forEach插入可能存在的性能问题,但用户当前的问题更多是关于动态判空而非性能。不过需要注意批量插入的数据量问题,但用户当前的需求是判空处理。
可能的解决方案是,在foreach外部统一判断整个集合是否为空,避免传入空集合导致SQL错误。同时,在foreach内部的每个字段使用if标签判断是否为空,但需要处理可能出现的逗号问题,比如使用trim标签包裹字段列表,自动处理多余的逗号。
例如,在插入语句中,字段列表和值列表都需要动态生成,使用trim来处理可能的前缀和后缀,比如:
INSERT INTO table
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="item.col1 != null">col1,</if>
<if test="item.col2 != null">col2,</if>
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="item.col1 != null">#{item.col1},</if>
<if test="item.col2 != null">#{item.col2},</if>
</trim>
但这样每个记录的字段列表可能不同,导致SQL语法错误,因为批量插入时每个VALUES子句的字段数量必须一致。因此,这种方法可能不可行。
另一种思路是,在Java端处理,确保传入的集合中的每个对象都包含所有必要的字段,或者设置默认值,这样在插入时不需要动态判断字段是否为空。但用户希望直接在MyBatis的XML中处理,减少Java端的判断。
或者,可以在插入语句中,为可能为空的字段设置默认值,或者使用数据库的默认值。但这可能不符合业务需求。
可能需要使用MyBatis的script标签,允许在动态SQL中使用更复杂的逻辑,结合foreach和if标签。例如:
<insert id="insertBatch">
INSERT INTO table (col1, col2)
<foreach collection="list" item="item" separator=",">
<trim prefix="(" suffix=")">
<if test="item.col1 != null">#{item.col1},</if>
<if test="item.col2 != null">#{item.col2},</if>
<trim suffixOverrides=",">
<!-- 处理可能多余的逗号 -->
</trim>
</trim>
</foreach>
</insert>
但这样可能会在生成每个VALUES子句时,由于字段数量不一致导致错误。例如,某些记录可能col1为空,导致生成的值为(, col2),这显然不正确。
因此,正确的做法可能是在整个批量插入中,所有记录的字段结构必须一致。也就是说,如果在某个记录中某个字段为空,其他记录中该字段也必须处理为空,或者在SQL中使用COALESCE或默认值。
但用户的需求是在MyBatis中动态处理,所以可能的解决方案是:
1. 在foreach外部判断整个集合是否为空,避免空集合执行插入。
2. 在foreach内部的每个字段使用if标签,但确保所有记录生成的字段列表相同,这需要所有记录的结构一致,即对于每个item,需要判空的字段在所有item中都为空或不为空,这显然不现实。
因此,可能正确的做法是,在插入时,允许某些字段为空,但数据库表设计允许这些字段为NULL,这样即使插入时传递null值,也不会报错,而不需要在MyBatis中动态判断。或者,如果必须动态排除某些字段,可能需要为每个记录生成独立的INSERT语句,但这会影响性能,特别是在批量插入时。
不过,用户的问题可能更倾向于在批量插入时,当整个集合为空时,不执行插入操作,而不是处理每个字段的空值。例如,当传入的list为空时,避免生成INSERT语句。这可以通过在foreach外层使用if标签判断list是否为空来解决。
例如:
<insert id="insertBatch">
INSERT INTO table (col1, col2)
VALUES
<if test="list != null and list.size() > 0">
<foreach collection="list" item="item" separator=",">
(#{item.col1}, #{item.col2})
</foreach>
</if>
</insert>
但这样如果list为空,整个VALUES部分会被忽略,导致SQL语法错误,因为INSERT INTO table (col) VALUES后面没有内容。因此,正确的做法是在整个插入语句外层使用if标签,当list为空时不执行插入操作。
例如:
<insert id="insertBatch">
<if test="list != null and list.size() > 0">
INSERT INTO table (col1, col2)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.col1}, #{item.col2})
</foreach>
</if>
</insert>
但这样当list为空时,整个insert语句不会生成,可能返回影响行数为0,避免SQL错误。这样解决了在传入空list时的判空问题。
但用户的问题可能更复杂,比如在foreach循环内部,每个item中的某些字段需要判空。例如,某个字段可能为null,需要在插入时处理,比如跳过该字段或者设置默认值。这时候,如果在foreach内部的每个字段使用if标签,例如:
<foreach collection="list" item="item" separator=",">
(#{item.col1}, <if test="item.col2 != null">#{item.col2}</if><else>DEFAULT</else>)
</foreach>
但MyBatis的if标签不支持else,需要使用choose when otherwise标签:
<foreach collection="list" item="item" separator=",">
(#{item.col1},
<choose>
<when test="item.col2 != null">#{item.col2}</when>
<otherwise>DEFAULT</otherwise>
</choose>)
</foreach>
但这样会导致每个记录的VALUES部分可能不同,例如有的用DEFAULT,有的用具体的值,这需要数据库允许这样的语法。例如,如果col2允许NULL,那么可以直接插入#{item.col2},而无需判断,当item.col2为null时,数据库会自动插入NULL。
因此,可能用户的问题在于当传入的list为空时,如何避免执行插入语句,而不是处理每个字段的空值。根据引用[1]中的示例,在in查询时使用if判断list是否为空,避免生成错误的in条件。类似的,在插入时,可以在外层使用if标签判断list是否为空,避免生成整个插入语句。
所以,解决方案可能是在insert标签内部包裹一个if标签,判断list是否为空且size>0,从而决定是否生成插入语句。同时,在foreach内部处理每个字段的空值可能需要结合其他动态SQL标签,但需要注意批量插入时字段结构的一致性。
总结可能的解决方案:
1. 外层判空:在插入语句外层使用if标签判断list是否为空,避免执行插入。
2. 内部处理字段空值:使用choose或if标签处理每个字段的空值,但需要确保所有记录的字段结构一致,或者在数据库层处理NULL值。
现在需要将这些思路整理成结构化的回答,包括代码示例和相关问题。</think>### 解决方案:MyBatis中`<foreach>`循环插入结合`<if>`判空的实现方法
在MyBatis中,使用`<foreach>`标签进行批量插入时,若需结合`<if>`标签判空,需注意**动态SQL的结构一致性**和**集合判空的逻辑控制**。以下是具体实现步骤:
---
#### 1. 外层集合判空
在批量插入前,需先判断传入的集合是否为空。若为空则跳过整个插入操作,避免生成无效SQL语句。
```xml
<insert id="batchInsert">
<if test="list != null and list.size() > 0">
INSERT INTO your_table (column1, column2, column3)
VALUES
<foreach collection="list" item="item" separator=",">
(
<if test="item.field1 != null">#{item.field1},</if>
<if test="item.field1 == null">DEFAULT,</if>
<if test="item.field2 != null">#{item.field2},</if>
<if test="item.field2 == null">DEFAULT,</if>
<if test="item.field3 != null">#{item.field3}</if>
<if test="item.field3 == null">DEFAULT</if>
)
</foreach>
</if>
</insert>
```
**关键点**:
- 外层通过`<if test="list != null and list.size() > 0">`控制插入逻辑[^1]。
- 每个字段使用`<if>`标签判断是否为空,若为空则插入数据库默认值(需数据库支持`DEFAULT`关键字)。
---
#### 2. 使用`<trim>`处理动态字段(适用于字段数量固定的场景)
若需动态排除某些字段,但需保证所有记录的字段数量一致,可使用`<trim>`标签处理多余的逗号:
```xml
<insert id="batchInsert">
<if test="list != null and list.size() > 0">
INSERT INTO your_table
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="list[0].field1 != null">column1,</if>
<if test="list[0].field2 != null">column2,</if>
column3 <!-- 必填字段 -->
</trim>
VALUES
<foreach collection="list" item="item" separator=",">
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="item.field1 != null">#{item.field1},</if>
<if test="item.field2 != null">#{item.field2},</if>
#{item.field3}
</trim>
</foreach>
</if>
</insert>
```
**关键点**:
- 通过`list[0]`动态生成字段列表,要求所有记录的字段结构一致[^2]。
- `<trim suffixOverrides=",">`自动移除末尾多余的逗号。
---
#### 3. 使用`<choose>`处理复杂逻辑
若字段存在多条件判空逻辑,可结合`<choose>`标签:
```xml
<foreach collection="list" item="item" separator=",">
(
<choose>
<when test="item.field1 != null">#{item.field1}</when>
<otherwise>DEFAULT</otherwise>
</choose>,
<choose>
<when test="item.field2 != null and item.field2 != ''">#{item.field2}</when>
<otherwise>NULL</otherwise>
</choose>
)
</foreach>
```
---
### 注意事项
1. **集合判空必须在外层**:避免因空集合导致SQL语法错误[^1]。
2. **字段一致性**:批量插入时,所有记录的字段数量和顺序必须一致。
3. **性能权衡**:若字段判空逻辑复杂,建议在Java层预处理数据,减少动态SQL解析开销[^4]。
---
阅读全文
相关推荐







这是我的表结构:
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">
</bean>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
</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>
encoding
UTF-8
</init-param>
<init-param>
forceEncoding
true
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
contextConfigLocation
classpath:application-*.xml
</context-param>
org.springframework.web.context.ContextLoaderListener
<servlet>
<servlet-name>Dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
contextConfigLocation
classpath:spring-mvc.xml
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<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>
</head>
<body>
首页
动物信息
活动预约
用户交流
<%
String username = (String) session.getAttribute("username");
String userRole = (String) session.getAttribute("role");
String userStatus = (String) session.getAttribute("status");
if ("饲养者".equals(userRole)) {
out.println("我的动物");
} else if ("管理员".equals(userRole)) {
out.println("所有动物");
}
if (username == null) {
out.println("登录/注册");
} else {
out.println("退出登录");
out.println("登录时间: " + session.getAttribute("loginTime") + "");
}
%>
<%
if ("游客".equals(userRole)) {
%>
探索动物世界
<input type="text" placeholder="搜索动物...">
<button onclick="window.location.href='${pageContext.request.contextPath}/activities.jsp'">立即预约活动</button>
<%
} else if ("饲养者".equals(userRole)) {
%>
饲养者面板
欢迎,<%= username %>!您当前状态:<%= userStatus %>
<%
} else if ("管理员".equals(userRole)) {
%>
管理员面板
欢迎,<%= username %>!您当前状态:<%= userStatus %>
<%
} else {
%>
欢迎来到动物园数字档案管理系统
请登录或注册以获取更多功能。
<button onclick="window.location.href='${pageContext.request.contextPath}/login/login.jsp'">登录/注册</button>
<%
}
%>
</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>
</head>
<body>
<jsp:include page="/header.jsp"/>
添加新动物
<form action="${pageContext.request.contextPath}/animal/add" method="post" enctype="multipart/form-data">
<label for="name">动物名称:</label>
<input type="text" id="name" name="name" required>
<label for="species">种类:</label>
<input type="text" id="species" name="species" required>
<label for="gender">性别:</label>
<select id="gender" name="gender" required>
<option value="">请选择</option>
<option value="雄">雄</option>
<option value="雌">雌</option>
</select>
<label for="age">年龄:</label>
<input type="number" id="age" name="age" min="0" required>
<label for="zone">位置:</label>
<input type="text" id="zone" name="zone" required>
<label for="photo_url">上传照片:</label>
<input type="file" id="photo_url" name="photo_url" multiple>
<label for="nature">性格:</label>
<input type="text" id="nature" name="nature" required>
<label for="favourite">喜好描述:</label>
<textarea id="favourite" name="favourite"></textarea>
<button type="submit" class="btn btn-primary">添加动物</button>
取消
</form>
注意:查询查的是动物完整的信息(包括图片),添加也要添加动物完整的信息,可以对数据库插入动物图片。这需要对表进行关联。
请根据我的配置和我给出的添加动物页面add_aniaml.jsp,用javaee的ssm整合框架实现饲养者和管理者对动物的增删改查,,以及写出对应的jsp页面:在/animal/目录内,并修改index页面。包括(controller接口,mapper接口,service,serviceimpl和Mapper新配置)。其中饲养者登录时:显示我的动物导航栏,点击进入页面只能对自己添加的动物进行修改数据和删除,也可以在该页面添加新的动物。而管理者登录时:显示所有动物导航栏,点击进入页面,可以对全部动物信息增删改。饲养者和管理者可以对动物所有信息进行写入。












