MyBatis
介紹:iBATIS 一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架.iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAO),同時還提供一個利用這個框架開發的 JPetStore實例.
總體來說 MyBatis 主要完成兩件事情:
1.根據 JDBC 規范建立與數據庫的連接.
2.通過Annotaion/XML+JAVA反射技術,實現 Java 對象與關系數據庫之間相互轉化.
Hibernate(ORM) MyBatis3(SQL語句映射)
SessionFactory SqlSessionFactory
Session SqlSession
Session : 會話(持續的一段有效時間)
HttpSession : 代表瀏覽器打開到瀏覽器關閉.
Session : 代表數據庫連接(Connection)的獲取到數據庫連接的關閉.
SqlSession : 代表數據庫連接(Connection)的獲取到數據庫連接的關閉.
MyBatis3下載與安裝:
-- 下載地址: https://github.com/mybatis/mybatis-3/releases
-- mybatis-3.3.0.zip | mybatis-3-mybatis-3.3.0.zip (2015.5.24)
-- 解壓mybatis-3.3.0.zip:
-- lib : 存放的是第三方的jar(需要依賴的jar).
-- mybatis-3.3.0.jar (自己的jar).
-- mybatis-3.3.0.pdf (學習文檔).
MyBatis3入門
1:拷貝jar包
拷貝jar(mybatis-3.3.0\lib\*.jar、mybatis-3.3.0.jar、mysql驅動).
2:在src目錄下提供全局配置文件
mybatis-config.xml
MyBatis的CRUD
第一種(基於映射文件)
xxxMapper.xml(命名空間,用來匹分不同的sql語句).
<insert/>
<update/>
<delete/>
<select/>
一張表對應一個sql語句映射文件.
插入數據:
-- 定義sql語句:
<insert id="save"> sql語句 </insert>
-- 執行插入數據的方法:
int res = sqlSession.insert("namespace(配置文件的命名空間).id(定義sql語句的id)", 插入的參數);
可以返回int類型res :受影響的記錄條數.
<insert/>可以設置的類型:
useGeneratedKeys:是否返回主鍵id, 是否用生成的主鍵列的值
keyColumn : 指定主鍵列的列名(表的)
keyProperty: 指定封裝數據對象的屬性名(類的)
例如:<insert id="save2" keyColumn="ID" keyProperty="id" useGeneratedKeys="true"/>
可以配置全局的返回主鍵id值
(在MyBatis配置文件中配置)
<settings>
<!-- 配置用生成的主鍵值 -->
<setting name="useGeneratedKeys" value="true"/>
</settings>
修改數據:
定義sql語句:
<update id="update">
update province set name = #{name}, create_date = #{createDate} where id = #{id}
</update>
-- 執行update語句的方法.
int res = sqlSession.update("namespace(配置文件的命名空間).id(定義sql語句的id), "參數");
刪除數據:
<delete id="delete">
delete from province where id = #{id}
</delete>
-- 執行delete語句的方法.
int res = sqlSession.delete("namespace(配置文件的命名空間).id(定義sql語句的id), "參數");
查詢數據:
<select id="唯一標識符" resultType="cn.itcast.mybatis.pojo.Province">
查詢的sql語句
</select>
<select>可以設置的類型
-- resultType: 返回類型(查詢表中數據用哪個類來封裝,如果要引用類型必須完整路徑類名)
<select id="get2" resultType="cn.itcast.mybatis.pojo.Province">
SELECT p.id, p.name,p.create_date AS createDate FROM province AS p where p.id = #{id}
</select>
-- resultMap:自定義類型(可以配置全局引用類型,通過resultMap引入)
<resultMap type="cn.itcast.pojo.Province(接口名或類名)" id="provineMap(自定義別名)" autoMapping="true(是否自動裝配)">
<!--
column : 列名
property : 屬性名
字段名和類的屬性值名一樣可以不配,不一致必須配
-->
<result column="CREATE_DATE" property="createDate"/>
</resultMap>
(如果在配置文件掃描實體包,type可以不寫完整包名只寫類名)
查詢返回數據是通過session給的類型
-- 查詢返回一個集合:
List<T> lists = sqlSession.selectList();
-- 查詢返回一條記錄:
Province p = sqlSession.selectOne();
第二種(基於數據訪問接口 +映射文件)
1:需要定義數據訪問接口類
2:需要 xxxMapper.xml SQL語句定義文件.:
ProvinceMapper.xml 映射文件中命名空間必須填寫接口的完整路徑名
namespace="cn.itcast.mybatis.mapper.ProvinceMapper"
原因:
代表ProvinceMapper.xml 文件中的SQL語句用ProvinceMapper類中的方法進行操作.
約定:ProvinceMapper接口中的方法必須為ProvinceMapper.xml文件中的sql語句id值.
3:獲取數據訪問接口代理對象
provinceMapper = session.getMapper(ProvinceMapper.class);
注意:
1:映射文件CRUD中的id名必須填寫對應的接口方法名
映射文件:
<insert id="save1">
insert into province(name, create_date) values(#{name},#{createDate})
</insert>
接口類:
public int save1(Province province);
2:通過ProvinceMapper代理點出初入的接口方法
第三種(基於數據訪問接口 + 注解 + 映射文件.)
1:定義數據接口類
2:定義xxxMapper.xml SQL映射文件
3:在接口方法上使用注解寫入CRUD語句
添加:@Insert("sql語句")
@SelectKey(keyColumn="id", // 主鍵列的列名
before=false, // 插入之后返回id值
keyProperty="id", // Province對象中的屬性
statement="select last_insert_id()", // 查詢語句
resultType=Integer.class) // 返回的主鍵列數據類型
修改:@Update("sql語句")
@Update("update province set name = #{name}, create_date = #{createDate} where id = #{id}")
#{name} --> 如果是對象就調它的getName方法
#{name} --> 如果是Map集合就根據它的key取value.
刪除:@Delete("sql語句")
查詢:@Select("sql語句")
@ResultType() // 返回的數據類型
@Select("select * from province where id = #{id}")
@ResultMap("provinceMap") // 引用ProvinceMapper.xml中的<resultMap/>的id值
動態sql語句
在第二種基礎之上進行改進,在映射文件中寫入:
<select id="find1" resultMap="provineMap">
select * from province
<where>
<if test="name !=null && name!=''">
name like CONCAT('%'+#{name}+'%')
</if>
<if test="id >0">
and id >#{id}
</if>
</where>
</select>
可以加入條件語句
Where標簽
-- <where/> : 會根據它里面的if條件生成where字符串
If標簽
-- <if> :
條件判斷.
<if test="name != null && name != ''">
name like CONCAT('%', #{name},'%')
</if>
For標簽
<foreach> :
迭代集合或者數組
<!-- 迭代集合或者數組
collection : list集合 、 array數組
open : 打開時加什么
close : 關閉時加什么
separator : 中間分隔符
item : 數組元素
-->
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
Set標簽
修改時用,會根據它里面的if條件生成set字符串.
update province
<set>
<!-- 判斷name -->
<if test="p.name != null && p.name !=''">
name = #{p.name},
</if>
<if test="p.createDate != null">
create_date = #{p.createDate},
</if>
</set>
Trim標簽
在sql語句字符串前后添加什么
<!--
prefix : 前綴加什么
suffix: 后綴加什么
-->
<trim prefix="select * from province" suffix="order by id asc">
<where>
<if test="name != null && name !=''">
name like concat('%',#{name},'%')
</if>
</where>
</trim>
可以定義全局的sql語句片段
<sql id="sql1">
from province
<where>
<if test="province.name!=null && province.name!=''">
name like CONCAT('%'+#{province.name}+'%'")
</if>
<if test="province.id > 0">
and id >#{province.id}
</if>
</where>
</sql>
注意:
1:在接口定義方法中,由於傳多個參數會無法識別,需要在方法傳值中用參數標簽聲明
List<Province> finByPage(@Param("province")Province province,
@Param("id")int start,
@Param("name")int page);
(1):方法中只傳一個對象可以不寫注解
(2):方法中只傳map集合可以不寫注解
(3):方法中只傳一個參數可以不寫注解
(4):多個參數必須寫(string也是對象)
關聯映射
一對多
在xml映射文件中必須制定關聯的屬性,如果是單一對象的一方,用< association >標簽,如果是集合對象的一方用< collection >。
單一對象的一方
<resultMap type="City" id="provinceMap" extends="beanCity">
<!-- 省份與城市存在1-N關聯 List<City>
property : 指定關聯的屬性
column : 主鍵列(關聯的列)
ofType : 指定集合中數據類型 City
javaType : 該關聯的屬性的java類型
select : 引用那個查詢方法的id(完整路徑名)
-->
<association property="province"
column="province_id"
javaType="Province"
select="cn.itcast.mapper.ProvinceMapper.get"/>
</resultMap>
有集合的一方
<resultMap type="Province" id="provineMap" extends="beanMap">
<!-- 省份與城市存在1-N關聯 List<City>
property : 指定關聯的屬性
column : 主鍵列(關聯的列)
ofType : 指定集合中數據類型 City
javaType : 該關聯的屬性的java類型
select : 引用那個查詢方法的id(完整路徑名)
-->
<collection property="cities" column="id"
ofType="City" javaType="list"
select="cn.itcast.mapper.CityMapper.finByPage"/>
</resultMap>
封裝兩張表時
<resultMap type="City" id="provinceMap2" extends="beanCity">
<association property="province" column="province_id" javaType="Province">
<result column="pid" property="id"/>
<result column="pname" property="name"/>
<result column="create_date" property="createDate"/>
</association>
</resultMap>
多對多
兩邊都是用集合定義屬性
需要查詢的一邊集合
<resultMap type="Teacher" id="teacherMap" autoMapping="true">
<collection property="students" column="id"
ofType="Student" javaType="java.util.Set"
select="cn.itcast.mapper.StudentMapper.findByPage"/>
</resultMap>
集合需要存放的對象
<select id="findByPage" resultType="Student">
SELECT s.* FROM `tea_2_stu` AS ts, `student` AS s, `teacher` AS t
WHERE ts.`STU_ID` = s.`ID` AND ts.`TEA_ID` = t.`ID` AND t.`ID` = #{id}
</select>
延遲加載和緩存
延遲加載
在MyBatis-config.xml配置文件,全局配置<settings>標簽里,寫入
1:lazyLoadingEnabled與aggressiveLazyLoading必須指定兩個的值才能實現延遲加載
<!-- 全局的屬性設置 -->
<settings>
<!-- 配置用生成的主鍵值 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 開啟延遲加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 設置按需要加載 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 配置使用緩存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
對象緩存
1:除了在MyBatis-config.xml配置文件中需要寫入cacheEnabled為開啟
2:還需要在映射文件中進行配置
<!-- 配置使用緩存
eviction : 緩存中對象的淘汰算法:LRU(Least Recently Used)近期最少使用算法|FIFO(First Input First Output)先入先出隊列
flushInterval: 指緩存過期時間(單位為毫秒)
readOnly : 是否只讀
size : 指緩存多少個對象(默認值為1024)
-->
<cache eviction="LRU"
flushInterval="60000"
readOnly="true"
size="1024"/>
Spring
Spring整合MyBatis
在applicationContext.xml配置文件中
1:配置SqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource" //注入數據源
p:configLocation="classpath:mybatis-config.xml" //讀取配置文件
p:typeAliasesPackage="cn.itcast.ssm.pojo" //掃描包下實體類並根據類名創建實體
p:mapperLocations="classpath:mapper/*.xml"/> //掃描映射文件
2:配置數據訪問接口代理對象Bean
單個配置
<bean id="noticeMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"
p:mapperInterface="cn.itcast.ssm.mapper.NoticeMapper"
p:sqlSessionFactory-ref="sqlSessionFactory"/>
批量配置包掃描(推薦)
<!-- 配置數據訪問接口代理對象Bean(批量配置,采用包掃描)
它掃描基礎包下所有的數據訪問接口類,掃描后會創建接口的代理對象,再交由Spring容器
bean的id默認為接口的類名首字小寫-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:sqlSessionFactoryBeanName="sqlSessionFactory"
p:basePackage="cn.itcast.ssm.mapper"/>
3:配置數據源事務管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
4:聲明式事務配置
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定義事務屬性 -->
<tx:attributes>
<!-- set方法開頭只能做查詢 read-only(true) 沒有開啟事務 -->
<tx:method name="set*" read-only="true"/>
<!-- get方法開頭只能做查詢 read-only(true) 沒有開啟事務 -->
<tx:method name="get*" read-only="true"/>
<!-- 剩余的方法可以做CUD R(查詢也可以做) read-only(false) 開啟了事務 -->
<tx:method name="*" read-only="false" rollback-for="java.lang.RuntimeException"/>
</tx:attributes>
</tx:advice>
5:需要另外配置的全局屬性需要創建一個MyBatis-config.xml配置文件
<!-- 全局的屬性設置 -->
<settings>
<!-- 配置用生成的主鍵值 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 開啟延遲加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 設置按需要加載 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 配置使用緩存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
整合SSM
配置Spring配置文件
添加並配置“applicationContext.xml”文件;主要配置組件掃描(service/mapper),屬性文件,數據源,事務控制。
<context:component-scan base-package="cn.itcast.ssm.service.impl"></context:component-scan>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<!-- 允許JVM參數覆蓋 -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<!-- 忽略沒有找到的資源文件 -->
<property name="ignoreResourceNotFound" value="true" />
<!-- 配置資源文件 -->
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<!-- 數據庫驅動 -->
<property name="driverClass" value="${jdbc.driver}" />
<!-- 相應驅動的jdbcUrl -->
<property name="jdbcUrl" value="${jdbc.url}" />
<!-- 數據庫的用戶名 -->
<property name="username" value="${jdbc.username}" />
<!-- 數據庫的密碼 -->
<property name="password" value="${jdbc.password}" />
<!-- 檢查數據庫連接池中空閑連接的間隔時間,單位是分,默認值:240,如果要取消則設置為0 -->
<property name="idleConnectionTestPeriod" value="60" />
<!-- 連接池中未使用的鏈接最大存活時間,單位是分,默認值:60,如果要永遠存活設置為0 -->
<property name="idleMaxAge" value="30" />
<!-- 每個分區最大的連接數 -->
<property name="maxConnectionsPerPartition" value="150" />
<!-- 每個分區最小的連接數 -->
<property name="minConnectionsPerPartition" value="5" />
</bean>
<!-- 定義事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 定義事務策略 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--所有以query開頭的方法都是只讀的 -->
<tx:method name="query*" read-only="true" />
<!--其他方法使用默認事務策略 -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<!-- 配置切入點 -->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* cn.itcast.ssm.service.impl.*.*(..))" />
<!--將定義好的事務處理策略應用到上述的切入點 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" />
</aop:config>
</beans>
添加jdbc.properties和log4j.properties文件
配置spring與mybatis的配置文件
添加並配置“applicationContext-mybatis.xml”文件;主要配置sqlSessionFactory和mapper接口的掃描。
<!-- 定義Mybatis的SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 設置Mybatis的總配置文件路徑 -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"></property>
<!-- 設置所有mapper文件的路徑 -->
<property name="mapperLocations" value="classpath:mybatis/mappers/*.xml"></property>
<!-- 設置類型別名 -->
<property name="typeAliasesPackage" value="cn.itcast.ssm.pojo"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- mapper接口所在的包 -->
<property name="basePackage" value="cn.itcast.ssm.mapper"></property>
</bean>
</beans>
配置spring MVC配置文件
添加並配置“xxx-servlet.xml”配置文件;主要配置注解驅動、屬性文件、處理器掃描、視圖解析器等。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<!-- 允許JVM參數覆蓋 -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<!-- 忽略沒有找到的資源文件 -->
<property name="ignoreResourceNotFound" value="true" />
<!-- 配置資源文件 -->
<property name="locations">
<list>
<value>classpath:env.properties</value>
</list>
</property>
</bean>
<!-- 注解驅動 -->
<mvc:annotation-driven/>
<context:component-scan base-package="cn.itcast.ssm.controller"></context:component-scan>
<!-- 配置視圖解析器 -->
<!-- Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" -> "/WEB-INF/jsp/test.jsp" -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 定義文件上傳解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設置默認字符編碼 -->
<property name="defaultEncoding" value="uft-8"></property>
<!-- 設置最大上傳文件大小(單位B)5*1024*1024=5242880B=5MB -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
<!-- 解決靜態資源404問題 -->
<mvc:default-servlet-handler/>
</beans>
配置web.xml文件
在web.xml文件中;設置spring的監聽器、字符過濾器、spring mvc的servlet配置等信息。
<?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">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*</param-value>
</context-param>
<!-- 解決rest時put方式提交無法獲取表單數據 -->
<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>
<!-- 解決rest時delete方式提交無法獲取表單數據,通過post添加_method參數模擬delete方式 -->
<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>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置spring mvc前端控制器 -->
<servlet>
<servlet-name>ssm</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/ssm-servlet.xml</param-value>
</init-param>
<!-- 隨着應用服務器啟動而初始化 若不配置,則第一次請求后完成初始化 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ssm</servlet-name>
<!-- ssm的映射規則: 可以配置:/、/xxx/*、*.* 不可配置:/* 與應用服務器配置默認沖突 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<display-name>ssm</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Restful風格
什么是Rest:
REST是一種設計風格。它不是一種標准,也不是一種軟件,而是一種思想。
RESTful風格的一大特色就是使用URI來標識資源。
URI:統一資源標識符(Uniform Resource Identifier)-- 抽象資源
請求方法:
GET:獲取一個資源
POST:新增一個資源
PUT:更新一個資源的狀態
DELETE:刪除一個資源
接口定義:
http方法 |
資源操作 |
冪等 |
安全 |
GET |
SELECT |
是 |
是 |
POST |
INSERT |
否 |
否 |
PUT |
UPDATE |
是 |
否 |
DELETE |
DELETE |
是 |
否 |
冪等性:對同一REST接口的多次訪問,得到的資源狀態是相同的。
安全性:對該REST接口訪問,不會使服務器端資源的狀態發生改變。
響應狀態碼:
Spring MVC實現RESTful:
Spring MVC原生態的支持了REST風格的架構設計。Spring MVC 對 RESTful應用提供了以下支持:
l 利用@RequestMapping 指定要處理請求的URI和HTTP請求的動作類型
l 利用@PathVariable將URI請求模板中的變量映射到處理方法參數上
l 利用Ajax,在客戶端發出PUT、DELETE動作的請求
書寫格式:
Get請求(獲取參數):
訪問方法:
Post請求(新增用戶):
訪問方法:
、
Put請求(修改用戶):
配置過濾器;由於put方式在提交表單數據時不能在后台中獲取到,所以在web.xml中添加過濾器實現put方式獲取數據;
<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>
訪問方式
Delete(刪除用戶):
配置過濾器:由於delete方式提交時后台無法獲取表單數據,只能通過POST方式並在提交的過程中附帶_method參數指定值為DELETE,模擬DELETE提交;所以也需要在web.xml中添加過濾器;
<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>
請求方式:
SpringMVC
SpringMVC與Struts2區別
1:SpringMVC的入口是Servlet,Struts2的入口是Filter,兩者的實現機制不同。
2:SpringMVC基於方法設計,傳遞參數是通過方法形參,其實現是單例模式(也可以改為多例,推薦用單例),Struts2基於類設計,傳遞參數是通過類的屬性,只能是多例實現,性能上SpringMVC更高一些。
3:參數傳遞方面,Struts2是用類的屬性接收的,也就是在多個方法間共享,而SpringMVC基於方法,多個方法間不能共享。
頁面REST插件測試
1:注意:需要穿json格式需要改選項
2:需要多個參數可以選擇
SpringMVC執行流程
開發SpringMVC步驟
1:配置web.xml
<!-- 配置spring mvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 隨着應用服務器啟動而初始化
若不配置,則第一次請求后完成初始化
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
springmvc的映射規則:
可以配置:/、/xxx/*、*.*
不可配置:/* 與應用服務器配置默認沖突
-->
<url-pattern>*.mvc</url-pattern>
</servlet-mapping>
【注意】DispatcherServlet的配置文件路徑默認為:
/WEB-INF/{servlet-name}-servlet.xml ,這個名稱可以通過contextConfigLocation參數修改。
2:配置映射器
<!-- 注解驅動這一步相當於配置了映射器與適配器 -->
<mvc:annotation-driven/>
<!-- 配置處理器 -->
<!-- <bean name="/hello.mvc" class="cn.itcast.springmvc.controller.HelloController"/> -->
<context:component-scan base-package="cn.itcast.springmvc.controller"/> // 包掃描
<!-- 配置視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
3:寫處理器處理業務邏輯
@Controller
@RequestMapping("/demo") //相當於struts2的命名空間
public class DemoController {
@RequestMapping("/show1") //需要/demo加上此方法命名空間
public ModelAndView show1(){
ModelAndView mv = new ModelAndView("text");
mv.addObject("msg", "show1");
return mv;
}
轉發:forward
重定向:redirect
注意:
@RequestMapping三種映射兩種限定
映射:1.普通url地址,2.*通配符如/**/demo、/*/show1,3.占位符{abc}
如/show1/jkjf.mvc
限定:1.限定方法2.限定參數
1:@PathVariable標簽指定的是頁面訪問的地址命名空間訪問如下:/abcd/show6.mvc
@RequestMapping("/{userId}/show6")
public ModelAndView show6(@PathVariable("userId")String userId)
2: @RequestParam指定的是頁面帶參數的值例如:/show7.mvc?requestType=faafsa
3: @ResponseBody把json轉為pojo對象,@RequestBody把pojo對象轉為json字符串
4:所有在頁面地址欄url上輸入中文需要帶入后台的參數,都和get請求轉碼一樣,需要進行處理 :
byte[] bytes = userId.getBytes("iso-8859-1");
String id =new String(bytes,"utf-8");
mv.addObject("msg", "show4 "+id);
5:URLEncoder的編碼和URLDecoder解碼只能用於中文參數需要重定向到某個接參的方法進行url解碼例如:
@RequestMapping("/show9")
public ModelAndView show9() throws Exception{
ModelAndView mv =new ModelAndView("redirect:show10.mvc");
mv.addObject("msg", URLEncoder.encode("張三", "utf-8"));
return mv;
}
@RequestMapping("/show10")
public ModelAndView show10(@RequestParam(value="msg")String requestType) throws Exception{
ModelAndView mv =new ModelAndView("text");
mv.addObject("msg", "這是我的第一個注解的spring mvc應用。方法為:show9重定向而來;攜帶數據"+URLDecoder.decode(requestType, "utf-8"));
return mv;
}
6.@Value("${PIC_UPLOAD_PATH}") 獲取properties配置文件key值
private String PIC_UPLOAD_PATH;
*-servlet.xml配置文件進行配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<!-- 允許JVM參數覆蓋 -->
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<!-- 忽略沒有找到的資源文件 -->
<property name="ignoreResourceNotFound" value="true" />
<!-- 配置資源文件 -->
<property name="locations">
<list>
<value>classpath:env.properties</value>
</list>
</property>
</bean>
上傳與下載
上傳:
1:引入jar包
將commons-fileupload-1.3.1.jar,commons-io-2.4.jar引入項目
2:添加配置文件在**-servlet.xml文件
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設置默認字符編碼 -->
<property name="defaultEncoding" value="uft-8"></property>
<!-- 設置最大上傳文件大小(單位B)5*1024*1024=5242880B=5MB -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
3:單文件上傳,在方法中引入(@RequestParam("file") MultipartFile multipartFile)
@RequestMapping("/upload1")
public String uploadFile1(@RequestParam("file") MultipartFile multipartFile){
try {
if(multipartFile != null){
//保存文件
//獲取文件保存路徑
String path = PIC_UPLOAD_PATH;
//保存文件
multipartFile.transferTo(new File(path,multipartFile.getOriginalFilename()));
}
} catch (Exception e) {
e.printStackTrace();
}
return "redirect:/success.jsp";
}
多文件上傳用數組接收:@RequestParam("files") MultipartFile[] multipartFiles
@RequestMapping("/upload2")
public String upload2(@RequestParam("files") MultipartFile[] multipartFiles) throws Exception{
if (multipartFiles != null) {
//獲取服務器中upload目錄所在的服務器絕對路徑
String path = servletContext.getRealPath("/upload");
for (MultipartFile mf : multipartFiles) {
//將上傳的文件保存文件到指定路徑
mf.transferTo(new File(path + File.separator + mf.getOriginalFilename()));
}
}
return "redirect:/success.jsp";
}
下載(Excel):
Spring MVC默認的Excel操作api組件為poi,所以需引入poi-xx.jar包到項目中。
具體和struts2一樣
攔截器
使用場景:攔截器一般可使用的場景:日志記錄、權限檢查、性能監控、通用行為(本地化信息、主題信息)。
Spring MVC的攔截器接口定義了三個方法:
preHandle 調用handler之前執行;
postHandle 調用handler之后執行(如沒調用執行handler將不執行此方法;也就是如果preHandle方法返回false的話,postHandle方法必定不執行);
afterCompletion 視圖渲染完之后並且preHandle方法返回true時執行。
執行過程
當有多個攔截器時,按照上述執行過程,每個攔截器中的三個方法執行的順序:preHandle按順序執行,postHandle和afterCompletion都是逆序執行。
自定義攔截器:
1:使用HandlerInterceptor接口
2:添加攔截器配置(配置多個攔截器)
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**/**.mvc"/>
<bean class="cn.itcast.springmvc.interceptor.MyHandlerInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**/**.mvc"/>
<bean class="cn.itcast.springmvc.interceptor.MyHandlerInterceptor2"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**/**.mvc"/>
<bean class="cn.itcast.springmvc.interceptor.MyHandlerInterceptor3"></bean>
</mvc:interceptor>
</mvc:interceptors>
靜態資源404與日期問題
在web.xml中配置
當配置的DispatcherServlet的url-pattern為“/”時,意思是匹配所有資源,那么也就包括了系統的所有html、js、css、images等這些靜態資源,而后台的Handler是無法處理靜態資源的;導致找不到資源出現404報錯。在Spring MVC中可以在配置文件中添加<mvc:default-servlet-handler/>解決此問題。意思是將靜態資源轉交給服務器處理
解決字符轉日期問題
在表單中輸入日期后提交到后台,如果接收的對象對應的屬性類型為日期的那么會提交失敗,原因是轉換類型失敗。解決此問題在Spring MVC中非常簡單,在對應的對象的屬性上添加@DateTimeFormat注解進行轉換即可。具體如下: