整合SSM

目录

1. 设计流程

graph LR
id1[需求分析]
id2[设计数据库]
id3[业务]
id4[前端页面]

id1 --> id2
id2 --> id3
id3 --> id4

2. 创建一个数据库表

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,'从进门到进牢');

3. 配置依赖

<?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>com.wang</groupId>
<artifactId>ssmBuild</artifactId>
<version>1.0-SNAPSHOT</version> <!--依赖: junit, 数据库驱动, 连接池, servlet, jsp, mybatis, mybatis-spring, spring-->
<dependencies>
<!--Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency> <!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency> <!--数据库连接池: c3p0-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency> <!--Servlet JSP jstl 标准标签库(standard)-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency> <!--mybatis mybatis-spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency> <!--Spring(MVC JDBC)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency> <!--Lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies> <!--静态资源导出-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource> <resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build> </project>

4. 准备项目框架

  • 在java目录下新建

    • dao
    • pojo
    • service
    • controller
  • 在resource目录下配置mybatis和spring的核心配置文件

    • 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> <!--配置数据源, 交给Spring去做--> <!--设置别名--> <!--映射Mapper--> </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
    http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
  • 在resource目录下写数据库的配置文件database.properties

jdbc.driver = com.mysql.jdbc.Driver
# 如果使用的是MySQL8.0+, 增加一个时区的配置: &serverTimezone=Asia/Shanghai
jdbc.url = jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username = root
jdbc.password = 123456

5. Mybatis层

1. 编写实体类

package com.wang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@AllArgsConstructor
@NoArgsConstructor
public class Books { private int bookID;
private String bookName;
private int bookCounts;
private String detail; }

2. 编写Mapper接口和xml

1. Mapping接口

package com.wang.dao;

import com.wang.pojo.Books;
import org.apache.ibatis.annotations.Param; import java.util.List; public interface BookMapping { //增加一本书
int addBook(Books books); //删除一本书
int deleteBookById(@Param("bookID") int id); //更新一本书
int updateBook(Books books); //查询一本书
Books queryBookById(@Param("bookID") int id); //查询全部的书
List<Books> queryAllBook();
}

