整合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. mapper.xml文件中传入list参数报错 ‘ ’附近有语法错误

    mapper.xml文件中传入list参数,使用foreach循环遍历值,但是在遍历的过程中出错了,具体代码如下所示 mapper.xml <select id="selectByCo ...

  2. C#LeetCode刷题-极小化极大

    极小化极大篇 # 题名 刷题 通过率 难度 375 猜数字大小 II   23.4% 中等 464 我能赢吗   25.5% 中等 486 预测赢家   40.4% 中等 843 猜猜这个单词   2 ...

  3. C#算法设计排序篇之02-快速排序(附带动画演示程序)

    快速排序(Quick Sort) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/677 访问. 快速排序由C. A. R ...

  4. JavaScript npm/nrm 切换安装依赖的镜像源

    nrm: npm registry manager npm 镜像源管理工具 安装nrm npm install -g nrm 查看所有的镜像源 nrm ls # nrm ls npm -------- ...

  5. Umlet和draw.io 使用心得

    文章目录 软件使用心得 1. Umlet 画图软件 1.1 前言 1.2 优点 1.3使用小trick 1.3.1 灵活改变箭头形式 1.3.2 整体复制 1.3.3 快速复制 2. draw.io ...

  6. golang 标准库

    前言 不做文字搬运工,多做思路整理 就是为了能速览标准库,只整理我自己看过的...... 最好能看看英文的 标准库 fmt strconv string 跳转 golang知识库总结

  7. 精灵小巧的 Jsonpath 万精油:Snack3

    前几天和一个群里的朋友交流一个需求:在 Json 里像 XPath 一样找出节点,并修改值,然后输出新的Json. 很多人马上就会说,Jsonpath 啊. 是的 Jsonpath 确实能快速找出节点 ...

  8. Android TextView 字数过多,用跑马灯滚动形式实现

    上代码: <TextView android:layout_width="120dp" android:layout_height="wrap_content&qu ...

  9. React 17 要来了,非常特别的一版

    写在前面 React 最近发布了v17.0.0-rc.0,距上一个大版本v16.0(发布于 2017/9/27)已经过去近 3 年了 与新特性云集的 React 16及先前的大版本相比,React 1 ...

  10. 【测试技术分享】Liunx常用操作命令集合

    Linux命令 ls 查看文件目录内容 ls -lha  l:详细信息 h:人性化显示 a:查看隐藏目录 ls -目录名  查看指定目录 d rwx rwx rwx d:文件夹 -:文件 rwx:拥有 ...