SSM 實戰項目①丨圖書管理系統 丨(1) SSM 整合

SSM整合

本篇隸屬於《SSM 實戰項目①丨圖書管理系統 》

詳情請見:SSM 實戰項目①丨圖書管理系統 丨(0) 項目概要及本系列介紹

本篇內容可作爲 SSM 開發的基礎代碼框架使用,相關代碼已單獨抽離出來放在 Github 上。

Github 鏈接爲:SSM 整合通用框架


一、創建 Maven 工程

1. 創建 Maven 的 webapp 工程
image-20200605195157076
2. 輸入項目名
image-20200605195255576
3. 建立相應的文件夾

這個是初始狀況,很顯然是不夠的,這裏連個寫 java 代碼的地方都沒有。

image-20200605195518456

這裏要注意在創建文件夾的時候要爲重要的文件夾做相應的綁定操作,具體如下:

image-20200605195715467

後面的 resources 和 test 同上進行綁定處理。

爲減小篇幅,下面直接附上結果圖:

image-20200605200404880

二、引入 jar 包

Maven 中央倉庫連接:Maven 中央倉庫

1. Spring 相關包
  • springmvc(引入spring的核心包和springmvc)
<!--springMVC-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.0.2.RELEASE</version>
</dependency>
  • spring-jdbc(事務控制)
<!--spring jdbc-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>5.0.2.RELEASE</version>
</dependency>
  • spring-apects(面向切面編程,基於配置的事務控制會用到)
<!--spring 面向切面編程-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>5.0.2.RELEASE</version>
</dependency>
2. Mybatis 相關包
  • Mybatis 基礎包
<!--mybatis-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.4.5</version>
</dependency>
  • Mybatis 和 Spring 整合的適配包
<!--spring mybatis-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>1.3.1</version>
</dependency>
  • Mybatis Generator(逆向工程代碼生成器)
<!-- mybatis generator -->
<dependency>
  <groupId>org.mybatis.generator</groupId>
  <artifactId>mybatis-generator-core</artifactId>
  <version>1.3.5</version>
</dependency>
3. 數據庫連接池及驅動
  • c3p0
<!--c3p0-->
<dependency>
  <groupId>c3p0</groupId>
  <artifactId>c3p0</artifactId>
  <version>0.9.1.2</version>
</dependency>
  • Mysql 數據庫驅動
<!--mysql-->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.19</version>
</dependency>
4. 測試相關包
  • junit
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

PS:Spring 5 搭配的 Junit 版本必須在 4.12 及以上,否則項目運行會報錯。

  • spring-test
<!--test-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.0.2.RELEASE</version>
</dependency>
5. Java Web 相關包
  • jstl
<!--jstl-->
<dependency>
  <groupId>jstl</groupId>
  <artifactId>jstl</artifactId>
  <version>1.2</version>
</dependency>
  • servlet-api
<!--servlet-->
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>
  • jsp-api
<!--jsp-api-->
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.1</version>
  <scope>provided</scope>
</dependency>

這個 jar 包尚硅谷的教學視頻裏面沒有引入,但是筆者開發時不引入這個 jar 包的時候在 jsp 頁面中寫代碼會出現一點小問題。

6. 數據校驗相關包
  • JSR303 數據校驗(後端校驗的時候可以用)
<!--JSR303數據校驗-->
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>6.1.0.Final</version>
</dependency>
7. 分頁查詢支持
  • pageHelper
<!--pageHelper-->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.0.0</version>
</dependency>
8. Json 數據綁定
  • Jackson-databind(我們這個項目後端傳給前端的數據統一封裝成 json 數據串)
<!-- jackson -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.9.10.4</version>
</dependency>

三、Tomcat 配置

1. 添加 Tomcat Server

image-20200605212914266

2. 部署

image-20200605213017160

關於這兩個部署路徑有什麼區別,可以參考下面的文章,其中的 404 Not Found 有涉及到:

