# 與 $ 的區(qū)別
#
是把傳遞的變量轉(zhuǎn)換成字符串, 自動(dòng)加上引號(hào),比如 name=#{id}
, 替換之后就是name="admin"
,
$
不會(huì)把變量加引號(hào),直接使用,name=#{id}
替換之后就是
name=admin
,這肯定不對(duì), 但是當(dāng)使用order by語(yǔ)句時(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映射的幾種方式
- 通過(guò)注解映射
@Select("select * from user where id=#{id}")
User selectUser(int id);
- 通過(guò)xml文件映射.
需要在xml定義的namespace中寫對(duì)用接口類的包名+類名
每個(gè)sql語(yǔ)句的id和接口類方法相同.
SqlSessionFactoryBuilder
這個(gè)類可以被實(shí)例化、使用和丟棄,一旦創(chuàng)建了 SqlSessionFactory,就不再需要它了。因此 SqlSessionFact
oryBuilder 實(shí)例的最佳范圍是方法范圍(也就是局部方法變量)。你可以重用 SqlSessionFactoryBuilder 來(lái)創(chuàng)
建多個(gè) SqlSessionFactory 實(shí)例,但是最好還是不要讓其一直存在以保證所有的 XML 解析資源開(kāi)放給更重要的
事情。
SqlSessionFactory
SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在,沒(méi)有任何理由對(duì)它進(jìn)行清除或重建。使用 S
qlSessionFactory 的最佳實(shí)踐是在應(yīng)用運(yùn)行期間不要重復(fù)創(chuàng)建多次,多次重建 SqlSessionFactory 被視為一種
代碼"壞味道(bad smell)"。因此 SqlSessionFactory 的最佳范圍是應(yīng)用范圍。有很多方法可以做到,最簡(jiǎn)單
的就是使用單例模式或者靜態(tài)單例模式
每個(gè)數(shù)據(jù)庫(kù)對(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ì)象相似的范圍
中。換句話說(shuō),每次收到的 HTTP 請(qǐng)求,就可以打開(kāi)一個(gè) SqlSession,返回一個(gè)響應(yīng),就關(guān)閉它。這個(gè)關(guān)閉操
作是很重要的,你應(yīng)該把這個(gè)關(guān)閉操作放到 finally 塊中以確保每次都能執(zhí)行關(guān)閉。
映射器實(shí)例(Mapper Instances)
映射器是創(chuàng)建用來(lái)綁定映射語(yǔ)句的接口。映射器接口的實(shí)例是從 SqlSession 中獲得的。因此從技術(shù)層面講,映
射器實(shí)例的最大范圍是和 SqlSession 相同的,因?yàn)樗鼈兌际菑?SqlSession 里被請(qǐng)求的。盡管如此,映射器實(shí)
例的最佳范圍是方法范圍。也就是說(shuō),映射器實(shí)例應(yīng)該在調(diào)用它們的方法中被請(qǐng)求,用過(guò)之后即可廢棄。并不需
要顯式地關(guān)閉映射器實(shí)例,盡管在整個(gè)請(qǐng)求范圍(request scope)保持映射器實(shí)例也不會(huì)有什么問(wèn)題,但是很
快你會(huì)發(fā)現(xiàn),像 SqlSession 一樣,在這個(gè)范圍上管理太多的資源的話會(huì)難于控制。所以要保持簡(jiǎn)單,最好把映
射器放在方法范圍(method scope)內(nèi)。
settings
<settings>
<!-- 該配置影響的所有映射器中配置的緩存的全局開(kāi)關(guān)。-->
<setting name="cacheEnabled" value="true"/>
<!-- 延遲加載的全局開(kāi)關(guān)。當(dāng)開(kāi)啟時(shí),所有關(guān)聯(lián)對(duì)象都會(huì)延遲加
載。 特定關(guān)聯(lián)關(guān)系中可通過(guò)設(shè)置 fetchType 屬性來(lái)覆蓋該
項(xiàng)的開(kāi)關(guān)狀態(tài)。-->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 是否允許單一語(yǔ)句返回多結(jié)果集(需要兼容驅(qū)動(dòng))。 -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 使用列標(biāo)簽代替列名。不同的驅(qū)動(dòng)在這方面會(huì)有不同的表現(xiàn),
具體可參考相關(guān)驅(qū)動(dòng)文檔或通過(guò)測(cè)試這兩種不同的模式來(lái)觀察
所用驅(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)映射沒(méi)有定義嵌套結(jié)果集
映射的結(jié)果集。 FULL 會(huì)自動(dòng)映射任意復(fù)雜的結(jié)果集(無(wú)論是
否嵌套)-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!-- 配置默認(rèn)的執(zhí)行器。SIMPLE 就是普通的執(zhí)行器;REUSE
執(zhí)行器會(huì)重用預(yù)處理語(yǔ)句(prepared statements); BAT
CH 執(zhí)行器將重用語(yǔ)句并執(zhí)行批量更新。-->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!-- 設(shè)置超時(shí)時(shí)間,它決定驅(qū)動(dòng)等待數(shù)據(jù)庫(kù)響應(yīng)的秒數(shù)。-->
<setting name="defaultStatementTimeout" value="25"/>
<!-- 允許在嵌套語(yǔ)句中使用分頁(yè)(RowBounds)。 -->
<setting name="safeRowBoundsEnabled" value="false"/>
<!-- 是否開(kāi)啟自動(dòng)駝峰命名規(guī)則(camel case)映射,即從經(jīng)典
數(shù)據(jù)庫(kù)列名 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ì)話僅用在語(yǔ)句執(zhí)行上,對(duì)
相同 SqlSession 的不同調(diào)用將不會(huì)共享數(shù)據(jù)。-->
<setting name="localCacheScope" value="SESSION"/>
<!-- 當(dāng)沒(méi)有為參數(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),存在的意義僅在于用來(lái)減少類完全限定名
的冗余。例如:
<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 – 最近最少使用的:移除最長(zhǎng)時(shí)間不被使用的對(duì)象。
- FIFO – 先進(jìn)先出:按對(duì)象進(jìn)入緩存的順序來(lái)移除它們。
- 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"開(kāi)頭的,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