# 與 $ 的區(qū)別
#
是把傳遞的變量轉(zhuǎn)換成字符串, 自動(dòng)加上引號(hào),比如 name=#{id}
, 替換之后就是name="admin"
,
$
不會(huì)把變量加引號(hào),直接使用,name=#{id}
替換之后就是
name=admin
,這肯定不對(duì), 但是當(dāng)使用order by語句時(shí),
就必須得用$
符號(hào)了, 比如order by score
.
mybati常用JDBCTYPE映射關(guān)系
JDBC Type Java Type
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
BOOLEAN boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
DISTINCT mapping of underlying type
STRUCT Struct
REF Ref
DATALINK java.net.URL[color=red][/color]
mapper映射的幾種方式
- 通過注解映射
@Select("select * from user where id=#{id}")
User selectUser(int id);
- 通過xml文件映射.
需要在xml定義的namespace中寫對(duì)用接口類的包名+類名
每個(gè)sql語句的id和接口類方法相同.
SqlSessionFactoryBuilder
這個(gè)類可以被實(shí)例化柄粹、使用和丟棄癞埠,一旦創(chuàng)建了 SqlSessionFactory牍疏,就不再需要它了。因此 SqlSessionFact
oryBuilder 實(shí)例的最佳范圍是方法范圍(也就是局部方法變量)雇卷。你可以重用 SqlSessionFactoryBuilder 來創(chuàng)
建多個(gè) SqlSessionFactory 實(shí)例,但是最好還是不要讓其一直存在以保證所有的 XML 解析資源開放給更重要的
事情。
SqlSessionFactory
SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在关划,沒有任何理由對(duì)它進(jìn)行清除或重建小染。使用 S
qlSessionFactory 的最佳實(shí)踐是在應(yīng)用運(yùn)行期間不要重復(fù)創(chuàng)建多次,多次重建 SqlSessionFactory 被視為一種
代碼"壞味道(bad smell)"祭玉。因此 SqlSessionFactory 的最佳范圍是應(yīng)用范圍氧映。有很多方法可以做到,最簡單
的就是使用單例模式或者靜態(tài)單例模式
每個(gè)數(shù)據(jù)庫對(duì)應(yīng)一個(gè) SqlSessionFactory 實(shí)例
SqlSession
每個(gè)線程都應(yīng)該有它自己的 SqlSession 實(shí)例脱货。SqlSession 的實(shí)例不是線程安全的岛都,因此是不能被共享的,所
以它的最佳的范圍是請(qǐng)求或方法范圍振峻。絕對(duì)不能將 SqlSession 實(shí)例的引用放在一個(gè)類的靜態(tài)域臼疫,甚至一個(gè)類的
實(shí)例變量也不行。也絕不能將 SqlSession 實(shí)例的引用放在任何類型的管理范圍中扣孟,比如 Serlvet 架構(gòu)中的 Http
Session烫堤。如果你現(xiàn)在正在使用一種 Web 框架,要考慮 SqlSession 放在一個(gè)和 HTTP 請(qǐng)求對(duì)象相似的范圍
中凤价。換句話說鸽斟,每次收到的 HTTP 請(qǐng)求,就可以打開一個(gè) SqlSession利诺,返回一個(gè)響應(yīng)富蓄,就關(guān)閉它。這個(gè)關(guān)閉操
作是很重要的慢逾,你應(yīng)該把這個(gè)關(guān)閉操作放到 finally 塊中以確保每次都能執(zhí)行關(guān)閉立倍。
映射器實(shí)例(Mapper Instances)
映射器是創(chuàng)建用來綁定映射語句的接口。映射器接口的實(shí)例是從 SqlSession 中獲得的侣滩。因此從技術(shù)層面講口注,映
射器實(shí)例的最大范圍是和 SqlSession 相同的,因?yàn)樗鼈兌际菑?SqlSession 里被請(qǐng)求的君珠。盡管如此寝志,映射器實(shí)
例的最佳范圍是方法范圍。也就是說葛躏,映射器實(shí)例應(yīng)該在調(diào)用它們的方法中被請(qǐng)求澈段,用過之后即可廢棄。并不需
要顯式地關(guān)閉映射器實(shí)例舰攒,盡管在整個(gè)請(qǐng)求范圍(request scope)保持映射器實(shí)例也不會(huì)有什么問題败富,但是很
快你會(huì)發(fā)現(xiàn),像 SqlSession 一樣摩窃,在這個(gè)范圍上管理太多的資源的話會(huì)難于控制兽叮。所以要保持簡單芬骄,最好把映
射器放在方法范圍(method scope)內(nèi)。
settings
<settings>
<!-- 該配置影響的所有映射器中配置的緩存的全局開關(guān)鹦聪。-->
<setting name="cacheEnabled" value="true"/>
<!-- 延遲加載的全局開關(guān)账阻。當(dāng)開啟時(shí),所有關(guān)聯(lián)對(duì)象都會(huì)延遲加
載泽本。 特定關(guān)聯(lián)關(guān)系中可通過設(shè)置 fetchType 屬性來覆蓋該
項(xiàng)的開關(guān)狀態(tài)淘太。-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 是否允許單一語句返回多結(jié)果集(需要兼容驅(qū)動(dòng))。 -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列標(biāo)簽代替列名规丽。不同的驅(qū)動(dòng)在這方面會(huì)有不同的表現(xiàn)蒲牧,
具體可參考相關(guān)驅(qū)動(dòng)文檔或通過測(cè)試這兩種不同的模式來觀察
所用驅(qū)動(dòng)的結(jié)果。-->
<setting name="useColumnLabel" value="true"/>
<!-- 允許 JDBC 支持自動(dòng)生成主鍵赌莺,需要驅(qū)動(dòng)兼容冰抢。 如果設(shè)置為 t
rue 則這個(gè)設(shè)置強(qiáng)制使用自動(dòng)生成主鍵,盡管一些驅(qū)動(dòng)不能兼
容但仍可正常工作(比如 Derby)-->
<setting name="useGeneratedKeys" value="false"/>
<!-- 指定 MyBatis 應(yīng)如何自動(dòng)映射列到字段或?qū)傩浴?NONE 表示
取消自動(dòng)映射艘狭;PARTIAL 只會(huì)自動(dòng)映射沒有定義嵌套結(jié)果集
映射的結(jié)果集挎扰。 FULL 會(huì)自動(dòng)映射任意復(fù)雜的結(jié)果集(無論是
否嵌套)-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 配置默認(rèn)的執(zhí)行器。SIMPLE 就是普通的執(zhí)行器巢音;REUSE
執(zhí)行器會(huì)重用預(yù)處理語句(prepared statements)遵倦; BAT
CH 執(zhí)行器將重用語句并執(zhí)行批量更新。-->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 設(shè)置超時(shí)時(shí)間官撼,它決定驅(qū)動(dòng)等待數(shù)據(jù)庫響應(yīng)的秒數(shù)骇吭。-->
<setting name="defaultStatementTimeout" value="25"/>
<!-- 允許在嵌套語句中使用分頁(RowBounds)。 -->
<setting name="safeRowBoundsEnabled" value="false"/>
<!-- 是否開啟自動(dòng)駝峰命名規(guī)則(camel case)映射歧寺,即從經(jīng)典
數(shù)據(jù)庫列名 A_COLUMN 到經(jīng)典 Java 屬性名 aColumn 的
類似映射。-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!-- MyBatis 利用本地緩存機(jī)制(Local Cache)防止循環(huán)引
用(circular references)和加速重復(fù)嵌套查詢棘脐。 默認(rèn)值為
SESSION斜筐,這種情況下會(huì)緩存一個(gè)會(huì)話中執(zhí)行的所有查詢。
若設(shè)置值為 STATEMENT蛀缝,本地會(huì)話僅用在語句執(zhí)行上顷链,對(duì)
相同 SqlSession 的不同調(diào)用將不會(huì)共享數(shù)據(jù)。-->
<setting name="localCacheScope" value="SESSION"/>
<!-- 當(dāng)沒有為參數(shù)提供特定的 JDBC 類型時(shí)屈梁,為空值指定 JDBC
類型嗤练。 某些驅(qū)動(dòng)需要指定列的 JDBC 類型,多數(shù)情況直接用
一般類型即可在讶,比如 NULL煞抬、VARCHAR 或 OTHER。-->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!--指定哪個(gè)對(duì)象的方法觸發(fā)一次延遲加載构哺。-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
<!-- 指定當(dāng)結(jié)果集中值為 null 的時(shí)候是否調(diào)用映射對(duì)象的 sette
r(map 對(duì)象時(shí)為 put)方法革答,這對(duì)于有 Map.keySet() 依賴
或 null 值初始化的時(shí)候是有用的战坤。注意基本類型(int、boole
an等)是不能設(shè)置成 null 的残拐。-->
<setting name="callSettersOnNulls" value="false"/>
</settings>
typeAliases
類型別名是為 Java 類型設(shè)置一個(gè)短的名字途茫。它只和 XML 配置有關(guān),存在的意義僅在于用來減少類完全限定名
的冗余溪食。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
mapper文件cache
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
回收策略有
- LRU – 最近最少使用的:移除最長時(shí)間不被使用的對(duì)象囊卜。
- FIFO – 先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來移除它們。
- SOFT – 軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象错沃。
- WEAK – 弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象栅组。
- 還可使用自定義緩存對(duì)象
動(dòng)態(tài)SQL
- if
SELECT * FROM BLOG WHERE 1=1 and state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
- choose, when, otherwise
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE 1=1 and state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
類似多個(gè)if, else
- where
where 元素知道只有在一個(gè)以上的if條件有值的情況下才去插入"WHERE"子句。而且捎废,若最后的內(nèi)容是"AN
D"或"OR"開頭的笑窜,where 元素也知道如何將他們?nèi)コ?/li>
<select id="findActiveBlogLike"
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 author_name like #{author.name}
</if>
</where>
</select>
- trim
- set