使用SpringMVC進行跨服務器上傳文件出現的那些坑

3. 更改應用上下文

image-20200605213139814

這樣就部署完成了,這個應該比較簡單。

四、引入 Bootstrap(可選)

1. 官網下載 Bootstrap

官網:Bootstrap

2. 官網下載 jQuery(Bootstrap的js文件用到了jQuery、我們後面數據解析也用到了 jQuery)

官網:jQuery官網

jQuery API 中文文檔:jQuery API

3. 將Bootstrap 和 jQuery 加入項目中
image-20200605211615714
4. 在 jsp 中引入 Bootstrap 和 jQuery
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page isELIgnored="false" %>
<html>
<head>
    <%
        pageContext.setAttribute("APP_PATH",request.getContextPath()); //以 "/"開始,不以 "/" 結束
    %>
    <meta http-equiv="Content-Type" content="text/html" charset=UTF-8>
    <title>主界面</title>

    <!-- 引入 jQuery,要在引入 Bootstrap 之前 -->
    <script type="text/javascript" src="${APP_PATH}/static/js/jquery-1.11.3.js"></script>
    <!-- 引入 Bootstrap 的 js 文件 -->
    <script type="text/javascript" src="${APP_PATH}/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <!-- 引入 Bootstrap 的 css 文件 -->
    <link href="${APP_PATH}/static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- 引入自定義的 css 文件-->
    <link href="${APP_PATH}/static/css/login.css" rel="stylesheet">
</head>

這裏資源路徑的設置方式可以參考下面兩篇文章。

總結來說就是我們利用 request.getContextPath() 來獲取項目的根路徑並存放到 pageContext 域中(這個ContextPath其實就是我們上面的”更改應用上下文“),爲其設置名稱”APP_PATH“,我們要取出這個值的時候只需要利用 EL 表達式 ${APP_PATH} 取出來即可。

這樣我們整個項目的資源路徑問題就可以統一起來 —— 以服務器的根路徑爲基準

所以比如我們要訪問 jQuery 源碼的時候,直接:src="${APP_PATH}/static/js/jquery-1.11.3.js"。

JavaWeb 項目中的相對路徑問題

request.getContextPath() 路徑正確但是資源加載不出來的解決方案

5. 測試 Bootstrap 是否導入成功

用一個按鈕即可測試Bootstrap 是否導入成功。

  • 不用 Bootstrap

image-20200605214314797

  • 使用 Bootstrap 樣式

    • 上官方文檔查閱資料

      image-20200605214418313

    • 複製我們需要用的 class 就可以了,我們這裏演示紅色按鈕

      <body>
          <button type="button" class="btn-danger">按鈕</button>
      </body>
      

    image-20200605214632898

這就說明我們的 Bootstrap 引入成功啦~


下面將開始編寫 SSM 整合的關鍵配置文件,主要有5個部分:

  • web.xml
  • Spring
  • SpringMVC
  • Mybatis
  • Mybatis Generator

配置文件所在位置如下:

image-20200605232056691


五、編寫 web.xml

web.xml 配置文件主要是配置 JavaWeb 相關的東西,比如監聽器、前端控制器、字符編碼過濾器、請求轉換器等等。

1. 配置項目一啓動,就加載 Spring 的容器
  <!--1、配置項目一啓動,就加載 Spring 的容器-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

  <!--1-2 配置監聽器:當項目加載的時候就監聽 Spring 的配置文件 applicationContext.xml-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
2. 配置 SpringMVC 的前端控制器
  <!-- 2、配置 SpringMVC 的前端控制器 -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
3. 配置編碼過濾器
  <!-- 3、配置字符編碼過濾器,必須放在所有過濾器之前 -->
  <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>
    <!--配置強制請求編碼都爲utf-8-->
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
4. 配置請求方式的過濾器
  <!--4、使用 REST 風格 URI,將頁面普通的 POST 請求轉爲指定的 DELETE 或 PUT 請求-->
  <filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!--過濾PUT請求,將其轉爲POST-->
  <filter>
    <filter-name>httpPutFormContentFilter</filter-name>
    <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>httpPutFormContentFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

