Mybayis的项目使用的Mapping文件使用总结参考(一)
作者:longgangbai
以前用過ibatis2,但是聽說ibatis3有較大的性能提升,而且設計也更合理,他不兼容ibatis2.盡管ibatis3還是beta10的狀態(tài),但還是打算直接使用ibatis3.0,?
ibatis3.0應該更簡單高效.最近還自己寫了個ibatis3.0與spring集成的bean,運行還正常,還自鳴得意了一番,但是當獨立使用ibatis時,在事務管理這個方面還是出現(xiàn)不少問題,所以還是打算再認真研究一番ibatis3.0
1.SqlSessionFactory?
每個ibatis應用都應該只有一個SqlSessionFactory的實例對象,所以一般設置為static屬性或者使用spring管理時返回singleton類型,與spring集成時其實也是寫一個怎樣構建SqlSessionFactory的Bean,?
構建SqlSessionFactory一般是SqlSessionFactoryBuild通過讀取ibatis的配置文件而進行build的:?
Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");?
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuild().build(reader);
配置文件SqlMapConfig.xml的一般結構(元素順序不能變)?
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> <configuration> <properties resource="jdbc.properties" /> <settings> <setting name="cacheEnabled" value="false" /> <setting name="lazyLoadingEnabled" value="true" /> <setting name="multipleResultSetsEnabled" value="false" /> <setting name="useColumnLabel" value="true" /> <setting name="defaultExecutorType" value="SIMPLE" /> </settings> <typeAliases> <typeAlias alias="Person" type="test.Person"/> </typeAliases> <environments default="dev"> <environment id="dev"> <transactionManager type="jdbc"> <property name="" value="" /> </transactionManager> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${user}" /> <property name="password" value="${password}" /> </dataSource> </environment> </environments> <mappers> <mapper resource="sqlMappers/Person.xml" /> <mapper resource="sqlMappers/UserShop.xml" /> </mappers> </configuration><settings />是配置ibatis的具體行為屬性的,?
<typeAliases />是為了將較長的module類名簡化,在<mappers />里可以使用?
<environment />是配置transaction manager和connection pooling的?
<mappers />是sql語句的構造地方,一般每個module對應一個文件
2.SqlSession?
可以從SqlSessionFactory得到SqlSession: sessionFactory.openSession();?
SqlSession是一切Sql相關數(shù)據(jù)庫操作的中心,insert,select,update,delete...?
SqlSession不是線程安全的(也就是有狀態(tài)的),所以它的作用域最好是在一個Thread下,每個Thread有自己的SqlSession對象實例,彼此不相關.?
Never keep references to a SqlSession instance in a static field or even an instance field of a class.? Never keep references to a?
SqlSession in any sort of managed scope, such as HttpSession of of the Servlet framework.
默認sessionFacory.openSession()拿到的SqlSession不是自動commit的,所以如果是更新操作必須自己執(zhí)行session.commit()?
關閉SqlSession很重要,必須保證在線程結束時關閉這個SqlSession,可以在finally中?
session.close();?
那跟Spring集成是怎樣做到這一點的呢,因為dataSource是由spring管理的,所以他可以保證在一個Thread的每個方法中拿到的Connection是同一個對象,?
雖然每個方法從sessionFactory.openSession()拿到的SqlSession對象是不同的,但是sqlSession對象中的connection是相同的,所以spring就可以在service層的方法結束之前將這個connection commit跟close,這樣就實現(xiàn)了事務控制.?
我們往往在dao層是一個方法對應一個sql語句的,不在這里控制事務,控制事務應該在service層, dao的每個方法拿到的sqlsession對象都是不相同的(盡管它的connection可能相同).?
那我們應該怎樣在沒有spring的情況下實現(xiàn)ibatis的事務控制呢?還要保持dao的結構,以保持能跟spring隨時切換??
看來ThreadLocal要派上用場了?
---占位----
3.講完了SqlSession這個大頭,再來說說具體的配置信息?
配置文件結構?
configuration?
??? properties?
??? settings?
??? typeAliases?
??? typeHandlers?
??? objectFactory?
??? plugins?
??? environments?
?????? environment?
?????????? transactionManager?
?????????? dataSource?
??? mappers?
???????
4.ibatis可以配置多個environment環(huán)境?
供開發(fā),測試,上線等切換?
但是一個SqlSessionFactory只能對應一個environment,?
也就是 one SqlSessionFactory per database
5.transactionManager?
There are two TransactionManager types (i.e. type=”?????”) that are included with iBATIS:?
??? JDBC – This configuration simply makes use of the JDBC commit and rollback facilities directly.? It relies on the connection retrieved from the dataSource to manage the scope of the transaction.???
??? MANAGED? – This configuration simply does nothing, quite literally.? It never commits, rolls back or closes a connection.? Instead, it lets the container manage the full lifecycle of the transaction (e.g. Spring or a JEE Application Server context).
6.dataSource的配置?
類型可使用UNPOOLED,POOLED,JNDI三種
7.接下來是重頭戲mappers?
這里是我們直接寫sql的地方,ibatis在這里也花了最多功夫,特別是關于select的mapper.
select 元素的所有的如下:
<selectid=""parameterType=""resultType=""resultMap=""flushCache=""useCache=""timeout=""fetchSize=""statementType=""resultSetType="">?? 在Ibatis3中parameterMap已經(jīng)不再使用。
(1).select?
<select id="getUser" parameterType="int" resultType="test.User">?
?????? select * from user where userId = #{value}?
</select>?
注意#{value},resultType可以換成resultMap,這個resultMap就比較復雜了,也是最強大的工具,可以完成復雜的mapper(resultSet->object)
(2).insert,update,delete?
這幾個操作都比較類似,返回的一般是受影響的行數(shù).?
insert 可以返回auto_increament的值?
這樣,傳入的Person類對象的userId就會被set成auto_increament那個值.
(3).可以使用<sql id="columns">name,age</sql>構造可重用的sql片段?
這樣就可以在那四個主要的元素里用<include refid="columns">引用這個常用sql片段
(4).resultMap很復雜,它可以處理一對一,一對多,多對多關系?
比如一個blog對應一個author, 一個blog對應多個post, 一個post對應多個comment?
resultMap的結構:?
resultMap?
??? constructor (向java構造函數(shù)設置值)?
?????? idArg?
?????? arg?
??? id (id result,同result)?
??? result (字段映射注入)?
??? association (一對一關系,它里面有自己的result映射)?
??? collection? (一對多關系, 它里面有自己的result映射,和可能的collection)?
??? discriminator
(5).association (一個Blog對應一個Author)?
<resultMap id="blogResult" type="Blog"> <association property="author" column="blog_author_id" javaType="Author"> <id property="id" column="author_id" /> <result property="username" column="author_username" /> </associaton> </resultMap>當然association也可以使用?
<association property="author" column="blog_author_id" javaType="Author" resultMap="authorResult"/>
在Blog類定義里會有一個Author類字段,會自動裝載數(shù)據(jù)?
private Author author;
(6).collection (一個Blog對應多個Post)?
<resultMap id="blogResult" type="Blog"> <collection property="posts" column="blog_id" ofType="Post" javaType="ArrayList" resultMap="postResult" /> </resultMap> collection也可以精簡為 <collection property="posts" ofType="Post" resultMap="postResult" /> 相就地,在Blog類定義里會有: private List<Post> posts8.cache?
其實我是不打算在ibatis這層做cache的,一般cache還是在service層做.?
ibatis對于select才會進行cache,而我覺得這個時候cache沒多大意義,因為多次請求相同的select語句(sql相同)而又沒有進行表的相關update的情況并不多.?
但還是看看ibatis是怎樣處理cache的?
要開啟cache,需要在mapper文件中加上一句: <cache />?
(1).cache所有select的結果?
(2).在同一mapper文件中的insert,update,delete會flush cache?
(3).cache使用least recently used(LRU)算法?
(4).cache沒有定時flush的功能?
(5).cache保存1024個對象或list引用?
(6).cache是read/write cache, 從cache拿出對象不是共享的,caller可以任意修改而不用擔心其他caller也拿到相同的對象(相同的reference)
9.動態(tài)SQL?
以前用jdbc時經(jīng)常要根據(jù)輸入條件而組裝成不同的sql,這種就是動態(tài)sql?
ibatis的動態(tài)sql關鍵詞:?
(2).choose(when,otherwise)只選擇其中一種情況?
<select ...> <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND title like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>(3).trim, where, set?
<select id="findBlog" paramaterType="Blog" resultType="Blog"> select * from blog <where> <if test=”state != null”> state = ${state} </if> <if test=”title != null”> AND title like ${title} </if> <if test=”author != null and author.name != null”> AND title like ${author.name} </if> </where> </select> <update id="updateAuthorIfNecessary" parameterType="domain.blog.Author"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update>?
(4).foreach?
<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>10.ibatis的annotation?
ibatis3.0也增加了annotation,當然主要還是用在mapper這個問題上?
個人感覺是雞肋,暫時不會使用.
轉載于:https://www.cnblogs.com/lxl57610/p/7399184.html
總結
以上是生活随笔為你收集整理的Mybayis的项目使用的Mapping文件使用总结参考(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj1986 Distance Que
- 下一篇: Loadrunner进行HTTPS协议性