MyBatis之引數配置
MyBatis最簡單的例項也已跑通,實現了增刪改查,涉及到複雜情況就是兩眼一抹黑。這篇主要講講引數配置,方便後期專案,我這裡沒有從頭到尾地去講每個引數的使用,而是在實際使用中遇到了問題才會去看,故可能沒法給您提供有效的幫助。
設定引數 | 描述 | 有效值 | 預設值 |
---|---|---|---|
cacheEnabled | 該配置影響的所有對映器中配置的快取的全域性開關。 | true | false | true |
lazyLoadingEnabled | 延遲載入的全域性開關。當開啟時,所有關聯物件都會延遲載入。 特定關聯關係中可通過設定fetchType屬性來覆蓋該項的開關狀態。 | true | false | false |
aggressiveLazyLoading | 當啟用時,對任意延遲屬性的呼叫會使帶有延遲載入屬性的物件完整載入;反之,每種屬性將會按需載入。 | true | false | true |
multipleResultSetsEnabled | 是否允許單一語句返回多結果集(需要相容驅動)。 | true | false | true |
useColumnLabel | 使用列標籤代替列名。不同的驅動在這方面會有不同的表現, 具體可參考相關驅動文件或通過測試這兩種不同的模式來觀察所用驅動的結果。 | true | false | true |
useGeneratedKeys |
允許 JDBC 支援自動生成主鍵(使用jdbc的getGenereatedKeys方法獲取主鍵並賦值到keyProperty設定的屬性中,useGeneratedKeys="true |
true | false | false |
autoMappingBehavior | 指定 MyBatis 應如何自動對映列到欄位或屬性。 NONE 表示取消自動對映;PARTIAL 只會自動對映沒有定義巢狀結果集對映的結果集。 FULL 會自動對映任意複雜的結果集(無論是否巢狀)。 | NONE, PARTIAL, FULL | PARTIAL |
defaultExecutorType | 配置預設的執行器。SIMPLE 就是普通的執行器;REUSE 執行器會重用預處理語句(prepared statements); BATCH 執行器將重用語句並執行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 設定超時時間,它決定驅動等待資料庫響應的秒數。 | Any positive integer | Not Set (null) |
defaultFetchSize | Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a query setting. | Any positive integer | Not Set (null) |
safeRowBoundsEnabled | 允許在巢狀語句中使用分頁(RowBounds)。 | true | false | False |
mapUnderscoreToCamelCase | 是否開啟自動駝峰命名規則(camel case)對映,即從經典資料庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似對映。 | true | false | False |
localCacheScope | MyBatis 利用本地快取機制(Local Cache)防止迴圈引用(circular references)和加速重複巢狀查詢。 預設值為 SESSION,這種情況下會快取一個會話中執行的所有查詢。 若設定值為 STATEMENT,本地會話僅用在語句執行上,對相同 SqlSession 的不同調用將不會共享資料。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 當沒有為引數提供特定的 JDBC 型別時,為空值指定 JDBC 型別。 某些驅動需要指定列的 JDBC 型別,多數情況直接用一般型別即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER | OTHER |
lazyLoadTriggerMethods | 指定哪個物件的方法觸發一次延遲載入。 | A method name list separated by commas | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定動態 SQL 生成的預設語言。 | A type alias or fully qualified class name. | org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver |
callSettersOnNulls | 指定當結果集中值為 null 的時候是否呼叫對映物件的 setter(map 物件時為 put)方法,這對於有 Map.keySet() 依賴或 null 值初始化的時候是有用的。注意基本型別(int、boolean等)是不能設定成 null 的。 | true | false | false |
logPrefix | 指定 MyBatis 增加到日誌名稱的字首。 | Any String | Not set |
logImpl | 指定 MyBatis 所用日誌的具體實現,未指定時將自動查詢。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | Not set |
proxyFactory | 指定 Mybatis 建立具有延遲載入能力的物件所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 or above) |
vfsImpl | Specifies VFS implementations | Fully qualified class names of custom VFS implementation separated by commas. | Not set |
1.主鍵自增長:
見過多數教程都說自增長要加useGeneratedKeys="true"和keyProperty="主鍵欄位",然而MySQL在對錶設定了auto_increment之後即可實現自增長,那麼為何要用useGeneratedKeys="true"和keyProperty屬性呢?
int pk = sqlSession.insert("UserMapper.insertUser",user1);
System.out.println("輸出:"+pk);
不管是否設定useGenerateKeys="true"都返回1,這個1為操作的記錄條數;
要返回主鍵用操作的物件get該主鍵,例如:System.out.println("我才是主鍵:"+ user1.getId());
useGenerateKeys="false"則user1.getId()返回0;
- <insert id="insertUser" parameterType="sysUser" useGeneratedKeys="true" keyProperty="id">
- insert into `user`(userName, birthday, salary, address)
- values(#{userName}, #{birthday}, #{salary}, #{address})
- </insert>
- <insert id="insert" parameterType="map">
- insert into table1 (name) values (#{name})
- <selectKey resultType="java.lang.Integer" keyProperty="id">
- CALL IDENTITY()
- </selectKey>
- </insert>
2.實體類屬性和表字段不一致:
表結構:
- CREATETABLE `user` (
- `id` INT(11) PRIMARYKEY AUTO_INCREMENT,
- `user_name` VARCHAR(50),
- `birthday` DATE,
- `salary` DECIMAL(8,2),
- `address` VARCHAR(200)
- ) ENGINE=INNODB CHARSET=utf8;
實體類屬性:
- publicclass Users {
- privateint id;
- private String userName;
- private Date birthday;
- private Double salary;
- private String address;
- ...
- }
類的配置檔案修改
- <insert id="insertUser" parameterType="sysUser" useGeneratedKeys="true" keyProperty="id">
- insert into `user`(user_name, birthday, salary, address)
- values(#{userName}, #{birthday}, #{salary}, #{address})
- </insert>
發現直接這樣對應就可以解決類屬性和表字段不一致的問題,那麼什麼時候才需要在類的配置檔案中設定resultMap呢?
答:insert sql語句中values與表字段一一對應所以不存在相關問題,其它方式sql語句沒有對應的情況則
查詢中出現的問題:
- <select id="findUserById" parameterType="int" resultType="sysUser">
- select * from `user` where id = #{id}
- </select>
返回記錄的user.getUserName() == null(沒報錯,由於實體類屬性和資料表字段無法對應出現的問題)
第一種方法:對sql語句的表字段取別名,欄位別名與實體類屬性一致即可(如果我要查詢全表字段,欄位一致的也要列出來,會比較煩);
- <select id="findUserById" parameterType="int" resultType="sysUser">
- select user_name userName, address from `user` where id = #{id}
- </select>
第二種方式:在類配置檔案mapper內設定resultMap;
- <!--通過<resultMap>對映實體類屬性名和表的欄位名對應關係 -->
- <resultMap type="com.chensan.sys.Users" id="sysUser">
- <!-- 用id屬性來對映主鍵欄位 -->
- <id property="id" column="id"/>
- <!-- 用result屬性來對映非主鍵欄位 -->
- <result property="userName" column="user_name"/>
- </resultMap>
然後第二種方式測出的結果user.getUserName() == null,搞了半天發現resultType需要改成resultMap,真的是要抽自己;
- <select id="findUserById" parameterType="int" resultMap="sysUser">
- select * from `user` where id = #{id}
- </select>