本項目我們接口都遵循 Restful 風格。

Restful 風格可以參考本文:SSM 實戰項目①丨圖書管理系統 丨技術儲備丨(2)RESTful API 接口設計總結

也可以參考其他博主寫的文章,筆者覺得非常不錯:RESTful API 設計指南

百度百科:RESTful

六、編寫 dispatcherServlet-servlet.xml

這是 SpringMVC 的配置文件,包含網站跳轉邏輯的控制和配置 (該配置文件必須放在跟 web.xml 同級的目錄下)。

1. 配置要掃描的包
    <!-- 1. 配置要掃描的包,
        這裏因爲它是SpringMVC的配置文件,只需要掃描控制器,所以我們配置只掃描控制器 context:include-filter
        要使這個配置生效,我們還需要禁用它默認的過濾規則  use-default-filters="false"
    -->
    <context:component-scan base-package="com" use-default-filters="false">
        <!-- 只掃描控制器 -->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
2. 配置視圖解析器:方便頁面返回解析
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/views/"></property>
  <property name="suffix" value=".jsp"></property>
</bean>
3. 將 SpringMVC 不能處理的請求交給 Tomcat:這樣靜態資源和動態資源都可以請求到了
<mvc:default-servlet-handler/>
4. 配置 SpringMVC 的註解支持,使其支持一些更高級的功能:如 JSR303 校驗,快捷的 AJAX 請求,映射動態請求
<mvc:annotation-driven/>

七、編寫 jdbcconfig.properties

這是數據庫的配置文件

dbc.jdbcUrl = jdbc:mysql://localhost:3306/luojia_library_db?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8
jdbc.driverClass = com.mysql.cj.jdbc.Driver
jdbc.user = root
jdbc.password = root

八、編寫 applicationContext.xml

這是 Spring 的配置文件:主要配置和業務邏輯有關的。

Spring 配置文件的核心點 總結:

  • 數據源(1-3)

  • 與 Mybatis 整合(4-5)

  • 事務控制(6-8)

  • 批量操作支持(9)

0. 引入 schema
<?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
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">
1. 配置要掃描的包:和SpringMVC 不同的是,它除了 controller 之外的都要
<context:component-scan base-package="com">
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
2. 引入外部的數據庫配置文件
<context:property-placeholder location="classpath:jdbcconfig.properties"></context:property-placeholder>
3. 數據源
<bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>
4. 配置和 Mybatis 的整合
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 4-1 指定 Mybatis 全局配置文件的位置 -->
    <property name="configLocation" value="classpath:mybatis-config.xml" ></property>
    <!-- 4-2 指定數據源 -->
    <property name="dataSource" ref="pooledDataSource"></property>
    <!-- 4-3 指定 Mapper 配置文件 -->
    <property name="mapperLocations" value="classpath:mapper/*.xml" ></property>
</bean>
5. 配置掃描器,將 Mybatis 接口的實現加入到 ioC 容器中
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 5-1 掃描所以的 dao 接口的實現,加入到 Spring IoC 容器中-->
    <property name="basePackage" value="com.dao"></property>
</bean>
6. 配置事務控制
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- 6-1 控制住數據源 -->
    <property name="dataSource" ref="pooledDataSource"></property>
</bean>
7. 啓基於註解的事務 or 使用 xml 配置形式的事務 (推薦後者)
<aop:config>
    <!-- 7-1 配置切入點表達式 -->
    <aop:pointcut id="txPoint" expression="execution(*e com.service..*(..))"/>
    <!-- 7-2 配置事務增強 -->
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"></aop:advisor>
</aop:config>
8. 配置事務增強
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <!-- 8-1 配置切入點切入的所有方法都是事務方法 -->
        <tx:method name="*"/>
        <!--8-2 配置所有get開頭的方法都是自讀的:安全性更強-->
        <tx:method name="get*" read-only="true"/>
    </tx:attributes>
