一、SSM概要
與SSH(Struts/Spring/Hibernate/)一樣,Spring+SpringMVC+MyBatis也有一個簡稱SSM,Spring實現業務對象管理,Spring MVC負責請求的轉發和視圖管理, MyBatis作為數據對象持久化引擎。這樣搭配的優點是:輕量、自由度高、Spring與Spring MVC契合度更好。通過一個商品管理示例完成SSM框架的集成,可以將前面學習過的一些內容整合起來。
1.1、SpringMVC
1.客戶端發送請求到DispacherServlet(分發器)
2.由DispacherServlet控制器查詢HanderMapping,找到處理請求的Controller
3.Controller調用業務邏輯處理后,返回ModelAndView
4.DispacherSerclet查詢視圖解析器,找到ModelAndView指定的視圖
5.視圖負責將結果顯示到客戶端
1.2、Spring
1.Spring是一個輕量級的控制反轉(IOC)和面向切面(AOP)的容器架構,IOC容器包含並管理應用對象的配置和生命周期,你可以配置你的每個bean如何被創建,也可以配置每個bean是只有一個實例,還是每次需要時都生成一個新的實例,以及它們是如何相互關聯的。
2.IOC思想最核心的地方在於,資源不由使用資源的雙方管理,而由不使用資源的第三方管理,這可以帶來很多好處。
第一,資源集中管理,實現資源的可配置和易管理。
第二,降低了使用資源雙方的依賴程度,也就是我們說的耦合度。
3.容器提供了AOP技術,利用它很容易實現如權限攔截、運行期監控等功能。
1.3、MyBatis
1.MyBatis是支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及結果集的檢索。MyBatis使用簡單的XML或注解用於配置和原始映射,將接口和Java的POJOs(Plan Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
2.MyBatis的操作都是圍繞一個sqlSessionFactory實例展開的。MyBatis通過配置文件關聯到各實體類的Mapper文件,Mapper文件中配置了每個類對數據庫所需進行的sql語句映射。在每次與數據庫交互時,通過sqlSessionFactory拿到一個sqlSession,再執行sql命令。
1.4、Maven多模塊
JavaEE項目開發中為了便於后期的維護,一般會進行分層開發,分層之后,各個層之間的職責會比較明確,后期維護起來也相對比較容易。
《一個小時學會Maven》可以獲得更多幫助
二、數據庫
打開MySQL數據庫,創建一個表,這里以goods表為例,一個用於存放商品的表,共4個字段id表示編號,name表示商品名稱,picture表示圖片,price表示價格。SQL腳本如下:
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `goods` -- ---------------------------- DROP TABLE IF EXISTS `goods`; CREATE TABLE `goods` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(200) NOT NULL, `price` decimal(10,2) DEFAULT '0.00', `picture` varchar(100) DEFAULT 'default.jpg', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of goods -- ---------------------------- INSERT INTO `goods` VALUES ('1', 'G7 中原G7三合一濃醇咖啡固體飲料1200', '66.50', '1.jpg'); INSERT INTO `goods` VALUES ('2', '百草味東北松子200gx2袋 堅果炒貨零', '42.90', '2.jpg'); INSERT INTO `goods` VALUES ('3', '奈津香 桂圓干500gx2袋莆田特產5A桂', '39.90', '3.jpg'); INSERT INTO `goods` VALUES ('4', '益達尊享護齒裝草本40粒+冰檸40粒+西', '25.90', '4.jpg'); INSERT INTO `goods` VALUES ('5', '猴坑茶業2016新茶原產地手工太平猴魁特', '168.00', '5.jpg'); INSERT INTO `goods` VALUES ('6', '嘻魷記 休閑零食 麻辣香辣奶香炭燒 5種', '39.80', '6.jpg'); INSERT INTO `goods` VALUES ('7', '榮業鴻福五分瘦臘腸 香港土特產香腸臘味', '126.80', '7.jpg'); INSERT INTO `goods` VALUES ('8', '蓓琳娜(BELLINA)3L PDO特級初榨橄欖油', '178.00', '8.jpg'); INSERT INTO `goods` VALUES ('10', '榮業鴻福五分瘦臘腸 香港土特產香腸臘味', '30.60', '9.jpg');
結果:
三、創建多模塊項目
3.1、各模塊的功能
common模塊:通用模塊,不依賴其它任何模塊,主要有utils、可以在多個不同項目中得勝的內容
entitie模塊:POJO、VO、DTO
dao模塊:數據持久化,訪問數據庫,這里使用Mybatis
service模塊:業務模塊,處理業務邏輯
webui模塊:B/S結構的表示層,主要用於在瀏覽器中顯示數據,提供用戶接口
3.2、創建項目結構
創建父模塊,不使用骨架的maven普通項目
創建子模塊commons
創建不使用骨架的maven普通項目
entity、dao、service模塊創建方法與命名規范同上。
webui需要創建一個使用webapp骨架的maven項目:
完成的項目結構如下:
《一個小時學會Maven》可以獲得更多幫助
四、添加各模塊間的依賴
子模塊默認是繼承父模塊的,這里全部使用按需依賴。
dao模塊的pom:
<dependencies> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-common</artifactId> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-entity</artifactId> </dependency> </dependencies>
service的pom:
<dependencies> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-dao</artifactId> </dependency> </dependencies>
因為依賴具有傳遞性,在service中可以間接的依賴到entity與common
webui的pom:
<dependencies> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-service</artifactId> </dependency> </dependencies>
依賴完成的結果:
五、完成POJO實體模塊
完成這一層之前先明確一下幾個容易混淆的概念:
5.1、POJO
POJO(Plain Ordinary Java Object)簡單的Java對象,實際就是普通JavaBeans,是為了避免和EJB混淆所創造的簡稱。
其中有一些屬性及其getter、setter方法的類,沒有業務邏輯,有時可以作為VO(value-object)或DTO(Data Transfer Object)來使用。不允許有業務方法,也不能攜帶connection之類的方法。
5.2、JavaBean
JavaBean是Java語言寫成的可重用組件。JavaBean則比 POJO復雜很多, Java Bean 是可復用的組件,對 Java Bean 並沒有嚴格的規范,理論上講,任何一個 Java 類都可以是一個 Bean 。EJB則是Enterprise JavaBean,是JavaEE的一部分,定義了一個用於開發基於組件的企業多重應用程序標准。
5.3、Entity
實體bean,一般是用於ORM對象關系映射,一個實體映射成一張表,一般無業務邏輯代碼。
負責將數據庫中的表記錄映射為內存中的Entity對象,事實上,創建一個EntityBean對象相當於創建一條記錄,刪除一個EntityBean對象會同時從數據庫中刪除對應記錄,修改一個Entity Bean時,容器會自動將Entity Bean的狀態和數據庫同步。
5.4、Domain Model
業務對象模型(也叫領域模型 domain model)是描述業務用例實現的對象模型。又稱概念模型、領域對象模型、分析對象模型。領域模型中的實體類分為四種類型:VO、DTO、DO、PO
VO(View Object):視圖對象,用於展示層,它的作用是把某個指定頁面(或組件)的所有數據封裝起來。
DTO(Data Transfer Object):數據傳輸對象,這個概念來源於J2EE的設計模式,原來的目的是為了EJB的分布式應用提供粗粒度的數據實體,以減少分布式調用的次數,從而提高分布式調用的性能和降低網絡負載,但在這里,我泛指用於展示層與服務層之間的數據傳輸對象。
DO(Domain Object):領域對象,就是從現實世界中抽象出來的有形或無形的業務實體。
PO(PersistentObject):持久化對象,它跟持久層(通常是關系型數據庫)的數據結構形成一一對應的映射關系,如果持久層是關系型數據庫,那么,數據表中的每個字段(或若干個)就對應PO的一個(或若干個)屬性。
5.5、實體模塊
Goods商品POJO對象如下:
package com.zhangguo.ssm01.entity; import java.io.Serializable; import java.math.BigDecimal; /** * 商品POJO */ public class Goods implements Serializable { private int id; private String name; private BigDecimal price; private String picture; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } @Override public String toString() { return "Goods{" + "id=" + id + ", name='" + name + '\'' + ", price=" + price + ", picture='" + picture + '\'' + '}'; } }
六、完成Commons通用工具模塊
commons通用模塊主要是為項目中其它模塊提供輔助功能,如utils工具類等內容:
依賴:
父模塊的pom:

