SSM框架整合理解
把IntelliJ IDEA+Maven+Spring + SpringMVC + MyBatis項(xiàng)目部署,框架流程梳理調(diào)試了一遍,加深自己的理解。
回顧SSM框架
Spring
Spring就像是整個(gè)項(xiàng)目中裝配bean的大工廠,在配置文件中可以指定使用特定的參數(shù)去調(diào)用實(shí)體類的構(gòu)造方法來實(shí)例化對(duì)象。
Spring的核心思想是IoC(控制反轉(zhuǎn)),即不再需要程序員去顯式地new一個(gè)對(duì)象,而是讓Spring框架幫你來完成這一切。
SpringMVC
SpringMVC在項(xiàng)目中攔截用戶請(qǐng)求,它的核心Servlet即DispatcherServlet承擔(dān)中介或是前臺(tái)這樣的職責(zé),將用戶請(qǐng)求通過HandlerMapping去匹配Controller,Controller就是具體對(duì)應(yīng)請(qǐng)求所執(zhí)行的操作。SpringMVC相當(dāng)于SSH框架中struts。
mybatis
mybatis是對(duì)jdbc的封裝,它讓數(shù)據(jù)庫底層操作變的透明。mybatis的操作都是圍繞一個(gè)sqlSessionFactory實(shí)例展開的。mybatis通過配置文件關(guān)聯(lián)到各實(shí)體類的Mapper文件,Mapper文件中配置了每個(gè)類對(duì)數(shù)據(jù)庫所需進(jìn)行的sql語句映射。在每次與數(shù)據(jù)庫交互時(shí),通過sqlSessionFactory拿到一個(gè)sqlSession,再執(zhí)行sql命令。
SSM框架流程

