Spring、SpringMVC、Mybatis整合之工程的搭建
SSM框架整合之環境配置部分
學習完了Spring、SpringMVC、Mybatis框架,我們就可以嘗試系統將三者進行整合。整合並不複雜,我們只需要實現最基礎的配置,即可輕鬆的掌握SSM框架是如何實際專案中使用的。
基於上一篇博文:maven起步,我們應該知道了如何搭建maven專案,那麼在此基礎上,手把手教你搭建Spring、SpringMVC、Mybatis框架的環境。
原始碼請 點選這裡 前往我的GitHub。
關於專案
專案環境
專案框架:後端:spring+mybatis+springmvc; 前端:bootstrap+Font Awesome圖示集 測試環境:IDEA+tomcat7+mysql5.7+jdk8+maven 資料庫名稱:ssm
專案功能
1. 使用者登入
2. 客戶資訊的增、刪、改、查
3. 客戶資訊的列表展示和分頁查詢功能
專案結構
directory.png
備註
如上這是一個標準的maven專案(對maven專案的搭建有不懂的可以檢視我的博文:maven起步
img: 放了一些README.md文件所需要得圖片,沒有實際意義。
controller: web層,存放springmvc的相關控制器類。
mapper: 存放介面和對映檔案。因為本專案採用了mybatis的介面開發,所以需要將介面和對映檔案放在同一目錄下,並且名稱相同。
pojo: 存放Java的實體類
service: 業務層,用於存放一些業務層程式碼。
不要奇怪為什麼沒有出現Dao層,因為本專案相對簡單,並沒有多複雜的邏輯,所以也就必要再寫一個Dao層進行擴充套件。
resources: 是maven專案存放配置檔案的根目錄,在本例中包含兩個子資料夾:
resource
、spring
。前者是存放一些如logback.properties
的配置檔案;後者是存放spring的配置檔案(spring和springmvc)。my.sql: 存放了關於專案資料庫建立和表建立的SQL語句。
fonts: 存放一些字型的配置檔案。為了頁面的美感,我們採用了Awesome
圖示集。lib: 包含了專案中用到的一些前端類庫。
page: 包含所有前端頁面。
整合思路
繼上一篇博文:Spring MVC起步其實我們已經瞭解瞭如何整合Spring和Spring MVC框架。那麼,接下來我們就需要了解如何在此基礎上整合Mybatis框架。
首先須知Mybatis框架是一個持久層框架,而Spring MVC是WEB層框架,Spring框架則充當著業務層的角色。那麼將三者聯絡起來正好組成了web--service--dao
的三層架構體系。那麼整合思路就如下所示了:
- 整合dao(即mapper),實現Mybatis和Spring的整合
- 整合service,由Spring管理service介面,在service中可以呼叫dao(mapper)
- 整合web(controller),實現Spring MVC和Spring的整合,在controller中呼叫service
jar依賴
<dependencys>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- 1.日誌 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 2.資料庫 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- DAO: MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 3.Servlet web -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 4.Spring -->
<!-- 1)Spring核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!-- 2)Spring DAO層 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!-- 3)Spring web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<!-- 4)Spring test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
</dependencies>
以上是SSM框架最基本的依賴配置,很多時候專案中的報錯是因為jar包衝突,為避免儘量採用同一版本的jar依賴。
注: 因為本專案使用的是IDEA,我們還需要在pom.xml中寫入以下配置,以便IDEA能夠檢測到maven工程非resources目錄下的配置檔案
<build>
<finalName>ssm</finalName>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
XML配置檔案
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_paging?useUnicode=true&characterEncoding=UTF-8
jdbc.username=使用者名稱
jdbc.password=密碼
把資料庫資訊單獨提取到一個檔案中,在XML中先使用<context:property-placeholder>
載入配置檔案,然後使用${jdbc.xx}
的格式呼叫即可。
注意:在jdbc.url屬性中對應的資料庫連結要規定字元編碼為UTF-8,因為我遇到的情況就是我在建立資料庫和表的時候都指定了字符集,但是前臺儲存進來的資料還是會亂碼,就是專案在連結資料庫時沒有指定字元編碼的原因
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>/WEB-INF/index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置spring的字元編碼過濾器,保證request請求的中文字元不會亂碼(注意這個過濾器要放到最前面) -->
<filter>
<filter-name>CharacterEncoding</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>CharacterEncoding</filter-name>
<!-- 設定這個字元編碼過濾器作用與每一個請求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置Spring的servlet監聽器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 載入spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/beans.xml</param-value>
</context-param>
<!-- 配置springmvc的前端控制器,request請求會先經過這個控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 同時載入Spring MVC的配置檔案。request經過了前端控制器接下來就根據對映器判斷該請求需要走哪個控制器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<!-- *.do 表示我們請求對映路徑字尾為.do, 我們也可以設定為/ -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
在web.xml
中的配置主要是三方面:
- 配置Spring的字元編碼過濾器:
CharacterEncodingFilter
(防止request請求中文亂碼)。 - 配置Spring的servlet監聽器:
ContextLoaderListener
,告訴Spring需要載入那哪些配置檔案來完成Spring的上下文。配置檔案通過contextConfigLocation
指定。 - 配置Spring MVC的前端控制器(所有的request請求都會先經過這個前端控制器)。
beans.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
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置註解掃描 -->
<context:component-scan base-package="cn.tycoding.service"/>
<!-- 載入配置檔案 -->
<context:property-placeholder location="classpath:resource/jdbc.properties"/>
<!-- 資料庫連線池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 配置連線池屬性 -->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- c3p0連線池的私有屬性 -->
<property name="maxPoolSize" value="30" />
<property name="minPoolSize" value="10" />
<!-- 關閉連線後不自動commit -->
<property name="autoCommitOnClose" value="false" />
<!-- 獲取連線超時時間 -->
<property name="checkoutTimeout" value="10000" />
<!-- 當獲取連線失敗重試次數 -->
<property name="acquireRetryAttempts" value="2" />
</bean>
<!-- 配置SqlSessionFactory物件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入資料庫連線池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 掃描pojo包,使用別名配置(在mybatis中可以使用別名,即pojo的名稱) -->
<property name="typeAliasesPackage" value="cn.tycoding.pojo"/>
<!-- 掃描mapper的配置檔案 -->
<property name="mapperLocations" value="classpath:cn/tycoding/mapper/*.xml"/>
<!--也可以引入mybatis配置檔案 -->
<!--<property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml"/>-->
</bean>
<!-- 使用mybatis的介面代理開發模式(必須保證介面和對應的mybatis的xml名稱相同,且在一個資料夾內) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.tycoding.mapper"/>
<!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>-->
</bean>
</beans>
備註:
本例中beans.xml
主要配置兩塊內容:1.連線池;2.Mybatis-Spring的配置
(當然可能這並不很標準,例如一些事物管理器,在這裡我並沒有配置;同樣,你還可以將相關的Mybatis的配置提取出來,只要在最後web.xml
中載入這個配置檔案就可以了。
SqlSessionFactoryBean
Spring框架簡化資料庫訪問的方式之一就是管理資料庫連線的宣告週期和ORM框架的Session,以確保他們正常的開啟和關閉。而在mybatis-spring中,SqlSessionFactoryBean實現了Spring的FactoryBean介面,用於建立SqlSessionFactory
。
dataSource
是必要的配置,上面我們僅僅是寫了資料來源配置,接下來的資料庫訪問物件肯定要使用這個資料來源來獲取連結物件,所以必須指定資料來源。typeAliases
則是啟用別名配置,typeAliasesPackage
則會為pojo
包下的所有類物件都配置別名,當我們在對應的XML對映中指定ResultType
等時,就可以直接寫pojo的類名,而不需要寫全限定名。mapperLocations
: 用於指定Mapper的XML檔案位置(對於那種Mapper介面和XML配置同名且在同一個配置資料夾下,Mybatis其實會根據Mapper的Class檔案自動找對應的XML配置檔案,但是這裡我建議寫上)。configLocation
: 用於指定mybatis的配置檔案位置,因為本專案中並沒有涉及太多複雜的邏輯,所以這裡我就沒有特意配置mybatis的config。
MapperScannerConfigurer
在瞭解MapperScannerConfigurer
之前我們需要了解一下MapperFactoryBean
,Mybatis-Spring提供了一個動態代理的實現:MapperFactoryBean
,他能實現將對映器介面(因為代理建立在執行環境中,那麼指定的對映器必須是介面而不是實現類)直接注入到service的Bean中。這樣通過代理物件去建立編寫資料訪問物件,從而代替SqlSessionTepmlate
等工具。
但是在Mybatis-Spring中還提供了一個轉換器MapperScannerConfigurer
,它會查詢類路徑下的對映器(介面)並自動將他們建立成MapperFactoryBean
。通過將介面轉換成Spring容器中的Bean,在Service層直接注入介面即可,這樣大大簡化了Dao層例項的編寫。basePackage
正是指定介面的位置。
注意我們這裡並不需要指定SqlSessionFactory
(即我們註釋掉的部分),因為使用MapperScannerConfigurer
會建立MapperFactoryBean
後自動裝配(XML配置)。但是如果存在多個dataSource
,該自動裝配可能就會失效,這時我們必須使用sqlSessionFacoryBeanName
來指定引用哪個bean
。
在beans.xml
配置階段算是基本告一段落,我們回想一下:在沒有使用Mybatis前我們使用Spring提供的JDBC模板來訪問資料庫,我們發現這種方式程式碼量特別大,而且於Java程式碼的耦合性也比較大,Mybatis則正好彌補了這些缺點,它使用的XML配置更加的小巧方便且支援原生SQL的編寫。
Mybatis-Spring提供了移動動態代理的方式來代替手工的SqlSessionTemplate
編寫資料庫訪問物件,我們只需要編寫一個介面,通過在Mapper對應的XML中直接寫SQL就可以進行資料庫訪問。當然我們必須配置SqlSessionFactoryBean
和MapperScannerConfigurer
。
springmvc.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/context/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 開啟註解掃描 -->
<context:component-scan base-package="com.TyCoding.controller"/>
<!-- 配置springmvc的基本控制器,並開啟了對json資料格式的支援 -->
<mvc:annotation-driven/>
<!-- 配置springmvc的檢視解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
在博文初識Spring MVC我們已經對SpringMVC有了一定的瞭解。那麼在這裡我們回顧一下SpringMVC的架構設計:
1.png
那麼SpringMVC的XML無非就是:
- 配置SpringMVC前端控制器。
- 配置SpringMVC的基本控制器(處理請求的Spring元件)。
- 配置檢視解析器。
所以:
- 首先在
web.xml
中配置SpringMVC的前端控制器:DispatcherServlet
。 - 在
springmvc.xml
中配置SpringMVC的基本控制器:<mvc:annotation-driven>
(註解驅動方式)。 - 開啟註解掃描:
<context:component-scan>
,主要掃描Controller層的註解(因為SpringMVC是web層框架)。 - 配置SpringMVC的檢視解析器:
InternalResourceViewResolver
,用於當Controller處理完請求後將處理後的資料結果返回給檢視層(JSP等)。
配置pojo和sql
pojo
在專案pojo
資料夾下建立User.java
和Customer.java
以及PageBean.java
1.User
//使用者id
private int uid;
//使用者登入名
private String username;
//使用者密碼
private String password;
...
getter/setter方法省略
2.Customer
//客戶的id
private int c_id;
//客戶的姓名
private String c_name;
//客戶的電話
private String c_telephone;
//客戶的住址
private String c_address;
//客戶備註
private String c_remark;
...
getter/setter方法省略
3.PageBeanPageBean
為實現分頁瘋轉給的JavaBean,詳細欄位屬性請檢視註釋。
public class PageBean<T> implements Serializable {
//當前頁
private int pageCode;
//總頁數=總條數/每頁顯示的條數
private int totalPage;
//總記錄數
private int totalCount;
//每頁顯示的記錄條數
private int pageSize;
//每頁顯示的資料
private List<T> beanList;
}
這裡用了自定義泛型類<T>
就是實現由後臺決定這個分頁Bean要去封裝那種型別的資料,我們呼叫時傳入型別就會封裝什麼型別資料。比如我們需要對Customer分頁,在呼叫這個類是就寫new PageBean<Customer>()
。那麼資料就會強制繫結為這個Customer
類的資料。
sql
建立資料庫並編寫專案所需要的表結構,寫入測試資料。
create database ssm character set utf8;
use ssm;
create table user(
uid int primary key auto_increment,
username varchar(100),
password varchar(100)
) default charset = utf8;
create table customer(
c_id int primary key auto_increment,
c_name varchar(100),
c_telephone varchar(100),
c_address varchar(100),
c_remark varchar(100)
) default charset = utf8;
# 插入資料
insert into user values(1,'admin','admin');
insert into customer values(1,'塗陌','123456789','你猜','不想寫備註');
insert into customer values(2,'逗瓜','123456789','你猜','不想寫備註');
insert into customer values(3,'憤青','123456789','你猜','不想寫備註');
insert into customer values(4,'鹹魚','123456789','你猜','不想寫備註');
insert into customer values(5,'小白','123456789','你猜','不想寫備註');
insert into customer values(6,'菜雞','123456789','你猜','不想寫備註');
綜上
到目前為止我們已經完成了Spring、SpringMVC、Mybatis的基本配置,並建立了專案所需的實體類以及資料庫表。
最後我們需要將該專案部署到Tomcat伺服器上。如果配置正確,那麼在瀏覽器上回彈出index頁面。
喜歡的話請幫忙轉發一下能讓更多有需要的人看到吧。有些技術上的問題大家可以多探討一下,謝謝!
更多問題平時可以在QQ群裡交流:909723834。有加群的朋友請記得備註上CSDN,謝謝。