整合SSM 刷课笔记
准备工作
1、 创建一个普通的Maven项目
2、 导入相关依赖 (pom.xml)
<!-- 版本管理 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Junit:测试代码 -->
<junit.version>4.12</junit.version>
<!-- 数据库驱动 -->
<mysql.connector.java.version>8.0.22</mysql.connector.java.version>
<!-- c3p0连接池 -->
<c3p0.version>0.9.5.2</c3p0.version>
<!-- Servlet JSP -->
<servlet.version>2.5</servlet.version>
<jsp-api.version>2.2</jsp-api.version>
<!-- JSP标签库 -->
<jstl.version>1.2</jstl.version>
<!-- Mybatis -->
<mybatis.version>3.5.6</mybatis.version>
<mybatis-spring.version>2.0.5</mybatis-spring.version>
<!-- Spring -->
<spring.version>5.2.10.RELEASE</spring.version>
<!-- Spring AOP -->
<aspectjweaver.version>1.9.6</aspectjweaver.version>
</properties>
<!-- 依赖: Junit, 数据库驱动, 连接池, servlet, jsp, Mybatis, mybatis-spring,spring -->
<dependencies>
<!-- Junit:测试代码 -->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- 数据库驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.java.version}</version>
</dependency>
<!-- c3p0连接池 -->
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>${c3p0.version}</version>
</dependency>
<!-- Servlet JSP -->
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- JSP标签库 -->
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- Mybatis -->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<!-- Spring -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring操作数据库的话,还需要一个spring-jdbc -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring AOP -->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectjweaver.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
3、 Maven资源过滤设置 (pom.xml)
<!-- 静态资源导出问题 -->
<build>
<!-- 在build中配置Resources, 来防止我们资源导出失败的问题 -->
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
4、 创建数据库、数据表和初始化数据
CREATE DATABASE ssmbuild;
USE ssmbuild;
CREATE TABLE `books`(
`bookID` INT NOT NULL AUTO_INCREMENT COMMENT '书id',
`bookName` VARCHAR(100) NOT NULL COMMENT '书名',
`bookCounts` INT NOT NULL COMMENT '数量',
`detail` VARCHAR(200) NOT NULL COMMENT '描述',
KEY `bookID`(`bookID`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`)VALUES
(1,'Java',1,'从入门到放弃'),
(2,'MySQL',10,'从删库到跑路'),
(3,'Linux',5,'从进门到进牢')
5、 IDEA连接上数据库
Idea连接URL: jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
6、 初步建立相应文件
头文件获取: mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
头文件获取: 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
database.properties
# 数据库驱动
jdbc.driver = com.mysql.cj.jdbc.Driver
# 连接数据库的URL地址 如果使用的是 MySQL 8.0+,需要增加时区的配置;serverTimezone=Asia/Shanghai
jdbc.url = jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
# 数据库的用户名
jdbc.username = root
# 数据库的密码
jdbc.password =
一、 Mybatis层
1、 mybatis-config.xml
<!-- 配置数据源,但是整合Spring后,交给Spring去做了 -->
<!-- 取别名,使用类名首字母小写 -->
<!-- 指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean;
在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
-->
<typeAliases>
<package name="com.muzi.pojo" />
</typeAliases>
2、 创建实体类
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
// getter and setter ...
}
3、 创建dao层 BooksMapper
public interface BooksMapper {
// 增加一本书
int addBook(Books book);
// 删除一本书
int deleteBook(@Param("bookId") int id);
// 更新一本书
int updateBook(Books book);
// 查询一本书
Books queryBook(@Param("bookId") int id);
// 查询全部的书
List<Books> queryAllBook();
}
4、 创建 Mapper.xml 文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.muzi.dao.BooksMapper">
<insert id="addBook" parameterType="Books" >
insert into ssmbuild.books(bookName, bookCounts, detail)
VALUES (#{bookName}, #{bookCounts}, #{detail});
</insert>
<delete id="deleteBook" parameterType="int">
delete from ssmbuild.books where bookID = #{bookId};
</delete>
<update id="updateBook" parameterType="Books" >
update ssmbuild.books
set bookName=#{bookName}, bookCounts=#{bookCounts}, detail=#{detail}
where bookID = #{bookID};
</update>
<select id="queryBook" parameterType="int" resultType="Books">
select * from ssmbuild.books where bookID = #{bookId};
</select>
<select id="queryAllBook" resultType="Books">
select * from ssmbuild.books;
</select>
</mapper>
5、 mybatis-config.xml 中的映射
<mappers>
<mapper class="com.muzi.dao.BooksMapper" />
<!-- <mapper resource="路径" /> -->
</mappers>
6、 创建业务层 BooksService
public interface BooksService {
// 增加一本书
int addBook(Books book);
// 删除一本书
int deleteBook(int id);
// 更新一本书
int updateBook(Books book);
// 查询一本书
Books queryBook(int id);
// 查询全部的书
List<Books> queryAllBook();
}
7、 创建业务层实现类 BooksServiceImpl : 调用dao层 组合DAO
public class BooksServiceImpl implements BooksService {
// service: 调用dao层 组合DAO
private BooksMapper booksMapper;
public void setBooksMapper(BooksMapper booksMapper) {
this.booksMapper = booksMapper;
}
public int addBook(Books book) {
return booksMapper.addBook(book);
}
public int deleteBook(int id) {
return booksMapper.deleteBook(id);
}
public int updateBook(Books book) {
return booksMapper.updateBook(book);
}
public Books queryBook(int id) {
return booksMapper.queryBook(id);
}
public List<Books> queryAllBook() {
return booksMapper.queryAllBook();
}
}
二、 Spring层
1、 创建并配置 Spring 和 Mybatis 整合的配置文件:spring-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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1. 关联数据库配置文件 -->
<context:property-placeholder location="classpath:database.properties" />
<!-- 2. 连接池
dbcp: 半自动化操作,不能自动连接
c3p0: 自动化操作(自动化的加载配置文件,并且可以自动设置到对象中!)
druid: ... hikari: ...
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- c3p0 连接池私有属性 -->
<property name="maxPoolSize" value="30" />
<property name="minPoolSize" value="10" />
<!-- 关闭连接后不自动 commit -->
<property name="autoCommitOnClose" value="false" />
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000" />
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2" />
</bean>
<!-- 3. sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 绑定 Mybatis 的配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<!-- 4. 配置 Dao 接口扫描包,动态的实现了 Dao 接口可以注入到 Spring 容器中! -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
<!-- 注入 sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 要扫描的 Dao 包 -->
<property name="basePackage" value="com.muzi.dao" />
</bean>
</beans>
2、 创建并配置 Spring 和 Service 整合的配置文件:spring-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
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1. 扫描 service 下的包 -->
<context:component-scan base-package="com.muzi.service" />
<!-- 2. 将我们的所有业务类:注入到 Spring ,可以通过 配置 或者 注解 实现 -->
<bean id="booksServiceImpl" class="com.muzi.service.BooksServiceImpl" >
<property name="booksMapper" ref="booksMapper" />
</bean>
<!-- 3. 声明式事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 4. AOP 事务支持 -->
</beans>
- 2.2步 注解实现:使用 @Service 和 @Autowired 注解。
@Service
public class BooksServiceImpl implements BooksService {
// service: 调用dao层 组合DAO
@Autowired
private BooksMapper booksMapper;
public void setBooksMapper(BooksMapper booksMapper) {
this.booksMapper = booksMapper;
}
public int addBook(Books book) {
return booksMapper.addBook(book);
}
public int deleteBook(int id) {
return booksMapper.deleteBook(id);
}
public int updateBook(Books book) {
return booksMapper.updateBook(book);
}
public Books queryBook(int id) {
return booksMapper.queryBook(id);
}
public List<Books> queryAllBook() {
return booksMapper.queryAllBook();
}
}
三、 SpringMVC层
1、 添加Web支持
2、 配置 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">
<!-- 1.注册:DispatcherServlet 这是SpringMVC的核心,请求分发器,前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 关联一个SpringMVC的配置文件:【servlet-name】-servlet.xml (Spring配置文件) -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 启动级别-1 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 2. 乱码过滤 -->
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 3. Session -->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
注!!!:web.xml 中我们绑定配置文件 spring-mvc.xml,但它没有关联到 spring-service.xml 即service层的配置文件。 所以没有扫描到service层的包,所以将web.xml 的配置文件的 xml<param-value>classpath:spring-mvc.xml</param-value>
改为 xml<param-value>classpath:applicationContext.xml</param-value>
(后面编写功能有说明)
<!-- 关联一个SpringMVC的配置文件:【servlet-name】-servlet.xml (Spring配置文件) -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
3、 编写关联的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"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1. 注解驱动
支持mvc注解驱动
在Spring中一般采用 @RequestMapping 注解来完成映射关系
要是 @RequestMapping 注解生效
必须向上下文注册 DefaultAnnotationHandlerMapping
和一个 AnnotationMethodHandlerAdapter 实例
这两个实例分别在类级别和方法级别处理
而 annotation-driven 配置帮助我们自动完成上述两个实例的注入
-->
<mvc:annotation-driven />
<!-- 2. 静态资源过滤:让 Spring MVC 不处理静态资源文件 : .css .js .html .mp3 .mp4... -->
<mvc:default-servlet-handler />
<!-- 3. 扫描包:controller包 自动扫描包,让指定包下的注解生效,由 IOC 容器统一管理 -->
<context:component-scan base-package="com.muzi.controller" />
<!-- 4. 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
- 关于JSON乱码问题
<!-- JSON 乱码 -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" >
<constructor-arg value="UTF-8" />
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false" />
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
4、 创建jsp目录
####四、SSM整合结束
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 三层结构 -->
<import resource="spring-dao.xml" />
<import resource="spring-service.xml"/>
<import resource="spring-mvc.xml" />
</beans>
五、编写功能
- ####查询书籍
BooksController类
@Controller
@RequestMapping("/books")
public class BooksController {
// controller 调用 service
@Autowired
@Qualifier("booksServiceImpl")
private BooksService booksService;
// 查询全部的书籍,并且返回到书籍展示界面
@RequestMapping("allBook")
public String queryBookList(Model model){
List<Books> booksList = booksService.queryAllBook();
model.addAttribute("booksList", booksList);
return "allBook";
}
}
base.jsp
<!-- <head> 内容 </head> -->
<html>
<head>
<!-- Bootstrap -->
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/static/css/bootstrap-4.5.0-dist/css/bootstrap.min.css">
<!-- JQuery -->
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-3.4.1/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/popper.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/css/bootstrap-4.5.0-dist/js/bootstrap.min.js"></script>
</head>
</html>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="WEB-INF/jsp/templates/base.jsp" %>
<html>
<head>
<title>index</title>
</head>
<body>
<div class="container">
<div class="row justify-content-center bg-light" style="height: 100%">
<div class="align-self-center">
<a href="${pageContext.request.contextPath}/books/allBook" class="btn btn-primary btn-lg btn-block">进入书籍展示界面</a>
</div>
</div>
</div>
</body>
</html>
数据展示:allBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="./templates/base.jsp"%>
<html>
<head>
<title>书籍展示</title>
</head>
<body>
<div class="container justify-content-md-center">
<div class="container justify-content-md-center" style="margin-top: 50px; margin-bottom: 50px;">
<h1 class="text-center">书籍展示</h1>
</div>
<table class="table table-striped table-hover">
<thead class="table-primary">
<tr>
<th scope="col">书籍编号</th>
<th scope="col">书籍名称</th>
<th scope="col">书籍数量</th>
<th scope="col">书籍描述</th>
</tr>
</thead>
<%-- 将数据从数据库查询出来,遍历:forEach var:遍历出来的值的名称 items:遍历的数据--%>
<tbody>
<c:forEach var="book" items="${booksList}">
<tr>
<th scope="row">${book.bookID}</th>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</body>
</html>
====================================================================
启动Tomcat: 500错误 NoSuchBeanDefinitionException: No qualifying bean
步骤:
1、 查看这个 bean 是否注入成功
- 看配置文件 spring-service.xml 已经存在 booksServiceImpl
- IDEA 提示也能跳转到配置 booksServiceImpl 的 bean
2、 Junit 单元测试,看我们的代码是否能查出结果
public class MyTest {
@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BooksService booksServiceImpl = context.getBean("booksServiceImpl", BooksService.class);
List<Books> books = booksServiceImpl.queryAllBook();
for (Books book : books) {
System.out.println(book);
}
}
}
3、 问题一定不在我们的底层,是 Spring 出了问题。
4、 SpringMVC 整合的时候,没有调用到我们 service 层的 bean
1. applicationContext.xml 没有注入 bean
2. web.xml 中我们也绑定过配置文件 spring-mvc.xml,所以它没有绑定到 spring-service 层的文件。没有扫描到service层的包,没有service的bean。所以将web.xml 的配置文件改为 applicationContext.xml
<!-- 关联一个SpringMVC的配置文件:【servlet-name】-servlet.xml (Spring配置文件) -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
====================================================================
页面入口
allBook.jsp
<div class="container justify-content-md-center" style="margin-top: 50px; margin-bottom: 50px;">
<h1 class="text-center">书籍展示</h1>
<a href="${pageContext.request.contextPath}/books/toAddBookPage" type="button" class="btn btn-primary">增加书籍</a>
</div>
BooksController
// 跳转到增加书籍界面
@RequestMapping("/toAddBookPage")
public String toAddBookPage(){
return "addBook";
}
// 新增书籍
@RequestMapping("/addBook")
public String addBook(Books book){
System.out.println("book==>" + book);
booksService.addBook(book);
// 重定向
return "redirect:/books/allBook";
}
addBook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="./templates/base.jsp"%>
<html>
<head>
<title>增加书籍</title>
</head>
<body>
<div class="container justify-content-md-center">
<div class="container justify-content-md-center" style="margin-top: 50px; margin-bottom: 50px;">
<h1 class="text-center">新增书籍</h1>
</div>
<form action="${pageContext.request.contextPath}/books/addBook" method="post">
<div class="form-group">
<label for="bookName">书籍名称</label>
<input name="bookName" type="text" class="form-control" id="bookName" required>
</div>
<div class="form-group">
<label for="bookCounts">书籍数量</label>
<input name="bookCounts" type="number" class="form-control" id="bookCounts" required>
</div>
<div class="form-group">
<label for="bookDetail">书籍描述</label>
<input name="detail" type="text" class="form-control" id="bookDetail" required>
</div>
<button type="submit" class="btn btn-primary">新增</button>
</form>
</div>
</body>
</html>
提交修改表单时,注意 id 的值。
可以使用前端隐藏域:
<form ......>
<input type="hidden" name="bookID" value="${xxx}">
......
</form>