SSM框架搭建
創(chuàng)建Maven的Web項(xiàng)目
- 通過IntelliJ IDEA創(chuàng)建maven項(xiàng)目:
- 選中Createfrom archetype,選擇maven-archetype-webapp
- 在Properties中添加一個(gè)參數(shù) archetypeCatalog=internal,提高maven項(xiàng)目構(gòu)建速度
- SSH框架Web項(xiàng)目框架
- main:
- 創(chuàng)建java文件夾:項(xiàng)目代碼
- resources文件夾:
- mapping文件夾:數(shù)據(jù)庫表xml
- xml配置文件
- webapp:
- WEB-INF:
- 創(chuàng)建jsp文件夾:不同顯示頁面
- web.xml:配置文件
- WEB-INF:
- main:
- Tomcat啟動(dòng)項(xiàng)目
- 為項(xiàng)目配置Tomcat
配置各種XML
-
pom.xml——引入項(xiàng)目所需要的jar包
- spring核心依賴
- mybatis依賴
- mybatis-spring整合包依賴
- mysql驅(qū)動(dòng)依賴
- 其他依賴:
- 日志相關(guān):log4j、slf4j
- 連接池相關(guān):commons-dbcp、c3p0、Druid
- Json相關(guān):fastjson
- 其他:jstl
- PS:此外還有SpringBoot可以簡化xml中的配置項(xiàng)數(shù)量。SpringBoot完全拋棄了繁瑣的XML文件配置方式,而是替代性地用注解方式來實(shí)現(xiàn)。
- 參考文章:IDEA下從零開始搭建SpringBoot工程
- 調(diào)試過程中的錯(cuò)誤有很大一部分是所引的jar沒有在pom.xml配置,這部分需要仔細(xì)細(xì)致。
- 關(guān)于jar包的版本號(hào)的修改,可以在<properties></properties>標(biāo)簽中用變量保存版本號(hào),<dependencies></dependencies>中具體的jar包的版本用變量代替,方便后續(xù)修改。
-
web.xml
- 這是整個(gè)web項(xiàng)目的配置文件。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>cloudmusic_ssm_demo</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mybatis.xml</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <!-- 編碼過濾器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- spring監(jiān)聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 防止spring內(nèi)存溢出監(jiān)聽器,比如quartz --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- 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> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <!-- 此處也可以配置成 *.do 形式 --> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/index.jsp</welcome-file> </welcome-file-list> <!-- session配置 --> <session-config> <session-timeout>15</session-timeout> </session-config> </web-app>- <servlet>中的配置,加載SpringMVC的配置文件。
- SpringMVC具有統(tǒng)一的入口DispatcherServlet,所有的請(qǐng)求都通過DispatcherServlet。DispatcherServlet是前置控制器,配置在web.xml文件中的。攔截匹配的請(qǐng)求,Servlet攔截匹配規(guī)則要自已定義,把攔截下來的請(qǐng)求,依據(jù)某某規(guī)則分發(fā)到目標(biāo)Controller來處理。
- 攔截所有的請(qǐng)求,并加載所有的ssm配置文件(路徑為classpath:spring-mvc.xml)
- 在web.xml中使用contextConfigLocation參數(shù)定義要裝入的Spring配置文件。
- 加載路徑為classpath:spring-mybatis.xml文件
- 參考文章: SSM:spring+springmvc+mybatis框架中的XML配置文件功能詳細(xì)解釋
-
spring-mvc.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:p="http://www.springframework.org/schema/p" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- 自動(dòng)掃描 @Controller--> <context:component-scan base-package="com.ssm.demo.controller"/> <!--避免IE執(zhí)行AJAX時(shí),返回JSON出現(xiàn)下載文件 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property> </bean> <!-- 啟動(dòng)SpringMVC的注解功能,完成請(qǐng)求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter"/> <!-- JSON轉(zhuǎn)換器 --> </list> </property> </bean> <!-- 定義跳轉(zhuǎn)的文件的前后綴 ,視圖模式配置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp"/> </bean> <!-- 文件上傳配置 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 默認(rèn)編碼 --> <property name="defaultEncoding" value="UTF-8"/> <!-- 上傳文件大小限制為31M,31*1024*1024 --> <property name="maxUploadSize" value="32505856"/> <!-- 內(nèi)存中的最大值 --> <property name="maxInMemorySize" value="4096"/> </bean> </beans>- controller注入:使用組件掃描方式,掃描包下面所有的Controller,可以使用注解來指定訪問路徑。
- Spring 所有功能都在 Bean 的基礎(chǔ)上演化而來,所以必須事先將 Controller 變成 Bean。配置了一個(gè) AnnotationMethodHandlerAdapter,它負(fù)責(zé)根據(jù) Bean 中的 Spring MVC 注解對(duì) Bean 進(jìn)行加工處理,使這些 Bean 變成控制器并映射特定的 URL 請(qǐng)求。
- 視圖解析:在Controller中設(shè)置視圖名的時(shí)候會(huì)自動(dòng)加上前綴和后綴。
-
spring-mybatis.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: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-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 自動(dòng)掃描 --> <context:component-scan base-package="com.ssm.demo"/> <!-- 第一種方式:加載一個(gè)properties文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties"/> </bean> <!-- 第二種方式:加載多個(gè)properties文件 <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="locations"> <list> <value>classpath:jdbc.properties</value> <value>classpath:common.properties</value> </list> </property> <property name="fileEncoding" value="UTF-8"/> </bean> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"> <property name="properties" ref="configProperties"/> </bean> --> <!-- 配置數(shù)據(jù)源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClass}"/> <property name="url" value="${jdbcUrl}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> <!-- 初始化連接大小 --> <property name="initialSize" value="${initialSize}"></property> <!-- 連接池最大數(shù)量 --> <property name="maxActive" value="${maxActive}"></property> <!-- 連接池最大空閑 --> <property name="maxIdle" value="${maxIdle}"></property> <!-- 連接池最小空閑 --> <property name="minIdle" value="${minIdle}"></property> <!-- 獲取連接最大等待時(shí)間 --> <property name="maxWait" value="${maxWait}"></property> </bean> <!-- mybatis和spring完美整合,不需要mybatis的配置映射文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 自動(dòng)掃描mapping.xml文件 --> <property name="mapperLocations" value="classpath:mapping/*.xml"></property> </bean> <!-- DAO接口所在包名,Spring會(huì)自動(dòng)查找其下的類 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.ssm.demo.dao"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- (事務(wù)管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- (事務(wù)管理)transaction manager, use JtaTransactionManager for global tx --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>- 自動(dòng)掃描,自動(dòng)注入,配置數(shù)據(jù)庫
- 自動(dòng)掃描,將標(biāo)注Spring注解的類自動(dòng)轉(zhuǎn)化Bean,同時(shí)完成Bean的注入
- 加載數(shù)據(jù)資源屬性文件
- 配置數(shù)據(jù)源(三種方式,采用DBCP)
- 配置sessionfactory
- 裝配Dao接口
- 聲明式事務(wù)管理
- 注解事務(wù)切面
- Mapper.xml映射文件中定義了操作數(shù)據(jù)庫的sql,每一個(gè)sql是一個(gè)statement,映射文件是myBatis的核心。
- 自動(dòng)掃描,自動(dòng)注入,配置數(shù)據(jù)庫
-
jdbc.properties:JDBC屬性文件
driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/db_ssm?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull username=root password=147789 #定義初始連接數(shù) initialSize=0 #定義最大連接數(shù) maxActive=20 #定義最大空閑 maxIdle=20 #定義最小空閑 minIdle=1 #定義最長等待時(shí)間 maxWait=60000
創(chuàng)建業(yè)務(wù)流程
以數(shù)據(jù)庫查詢表內(nèi)容為例
持久層:DAO層(mapper)做數(shù)據(jù)持久層的工作,負(fù)責(zé)與數(shù)據(jù)庫進(jìn)行聯(lián)絡(luò)的一些任務(wù)都封裝在此,
- DAO層的設(shè)計(jì)首先是設(shè)計(jì)DAO的接口,
- 然后在Spring的配置文件中定義此接口的實(shí)現(xiàn)類,
- 然后就可在模塊中調(diào)用此接口來進(jìn)行數(shù)據(jù)業(yè)務(wù)的處理,而不用關(guān)心此接口的具體實(shí)現(xiàn)類是哪個(gè)類,顯得結(jié)構(gòu)非常清晰,
- DAO層的數(shù)據(jù)源配置,以及有關(guān)數(shù)據(jù)庫連接的參數(shù)都在Spring的配置文件中進(jìn)行配置。
業(yè)務(wù)層:Service層 主要負(fù)責(zé)業(yè)務(wù)模塊的邏輯應(yīng)用設(shè)計(jì)。
- 首先設(shè)計(jì)接口,再設(shè)計(jì)其實(shí)現(xiàn)的類
- 接著再在Spring的配置文件中配置其實(shí)現(xiàn)的關(guān)聯(lián)。這樣我們就可以在應(yīng)用中調(diào)用Service接口來進(jìn)行業(yè)務(wù)處理。
- Service層的業(yè)務(wù)實(shí)現(xiàn),具體要調(diào)用到已定義的DAO層的接口,
- 封裝Service層的業(yè)務(wù)邏輯有利于通用的業(yè)務(wù)邏輯的獨(dú)立性和重復(fù)利用性,程序顯得非常簡潔。
表現(xiàn)層:Controller層(Handler層)負(fù)責(zé)具體的業(yè)務(wù)模塊流程的控制
- 在此層里面要調(diào)用Service層的接口來控制業(yè)務(wù)流程,
- 控制的配置也同樣是在Spring的配置文件里面進(jìn)行,針對(duì)具體的業(yè)務(wù)流程,會(huì)有不同的控制器,我們具體的設(shè)計(jì)過程中可以將流程進(jìn)行抽象歸納,設(shè)計(jì)出可以重復(fù)利用的子單元流程模塊,這樣不僅使程序結(jié)構(gòu)變得清晰,也大大減少了代碼量。
模型層:Model層 主要存放實(shí)體類
項(xiàng)目代碼結(jié)構(gòu):
-
controller:
- “@RequestMapping”請(qǐng)求路徑映射,如果標(biāo)注在某個(gè)controller的類級(jí)別上,則表明訪問此類路徑下的方法都要加上其配置的路徑;最常用是標(biāo)注在方法上,表明哪個(gè)具體的方法來接受處理某次請(qǐng)求。
- 調(diào)用service層方法
- spring mvc 支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void。本文返回的是String,通過model進(jìn)行使用。
-
service:建立service接口和實(shí)現(xiàn)類
- impl:接口對(duì)應(yīng)實(shí)現(xiàn)類:
- 調(diào)用Dao層的數(shù)據(jù)庫操作以及model層的實(shí)體類
- impl:接口對(duì)應(yīng)實(shí)現(xiàn)類:
-
dao
- 定義接口中的方法
- 一個(gè)Dao對(duì)應(yīng)一個(gè)對(duì)應(yīng)的mapper文件,實(shí)現(xiàn)Dao對(duì)應(yīng)的定義的接口方法
-
mapping:
- mapper.xml:實(shí)現(xiàn)dao中接口定義的方法
<?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.ssm.demo.dao.UserDao"> <resultMap id="UserBaseMap" type="com.ssm.demo.model.User"> <id column="id" property="id" jdbcType="BIGINT"/> <result column="user_name" property="userName" jdbcType="VARCHAR"/> <result column="user_phone" property="userPhone" jdbcType="VARCHAR"/> <result column="user_email" property="userEmail" jdbcType="VARCHAR"/> <result column="user_pwd" property="userPwd" jdbcType="VARCHAR"/> <result column="pwd_salt" property="pwdSalt" jdbcType="VARCHAR"/> <result column="create_time" property="createTime" jdbcType="DATE"/> <result column="modify_time" property="modifyTime" jdbcType="DATE"/> <result column="is_delete" property="isDelete" jdbcType="SMALLINT"></result> </resultMap> <select id="selectUserById" parameterType="java.lang.Long" resultMap="UserBaseMap"> SELECT * FROM t_user WHERE id = #{userId} </select> <select id="selectUserByPhoneOrEmail" resultMap="UserBaseMap"> SELECT * FROM t_user WHERE user_email = #{emailOrPhone} OR user_phone = #{emailOrPhone} AND user_state = #{state} </select> <select id="selectAllUser" resultMap="UserBaseMap"> SELECT * FROM t_user </select> </mapper>- namespace:當(dāng)前庫表映射文件的命名空間,唯一的不能重復(fù)
- 映射實(shí)體類的數(shù)據(jù)類型 id:resultMap的唯一標(biāo)識(shí)
- column:庫表的字段名 property:實(shí)體類里的屬性名
- id:當(dāng)前sql的唯一標(biāo)識(shí)
- parameterType:輸入?yún)?shù)的數(shù)據(jù)類型
- 返回值的數(shù)據(jù)類型:resultMap適合使用返回值是自定義實(shí)體類的情況 ; resultType適合使用返回值的數(shù)據(jù)類型是非自定義的,即jdk的提供的類型。
- {}:用來接受參數(shù)的,如果是傳遞一個(gè)參數(shù)#{id}內(nèi)容任意,如果是多個(gè)參數(shù)就有一定的規(guī)則,采用的是預(yù)編譯的形式select
-
model
- 實(shí)體屬性——對(duì)應(yīng)表中的元組的屬性
- getter和setter方法
DataBase ===> Entity ===> Mapper.xml ===> Mapper.Java ===> Service.java ===> Controller.java ===> Jsp.
參考文章
SSM框架整合(IntelliJ IDEA + maven + Spring + SpringMVC + MyBatis)
SSM框架感受
本質(zhì)上的MVC,xml配置、注解,以及mapper的映射,讓開發(fā)更加簡潔和思路清晰