2. Mapping.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.wang.dao.BookMapping"> <insert id="addBook" parameterType="Books">
insert into ssmbuild.books (bookName, bookCounts, detail)
VALUES (#{bookName}, #{bookCounts}, #{detail});
</insert> <delete id="deleteBookById" 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="queryBookById" resultType="Books">
select * from ssmbuild.books where bookID = #{bookID};
</select> <select id="queryAllBook" resultType="Books">
select * from ssmbuild.books;
</select> </mapper>

注意

编写接口时, 属性为基本类型时要加上@Param("")注解, 同时此注解可以解决属性名与数据库的字段名不一致的问题

3. 编写Service层

1. 接口

package com.wang.service;

import com.wang.pojo.Books;

import java.util.List;

public interface BookService {
//增加一本书
int addBook(Books books); //删除一本书
int deleteBookById(int id); //更新一本书
int updateBook(Books books); //查询一本书
Books queryBookById(int id); //查询全部的书
List<Books> queryAllBook();
}

2. 实现类

package com.wang.service;

import com.wang.dao.BookMapper;
import com.wang.pojo.Books; import java.util.List; public class BookServiceImpl implements BookService{ //service层 调 dao层: 组合dao
private BookMapping bookMapping; //添加setter, Spring可以直接注入到mapper
public void setBookMapping(BookMapping bookMapping) {
this.bookMapping = bookMapping;
} @Override
public int addBook(Books books) {
return bookMapping.addBook(books);
} @Override
public int deleteBookById(int id) {
return bookMapping.deleteBookById(id);
} @Override
public int updateBook(Books books) {
return bookMapping.updateBook(books);
} @Override
public Books queryBookById(int id) {
return bookMapping.queryBookById(id);
} @Override
public List<Books> queryAllBook() {
return bookMapping.queryAllBook();
}
}

注意

  • 此处Service层与Dao层的接口基本一致, 但是这样做实现了分层解耦, 方便之后添加一些业务
  • 在Service的实现类中, 调用dao, 同时对导入的dao编写一个Setter, 方便之后的Spring注入

4. 完善Mybatis核心配置文件

<?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> <!--配置数据源, 交给Spring去做--> <!--设置别名-->
<typeAliases>
<typeAlias type="com.wang.pojo.Books" alias="Books"/>
</typeAliases> <!--映射Mapper-->
<mappers>
<mapper resource="com/wang/dap/BookMapping.xml"/>
</mappers> </configuration>

6. Spring层

1. 配置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
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. 关联数据库配置文件-->
<context:property-placeholder location="classpath:database.properties"/> <!--2. 连接池
dbcp: 半自动化操作, 不能自动连接
c3p0: 自动化操作(自动化的加载配置文件, 并且可以自动配置到对象中!)
druid:
hikari: SpringBoot 2.X自带的
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--从properties中取出四个要素-->
<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.wang.dao"/>
</bean> </beans>

注意

  • 关于Spring包扫描后的类的名字

    • 如果连着两个大写的字母开头,则扫描进来的bean就是大写开头的;

      如果大写开头,后面跟小写,则扫描进来的是小写开头的
  • Spring-dao.xml要放在applicationContext的同一个上下文中, 可以在项目结构的module中配置, 也可以在applicationContext中导入

2. 配置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.wang.service"/> <!--2. 将我们的所有业务类注入到Spring, 可以通过配置或者注解实现-->
<bean id="BookServiceImpl" class="com.wang.service.BookServiceImpl">
<!--由于在BookServiceImpl中添加了bookMapper的实现类; 同时, 我们在Spring-dao中设置了自动扫描dao下的包, 因此我们可以直接注入-->
<property name="bookMapping" ref="bookMapping"/>
</bean> <!--3. 声明式事务配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> <!--4. aop事务支持(要使用aop要导入织入包)--> </beans>

注意

  • Spring-service.xml要放在applicationContext的同一个上下文中, 可以在项目结构的module中配置, 也可以在applicationContext中导入

3. 配置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
http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="Spring-dao.xml"/>
<import resource="Spring-service.xml"/> </beans>

7. 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"> <!--DispatcherServlet-->
<servlet>
<servlet-name>springmvc</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>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!--乱码过滤-->
<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>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!--Session: 配置Session过期时间为15分钟-->
<session-config>
<session-timeout>15</session-timeout>
</session-config> </web-app>

注意

  • 在DispatcherServlet中的url-pattern为 /
  • 在filter中的url-pattern为 */

3. 配置Spring-mvc

<?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/cache/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 1.注解驱动-->
<mvc:annotation-driven/> <!-- 2.静态资源过滤-->
<mvc:default-servlet-handler/> <!-- 3.扫描包: controller-->
<context:component-scan base-package="com.wang.controller"/> <!-- 4.视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean> <!-- 5.如果要使用Jackson, 要配置统一处理乱码的问题!--> </beans>

注意

  • 配置时的约束注意结尾为mvc, 同时, .xsd中间也要改成mvc
  • 视图解析器配置前缀时注意开头和结尾的 /
  • 如果要使用JackSon, 在此处配置解决乱码问题

4. 配置applicationContext.xml

将SpringMVC的配置文件引入总的配置文件

<?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
http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="Spring-dao.xml"/>
<import resource="Spring-service.xml"/>
<import resource="Spring-mvc.xml"/> </beans>

5. 添加库并配置Tomcat

在项目结构下的Artfact中, 添加一个lib目录, 将所有的库放入这个lib目录下

8. 如果出现bean不存在的排错思路

  1. 查看这个bean是否注入成功! ==> idea中能跳转则成功
  2. Junit单元测试, 看我们的代码是否能查询出结果!
  3. 如果上面都没有问题, 则问题一定不在我们的底层, 是Spring出了问题!
  4. SpringMVC, 整合的时候没有调用我们的service层的bean:
    1. applicationContext.xml 没有注入bean
    2. web.xml中, 我们也绑定过配置文件! 看配置文件是否绑全!(applicationContext.xml)

9. 查询全部书籍

1. 在controller中添加功能

package com.wang.controller;

import com.wang.pojo.Books;
import com.wang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller
@RequestMapping("/book")
public class BookController { //controller层 调 service 层
//这里使用Qualified, 指定了注入BookServiceImpl, 避免了自动装配注入对象模糊的问题
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService; //查询全部的书籍, 并且返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.queryAllBook(); model.addAttribute("list", list);
return "allBook";
} }

