SSM整合案例之書籍管理系統(超級詳細)

寫在前面:爲了應付面試,前幾天剛剛🦌完SSM框架黑馬的全部的視頻,並且做了筆記,最後還跟視頻着做了SSM的整合小案例,說實話這玩意然我覺得只學了個大概,感覺🚹的還在後頭,於是想多學着做幾個小demo,然後自己做一個項目帶去面試,在B站上面學了kuang神的SSM整合案例,覺得講的還不錯,當然自己敲的時候從中還遇到很多的問題,特來記錄一下。

1. 開發流程

2. 需求分析

實現一個書籍的管理系統,可以實現對書籍進行增刪改的操作。

3. 整合SSM流程

3.1 IDE開發環境

  • IDEA

  • MySQL 5.7

  • Tomcat 8.5

  • Maven 3.6

要求:需要熟練掌握MySQL數據庫,Spring,JavaWeb及MyBatis知識,簡單的前端知識;

3.2 數據庫環境

CREATE DATABASE `ssmbuild`;

USE `ssmbuild`;

DROP TABLE IF EXISTS `books`;

CREATE TABLE `books` (
`bookID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '書id',
`bookName` VARCHAR(100) NOT NULL COMMENT '書名', -- COMMENT 給字段名註釋
`bookCounts` INT(11) 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.3 pojo實體類

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {

    private int bookID;
    private String bookName;
    private int bookCounts;
    private String detail;

}

@Data
@AllArgsConstructor
@NoArgsConstructor
上面三個註解的作用可以直接生成我們常用的實體類方法,但是需要導入

        <!--導入Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

如下
在這裏插入圖片描述

3.4 maven基本環境

  1. 創建maven工程,選擇無骨架創建
    在這裏插入圖片描述在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述
  2. 導入項目所需依賴座標,在pom.xml文件中
<dependencies>
        <!--Junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--數據庫驅動-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- 數據庫連接池 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>

        <!--Servlet - JSP -->
        <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</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.2</version>
        </dependency>

        <!--Spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <!--導入Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>

        <!--添加事務-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>
    </dependencies>
  1. 建立項目目錄的基本結構和配置框架在這裏插入圖片描述
    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>

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>

3.5 MyBatis層編寫

3.5.1 dao層相關的代碼

  1. 準備數據庫配置文件

    1. 在resources資源文件中新建配置文件
      在這裏插入圖片描述

    2. 配置信息

      jdbc.driver=com.mysql.jdbc.Driver
      jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=utf8
      jdbc.username=root
      jdbc.password=123456
      
  2. 編寫mybatis-config.xml

    <!--爲pojo類取別名-->
    <typeAliases>
        <package name="com.liuzeyu.pojo"/>
    </typeAliases>

    <!--直接映射到掃描的接口包-->
    <mappers>
        <package name="com.liuzeyu.dao"/>
    </mappers>
  1. 編寫dao層接口

在這裏插入圖片描述

public interface BookMapper {

    //增加一個Book
    void addBook(Books books);

    //根據id刪除一個book
    void deleteBookById(@Param("bookId") int id);

    //更新Booke
    int updateBook(Books books);

    //根據id查詢
    Books queryBookById(@Param("bookId") int id);

    //查詢全部
    List<Books> findAll();

    //根據名稱模糊查詢
    List<Books> queryBook(@Param("bookName") String name);
}

  1. 編寫接口映射配置文件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.liuzeyu.dao.BookMapper">
    <!--新增books-->
    <select id="addBook" parameterType="books">
        insert into books(bookName,bookCounts,detail) values(#{bookName},#{bookCounts},#{detail});
    </select>
    <!--根據id刪除books-->
    <delete id="deleteBookById" parameterType="INT">
        delete from ssmbuild.books where bookID = #{bookId};
    </delete>
    <!--更新books-->
    <update id="updateBook" parameterType="books">
        update books set bookName = #{bookName},bookCounts=#{bookCounts},detail=#{detail} where bookID=#{bookID};
    </update>
    <!--根據id查詢-->
    <select id="queryBookById" parameterType="INT" resultType="books">
        select * from books where bookId=#{bookId};
    </select>
    <!--查詢全部-->
    <select id="findAll" resultType="Books">
        select * from books;
    </select>

    <!--根據名稱模糊查詢-->
    <select id="queryBook" resultType="Books">
        select * from books where bookName LIKE #{bookName};
    </select>
</mapper>

其中@Param就是爲了和接口的配置文件中的變量做映射的關係
在這裏插入圖片描述

3.5.2 service層相關的代碼

在這裏插入圖片描述

  1. service接口
public interface BookService {

    //增加一個Book
    void addBook(Books books);

    //根據id刪除一個book
    void deleteBookById(int id);

    //更新Booke
    int updateBook(Books books);

    //根據id查詢
    Books queryBookById(int id);

    //查詢全部
    List<Books> findAll();

    //根據名稱模糊查詢
    List<Books> queryBook(String name);
}

  1. 接口實現類
public class BookServiceImpl implements BookService{

    private BookMapper bookMapper = null;

    public void setBookMapper(BookMapper bookMapper) {
        this.bookMapper = bookMapper;
    }

    public void addBook(Books books) {
        bookMapper.addBook(books);
    }

    public void deleteBookById(int id) {
        bookMapper.deleteBookById(id);
    }

    public int updateBook(Books books) {
        return bookMapper.updateBook(books);
    }

    public Books queryBookById(int id) {
        Books books = bookMapper.queryBookById(id);
        return books;
    }

    public List<Books> findAll() {
        List<Books> booksList = bookMapper.findAll();
        return booksList;
    }

    public List<Books> queryBook(String name) {
        return bookMapper.queryBook(name);
    }
}

OK,到此處我們持久層和業務層的代碼編寫告一段落。

3.6 Spring層編寫

3.6.1 Spring整合mybatis

在resources下準備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">

    <!--配置spring整合mybatis,這裏的數據源使用c3p0-->
    <!--1. 加載數據庫配置文件-->
    <context:property-placeholder location="classpath:database.properties"/>

    <!--2. 配置數據庫連接-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="driverClass" value="${jdbc.driver}"/>
        <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全局配置文件(指定非spring的配置文件)-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <!--配置掃描dao的接口包,動態實現dao(動態代理dao)接口注入到IOC容器中-->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--給出要掃描的dao包-->
        <property name="basePackage" value="com.liuzeyu.dao"/>
    </bean>
</beans>

3.6.2 Spring整合service

在resources下準備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"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       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
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


    <!--1. 掃描service相關的bean-->
    <context:component-scan base-package="com.liuzeyu.service"/>

    <!--2. BookServiceImpl注入到IOC容器-->
    <bean id="bookService" class="com.liuzeyu.service.impl.BookServiceImpl">
        <!--掃描到spring-dao將接口加入到容器中,ref從容器中取出-->
        <property name="bookMapper" ref="bookMapper"></property>
     </bean>

    <!--3. 配置事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入數據庫連接池-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--添加aop的事務的織入:橫切service層-->
    <!--配置事務通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--給哪些方法配置事務-->
        <tx:attributes>
            <!-- read-only:用於指定事務是否只讀,通常查詢方法設置爲只讀
            propagation:指定事務的傳播行爲,默認值爲REQUIRED用於增刪改,SUPPORT用於查詢-->
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!--配置事務的切入-->
    <aop:config>
        <aop:pointcut id="txPoint" expression="execution(* com.liuzeyu.dao.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>

</beans>

3.7 SpringMVC層編寫

3.7.1 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_3_1.xsd"
         version="3.1">


    <!--添加前端控制器-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--配置啓動加載的配置文件,注意這裏加載主配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--配置處理請求亂碼-->
    <filter>
        <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--配置session過期時間-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>
</web-app>

3.7.2 Spring整合controller

<?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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/mvc
   https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--配置springmvc-->
    <!--1. 開啓springmvc註解驅動-->
    <mvc:annotation-driven/>

    <!--2. 靜態資源默認servlet配置-->
    <mvc:default-servlet-handler/>

    <!--3. 配置jsp顯示的視圖解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--4. 掃描web相關的bean-->
    <context:component-scan base-package="com.liuzeyu.controller"/>
</beans>

3.8 Spring配置文件大整合

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="classpath:spring-dao.xml"/>
    <import resource="classpath:spring-service.xml"/>
    <import resource="classpath:spring-mvc.xml"/>

</beans>

整合先告一段落。

3.9 具體功能實現

在控制類中編寫對應的處理請求與響應的方法。
在這裏插入圖片描述

@Controller
@RequestMapping("/books")   //父目錄
public class BookController {
    @Autowired  //自動裝配BookService
    private BookService bookService = null;
}

3.9.1 書籍展示功能

  1. 請求發起index.jsp
    主要用於進入書籍頁面展示
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
  <head>
    <title>$Title$</title>

    <style>
      a{
        text-decoration: none;
        color: black;
        font-size: 18px;
      }

      h3{
        width: 180px;
        height: 40px;
        text-align: center;
        margin: 100px auto;
        line-height: 40px;
        background: deepskyblue;
        border-radius: 4px;
      }
    </style>
  </head>
  <body>

  <h3>
    <a href="books/allBooks">展示所有書籍</a>
  </h3>
  </body>
</html>

  1. BookController類:
   /**
     * 處理展示所有書籍
     * @param model
     * @return
     */
    @RequestMapping("allBooks")
    public String list(Model model){
        List<Books> list = bookService.findAll();
        System.out.println(list);
        model.addAttribute("list",list);
        return "allBooks";
    }
  1. 展示頁面allBooks.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: liuzeyu
  Date: 2020/5/1
  Time: 14:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>書籍展示</title>
    <%--引入bootstrap的cdn--%>
    <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">
        <div class="col-md-12 column">
            <div class="page-header">
                <h2>
                    <small>書籍列表 —— 顯示所有書籍</small>
                </h2>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-4 column">
            <a href="/addBook.jsp" class="btn btn-primary pull-right">新增</a>
            <span>
                <form action="/books/queryBook" method="post">
                    <input type="text" name="bookName" placeholder="書籍名稱">
                    <input type="submit" value="搜索">
                </form>
            </span>
            <a href="/books/allBooks" class="btn btn-primary pull-right">顯示全部</a>
            <span style="color: red">${nill}</span>
        </div>
    </div>

    <div class="row clearfix">
        <div class="col-md-12"></div>
        <table class="table table-hover table-striped" >
            <thead>
            <tr>
                <th>書籍編號</th>
                <th>書籍名字</th>
                <th>書籍數量</th>
                <th>書籍詳情</th>
                <th>操作</th>
            </tr>
            </thead>

            <tbody>

            <c:forEach var="book" items="${list}">
                <tr>
                    <td>${book.getBookID()}</td>
                    <td>${book.getBookName()}</td>
                    <td>${book.getBookCounts()}</td>
                    <td>${book.getDetail()}</td>

                    <td>
                        <a href="/books/query/${book.bookID}" class="button">修改</a>
                        <a href="/books/deleteBook/${book.bookID}" class="button">刪除</a>
                    </td>
                </tr>
            </c:forEach>

            </tbody>
        </table>
    </div>
</div>

</body>
</html>

使用JSTL與EL語法來展示數據。

3.9.2 書籍添加功能

  1. jsp請求頁面allBooks.jsp(見3.8.1)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: liuzeyu
  Date: 2020/5/1
  Time: 14:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>書籍展示</title>
    <%--引入bootstrap的cdn--%>
    <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">
        <div class="col-md-12 column">
            <div class="page-header">
                <h2>
                    <small>書籍列表 —— 顯示所有書籍</small>
                </h2>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-4 column">
            <a href="/addBook.jsp" class="btn btn-primary pull-right">新增</a>
            <span>
                <form action="/books/queryBook" method="post">
                    <input type="text" name="bookName" placeholder="書籍名稱">
                    <input type="submit" value="搜索">
                </form>
            </span>
            <a href="/books/allBooks" class="btn btn-primary pull-right">顯示全部</a>
            <span style="color: red">${nill}</span>
        </div>
    </div>

    <div class="row clearfix">
        <div class="col-md-12"></div>
        <table class="table table-hover table-striped" >
            <thead>
            <tr>
                <th>書籍編號</th>
                <th>書籍名字</th>
                <th>書籍數量</th>
                <th>書籍詳情</th>
                <th>操作</th>
            </tr>
            </thead>

            <tbody>

            <c:forEach var="book" items="${list}">
                <tr>
                    <td>${book.getBookID()}</td>
                    <td>${book.getBookName()}</td>
                    <td>${book.getBookCounts()}</td>
                    <td>${book.getDetail()}</td>

                    <td>
                        <a href="/books/query/${book.bookID}" class="button">修改</a>
                        <a href="/books/deleteBook/${book.bookID}" class="button">刪除</a>
                    </td>
                </tr>
            </c:forEach>

            </tbody>
        </table>
    </div>
</div>

</body>
</html>

  1. BookController類:
    /**
     * 處理保存書籍
     * @param books
     * @return
     */
    @RequestMapping("addBook")
    public String save(Books books){
            bookService.addBook(books);
        return "redirect:allBooks";
        //寫成redirect:/books/allBooks可以,寫成redirect:books/allBooks就不行
        //allBooks是相對路徑
        //寫成redirect:/books/allBooks是絕對路徑
    }

3.9.3 書籍刪除功能

  1. jsp請求頁面allBooks.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: liuzeyu
  Date: 2020/5/1
  Time: 14:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>書籍展示</title>
    <%--引入bootstrap的cdn--%>
    <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">
        <div class="col-md-12 column">
            <div class="page-header">
                <h2>
                    <small>書籍列表 —— 顯示所有書籍</small>
                </h2>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-4 column">
            <a href="/addBook.jsp" class="btn btn-primary pull-right">新增</a>
            <span>
                <form action="/books/queryBook" method="post">
                    <input type="text" name="bookName" placeholder="書籍名稱">
                    <input type="submit" value="搜索">
                </form>
            </span>
            <a href="/books/allBooks" class="btn btn-primary pull-right">顯示全部</a>
            <span style="color: red">${nill}</span>
        </div>
    </div>

    <div class="row clearfix">
        <div class="col-md-12"></div>
        <table class="table table-hover table-striped" >
            <thead>
            <tr>
                <th>書籍編號</th>
                <th>書籍名字</th>
                <th>書籍數量</th>
                <th>書籍詳情</th>
                <th>操作</th>
            </tr>
            </thead>

            <tbody>

            <c:forEach var="book" items="${list}">
                <tr>
                    <td>${book.getBookID()}</td>
                    <td>${book.getBookName()}</td>
                    <td>${book.getBookCounts()}</td>
                    <td>${book.getDetail()}</td>

                    <td>
                        <a href="/books/query/${book.bookID}" class="button">修改</a>
                        <a href="/books/deleteBook/${book.bookID}" class="button">刪除</a>
                    </td>
                </tr>
            </c:forEach>

            </tbody>
        </table>
    </div>
</div>

</body>
</html>

  1. BookController類:
    /**
     * 刪除書籍
     * @param id
     * @return
     */
    @RequestMapping("deleteBook/{bookID}")
    public String delete(@PathVariable("bookID") Integer id){
        bookService.deleteBookById(id);
        return "redirect:/books/allBooks";
    }

3.9.4 書籍修改功能

  1. jsp請求界面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: liuzeyu
  Date: 2020/5/1
  Time: 14:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>書籍展示</title>
    <%--引入bootstrap的cdn--%>
    <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">
        <div class="col-md-12 column">
            <div class="page-header">
                <h2>
                    <small>書籍列表 —— 顯示所有書籍</small>
                </h2>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-4 column">
            <a href="/addBook.jsp" class="btn btn-primary pull-right">新增</a>
            <span>
                <form action="/books/queryBook" method="post">
                    <input type="text" name="bookName" placeholder="書籍名稱">
                    <input type="submit" value="搜索">
                </form>
            </span>
            <a href="/books/allBooks" class="btn btn-primary pull-right">顯示全部</a>
            <span style="color: red">${nill}</span>
        </div>
    </div>

    <div class="row clearfix">
        <div class="col-md-12"></div>
        <table class="table table-hover table-striped" >
            <thead>
            <tr>
                <th>書籍編號</th>
                <th>書籍名字</th>
                <th>書籍數量</th>
                <th>書籍詳情</th>
                <th>操作</th>
            </tr>
            </thead>

            <tbody>

            <c:forEach var="book" items="${list}">
                <tr>
                    <td>${book.getBookID()}</td>
                    <td>${book.getBookName()}</td>
                    <td>${book.getBookCounts()}</td>
                    <td>${book.getDetail()}</td>

                    <td>
                        <a href="/books/query/${book.bookID}" class="button">修改</a>
                        <a href="/books/deleteBook/${book.bookID}" class="button">刪除</a>
                    </td>
                </tr>
            </c:forEach>

            </tbody>
        </table>
    </div>
</div>

</body>
</html>

  1. BookController類:
    /**
     * 根據id查詢books
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("query/{bookID}")
    public String update(@PathVariable("bookID") Integer id,Model model){
        Books books = bookService.queryBookById(id);
        model.addAttribute("books",books);
        return "forward:/update.jsp";   //寫成redirect:/update.jsp爲什麼獲取不到數據
    }
  1. jsp更新界面
<%--
  Created by IntelliJ IDEA.
  User: liuzeyu
  Date: 2020/5/1
  Time: 11:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
  <title>新增書籍</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <!-- 引入 Bootstrap -->
  <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

  <div class="row clearfix">
    <div class="col-md-12 column">
      <div class="page-header">
        <h1>
          <small>更新書籍</small>
        </h1>
      </div>
    </div>
  </div>
  <form action="/books/updateBooks" method="post">
    <input type="hidden" name="bookID" value="${books.getBookID()}">
    書籍名稱:<input type="text" name="bookName" value="${books.getBookName()}"><br><br><br>
    書籍數量:<input type="text" name="bookCounts" value="${books.getBookCounts()}"><br><br><br>
    書籍詳情:<input type="text" name="detail" value="${books.getDetail()}"><br><br><br>
    <input type="submit" value="更新">
  </form>

</div>

  1. BookController類:
    /**
     * 更新books
     * @param books
     * @return
     */
    @RequestMapping("updateBooks")
    public String update(Books books){
        bookService.updateBook(books);
        return "redirect:allBooks";
    }

3.9.5 書籍模糊查詢功能

  1. jsp請求界面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: liuzeyu
  Date: 2020/5/1
  Time: 14:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>書籍展示</title>
    <%--引入bootstrap的cdn--%>
    <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">
        <div class="col-md-12 column">
            <div class="page-header">
                <h2>
                    <small>書籍列表 —— 顯示所有書籍</small>
                </h2>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-4 column">
            <a href="/addBook.jsp" class="btn btn-primary pull-right">新增</a>
            <span>
                <form action="/books/queryBook" method="post">
                    <input type="text" name="bookName" placeholder="書籍名稱">
                    <input type="submit" value="搜索">
                </form>
            </span>
            <a href="/books/allBooks" class="btn btn-primary pull-right">顯示全部</a>
            <span style="color: red">${nill}</span>
        </div>
    </div>

    <div class="row clearfix">
        <div class="col-md-12"></div>
        <table class="table table-hover table-striped" >
            <thead>
            <tr>
                <th>書籍編號</th>
                <th>書籍名字</th>
                <th>書籍數量</th>
                <th>書籍詳情</th>
                <th>操作</th>
            </tr>
            </thead>

            <tbody>

            <c:forEach var="book" items="${list}">
                <tr>
                    <td>${book.getBookID()}</td>
                    <td>${book.getBookName()}</td>
                    <td>${book.getBookCounts()}</td>
                    <td>${book.getDetail()}</td>

                    <td>
                        <a href="/books/query/${book.bookID}" class="button">修改</a>
                        <a href="/books/deleteBook/${book.bookID}" class="button">刪除</a>
                    </td>
                </tr>
            </c:forEach>

            </tbody>
        </table>
    </div>
</div>

</body>
</html>

  1. BookController類
    @RequestMapping("queryBook")
    public String queryBook(String bookName,Model model){
        List<Books> list = bookService.queryBook("%"+bookName+"%");
        if(list == null || list.size() == 0){
            model.addAttribute("nill","沒有查到此類書籍");
        }
        model.addAttribute("list",list);
        return "allBooks";
    }

4. 遇到的問題及解決方案

3.5.1處

  1. JDBC的url設置安全連接爲true時,項目連接數據庫爆出異常
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=809080
HTTP Status 500 – Internal Server Error
Type Exception Report

Message Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
	org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
Root Cause

org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!

其實出現問題的具體原理還尚未清楚,但是處理方法很簡單,只需要將

useSSL=false   即可

3.4處

  1. post請求發送到服務器出現亂碼
<!--配置處理請求亂碼-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

找到過濾器的配置,發現少了初始化編碼格式

 <init-param>
     <param-name>encoding</param-name>
     <param-value>utf-8</param-value>
 </init-param>

3.7.2處

  1. 路徑跳轉的問題

重定向和轉發的區別

 * 
 *  a.瀏覽器地址有無變化
 *      轉發之後,地址欄無變化
 *      重定向之後,地址有變化
 *  b.目的地
 *      轉發的目的地有限制,只能轉發同一個web應用的(tomcat容器中)
 *      重定向的目的地沒有限制
 *  c.能否共享request和response
 *      轉發可以共享,重定向不行
 *
 *  d.發送的請求次數(可以按F12的newtwork窗口查看)
 *      重定向發送兩次,如果成功一次是304,一次是200
 *      轉發只發送一次,成功的狀態碼200

web資源的結構是

-web
	-WEB-INF
		-pages
			-allBooks.jsp
		-web.xml
	-index.jsp
	-addBook.jsp
	-update.jsp

問題:Controller方法的reuturn寫的路徑該如何寫?forward和redirec的路徑又該怎麼寫?
這個問題直接涉及到JavaWeb的知識。
在idea中,tomcat項目部署後,web資源目錄被部署到哪裏了?

ssm(項目名)
	-out
		-artifacts
			-ssm_kuang_book_war_exploded(這個目錄下的文件就是項目中web下的目錄部署後的)

幾處需要注意的返回值寫法!!

  1. 對於BookController類中的list方法,return的路徑寫法有
return "/allBooks";
return "allBooks";

和queryBook方法類似,切記不能寫後綴.jsp。

  1. save方法的返回值有兩種寫法
return "redirect:/books/allBooks";  //絕對路徑寫法
return "redirect:allBooks	//相對路徑寫法
return "redirect:books/allBooks";	//就不行
  1. 更新函數
    @RequestMapping("query/{bookID}")
    public String update(@PathVariable("bookID") Integer id,Model model){
        Books books = bookService.queryBookById(id);
        model.addAttribute("books",books);
        return "forward:/update.jsp";   //寫成redirect:/update.jsp爲什麼獲取不到數據
    }
    /**
     * 更新books
     * @param books
     * @return
     */
    @RequestMapping("updateBooks")
    public String update(Books books){
        bookService.updateBook(books);
        return "redirect:allBooks";
    }

這裏的return “forward:/update.jsp”;必須使用forward,否則不能將request查詢到的對象顯示出來,因爲forward可以在一次請求和響應間共享數據,而且數據包含在request域中也只能在一次的請求和響應間存在。如果換成重定向數據將在第一次請求時丟失,第二次請求將不再攜帶數據,所以不能使用重定向。

BookController全部代碼:

/**
 * Created by liuzeyu on 2020/5/1.
 */
@Controller
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService = null;
    /**
     * 處理展示所有書籍
     * @param model
     * @return
     */
    @RequestMapping("allBooks")
    public String list(Model model){
        List<Books> list = bookService.findAll();
        System.out.println(list);
        model.addAttribute("list",list);
        return "/allBooks";
    }
    /**
     * 處理保存書籍
     * @param books
     * @return
     */
    @RequestMapping("addBook")
    public String save(Books books){
            bookService.addBook(books);
        return "redirect:allBooks";
        //寫成redirect:/books/allBooks可以,寫成redirect:books/allBooks就不行
        //allBooks是相對路徑
        //寫成redirect:/books/allBooks是絕對路徑
    }
    /**
     * 刪除書籍
     * @param id
     * @return
     */
    @RequestMapping("deleteBook/{bookID}")
    public String delete(@PathVariable("bookID") Integer id){
        bookService.deleteBookById(id);
        return "redirect:/books/allBooks";
    }
    /**
     * 根據id查詢books
     * @param id
     * @param model
     * @return
     */
    @RequestMapping("query/{bookID}")
    public String update(@PathVariable("bookID") Integer id,Model model){
        Books books = bookService.queryBookById(id);
        model.addAttribute("books",books);
        return "forward:/update.jsp";   //寫成redirect:/update.jsp爲什麼獲取不到數據
    }
    /**
     * 更新books
     * @param books
     * @return
     */
    @RequestMapping("updateBooks")
    public String update(Books books){
        bookService.updateBook(books);
        return "redirect:allBooks";
    }

    @RequestMapping("queryBook")
    public String queryBook(String bookName,Model model){
        List<Books> list = bookService.queryBook("%"+bookName+"%");
        if(list == null || list.size() == 0){
            model.addAttribute("nill","沒有查到此類書籍");
        }
        model.addAttribute("list",list);
        return "allBooks";
    }
}

3.3處

  1. 如果idea遇到按Alt +7無法類的方法,如下
    在這裏插入圖片描述
    應該是沒有安裝Lombok插件,進入idea 的setting->Plugings安裝後,重啓idea即可
    在這裏插入圖片描述

5. 總結

已經接觸了兩個SSM整合小案例,發現整合的手段不盡相同,最大的區別在於配置文件的整合順序,但是配置內容都是大同小異。此項目還有很多需要優化的地方,例如可以增加登錄註冊功能,並且添加攔截器過濾器等,許多值得優化的地方值得我再去深入學習SSM。

Github:https://github.com/liuzeyu12a/ssm-/tree/master

如有出入,懇請指教

不積跬步無以至千里,不積小流無以成江海。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章