1、Mybatis中#和$的區(qū)別?
● #相當(dāng)于對數(shù)據(jù)加上雙引號,$相當(dāng)于直接顯示數(shù)據(jù)
● #將傳入的數(shù)據(jù)都當(dāng)成一個字符串,會對自動傳入的數(shù)據(jù)加一個雙引號。如:order by#user_id#,如果傳入的值是111,那么解析成sql時的值為order by"111",如果傳入的值是id,則解析成的sql為order by "id".
● $將傳入的數(shù)據(jù)直接顯示生成在sql中。如:order by$user_id$,如果傳入的值是111,那么解析成sql時的值為order by user_id,如果傳入的值是id,則解析成的sql為order by id.
● #方式能夠很大程度防止sql注入,$方式無法防止Sql注入。
● $方式一般用于傳入數(shù)據(jù)庫對象,例如傳入表名.
● 創(chuàng)建SqlSessionFactory
● 通過SqlSessionFactory創(chuàng)建SqlSession
● 通過sqlsession執(zhí)行數(shù)據(jù)庫操作
● 調(diào)用session.commit()提交事務(wù)
● 調(diào)用session.close()關(guān)閉會話
● 數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費從而影響系統(tǒng)性能,使用數(shù)據(jù)庫鏈接池可解決此問題。解決:在SqlMapConfig.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫鏈接。
● Sql語句寫在代碼中造成代碼不易維護(hù),實際應(yīng)用sql變化的可能較大,sql變動需要改變java代碼。解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
● 向sql語句傳參數(shù)麻煩,因為sql語句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對應(yīng)。解決: Mybatis 自動將 java 對象映射至 sql 語句。
● 對結(jié)果集解析麻煩,sql 變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫記錄封裝成 pojo 對象解析比較方便。解決:Mybatis 自動將 sql 執(zhí)行結(jié)果映射至 java 對象。
● Mapper接口方法名和mapper.xml中定義的每個sql的id相同
● Mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的每個sql的parameterType的類型相同
● Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的每個sql的resultType的類型相同
● Mapper.xml文件中的namespace即是mapper接口的類路徑。
● 一級緩存:基于PerpetualCache的HashMap本地緩存,其存儲作用域為Session,當(dāng)flush或close之后,該Session中的所有Cache就將清空。
● 二級緩存與一級緩存其機制相同,默認(rèn)也是采用PerpetualCache的HashMap存儲,不同在于其存儲作用域為Mapper(namespace),并且可自定義存儲源,如Ehcache。作用域namespace是指對namespace所對應(yīng)的配置文件中所有的select操作結(jié)果都緩存,這樣不同線程之間就可以共用二級緩存。二級緩存可以設(shè)置返回的緩存對象策略:<cache readOnly="true">。當(dāng)readOnly="true"時,表示二級緩存返回給所有調(diào)用者同一個緩存對象實例,調(diào)用者可以update獲取的緩存實例,但是這樣可能會造成其他調(diào)用者出現(xiàn)數(shù)據(jù)不一致的情況(因為所有調(diào)用者調(diào)用的是同一個實例)。當(dāng)readOnly=“false”時,返回給調(diào)用者的是二級緩存總緩存對象的拷貝,即不同調(diào)用者獲取的是緩存對象不同的實例,這樣調(diào)用者對各自的緩存對象的修改不會影響到其他的調(diào)用者,即是安全的,所以默認(rèn)是readOnly="false";
● 對于緩存數(shù)據(jù)更新機制,當(dāng)某一個作用域(一級緩存Session/二級緩存Namespaces)進(jìn)行了C/U/D操作后,默認(rèn)該作用域下所有select中的緩存將被clear。
數(shù)據(jù)庫為 MySql 時:
<insert id="insert" parameterType="com.test.User" keyProperty="userId" useGeneratedKeys="true">
“keyProperty”表示返回的id要保存到對象的屬性中,“useGeneratedKeys”表示主鍵id為自增長模式。
數(shù)據(jù)庫為Oracle時:
<insert id="insert" parameterType="com.test.User">
<selectKey resultType="INTEGER" order="BEFORE" keyProperty="userId">
SELECT SEQ_USER.NEXTVAL as userId from DUAL
</selectKey>
insert into user
(user_id, user_name, modified, state)
values
(#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR}, #{modified,jdbcType=TIMESTAMP},#{state,jdbcType=INTEGER})
</insert>
由于Oracle沒有自增長這一說法,只有序列這種自增的形式,所以不能再使用“useGeneratedKeys”屬性。而是使用<selectKey>將ID獲取并賦值到對象的屬性中,insert插入操作時正常插入id。