2. 修改并美化主页

<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/9
Time: 16:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title> <style>
a {
text-decoration: none;
color: black;
font-size: 18px;
}
h3 {
width: 180px;
height: 38px;
margin: 100px auto;
text-align: center;
line-height: 38px;
background: deepskyblue;
border-radius: 5px;
}
</style> </head>
<body> <h3>
<%--此处要写${pageContext.request.contextPath} 后面的写绝对地址, 方便项目运行!--%>
<a href="${pageContext.request.contextPath}/book/allBook">进入到书籍页面</a>
</h3> </body>
</html>

3. 利用BootStrap和jstl美化并完成书籍查询页面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/9
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示</title> <%--BootStrap美化页面--%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head>
<body> <%--栅格--%>
<div class="container">
<%--清除浮动--%>
<div class="row clearfix">
<%--分屏12份--%>
<div class="col-md-12">
<div class="page-header">
<h1>
<small>
书籍列表 —————————————————— 显示所有书籍
</small>
</h1>
</div>
</div>
</div> <div class="row clearfix">
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
</tr>
</thead> <%--书籍从数据库中查询出来, 从这个list遍历出来 : foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div> </body>
</html>

10. 添加书籍

1. 在查询所有书籍的页面中添加跳转添加书籍的按钮

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/9
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示</title> <%--BootStrap美化页面--%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head>
<body> <%--栅格--%>
<div class="container">
<%--清除浮动--%>
<div class="row clearfix">
<%--分屏12份--%>
<div class="col-md-12">
<div class="page-header">
<h1>
<small>
书籍列表 —————————————————— 显示所有书籍
</small>
</h1>
</div>
</div>
</div> <div class="row clearfix">
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
</tr>
</thead> <%--书籍从数据库中查询出来, 从这个list遍历出来 : foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div> <%--增加书籍的按钮--%>
<div class="row clearfix">
<div class="row">
<div class="col-md-4 column">
<%--toAddBook--%>
<a href="${pageContext.request.contextPath}/book/toAddBook" class="btn btn-primary">
新增书籍
</a>
</div>
</div>
</div>
</div> </body>
</html>

2. 在controller中添加跳转和添加的功能

package com.wang.controller;

import com.wang.pojo.Books;
import com.wang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller
@RequestMapping("/book")
public class BookController { //controller层 调 service 层
//这里使用Qualified, 指定了注入BookServiceImpl, 避免了自动装配注入对象模糊的问题
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService; //查询全部的书籍, 并且返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.queryAllBook(); model.addAttribute("list", list);
return "allBook";
} //跳转到增加书籍页面
@RequestMapping("/toAddBook")
public String toAddPage() {
return "addBook";
} //添加书籍的请求
@RequestMapping("/addBook")
public String addBook(Books books) {
System.out.println("allBook ==> " + books);
bookService.addBook(books);
//重定向到allBook查询
return "redirect:/book/allBook";
} }

注意

  • 在jsp中添加了点击会跳转到/book/toAddBook的按钮, 这里会进一步跳转到addBook页面

  • /book/addBook是添加书籍的地址, 表单要提交到这里来处理!

  • 添加之后, 要重定向到查询全部书籍, 使用 return "redirect:/book/allBook";

3. 设计添加书籍的页面

<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/10
Time: 14:00
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增书籍</title> <%--BootStrap美化页面--%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head>
<body> <%--栅格--%>
<div class="container">
<%--清除浮动--%>
<div class="row clearfix">
<%--分屏12份--%>
<div class="col-md-12">
<div class="page-header">
<h1>
<small>
书籍列表 —————————————————— 新增书籍
</small>
</h1>
</div>
</div>
</div> <form action="${pageContext.request.contextPath}/book/addBook" method="post">
<div class="form-group">
<%--此处的label中的for标签对应下面input标签中的id, 这样点击label就可以直接到input!--%>
<label for="bookName">书籍名称:</label>
<%--input中的name要与实体类中的一致!--%>
<input type="text" class="form-control" id="bookName" name="bookName" required>
</div>
<div class="form-group">
<label for="bookCounts">书籍数量:</label>
<input type="text" class="form-control" id="bookCounts" name="bookCounts" required>
</div>
<div class="form-group">
<label for="detail">书籍描述:</label>
<input type="text" class="form-control" id="detail" name="detail" required>
</div>
<div class="form-group">
<input type="submit" class="form-control" value="添加">
</div>
</form> </div> </body>
</html>