<?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.zhangguo.ssm01</groupId> <artifactId>SSM01</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>Ssm01-common</module> <module>Ssm01-entity</module> <module>Ssm01-dao</module> <module>Ssm01-service</module> <module>Ssm01-webui</module> </modules> <properties> <!--項目內模塊--> <Ssm01-common.version>1.0-SNAPSHOT</Ssm01-common.version> <Ssm01-entity.version>1.0-SNAPSHOT</Ssm01-entity.version> <Ssm01-dao.version>1.0-SNAPSHOT</Ssm01-dao.version> <Ssm01-service.version>1.0-SNAPSHOT</Ssm01-service.version> <Ssm01-webui.version>1.0-SNAPSHOT</Ssm01-webui.version> <jackson.version>2.7.4</jackson.version> <commons-lang3.version>3.4</commons-lang3.version> <!--通用部分--> <log4j.version>2.6.1</log4j.version> <junit.version>4.10</junit.version> <!--Spring--> <spring.version>4.3.0.RELEASE</spring.version> <aspectjweaver.version>1.8.9</aspectjweaver.version> <cglib.version>3.2.4</cglib.version> <!--mybatis--> <mybatis-spring.version>1.3.0</mybatis-spring.version> <mysql-connector-java.version>5.1.38</mysql-connector-java.version> <mybatis.version>3.4.1</mybatis.version> <c3p0.version>0.9.1.2</c3p0.version> <!--spring mvc--> <jstl.version>1.2</jstl.version> <servlet-api.version>3.0.1</servlet-api.version> <jsp-api.version>2.1</jsp-api.version> <hibernate.version>5.2.2.Final</hibernate.version> <commons-io.version>2.4</commons-io.version> <commons-fileupload.version>1.3.1</commons-fileupload.version> <freemarker.version>2.3.23</freemarker.version> </properties> <dependencyManagement> <dependencies> <!--項目內的依賴--> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-common</artifactId> <version>${Ssm01-common.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-entity</artifactId> <version>${Ssm01-entity.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-dao</artifactId> <version>${Ssm01-dao.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-service</artifactId> <version>${Ssm01-service.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-webui</artifactId> <version>${Ssm01-webui.version}</version> </dependency> <!--common模塊--> <!--jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <!--apache-commons--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <!--log4j日志包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j.version}</version> </dependency> <!-- JUnit單元測試工具 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <!--Spring框架核心庫 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectJ AOP 織入器 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectjweaver.version}</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>${cglib.version}</version> </dependency> <!--mybatis-spring適配器 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> <!--Spring java數據庫訪問包,在本例中主要用於提供數據源 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!--mysql數據庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-java.version}</version> </dependency> <!-- mybatis ORM框架 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!--c3p0 連接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>${c3p0.version}</version> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- Servlet核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet-api.version}</version> </dependency> <!--JSP --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>${jsp-api.version}</version> </dependency> <!--JSR303 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.version}</version> </dependency> <!--文件上傳 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency> <!-- FreeMarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
commons的pom:
<?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"> <parent> <artifactId>SSM01</artifactId> <groupId>com.zhangguo.ssm01</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Ssm01-common</artifactId> <dependencies> <!--jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency> <!--apache-commons--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> </dependencies> </project>
添加相應的工具類:
如封裝頁面返回結果的JSON:

