




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、 基于注解的mybatis和spring整合分類: spring2013-02-22 21:37 3373人閱讀 評論(2) 收藏 舉報springSpring基于注解的mybatis和spring整合博客分類:· mybatis· spring· java· ibatis· 注解javaibatismybatisspring注解ibatis改名為mybatis已經將近一年了,mybatis3也發布了,但是相關的開發文檔卻很少,查閱了官方的使用指南,也是說的模糊不清,一筆 帶過,尤其是
2、注解部分,只是列舉了注解種類,卻沒有對應的例子,因此可能會給某些兄弟使用mybatis注解帶來困惑,我想就我微薄的知識想對 mybatis注解的使用以及和spring整合談談自己的看法,也希望大家猛烈的指正我的錯誤。 首先當然得下載和兩個JAR包,并放在WEB-INF的 lib目錄下(如果你使用maven,則jar會根據你的pom配置的依賴自動下載,并存放在你指定的maven本地庫中,默認是/.m2 /repository),前一個是mybatis核心包,后一個是和spring整合的包。 使用mybatis,必須有個全局配置文件configuration.xml,來配置my
3、batis的緩存,延遲加載等等一系列屬性,該配置文件示例如下: Java代碼 1. <?xml version="1.0" encoding="UTF-8" ?> 2. <!DOCTYPE configuration 3. PUBLIC "-/ibatis.apache.o
4、rg/DTD Config 3.0/EN" 4. "/dtd/ibatis-3-config.dtd"> 5. <configuration> 6. <settings> 7.
5、160; <!- 全局映射器啟用緩存 -> 8. <setting name="cacheEnabled" value="true" /> 9.
6、; <!- 查詢時,關閉關聯對象即時加載以提高性能 -> 10. <setting name="lazyLoadingEnabled" value="true" /> 11.
7、160; <!- 設置關聯對象加載的形態,此處為按需加載字段(加載字段由SQL指 定),不會加載關聯表的所有字段,以提高性能 -> 12. &
8、lt;setting name="aggressiveLazyLoading" value="false" /> 13. <!- 對于未知的SQL查詢,允許返回不同的結果集以達到通用的效果 -> 14.
9、160; <setting name="multipleResultSetsEnabled" value="true" /> 15. <!- 允許使用列標簽代替列名 -> 16.
10、 <setting name="useColumnLabel" value="true" /> 17. <!- 允許使用自定義的主鍵值(比如由程序生成的UUID 32位編碼作為鍵值),數據表的PK生成策略將被覆蓋
11、0;-> 18. <setting name="useGeneratedKeys" value="true" /> 19. <!- 給予被嵌套的resultMap以
12、字段-屬性的映射支持 -> 20. <setting name="autoMappingBehavior" value="FULL" /> 21. <!-
13、;對于批量更新操作緩存SQL以提高性能 -> 22. <setting name="defaultExecutorType" value="BATCH" /> 23. &
14、#160;<!- 數據庫超過25000秒仍未響應則超時 -> 24. <setting name="defaultStatementTimeout" value="25000" /> 25. </settings> 26.
15、160; <!- 全局別名設置,在映射文件中只需寫別名,而不必寫出整個類路徑 -> 27. <typeAliases> 28. <typeAlias alias="TestBean" 29.
16、 type="com.wotao.taotao.persist.test.dataobject.TestBean" /> 30. </typeAliases> 31. <!- 非注解的sql映射文件配置,如果使用mybatis注解,該mapper無需配置,但是如果mybatis注解中包含resultM
17、ap注解,則mapper必須配置,給resultMap注解使用 -> 32. <mappers> 33. <mapper resource="persist/test/orm/test.xml" /> 34. </mappers>
18、0;35. </configuration> 該文件放在資源文件的任意classpath目錄下,假設這里就直接放在資源根目錄,等會spring需要引用該文件。 查看ibatis-3-config.dtd發現除了settings和typeAliases還有其他眾多元素,比如 properties,objectFactory,environments等等,這些元素基本上都包含著一些環境配置,數據源定義,數據庫事務等等, 在單獨使用mybatis的時候非常重要,比如通過以構造參數的形式去實例化一個sqlsessionFactory,就像這樣: J
19、ava代碼 1. SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader); 2. SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, properties); 3. SqlSessionFactory factory = sqlSessionFactoryBuilder.b
20、uild(reader, environment, properties); 而typeHandlers則用來自定義映射規則,如你可以自定義將Character映射為varchar,plugins元素則放了一些攔截器接口,你可以繼承他們并做一些切面的事情,至于每個元素的細節和使用,你參考mybatis用戶指南即可。 現在我們用的是spring,因此除settings和typeAliases元素之外,其他元素將會失效,故不在此配置,spring會覆蓋這些元素的配置,比如在spring配置文件中指定c3p0數據源定義如下: Java代碼
21、 1. <!- c3p0 connection pool configuration -> 2. <bean id="testDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 3. des
22、troy-method="close"> 4. <!- 數據庫驅動 -> 5. <property name="driverClass" value="$
23、db.driver.class" /> 6. <!- 連接URL串 -> 7. <property name="jdbcUrl" value="$db.u
24、rl" /> 8. <!- 連接用戶名 -> 9. <property name="user" value="$db.username"
25、0;/> 10. <!- 連接密碼 -> 11. <property name="password" value="$db.password" />
26、 12. <!- 初始化連接池時連接數量為5個 -> 13. <property name="initialPoolSize" value="5" />&
27、#160; 14. <!- 允許最小連接數量為5個 -> 15. <property name="minPoolSize" value="5" />
28、60;16. <!- 允許最大連接數量為20個 -> 17. <property name="maxPoolSize" value="20" /> 18.
29、 <!- 允許連接池最大生成100個PreparedStatement對象 -> 19. <property name="maxStatements" value="100" /&g
30、t; 20. <!- 連接有效時間,連接超過3600秒未使用,則該連接丟棄 -> 21. <property name="maxIdleTime" value="3600"
31、; /> 22. <!- 連接用完時,一次產生的新連接步進值為2 -> 23. <property name="acquireIncrement" value="2
32、" /> 24. <!- 獲取連接失敗后再嘗試10次,再失敗則返回DAOException異常 -> 25. <property name="acquireRetryAttempts&
33、quot; value="10" /> 26. <!- 獲取下一次連接時最短間隔600毫秒,有助于提高性能 -> 27. <property name="acqui
34、reRetryDelay" value="600" /> 28. <!- 檢查連接的有效性,此處小弟不是很懂什么意思 -> 29. <property name=&
35、quot;testConnectionOnCheckin" value="true" /> 30. <!- 每個1200秒檢查連接對象狀態 -> 31. <property&
36、#160;name="idleConnectionTestPeriod" value="1200" /> 32. <!- 獲取新連接的超時時間為10000毫秒 -> 33.
37、0;<property name="checkoutTimeout" value="10000" /> 34. </bean> 配置中的$都是占位符,在你指定數據庫驅動打war時會自動替換,替換的值在你的父pom中配置,至于c3p0連接池的各種屬性詳細信息和用 法,你自行參考c3p0的官方文檔,這里要說明的是checkoutTimeout元素,記得千萬要設大一點,單位是毫秒,假如設置太小,有可能會導致沒 等數據
38、庫響應就直接超時了,小弟在這里吃了不少苦頭,還是基本功太差。 數據源配置妥當之后,我們就要開始非常重要的sessionFactory配置了,無論是hibernate還是mybatis,都需要一個sessionFactory來生成session,sessionFactory配置如下: Java代碼 1. <bean id="testSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
39、60;2. <property name="configLocation" value="classpath:configuration.xml" /> 3. <property name="dataSource" ref="testDataSource" /> 4. </bean>
40、 testSqlSessionFactory有兩處注入,一個就是前面提到的mybatis全局設置文件configuration.xml,另 一個就是上面定義的數據源了(注:hibernate的sessionFactory只需注入,數據源定義已經包含在 該文件中),好了,sessionFactory已經產生了,由于我們用的mybatis3的注解,因此spring的 sqlSessionTemplate也不用配置了,sqlSessionTemplate也不用注入到我們的BaseDAO中了,相應的,我們需要配置 一個映射器接口來對應sqlSessionTemplate,該映射器
41、接口定義了你自己的接口方法,具體實現不用關心,代碼如下: Java代碼 1. <!- data OR mapping interface -> 2. <bean id="testMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> 3. <property
42、name="sqlSessionFactory" ref="testSqlSessionFactory" /> 4. <property name="mapperInterface" value="com.wotao.taotao.persist.test.mapper.TestMapper" /> 5. </bean> 對
43、應于sqlSessionTemplate,testMapper同樣需要testSqlSessionFactory注入,另外一個注入就是 你自己定義的Mapper接口,該接口定義了操作數據庫的方法和SQL語句以及很多的注解,稍后我會講到。到此,mybatis和spring整合的文件 配置就算OK了(注:如果你需要開通spring對普通類的代理功能,那么你需要在spring配置文件中加入<aop:aspectj- autoproxy />),至于其他的如事務配置,AOP切面注解等內容不在本文范圍內,不作累述。 至此,一個完整的myabtis整合spring的配置文件看起來應該
44、如下所示: Java代碼 1. <?xml version="1.0" encoding="UTF-8"?> 2. <beans xmlns="/schema/beans" 3. xmlns:xsi="/2001/XMLSchema-instance"
45、60;xmlns:context="/schema/context" 4. xmlns:tx="/schema/tx" xmlns:aop="/schema/aop" 5. xsi:schemaLocation=&q
46、uot;/schema/beans /schema/beans/spring-beans-2.5.xsd 6. /schema/context /schema/context/spring-context-2.5.xsd 7. http:/www.springframework.
47、org/schema/tx /schema/tx/spring-tx-2.5.xsd 8. /schema/aop /schema/aop/spring-aop-2.5.xsd"> 9. 10. <!- c3p0 connection&
48、#160;pool configuration -> 11. <bean id="testDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 12. destroy-method="close"> 1
49、3. <property name="driverClass" value="$db.driver.class" /> 14. <property name="jdbcUrl" value="$db.url" />
50、0; 15. <property name="user" value="$db.username" /> 16. <property name="password" value="$db.password" />
51、 17. <property name="initialPoolSize" value="5" /> 18. <property name="minPoolSize" value="5" />
52、0; 19. <property name="maxPoolSize" value="20" /> 20. <property name="maxStatements" value="100" /> &
53、#160;21. <property name="maxIdleTime" value="3600" /> 22. <property name="acquireIncrement" value="2" /> &
54、#160;23. <property name="acquireRetryAttempts" value="10" /> 24. <property name="acquireRetryDelay" value="600" /&
55、gt; 25. <property name="testConnectionOnCheckin" value="true" /> 26. <property name="idleConnectionTestPeriod" value=&
56、quot;1200" /> 27. <property name="checkoutTimeout" value="10000" /> 28. </bean> 29. <bean id="test
57、SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 30. <property name="configLocation" value="classpath:configuration.xml" /> 31.
58、 <property name="dataSource" ref="testDataSource" /> 32. </bean> 33. <!- data OR mapping interface -> 34.
59、 <bean id="testMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> 35. <property name="sqlSessionFactory" ref="testSqlSessionFactory" />
60、160; 36. <property name="mapperInterface" value="com.wotao.taotao.persist.test.mapper.TestMapper" /> 37. </bean> 38. 39.
61、60;<!- add your own Mapper here -> 40. 41. <!- comment here, using annotation -> 42. <!- <bean id="sqlSessionTemplate" c
62、lass="org.mybatis.spring.SqlSessionTemplate"> -> 43. <!- <constructor-arg index="0" ref="sqlSessionFactory" /> -> 44. <!- </bean> -&g
63、t; 45. <!- base DAO class, for module business, extend this class in DAO -> 46. <!- <bean id="testBaseDAO" class="com.test.dao.T
64、estBaseDAO"> -> 47. <!- <property name="sqlSessionTemplate" ref="sqlSessionTemplate" /> -> 48. <!- </bean> -> 49.
65、0; <!- <bean id="testDAO" class="com.test.dao.impl.TestDAOImpl" /> -> 50. 51. <!- you can DI Bean if you don't like use annotati
66、on -> 52. 53. </beans> 到此為止,我們只講了mybatis和spring的整合,還沒有真正觸及mybatis的核心:使用mybatis注解代替映射文件編程(不過 官方文檔也說了,如果真正想發揮mybatis功能,還是需要用到映射文件,看來myabtis自己都對mybatis注解沒信心,呵呵),通過上述內 容,我們知道配置搞定,但是testMapper還沒有被實現,而注解的使用,全部集中在這個testMapper上,是mybatis注解的核心所在, 先來看一下這個testMapp
67、er接口是個什么樣的: Java代碼 1. /* 2. * The test Mapper interface. 3. * 4. * author HuangMin <a href="mailto:minhuang>send email</a> 5. * 6. * since 1.6
68、60;7. * version 1.0 8. * 9. * #TestMapper.java 2011-9-23 : afternoon 10:51:40 10. */ 11. CacheNamespace(size = 512) 12. public in
69、terface TestMapper 13. 14. /* 15. * get test bean by UID. 16. * 17. * param id 18.
70、160; * return 19. */ 20. SelectProvider(type = TestSqlProvider.class, method = "getSql") 21. Options(useCache = true, flush
71、Cache = false, timeout = 10000) 22. Results(value = 23. Result(id = true, property = "id", column =
72、160;"test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR), 24. Result(property = "testText", column = "test_text", j
73、avaType = String.class, jdbcType = JdbcType.VARCHAR) ) 25. public TestBean get(Param("id") String id); 26. 27. /* 28. *
74、0;get all tests. 29. * 30. * return 31. */ 32. SelectProvider(type = TestSqlProvider.class, method = "getAllS
75、ql") 33. Options(useCache = true, flushCache = false, timeout = 10000) 34. Results(value = 35.
76、160;Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR), 36. Result(pr
77、operty = "testText", column = "test_text", javaType = String.class, jdbcType = JdbcType.VARCHAR) ) 37. public List<TestBean> getAll(); 38. 39.
78、60; /* 40. * get tests by test text. 41. * 42. * param testText 43. * return 44.
79、; */ 45. SelectProvider(type = TestSqlProvider.class, method = "getByTestTextSql") 46. Options(useCache = true, flushCache = false, timeout =
80、160;10000) 47. ResultMap(value = "getByTestText") 48. public List<TestBean> getByTestText(Param("testText") String testText); 49. 50.
81、; /* 51. * insert a test bean into database. 52. * 53. * param testBean 54. */ 55.
82、60; InsertProvider(type = TestSqlProvider.class, method = "insertSql") 56. Options(flushCache = true, timeout = 20000) 57. public void insert(Param("t
83、estBean") TestBean testBean); 58. 59. /* 60. * update a test bean with database. 61. * 62. *
84、;param testBean 63. */ 64. UpdateProvider(type = TestSqlProvider.class, method = "updateSql") 65. Options(flushCache = true, timeout =&
85、#160;20000) 66. public void update(Param("testBean") TestBean testBean); 67. 68. /* 69. * delete a test by UID. 70. &
86、#160; * 71. * param id 72. */ 73. DeleteProvider(type = TestSqlProvider.class, method = "deleteSql") 74.
87、; Options(flushCache = true, timeout = 20000) 75. public void delete(Param("id") String id); 76. 下面逐個對里面的注解進行分析: CacheNamespace(size = 512) : 定義在該命名空間內允許使用內置緩存,最大值為512個對象引
88、用,讀寫默認是開啟的,緩存內省刷新時間為默認3600000毫秒,寫策略是拷貝整個對象鏡 像到全新堆(如同CopyOnWriteList)因此線程安全。 SelectProvider(type = TestSqlProvider.class, method = "getSql") : 提供查詢的SQL語句,如果你不用這個注解,你也可以直接使用Select("select * from .")注解,把查詢SQL抽取到一個類里面,方便管理,同時復雜的SQL也容易操作,type = TestSqlProvider.class就是存放SQL語句的類,而m
89、ethod = "getSql"表示get接口方法需要到TestSqlProvider類的getSql方法中獲取SQL語句。 Options(useCache = true, flushCache = false, timeout = 10000) : 一些查詢的選項開關,比如useCache = true表示本次查詢結果被緩存以提高下次查詢速度,flushCache = false表示下次查詢時不刷新緩存,timeout = 10000表示查詢結果緩存10000秒。 Results(value = Result(id = true, pro
90、perty = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR), Result(property = "testText", column = "test_text", javaType = String.class, jdbcType = JdbcType.VARCHAR) ) : 表示sql查詢返回的結果集,Results是以Result為元素的數組,Result表示單條屬性-字段的映射關系
91、,如:Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR)可以簡寫為:Result(id = true, property = "id", column = "test_id"),id = true表示這個test_id字段是個PK,查詢時mybatis會給予必要的優化,應該說數組中所有的Result組成了單個記錄的映射關系,而 Results則單個記錄
92、的集合。另外還有一個非常重要的注解ResultMap也和Results差不多,到時會講到。 Param("id") :全局限定別名,定義查詢參數在sql語句中的位置不再是順序下標0,1,2,3.的形式,而是對應名稱,該名稱就在這里定義。 ResultMap(value = "getByTestText") :重要的注解,可以解決復雜的映射關系,包括resultMap嵌套,鑒別器discriminator等等。注意一旦你啟用該注解,你將不得不在你的映 射文件中配置你的resultMap,而value = "getByTestT
93、ext"即為映射文件中的resultMap ID(注意此處的value = "getByTestText",必須是在映射文件中指定命名空間路徑)。ResultMap在某些簡單場合可以用Results代替,但是復雜查 詢,比如聯合、嵌套查詢ResultMap就會顯得解耦方便更容易管理。 一個映射文件如下所示: Java代碼 1. <?xml version="1.0" encoding="UTF-8" ?> &
94、#160;2. <!DOCTYPE mapper 3. PUBLIC "-//DTD Mapper 3.0/EN" 4. "/dtd/ibatis-3-mapper.dtd"> 5. 6. <mapper namespace="com.wotao.taotao.p
95、ersist.test.mapper.TestMapper"> 7. <resultMap id="getByTestText" type="TestBean"> 8. <id property="id" column="test_id" java
96、Type="string" jdbcType="VARCHAR" /> 9. <result property="testText" column="test_text" javaType="string" jdbcType="VARCHAR" />
97、10. </resultMap> 11. </mapper> 注意文件中的namespace路徑必須是使用resultMap的類路徑,此處是TestMapper,文件中 id="getByTestText"必須和resultMap中的value = "getByTestText"保持一致。 InsertProvider(type = TestSqlProvider.class, method = "insertSql&q
98、uot;) :用法和含義SelectProvider一樣,只不過是用來插入數據庫而用的。 Options(flushCache = true, timeout = 20000) :對于需要更新數據庫的操作,需要重新刷新緩存flushCache = true使緩存同步。 UpdateProvider(type = TestSqlProvider.class, method = "updateSql") :用法和含義SelectProvider一樣,只不過是用來更新數據庫而用的。 Param("testBean") :是一個自定
99、義的對象,指定了sql語句中的表現形式,如果要在sql中引用對象里面的屬性,只要使用testBean.id,testBean.textText即可,mybatis會通過反射找到這些屬性值。 DeleteProvider(type = TestSqlProvider.class, method = "deleteSql") :用法和含義SelectProvider一樣,只不過是用來刪除數據而用的。 現在mybatis注解基本已經講完了,接下來我們就要開始寫SQL語句了,因為我們不再使用映射文件編寫SQL,那么就不得不在java類里面 寫,就像上面提到的,我
100、們不得不在TestSqlProvider這個類里面寫SQL,雖然已經把所有sql語句集中到了一個類里面去管理,但聽起來似乎 仍然有點惡心,幸好mybatis提供SelectBuilder和SqlBuilder這2個小工具來幫助我們生成SQL語 句,SelectBuilder專門用來生成select語句,而SqlBuilder則是一般性的工具,可以生成任何SQL語句,我這里選擇了 SqlBuilder來生成,TestSqlProvider代碼如下: Java代碼 1. /* 2. * # test-afternoon10:
101、51:40 3. */ 4. package com.wotao.taotao.persist.test.sqlprovider; 5. 6. import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN; 7. import static org.apache.ibatis.jdbc.SqlBuilder.FROM; 8. import sta
102、tic org.apache.ibatis.jdbc.SqlBuilder.SELECT; 9. import static org.apache.ibatis.jdbc.SqlBuilder.SQL; 10. import static org.apache.ibatis.jdbc.SqlBuilder.WHERE; 11. import static org.apache.ibatis.jdbc.SqlBuilder.DELETE_FROM; &
103、#160;12. import static org.apache.ibatis.jdbc.SqlBuilder.INSERT_INTO; 13. import static org.apache.ibatis.jdbc.SqlBuilder.SET; 14. import static org.apache.ibatis.jdbc.SqlBuilder.UPDATE; 15. import static org.apache.ibatis.jdbc
104、.SqlBuilder.VALUES; 16. 17. import java.util.Map; 18. 19. /* 20. * The test sql Provider,define the sql script for mapping. 21. * 22. * author HuangMin
105、0;<a href="mailto:minhuang>send email</a> 23. * 24. * since 1.6 25. * version 1.0 26. * 27. * #TestSqlProvider.java 2011-9
106、-23 : afternoon 10:51:40 28. */ 29. public class TestSqlProvider 30. 31. /* table name, here is test */ 32. private static fi
107、nal String TABLE_NAME = "test" 33. 34. /* 35. * get test by id sql script. 36. * 37.
108、60;* param parameters 38. * return 39. */ 40. public String getSql(Map<String, Object> parameters) 41.
109、0; String uid = (String) parameters.get("id"); 42. BEGIN(); 43. SELECT("test_id, test_text"); 44.
110、; FROM(TABLE_NAME); 45. if (uid != null) 46. WHERE("test_id = #id,javaType=string,jdbcType=VA
111、RCHAR"); 47. 48. return SQL(); 49. 50. 51. /* 52. *
112、160;get all tests sql script. 53. * 54. * return 55. */ 56. public String getAllSql() 57. &
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論