注意

  • label中的for标签对应下面input标签中的id, 这样点击label就可以直接到input
  • form表单中, 各个标签的name属性的值为后端取到的属性的名称(getParameter("XXX")).submit提交后,我们使用Mybatis和SpringMVC可以直接取出其中的值(返回的属性会封装在对象中)
  • name属性要与pojo中的属性名完全一致!

11. 修改和删除书籍

1. 修改书籍查询页面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/9
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示</title> <%--BootStrap美化页面--%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head>
<body> <%--栅格--%>
<div class="container">
<%--清除浮动--%>
<div class="row clearfix">
<%--分屏12份--%>
<div class="col-md-12">
<div class="page-header">
<h1>
<small>
书籍列表 —————————————————— 显示所有书籍
</small>
</h1>
</div>
</div>
</div> <div class="row clearfix">
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</tr>
</thead> <%--书籍从数据库中查询出来, 从这个list遍历出来 : foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
<td>
<%--通过a标签携带参数 ==> 使用?参数名=${参数值}--%>
<a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.bookID}">修改</a>
&nbsp; | &nbsp;
<%--通过a标签携带参数 ==> 此处使用RestFul风格--%>
<a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div> <%--增加书籍的按钮--%>
<div class="row clearfix">
<div class="row">
<div class="col-md-4 column">
<%--toAddBook--%>
<a href="${pageContext.request.contextPath}/book/toAddBook" class="btn btn-primary">
新增书籍
</a>
</div>
</div>
</div>
</div> </body>
</html>

注意

  • 前端向后端传递参数, 如果不是表单的话, 通过a标签, 携带参数的URL

2. 在controller中添加跳转和修改以及删除的功能

package com.wang.controller;

import com.wang.pojo.Books;
import com.wang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @Controller
@RequestMapping("/book")
public class BookController { //controller层 调 service 层
//这里使用Qualified, 指定了注入BookServiceImpl, 避免了自动装配注入对象模糊的问题
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService; //查询全部的书籍, 并且返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.queryAllBook(); model.addAttribute("list", list);
return "allBook";
} //跳转到增加书籍页面
@RequestMapping("/toAddBook")
public String toAddPage() {
return "addBook";
} //添加书籍的请求
//由于提交了表单, 可以接收到一个Books对象
@RequestMapping("/addBook")
public String addBook(Books books) {
bookService.addBook(books);
//重定向到allBook查询
return "redirect:/book/allBook";
} //跳转到修改页面
//在前端中提交了id数据, 这里可以接收到(使用老版的方法)
//Model用来将其带给前端
@RequestMapping("/toUpdateBook")
public String toUpdatePage(int id, Model model) {
Books books = bookService.queryBookById(id);
model.addAttribute("queryResult", books);
return "updateBook";
} //修改书籍
@RequestMapping("/updateBook")
public String updateBook(Books books) {
bookService.updateBook(books);
return "redirect:/book/allBook";
} //删除书籍
@RequestMapping("/deleteBook/{bookID}")
public String deleteBook(@PathVariable("bookID") int id) {
bookService.deleteBookById(id);
return "redirect:/book/allBook";
} }

注意

  • 由于前端使用url向后端传递了参数, 保证属性名一致的情况下可以直接取到
  • Model对象用于将后端处理的结果传递给前端(相当于setAttribute), 这里使用addAtrribute("属性名", 对象)方法, 在前端使用${"属性名"}即可取出!