package com.zhangguo.ssm01.common.utils; import java.util.HashMap; import java.util.Map; /** * 返回數據封裝 */ public class R extends HashMap<String, Object> { private static final long serialVersionUID = 1L; public R() { put("code", 1); put("msg", "success"); } //錯誤時 public static R error() { return error(500, "未知異常,請聯系管理員"); } public static R error(String msg) { return error(500, msg); } public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } //成功時 public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; } public static R ok() { return new R(); } public static R ok(Object data) { return new R().put("data",data); } @Override public R put(String key, Object value) { super.put(key, value); return this; } }
太多了這里不一一介紹。
結果:
七、完成DAO數據訪問模塊
Spring學習總結(六)——Spring整合MyBatis完整示例
7.1、添加依賴
父模塊聲明:

<?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.zhangguo.ssm01</groupId> <artifactId>SSM01</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>Ssm01-common</module> <module>Ssm01-entity</module> <module>Ssm01-dao</module> <module>Ssm01-service</module> <module>Ssm01-webui</module> </modules> <properties> <!--項目內模塊--> <Ssm01-common.version>1.0-SNAPSHOT</Ssm01-common.version> <Ssm01-entity.version>1.0-SNAPSHOT</Ssm01-entity.version> <Ssm01-dao.version>1.0-SNAPSHOT</Ssm01-dao.version> <Ssm01-service.version>1.0-SNAPSHOT</Ssm01-service.version> <Ssm01-webui.version>1.0-SNAPSHOT</Ssm01-webui.version> <jackson.version>2.7.4</jackson.version> <commons-lang3.version>3.4</commons-lang3.version> <!--通用部分--> <log4j.version>2.6.1</log4j.version> <junit.version>4.10</junit.version> <!--Spring--> <spring.version>4.3.0.RELEASE</spring.version> <aspectjweaver.version>1.8.9</aspectjweaver.version> <cglib.version>3.2.4</cglib.version> <!--mybatis--> <mybatis-spring.version>1.3.0</mybatis-spring.version> <mysql-connector-java.version>5.1.38</mysql-connector-java.version> <mybatis.version>3.4.1</mybatis.version> <c3p0.version>0.9.1.2</c3p0.version> <!--spring mvc--> <jstl.version>1.2</jstl.version> <servlet-api.version>3.0.1</servlet-api.version> <jsp-api.version>2.1</jsp-api.version> <hibernate.version>5.2.2.Final</hibernate.version> <commons-io.version>2.4</commons-io.version> <commons-fileupload.version>1.3.1</commons-fileupload.version> <freemarker.version>2.3.23</freemarker.version> </properties> <dependencyManagement> <dependencies> <!--項目內的依賴--> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-common</artifactId> <version>${Ssm01-common.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-entity</artifactId> <version>${Ssm01-entity.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-dao</artifactId> <version>${Ssm01-dao.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-service</artifactId> <version>${Ssm01-service.version}</version> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-webui</artifactId> <version>${Ssm01-webui.version}</version> </dependency> <!--common模塊--> <!--jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <!--apache-commons--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <!--log4j日志包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j.version}</version> </dependency> <!-- JUnit單元測試工具 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <!--Spring框架核心庫 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectJ AOP 織入器 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectjweaver.version}</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>${cglib.version}</version> </dependency> <!--mybatis-spring適配器 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> <!--Spring java數據庫訪問包,在本例中主要用於提供數據源 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!--mysql數據庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-java.version}</version> </dependency> <!-- mybatis ORM框架 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!--c3p0 連接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>${c3p0.version}</version> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- Servlet核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet-api.version}</version> </dependency> <!--JSP --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>${jsp-api.version}</version> </dependency> <!--JSR303 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.version}</version> </dependency> <!--文件上傳 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency> <!-- FreeMarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
子模塊引用:
<?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"> <parent> <artifactId>SSM01</artifactId> <groupId>com.zhangguo.ssm01</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Ssm01-dao</artifactId> <dependencies> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-common</artifactId> </dependency> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-entity</artifactId> </dependency> <!--log4j日志包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> </dependency> <!-- JUnit單元測試工具 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <!--Spring框架核心庫 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <!-- aspectJ AOP 織入器 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> </dependency> <!--mybatis-spring適配器 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> <!--Spring java數據庫訪問包,在本例中主要用於提供數據源 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <!--mysql數據庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- mybatis ORM框架 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <!--c3p0 連接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> </dependency> </dependencies> </project>
7.2、數據庫配置屬性文件
在resources根目錄中定義db.properties
#mysql jdbc mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/gomall?useUnicode=true&characterEncoding=UTF-8 mysql.uid=root mysql.pwd=uchr@123
7.3、Spring-mybatis集成
applicationContext.xml,用於完成Spring-mybatis集成使用
<?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:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" 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-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> <!--1 引入屬性文件,在配置中占位使用 --> <context:property-placeholder location="classpath*:db.properties" /> <!--2 配置C3P0數據源 --> <bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <!--驅動類名 --> <property name="driverClass" value="${mysql.driver}" /> <!-- url --> <property name="jdbcUrl" value="${mysql.url}" /> <!-- 用戶名 --> <property name="user" value="${mysql.uid}" /> <!-- 密碼 --> <property name="password" value="${mysql.pwd}" /> <!-- 當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數 --> <property name="acquireIncrement" value="5"></property> <!-- 初始連接池大小 --> <property name="initialPoolSize" value="10"></property> <!-- 連接池中連接最小個數 --> <property name="minPoolSize" value="5"></property> <!-- 連接池中連接最大個數 --> <property name="maxPoolSize" value="20"></property> </bean> <!--3 會話工廠bean sqlSessionFactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 數據源 --> <property name="dataSource" ref="datasource"></property> <!-- 別名 --> <property name="typeAliasesPackage" value="com.zhangguo.ssm01.entity"></property> <!-- sql映射文件路徑 --> <property name="mapperLocations" value="classpath*:mappers/*Mapper.xml"></property> <!--mybatis配置文件位置--> <property name="configLocation" value="classpath:mybatis-config.xml"></property> </bean> <!--4 自動掃描對象關系映射 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定會話工廠,如果當前上下文中只定義了一個則該屬性可省去 --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> <!-- 指定要自動掃描接口的基礎包,實現接口 --> <property name="basePackage" value="com.zhangguo.ssm01.dao"></property> </bean> <!--5 聲明式事務管理 --> <!--定義事物管理器,由spring管理事務 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="datasource"></property> </bean> <!--支持注解驅動的事務管理,指定事務管理器 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!--6 容器自動掃描IOC組件 --> <context:component-scan base-package="com.zhangguo.ssm01.dao"></context:component-scan> <!--7 aspectj支持自動代理實現AOP功能 --> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> </beans>
7.4、路徑引用問題
模塊被引用后因為路徑問題可能會現在異常,如:java.io.FileNotFoundException: Could not open ServletContext resource [/classpath*:mybatis-config.xml]
詳細的異常日志如下:

D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\bin\catalina.bat run [2018-11-02 08:59:18,038] Artifact Ssm01-webui:war exploded: Waiting for server connection to start artifact deployment... Using CATALINA_BASE: "C:\Users\Administrator\.IntelliJIdea2017.2\system\tomcat\Unnamed_SSM01" Using CATALINA_HOME: "D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33" Using CATALINA_TMPDIR: "D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\temp" Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_111" Using CLASSPATH: "D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\bin\bootstrap.jar;D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\bin\tomcat-juli.jar" 02-Nov-2018 08:59:22.056 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.5.33 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Aug 12 2018 08:20:08 UTC 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server number: 8.5.33.0 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Windows 7 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 6.1 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: C:\Program Files\Java\jdk1.8.0_111\jre 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 1.8.0_111-b14 02-Nov-2018 08:59:22.063 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation 02-Nov-2018 08:59:22.064 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\Users\Administrator\.IntelliJIdea2017.2\system\tomcat\Unnamed_SSM01 02-Nov-2018 08:59:22.064 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33 02-Nov-2018 08:59:22.064 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=C:\Users\Administrator\.IntelliJIdea2017.2\system\tomcat\Unnamed_SSM01\conf\logging.properties 02-Nov-2018 08:59:22.064 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 02-Nov-2018 08:59:22.065 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote= 02-Nov-2018 08:59:22.065 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.port=1099 02-Nov-2018 08:59:22.065 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.ssl=false 02-Nov-2018 08:59:22.065 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.authenticate=false 02-Nov-2018 08:59:22.065 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.rmi.server.hostname=127.0.0.1 02-Nov-2018 08:59:22.065 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048 02-Nov-2018 08:59:22.066 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 02-Nov-2018 08:59:22.066 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs= 02-Nov-2018 08:59:22.066 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=C:\Users\Administrator\.IntelliJIdea2017.2\system\tomcat\Unnamed_SSM01 02-Nov-2018 08:59:22.066 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33 02-Nov-2018 08:59:22.066 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\temp 02-Nov-2018 08:59:22.066 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.17] using APR version [1.6.3]. 02-Nov-2018 08:59:22.067 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true]. 02-Nov-2018 08:59:22.067 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true] 02-Nov-2018 08:59:23.148 信息 [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.0.2o 27 Mar 2018] 02-Nov-2018 08:59:23.582 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"] 02-Nov-2018 08:59:23.617 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read 02-Nov-2018 08:59:23.645 信息 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"] 02-Nov-2018 08:59:23.647 信息 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read 02-Nov-2018 08:59:23.648 信息 [main] org.apache.catalina.startup.Catalina.load Initialization processed in 2577 ms 02-Nov-2018 08:59:23.727 信息 [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] 02-Nov-2018 08:59:23.728 信息 [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.33 02-Nov-2018 08:59:23.769 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"] 02-Nov-2018 08:59:23.790 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"] 02-Nov-2018 08:59:23.827 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 178 ms [2018-11-02 08:59:24,194] Artifact Ssm01-webui:war exploded: Artifact is being deployed, please wait... Connected to server 02-Nov-2018 08:59:33.225 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. 02-Nov-2018 08:59:33.505 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.ContextLoader.initWebApplicationContext Root WebApplicationContext: initialization started 02-Nov-2018 08:59:33.792 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\webapps\manager] 02-Nov-2018 08:59:34.178 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [D:\Documents\Downloads\Compressed\apache-tomcat-8.5.33-windows-x64\apache-tomcat-8.5.33\webapps\manager] has finished in [385] ms 02-Nov-2018 08:59:34.294 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.support.XmlWebApplicationContext.prepareRefresh Refreshing Root WebApplicationContext: startup date [Fri Nov 02 08:59:34 CST 2018]; root of context hierarchy 02-Nov-2018 08:59:34.550 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions Loading XML bean definitions from URL [jar:file:/C:/Users/Administrator/Desktop/mybatis-generator-gui-0.8.4/SSM01/Ssm01-webui/target/Ssm01-webui/WEB-INF/lib/Ssm01-dao-1.0-SNAPSHOT.jar!/applicationContext.xml] 02-Nov-2018 08:59:36.200 信息 [RMI TCP Connection(3)-127.0.0.1] org.springframework.context.support.PropertySourcesPlaceholderConfigurer.loadProperties Loading properties file from URL [jar:file:/C:/Users/Administrator/Desktop/mybatis-generator-gui-0.8.4/SSM01/Ssm01-webui/target/Ssm01-webui/WEB-INF/lib/Ssm01-dao-1.0-SNAPSHOT.jar!/db.properties] 02-Nov-2018 08:59:36.754 信息 [RMI TCP Connection(3)-127.0.0.1] com.mchange.v2.log.MLog.<clinit> MLog clients using java 1.4+ standard logging. 02-Nov-2018 08:59:36.929 信息 [RMI TCP Connection(3)-127.0.0.1] com.mchange.v2.c3p0.C3P0Registry.banner Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10] 02-Nov-2018 08:59:37.332 警告 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.support.XmlWebApplicationContext.refresh Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [jar:file:/C:/Users/Administrator/Desktop/mybatis-generator-gui-0.8.4/SSM01/Ssm01-webui/target/Ssm01-webui/WEB-INF/lib/Ssm01-dao-1.0-SNAPSHOT.jar!/applicationContext.xml]: Invocation of init method failed; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/classpath*:mybatis-config.xml] 02-Nov-2018 08:59:37.341 嚴重 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.ContextLoader.initWebApplicationContext Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in URL [jar:file:/C:/Users/Administrator/Desktop/mybatis-generator-gui-0.8.4/SSM01/Ssm01-webui/target/Ssm01-webui/WEB-INF/lib/Ssm01-dao-1.0-SNAPSHOT.jar!/applicationContext.xml]: Invocation of init method failed; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/classpath*:mybatis-config.xml] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4792) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1736) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:483) at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:432) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468) at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:324) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/classpath*:mybatis-config.xml] at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141) at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:407) at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:381) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ... 57 more 02-Nov-2018 08:59:37.348 嚴重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal One or more listeners failed to start. Full details will be found in the appropriate container log file 02-Nov-2018 08:59:37.349 嚴重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors [2018-11-02 08:59:37,425] Artifact Ssm01-webui:war exploded: Error during artifact deployment. See server log for details.
spring在構造sqlSessionFactory這個bean時報錯,原因是找不到配置文件:
Could not open ServletContext resource [/classpath*:mybatis-config.xml]
spring查找的路徑是:/classpath*:mybatis-config.xml
而這個路徑根本不是我們想要的,根本就是找錯了地方。
但是我們配置文件給出的路徑是:classpath*:mybatis-config.xml
我們將配置文件中下面的配置稍作修改,去掉classpath后面的 *
<property name="configLocation" value="classpath*:mybatis-config.xml" />
改為:
<property name="configLocation" value="classpath:mybatis-config.xml" />
之后,啟動正常,沒有報錯。
不同的類加載器 classLoader 在處理 classpath* 時存在可移植性問題。如果在使用 classpath* 時報錯,那么就應該去掉 * 直接使用classpath: ,如果還是報錯,那么可以去掉classpath直接使用路徑,在stackoverflow上有一個例子:http://stackoverflow.com/questions/6035464/could-not-open-servletcontext-resource
classpath* 和 classpath的區別:
classpath* prefix specifies that all classpath resources that match the given name must be obtained (internally, this essentially happens via a ClassLoader.getResources(...) call), and then merged to form the final application context definition.
1)classpath* 它會搜索所有的 classpath,找到所有符合條件的文件,包括jar文件中的配置文件。而classpath不會到jar文件中去尋找。
2)classpath* 存在可移植性問題,遇到問題時,應該使用classpath.
3)其實一般情況下我們根本沒有必要去使用classpath*,直接使用classpath就好了。
7.5、SqlSessionFactoryBean
能被Spring IOC容器管理的原因就是FactoryBean這個接口了,這是個支持泛型的接口:
能被Spring IOC容器管理的原因就是FactoryBean這個接口了,這是個支持泛型的接口: public interface FactoryBean<T> { @Nullable T getObject() throws Exception; @Nullable Class<?> getObjectType(); default boolean isSingleton() { return true; } } 當實現了這個接口的Bean在配置為被Spring接管時,存入IOC容器中的實例類型將會是實例化泛型的那個類型,從IOC容器中獲取時也是實例化泛型的那個類型,這種情況下,Spring 將會在應用啟動時為你 創建SqlSessionFactory對象,然后將它以 SqlSessionFactory為名來存儲。當把這個bean注入到Spring中去了以后,IOC容器中的其他類型就可以拿到SqlSession實例了,就可以進行相關的SQL執行任務了。
7.6、定義映射器與數據訪問接口
goodsMapper.xml 商品映射器
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--命名空間應該是對應接口的包名+接口名 --> <mapper namespace="com.zhangguo.ssm01.dao.GoodsDao"> <!--id應該是接口中的方法,結果類型如沒有配置別名則應該使用全名稱 --> <select id="getAll" resultType="Goods"> SELECT goods.id, goods.`name`, goods.price, goods.picture FROM goods <where> <if test="name!=null and name!=''"> and NAME like concat(concat('%',#{name}),'%') </if> </where> </select> </mapper>
GoodsDao接口
package com.zhangguo.ssm01.dao; import com.zhangguo.ssm01.entity.Goods; import org.apache.ibatis.annotations.Param; import java.util.List; public interface GoodsDao { /**獲得所有商品*/ public List<Goods> getAll(@Param("name") String name); }
7.7、測試及運行結果
GoodsDaoTest測試類
package com.zhangguo.ssm01.dao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Service; @Service public class GoodsDaoTest { @Autowired GoodsDao dao; public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); GoodsDao dao=ctx.getBean(GoodsDao.class); System.out.println(dao.getAll("特產")); } }
測試結果
此時的項目結構
7.8、使用JUnit+Spring測試
1、添加引用
除了junit4和spring的jar包,還需要spring-test.jar。引入如下依賴:
版本
<junit.version>4.12</junit.version> <spring-test.version>4.3.18.RELEASE</spring-test.version>
依賴
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring-test.version}</version> </dependency>
2、編寫測試用例
package dao.test; import com.zhangguo.ssm01.dao.GoodsDao; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; //指定bean注入的配置文件 @ContextConfiguration(locations = { "classpath:applicationContext.xml"}) //使用標准的JUnit @RunWith注釋來告訴JUnit使用Spring TestRunner @RunWith(SpringJUnit4ClassRunner.class) public class GoodsDaoTest { @Autowired GoodsDao dao; @Test public void testGetAll(){ System.out.println(dao.getAll(null)); } }
解釋
@RunWith(SpringJUnit4ClassRunner.class) //SpringJUnit支持,由此引入Spring-Test框架支持! @ContextConfiguration(locations = "classpath:applicationContext.xml") //多個配置文件的話可以用數組表示{“applicationContext.xml”,“applicationContext1.xml”},下面我會貼我的配置文件,只有一個配置文件; @ContextConfiguration("/spring-context.xml") //放在根路徑下(即類路徑下),然后<import resource="spring-dao.xml" />所有的配置文件和資源文件 @Transactional //這個非常關鍵,如果不加入這個注解配置,事務控制就會完全失效! @TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) //這里的事務關聯到配置文件中的事務控制器(transactionManager = "transactionManager"),同時指定自動回滾(defaultRollback = true)。這樣做操作的數據才不會污染數據庫! @AbstractTransactionalDataSourceSpringContextTests //要想構建這一系列的無污染純綠色事務測試框架就必須找到這個基類!(即所有事務均不生效) @ActiveProfiles(value="dev") //配置環境選擇
運行結果:
3、讓spring管理事務又不污染數據庫
package dao.test; import com.zhangguo.ssm01.dao.GoodsDao; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.Rollback; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; @ContextConfiguration({"classpath:applicationContext.xml"}) @RunWith(SpringJUnit4ClassRunner.class) @Transactional //@TransactionConfiguration(defaultRollback = true) //被棄用 @Rollback(true) //是否回滾 public class GoodsDaoTestPro { @Autowired GoodsDao dao; @Test public void testGetAll(){ System.out.println(dao.getAll(null)); } @Test public void testDeleteByIds(){ List<Integer> ids=new ArrayList<Integer>(); ids.add(1); ids.add(2); ids.add(5); int rows=dao.deleteByIds(ids); Assert.assertEquals(3,rows); } }
結果:
數據並沒有被刪除,回滾了
4、注意事項
*SpringJUnit4ClassRunner requires JUnit 4.12 or higher,Junit要求4.12或更高版本
*測試方法命名不能叫test方法,類也不能叫Test類
八、完成Service服務模塊
服務接口:
package com.zhangguo.ssm01.service; import com.zhangguo.ssm01.entity.Goods; import java.util.List; public interface GoodsService { List<Goods> queryGoodsByName(String name); }
服務實現:
package com.zhangguo.ssm01.service.impl; import com.zhangguo.ssm01.dao.GoodsDao; import com.zhangguo.ssm01.entity.Goods; import com.zhangguo.ssm01.service.GoodsService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class GoodServiceImpl implements GoodsService { @Autowired GoodsDao goodsDao; @Override public List<Goods> queryGoodsByName(String name) { if(StringUtils.isEmpty(name)){ name=null; } return goodsDao.getAll(name); } }
九、完成WebUI表示模塊
9.1、創建目錄
9.2、添加依賴
pom.xml
<?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"> <parent> <artifactId>SSM01</artifactId> <groupId>com.zhangguo.ssm01</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>Ssm01-webui</artifactId> <packaging>war</packaging> <name>Ssm01-webui Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.zhangguo.ssm01</groupId> <artifactId>Ssm01-service</artifactId> </dependency> <!-- Spring MVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <!-- JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <!-- Servlet核心包 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <!--JSP --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> </dependency> <!--JSR303 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> </dependency> <!--文件上傳 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> </dependency> <!-- FreeMarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency> </dependencies> <build> <finalName>Ssm01-webui</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.0.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.20.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
9.3、配置Spring MVC中心控制器
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_3_0.xsd" id="WebApp_ID" version="3.0"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <listener> <description>Spring容器加載監聽器</description> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <description>設置Spring加載時的配置文件位置,默認位置在WEB-INF/lib目錄下</description> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value> </context-param> <!--Spring MVC 前置Servlet,中心控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!--Spring MVC配置文件路徑 --> <param-value>classpath*:springmvc-servlet.xml</param-value> </init-param> <!-- 啟動動優先級,越小越早加載 --> <load-on-startup>1</load-on-startup> <!--Servlet3.0以上文件上傳配置 --> <multipart-config> <!--上傳文件的最大限制5MB --> <max-file-size>5242880</max-file-size> <!--請求的最大限制20MB --> <max-request-size>20971520</max-request-size> <!--當文件的大小超過臨界值時將寫入磁盤 --> <file-size-threshold>0</file-size-threshold> </multipart-config> </servlet> <!-- Servlet訪問的路徑映射,所有的訪問都必須經過調度用的前置控制品 --> <servlet-mapping> <servlet-name>springmvc</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!-- 路徑映射 --> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
9.4、配置Spring MVC
springmvc-servlet.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: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-4.3.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> <!-- 自動掃描包,實現支持注解的IOC --> <context:component-scan base-package="com.zhangguo.ssm01" /> <!-- Spring MVC不處理靜態資源 --> <mvc:default-servlet-handler /> <!-- 支持mvc注解驅動 --> <mvc:annotation-driven enable-matrix-variables="true" /> <!-- 配置映射媒體類型的策略 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="removeSemicolonContent" value="false" /> </bean> <!-- 內部視圖解析器,JSP與JSTL模板 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!--指定視圖渲染類 --> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <!--自動添加到路徑中的前綴 --> <property name="prefix" value="/WEB-INF/views/" /> <!--自動添加到路徑中的后綴 --> <property name="suffix" value=".jsp" /> <!--設置所有視圖的內容類型,如果視圖本身設置內容類型視圖類可以忽略 --> <property name="contentType" value="text/html;charset=UTF-8" /> <!-- 優先級,越小越前 --> <property name="order" value="1" /> </bean> <!--文件上傳解析器 --> <!--Spring MVC默認不能識別multipart格式的文件內容 --> <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"> </bean> </beans>
RequestMappingHandlerMapping,主要做的工作是將Contoller的帶RequestMapping方法,添加到處理方法映射器和路徑方法解決器中。
RequestMappingHandlerAdapter主要是解決請求的,會話,請求頭部處理,數據的綁定等,然后從容器中,獲取handlerMethod,處理業務邏輯,獲取數據,並渲染視圖,返回。
RequestMappingHandlerMapping會把Controller里面帶有@RequestMapping注解的方法都加到一個容器里面,然后RequestMappingHandlerAdapter根據里面的自定義配置可以對經過這些方法的請求的數據做一些額外的處理。例如我想對帶有@RequestMapping注解的方法的相應數據做一些處理,比如方法返回的都是實體對象類型的數據,我想配置把這些實體對象轉換成json串再返回給前端,可以像如下這么配置:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"><!-- 日期綁定 --> <bean class="com.qlk.cloud.baymax.common.utils.BindingInitializer"/> <!-- <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="conversionService"> <bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"></bean> </property> </bean> --> </property> <property name="messageConverters"> <list> <ref bean="stringHttpMessageConverter"/> <ref bean="mappingJacksonHttpMessageConverter"/> </list> </property> </bean> <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> <!-- 處理JSON數據轉換的 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <!-- 為了處理返回的JSON數據的編碼,默認是ISO-88859-1的,這里把它設置為UTF-8,解決有亂碼的情況 --> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean>
9.5、添加控制器
GoodsController.java
package com.zhangguo.ssm01.weui.controller; import com.zhangguo.ssm01.service.GoodsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/goods") public class GoodsController { @Autowired GoodsService goodsService; @RequestMapping("/queryGoods") public String queryGoods(Model model,String name){ model.addAttribute("goods",goodsService.queryGoodsByName(name)); return "goods/queryGoods"; } }
9.6、添加視圖
queryGoods.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>商品列表</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> </head> <body> <h2>商品列表</h2> <table width="100%" border="1"> <c:forEach items="${goods}" var="item"> <tr> <td>${item.id}</td> <td>${item.name}</td> <td>${item.price}</td> <td>${item.picture}</td> </tr> </c:forEach> </table> </body> </html>
十、測試並運行
配置tomcat,添加部署項目:
運行結果
十一、示例下載
https://zhangguo5.coding.net/public/SSM01/SSM01/git
十二、視頻
https://www.bilibili.com/video/av16991874/
十三、作業
1、完成一個商品管理功能,要求如下:
1.1、SSM、必須使用Spring+Spring MVC+MyBatis框架集成
1.2、兩個表,(商品,類型)
1.3、查詢,可多條件搜索,如按名稱與價格(區間)
1.4、刪除,提示
1.5、多刪除
1.6、添加,驗證
1.7、多添加(選作)
1.8、更新
1.9、分頁
1.10、上傳圖片
1.11、導出Excel
1.12、上傳並導入Excel(選作)
1.13、同時使用JSTL與AJAX完成
UI風格如下所示:
周二檢查,周五前考試
2、完成個人項目前后台所有頁面,周一展示。
3、SSM內部測試
要求使用SSM+Maven+MySQL+AJAX+JSTL實現一個簡單的會員管理系統
3.1、用戶注冊(用戶名、密碼、郵箱、手機號、注冊時間)
密碼要求MD5加密,存儲在數據庫中的密碼使用MD5加密
3.2、用戶登錄
登錄時驗證用戶名與密碼是否正確,密碼不要需要解密,只需要將用戶提交的密碼MD5加密后比較即可
登錄成功后后台顯示當前用戶的用戶名如:當前用戶:張果
如果用戶沒有登錄是不允許直接繞到后台的,如在瀏覽器輸入后台地址直接進入,可以使用過濾器或其它驗證方式
后台首頁
3.3、會員管理
編輯會員
重置密碼
刪除會員
多條件查詢會員(用戶名、郵箱、手機號)
分頁
退出系統
導出所有會員CSV
導入(選作)