</tx:advice>
9. 配置可以批量操作的sqlSession
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
    <constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>

九、編寫 mybatis-config.xml

這是 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">

                <!-- Mybatis 的全局配置文件 -->
<configuration>
    
    <settings>
        <!-- 1、開啓駝峯命名規則 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <!-- 2、起別名 -->
        <package name="com.bean"/>
    </typeAliases>

    <!--註冊 PageHelper-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--分頁合理化-->
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>

</configuration>

十、編寫mbg.xml

這是 Mybatis Generator 的配置文件,主要是設置生成的 bean/dao/mapper 的位置和規範。

Mybatis Generator 官網:Mybatis Generator

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>


    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 7. 默認生成的文件裏面是有註釋的,不要註釋 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>


        <!-- 1. 配置數據庫連接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/luojia_library_db"
                        userId="root"
                        password="root">
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>


        <!-- 2. Java 類型解析-->
        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- 3. 指定 javaBean 生成位置-->
        <javaModelGenerator targetPackage="com.bean" targetProject="./src/main/java"> <!--用"/"而不用"\"-->
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!-- 4. 指定 sql 映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="mapper"  targetProject="./src/main/resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- 5. 指定 dao 接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.dao"  targetProject="./src/main/java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!-- 6. 指定每個表的生成策略 -->
<!--        <table tableName="library_tbl" domainObjectName="Library"></table>-->
<!--        <table tableName="manager_tbl" domainObjectName="Manager"></table>-->
<!--        <table tableName="reader_tbl" domainObjectName="Reader"></table>-->
<!--        <table tableName="book_type_tbl" domainObjectName="BookType"></table>-->
<!--        <table tableName="book_tbl" domainObjectName="Book"></table>-->
<!--        <table tableName="bookcase_tbl" domainObjectName="Bookcase"></table>-->
<!--        <table tableName="book_toborrow_tbl" domainObjectName="BookToBorrow"></table>-->
<!--        <table tableName="book_return_tbl" domainObjectName="BookReturn"></table>-->
    </context>
</generatorConfiguration>

配置文件基本就告一段落了,正所謂:約定>配置>編碼。所以這個部分搞懂非常重要。而且,其實這部分都比較通用,整理出來,也便於日後複用。


十一、利用 Mybatis Generator 逆向工程生成 bean/dao/mapper

參考下面文章:

SSM 實戰項目①丨圖書管理系統 丨(2) Mybatis Generator 的基本使用

@Test
public void test() throws Exception{
    List<String> warnings = new ArrayList<String>();
    boolean overwrite = true;
    File configFile = new File("mbg.xml");
    ConfigurationParser cp = new ConfigurationParser(warnings);
    Configuration config = cp.parseConfiguration(configFile);
    DefaultShellCallback callback = new DefaultShellCallback(overwrite);
    MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
    myBatisGenerator.generate(null);
}

image-20200606110825352

十二、對 MBG 自動生成的文件進行改造,使其支持多表查詢

參考下面文章

SSM 實戰項目①丨圖書管理系統 丨(3) MyBatis Generator 拓展:支持多表聯合操作

十三、測試 Mapper

上面文章的鏈接中已經包含了測試部分,這裏爲了減小篇幅,就不贅述了~

到這裏,整個 SSM 高級整理就結束啦~筆者已將這部分單獨抽離出來分享到 Github 上,有需要的讀者可以在本篇文章的開頭拿到 Github 地址。


  • 學習資料推薦

筆者在學習 SSM 整合的時候,是參考了尚硅谷的一個教學視頻,覺得非常不錯,這裏推薦一下,本篇內容跟視頻中的P1-P12基本吻合。

尚硅谷SSM框架實戰,ssm整合教程


如有紕漏之處,還望不吝指出~

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