3. 设计修改书籍的页面

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/10
Time: 15:17
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改书籍</title> <%--BootStrap美化页面--%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head>
<body> <%--栅格--%>
<div class="container">
<%--清除浮动--%>
<div class="row clearfix">
<%--分屏12份--%>
<div class="col-md-12">
<div class="page-header">
<h1>
<small>
书籍列表 —————————————————— 修改书籍
</small>
</h1>
</div>
</div>
</div> <form action="${pageContext.request.contextPath}/book/updateBook" method="post">
<div class="form-group">
<%--此处的label中的for标签对应下面input标签中的id, 这样点击label就可以直接到input!--%>
<label for="bookName">书籍名称:</label>
<%--input中的name要与实体类中的一致!--%>
<%--value为文本框中显示的值, 这里从后台返回的对象中取出对应的字段--%>
<input type="text" class="form-control" id="bookName" name="bookName" value="${queryResult.bookName}" required>
</div>
<div class="form-group">
<label for="bookCounts">书籍数量:</label>
<input type="text" class="form-control" id="bookCounts" name="bookCounts" value="${queryResult.bookCounts}" required>
</div>
<div class="form-group">
<label for="detail">书籍描述:</label>
<input type="text" class="form-control" id="detail" name="detail" value="${queryResult.detail}" required>
</div>
<div class="form-group">
<input type="submit" class="form-control" value="修改">
</div>
<%--此处修改要传递bookID, 同时此属性不应该被修改, 因此要使用隐藏域--%>
<input type="hidden" name="bookID" value="${queryResult.bookID}">
</form> </div> </body>
</html>

注意

  • input标签中, value为文本框中显示的值

  • 需要从前端传递到后端但是不想让用户看到的值, 使用隐藏域

    <%--此处修改要传递bookID, 同时此属性不应该被修改, 因此要使用隐藏域--%>
    <input type="hidden" name="bookID" value="${queryResult.bookID}">

12. 搜索功能

添加一个通过书籍名称搜索书籍的功能

设计思路从下到上(dao ---> service ---> controller), 这样就方便修改

1. 修改前端页面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: Wang
Date: 2020/9/9
Time: 17:23
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示</title> <%--BootStrap美化页面--%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head>
<body> <%--栅格--%>
<div class="container">
<%--清除浮动--%>
<div class="row clearfix">
<%--分屏12份--%>
<div class="col-md-12">
<div class="page-header">
<h1>
<small>
书籍列表 —————————————————— 显示所有书籍
</small>
</h1>
</div>
</div>
</div> <div class="row clearfix">
<div class="col-md-12">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</tr>
</thead> <%--书籍从数据库中查询出来, 从这个list遍历出来 : foreach--%>
<tbody>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
<td>
<%--通过a标签携带参数 ==> 使用?参数名=${参数值}--%>
<a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.bookID}">修改</a>
&nbsp; | &nbsp;
<%--通过a标签携带参数 ==> 此处使用RestFul风格--%>
<a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div> <%--增加书籍的按钮--%>
<div class="row clearfix">
<div class="row">
<div class="col-md-4 column">
<%--toAddBook--%>
<a href="${pageContext.request.contextPath}/book/toAddBook" class="btn btn-primary">
新增书籍
</a> <%--显示全部书籍--%>
<a href="${pageContext.request.contextPath}/book/allBook" class="btn btn-primary">
显示全部书
</a>
</div> <div class="col-md-4 column"></div> <div class="col-md-8 column">
<%--查询书籍, style="float: right"为向右浮动--%>
<form action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float: right" class="form-inline">
<span style="color: red; font-weight: bold">${error}</span>
<%--placeholder为默认显示的值--%>
<input type="text" placeholder="请输入要查询的书籍" class="form-control" name="queryBookName">
<input type="submit" value="查询" class="btn btn-primary">
</form>
</div>
</div>
</div>
</div> </body>
</html>

注意

  • 如果想要贴边, 需要写浮动 style="float: right"

2. 在dao层中添加功能

package com.wang.dao;

import com.wang.pojo.Books;
import org.apache.ibatis.annotations.Param; import java.util.List; public interface BookMapping { //增加一本书
int addBook(Books books); //删除一本书
int deleteBookById(@Param("bookID") int id); //更新一本书
int updateBook(Books books); //查询一本书
Books queryBookById(@Param("bookID") int id); //查询全部的书
List<Books> queryAllBook(); //搜索书籍
Books queryBookByName(@Param("bookName") String bookName);
}
<?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.wang.dao.BookMapping"> <insert id="addBook" parameterType="Books">
insert into ssmbuild.books (bookName, bookCounts, detail)
VALUES (#{bookName}, #{bookCounts}, #{detail});
</insert> <delete id="deleteBookById" 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="queryBookById" resultType="Books">
select * from ssmbuild.books where bookID = #{bookID};
</select> <select id="queryAllBook" resultType="Books">
select * from ssmbuild.books;
</select> <select id="queryBookByName" resultType="Books">
select * from ssmbuild.books where bookName = #{bookName};
</select> </mapper>

3. 在service层中添加功能

package com.wang.service;

import com.wang.pojo.Books;

import java.util.List;

public interface BookService {
//增加一本书
int addBook(Books books); //删除一本书
int deleteBookById(int id); //更新一本书
int updateBook(Books books); //查询一本书
Books queryBookById(int id); //查询全部的书
List<Books> queryAllBook(); //搜索书籍
Books queryBookByName(String bookName);
}
package com.wang.service;

import com.wang.dao.BookMapping;
import com.wang.pojo.Books; import java.util.List; public class BookServiceImpl implements BookService{ //service层 调 dao层: 组合dao
private BookMapping bookMapping; //添加setter, Spring可以直接注入到mapper
public void setBookMapping(BookMapping bookMapping) {
this.bookMapping = bookMapping;
} @Override
public int addBook(Books books) {
return bookMapping.addBook(books);
} @Override
public int deleteBookById(int id) {
return bookMapping.deleteBookById(id);
} @Override
public int updateBook(Books books) {
return bookMapping.updateBook(books);
} @Override
public Books queryBookById(int id) {
return bookMapping.queryBookById(id);
} @Override
public List<Books> queryAllBook() {
return bookMapping.queryAllBook();
} @Override
public Books queryBookByName(String bookName) {
return bookMapping.queryBookByName(bookName);
}
}

4. 在controller层中添加功能

package com.wang.controller;

import com.wang.pojo.Books;
import com.wang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import java.util.ArrayList;
import java.util.List; @Controller
@RequestMapping("/book")
public class BookController { //controller层 调 service 层
//这里使用Qualified, 指定了注入BookServiceImpl, 避免了自动装配注入对象模糊的问题
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService; //查询全部的书籍, 并且返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.queryAllBook(); model.addAttribute("list", list);
return "allBook";
} //跳转到增加书籍页面
@RequestMapping("/toAddBook")
public String toAddPage() {
return "addBook";
} //添加书籍的请求
//由于提交了表单, 可以接收到一个Books对象
@RequestMapping("/addBook")
public String addBook(Books books) {
bookService.addBook(books);
//重定向到allBook查询
return "redirect:/book/allBook";
} //跳转到修改页面
//在前端中提交了id数据, 这里可以接收到(使用老版的方法)
//Model用来将其带给前端
@RequestMapping("/toUpdateBook")
public String toUpdatePage(int id, Model model) {
Books books = bookService.queryBookById(id);
model.addAttribute("queryResult", books);
return "updateBook";
} //修改书籍
@RequestMapping("/updateBook")
public String updateBook(Books books) {
bookService.updateBook(books);
return "redirect:/book/allBook";
} //删除书籍
@RequestMapping("/deleteBook/{bookID}")
public String deleteBook(@PathVariable("bookID") int id) {
bookService.deleteBookById(id);
return "redirect:/book/allBook";
} //查询书籍
@RequestMapping("/queryBook")
public String queryBook(String queryBookName, Model model) {
Books books = bookService.queryBookByName(queryBookName);
List<Books> list = new ArrayList<>();
list.add(books); //如果查询不存在, 返回全部书籍
if(books == null) {
list = bookService.queryAllBook();
model.addAttribute("error", "未查到该书籍");
}
model.addAttribute("list", list);
return "/allBook";
} }

注意

  • 为了复用查询的前端页面, 这里将查询结果封装为list, 传回前端页面即可使用!

  • 这里存在查询不存在的情况, 要考虑查询失败的响应

  • 失败后, 如果想返回全部的列表, 只需要将list放入全部书籍即可

SpringMVC-整合SSM的更多相关文章

  1. SSM整合(三):Spring4与Mybatis3与SpringMVC整合

    源码下载 SSMDemo 上一节整合了Mybatis3与Spring4,接下来整合SpringMVC! 说明:整合SpringMVC必须是在web项目中,所以前期,新建的就是web项目! 本节全部采用 ...

  2. 整合SSM框架必备基础—SpringMVC(下)

    在上一篇文章<整合SSM框架必备基础-SpringMVC(上)>中,胖达介绍了关于SpringMVC的诞生.优势以及执行流程等理论知识点,这篇文章打算在实操中加深一下对SpringMVC的 ...

  3. SpringMVC:ssm整合练习一

    西部开源-秦疆老师:MyBatis,Spring,SpringMVC 整合练习一 , 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! ss ...

  4. SpringMVC学习05(整合ssm)

    5.整合SSM 环境要求 环境: IDEA MySQL 5.7.19 Tomcat 9 Maven 3.6 要求: 需要熟练掌握MySQL数据库,Spring,JavaWeb及MyBatis知识,简单 ...

  5. shiro权限控制(一):shiro介绍以及整合SSM框架

    shiro安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证.授权.加密和会话管理等功能 . shiro能做什么? 认证:验证用户的身份 授权:对用户执行访问控制:判断用户是 ...

  6. Spring+MyBatis+SpringMvc整合Demo

    客户关系管理系统demo 项目分析 该demo使用技术及环境:ssm+maven+bootstrap+jsp+mysql+idea+jdk1.8 需求:客户管理,实现客户列表分页显示如下图 项目开始 ...

  7. Maven SpringMVC整合Mybatis

    关于Spring的核心理念和Mybatis的优点网上已经有很多文档做了说明.这篇博客,只记录springmvc整合mybatis时常见的知识点,以及注意事项,它只有最精简的几个模块,以帮助初学者迅速搭 ...

  8. SpringMVC整合Shiro权限框架

    尊重原创:http://blog.csdn.net/donggua3694857/article/details/52157313 最近在学习Shiro,首先非常感谢开涛大神的<跟我学Shiro ...

  9. JAVAEE——SpringMVC第一天:介绍、入门程序、架构讲解、SpringMVC整合MyBatis、参数绑定、SpringMVC和Struts2的区别

    1. 学习计划   第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a) 框架结构 b) 组件说明 4.SpringMVC整合MyBatis 5.参数绑定 a) Sp ...

  10. 优雅地搭建整合ssm项目

    spring + spring mvc + mybatis 三大框架建议观看 黑马程序员出品的 Springmvc+Mybatis由浅入深全套视频教程 Spring框架2016版视频 观看顺序 ,我个 ...

随机推荐

  1. Go语言入门系列(五)之指针和结构体的使用

    Go语言入门系列前面的文章: Go语言入门系列(二)之基础语法总结 Go语言入门系列(三)之数组和切片 Go语言入门系列(四)之map的使用 1. 指针 如果你使用过C或C++,那你肯定对指针这个概念 ...

  2. C#LeetCode刷题之#844-比较含退格的字符串​​​​​​​(Backspace String Compare)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4030 访问. 给定 S 和 T 两个字符串,当它们分别被输入到空 ...

  3. day 10 面向对象(=)

    1.魔法对象  __str _(self)     使用print(对象)输出的时候,自动调用该方法      return语句 返回一个值      class  类名:      del _str ...

  4. Redis设计与实现——数据结构与对象

    SDS 简单动态字符串 在redis数据库里面,包含字符串值得键值对在底层都是由SDS实现的. redis >  set msg "hello world" 1)键值对的键是 ...

  5. 【算法•日更•第二十三期】数据结构:two-pointer(尺取法)&莫队

    ▎引入 ☞『例题』 一道十分easy的题: 洛谷P1638 长度为n的序列,m种数 找一个最短区间,使得所有数出现一遍 n≤1e6 ,m≤2e3. ☞『分析』 这道题非常的简单,但是如果不会two-p ...

  6. linux root用户下没有.ssh目录

    .ssh 是记录密码信息的文件夹,如果没有登录过root的话,就没有 .ssh 文件夹,因此登录 localhost ,并输入密码就会生成了 ssh localhost

  7. Hbase写入流程图

    写入流程图

  8. ucore学习

    1.启动操作系统的bootloader,用于了解操作系统启动前的状态和要做的准备工作,了解运行操作系统的硬件支持,操作系统如何加载到内存中,理解两类中断--"外设中断"," ...

  9. A distributional code for value in dopamine-based reinforcement learning

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Nature 2020 汇报PPT: 链接:https://pan.baidu.com/s/1RWx6miX6iZUNgNfV9B69FQ ...

  10. ACM集训第一次积分赛赛前复习+day4

    不知不觉4天过去了,我们迎来了我们第一次积分赛,赛前的四天我们学了以下知识点吧: day 1.排序 之前一直想用qsort,但是总是写不明白,STL的sort()可以说是很方便了. 先写一个最基础的数 ...