在上一章中我們學習了《MyBatis學習總結(一)——ORM概要與MyBatis快速起步》,這一章主要是介紹MyBatis核心配置文件、使用介面+XML實現完整數據訪問、輸入參數映射與輸出結果映射等內容。 一、MyBatis配置文件概要 MyBatis核心配置文件在初始化時會被引用,在配置文件中定義 ...
在上一章中我們學習了《MyBatis學習總結(一)——ORM概要與MyBatis快速起步》,這一章主要是介紹MyBatis核心配置文件、使用介面+XML實現完整數據訪問、輸入參數映射與輸出結果映射等內容。
一、MyBatis配置文件概要
MyBatis核心配置文件在初始化時會被引用,在配置文件中定義了一些參數,當然可以完全不需要配置文件,全部通過編碼實現,該配置文件主要是是起到解偶的作用。如第一講中我們用到conf.xml文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/nfmall?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="uchr@123"/> </dataSource> </environment> </environments> <mappers> <!--<mapper resource="mapper/studentMapper.xml"/>--> <mapper class="com.zhangguo.mybatis02.dao.StudentMapper"></mapper> </mappers> </configuration>
MyBatis 的配置文件包含了會深深影響 MyBatis 行為的設置(settings)和屬性(properties)信息。文檔的頂層結構如下::
- configuration 配置
- properties 屬性
- settings 設置
- typeAliases 類型別名
- typeHandlers 類型處理器
- objectFactory 對象工廠
- plugins 插件
- environments 環境
- environment 環境變數
- transactionManager 事務管理器
- dataSource 數據源
- environment 環境變數
- databaseIdProvider 資料庫廠商標識
- mappers 映射器
二、MyBatis配置文件詳解
2.1、properties屬性
作用:將數據連接單獨配置在db.properties中,只需要在myBatisConfig.xml中載入db.properties的屬性值,在myBatisConfig.xml中就不需要對資料庫連接參數進行硬編碼。資料庫連接參數只配置在db.properties中,方便對參數進行統一管理,其它xml可以引用該db.properties。
db.properties的內容:
##MySQL連接字元串 #驅動 mysql.driver=com.mysql.jdbc.Driver #地址 mysql.url=jdbc:mysql://127.0.0.1:3306/nfmall?useUnicode=true&characterEncoding=UTF-8 #用戶名 mysql.username=root #密碼 mysql.password=uchr@123
在myBatisConfig.xml中載入db.properties
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--導入db.properties文件中的所有key-value數據--> <properties resource="db.properties"> <!--定義一個名稱為driver,值為com.mysql.jdbc.Driver的屬性--> <property name="driver" value="com.mysql.jdbc.Driver"></property> </properties> <!--環境配置,default為預設選擇的環境--> <environments default="work"> <!--開發--> <environment id="development"> <!--事務管理--> <transactionManager type="JDBC"/> <!--連接池--> <dataSource type="POOLED"> <!--引用屬性${mysql.driver}--> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </dataSource> </environment> <!--運行--> <environment id="work"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/nfmall?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="uchr@123"/> </dataSource> </environment> </environments> <mappers> <!--<mapper resource="mapper/studentMapper.xml"/>--> <mapper class="com.zhangguo.mybatis02.dao.StudentMapper"></mapper> </mappers> </configuration>
properties特性:
註意:
- 在properties元素體內定義的屬性優先讀取。
- 然後讀取properties元素中resource或url載入的屬性,它會覆蓋已讀取的同名屬性。
- 最後讀取parameterType傳遞的屬性,它會覆蓋已讀取的同名屬性
建議:
不要在properties元素體內添加任何屬性值,只將屬性值定義在properties文件中。
在properties文件中定義屬性名要有一定的特殊性,如xxxx.xxxx(jdbc.driver)
2.2、settings全局參數配置
mybatis框架運行時可以調整一些運行參數。比如,開啟二級緩存,開啟延遲載入等等。全局參數會影響mybatis的運行行為。
mybatis-settings的配置屬性以及描述
setting(設置) | Description(描述) | valid Values(驗證值組) | Default(預設值) |
cacheEnabled | 在全局範圍內啟用或禁用緩存配置 任何映射器在此配置下。 | true | false | TRUE |
lazyLoadingEnabled | 在全局範圍內啟用或禁用延遲載入。禁用時,所有相關聯的將熱載入。 | true | false | TRUE |
aggressiveLazyLoading | 啟用時,有延遲載入屬性的對象將被完全載入後調用懶惰的任何屬性。否則,每一個屬性是按需載入。 | true | false | TRUE |
multipleResultSetsEnabled | 允許或不允許從一個單獨的語句(需要相容的驅動程式)要返回多個結果集。 | true | false | TRUE |
useColumnLabel | 使用列標簽,而不是列名。在這方面,不同的驅動有不同的行為。參考驅動文檔或測試兩種方法來決定你的驅動程式的行為如何。 | true | false | TRUE |
useGeneratedKeys | 允許JDBC支持生成的密鑰。相容的驅動程式是必需的。此設置強制生成的鍵被使用,如果設置為true,一些驅動會不相容性,但仍然可以工作。 | true | false | FALSE |
autoMappingBehavior | 指定MyBatis的應如何自動映射列到欄位/屬性。NONE自動映射。 PARTIAL只會自動映射結果沒有嵌套結果映射定義裡面。 FULL會自動映射的結果映射任何複雜的(包含嵌套或其他)。 |
NONE,PARTIAL,FULL |
PARTIAL |
defaultExecutorType | 配置預設執行人。SIMPLE執行人確實沒有什麼特別的。 REUSE執行器重用準備好的語句。 BATCH執行器重用語句和批處理更新。 |
SIMPLE,REUSE,BATCH |
SIMPLE |
safeRowBoundsEnabled | 允許使用嵌套的語句RowBounds。 | true | false | FALSE |
mapUnderscoreToCamelCase | 從經典的資料庫列名A_COLUMN啟用自動映射到駱駝標識的經典的Java屬性名aColumn。 | true | false | FALSE |
localCacheScope | MyBatis的使用本地緩存,以防止迴圈引用,並加快反覆嵌套查詢。預設情況下(SESSION)會話期間執行的所有查詢緩存。如果localCacheScope=STATMENT本地會話將被用於語句的執行,只是沒有將數據共用之間的兩個不同的調用相同的SqlSession。 |
SESSION STATEMENT |
SESSION |
dbcTypeForNull | 指定為空值時,沒有特定的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 | 指定如果setter方法或map的put方法時,將調用檢索到的值是null。它是有用的,當你依靠Map.keySet()或null初始化。註意(如整型,布爾等)不會被設置為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 | CGLIB |
官方文檔settings的例子:
<setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="autoMappingBehavior" value="PARTIAL"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> <setting name="safeRowBoundsEnabled" value="false"/> <setting name="mapUnderscoreToCamelCase" value="false"/> <setting name="localCacheScope" value="SESSION"/> <setting name="jdbcTypeForNull" value="OTHER"/> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings>View Code
示例:
這裡設置MyBatis的日誌輸出到控制台:
<!--外部引入的內容將覆蓋內部定義的--> <properties resource="db.properties"> <!--定義一個名稱為driver,值為com.mysql.jdbc.Driver的屬性--> <property name="mysql.driver" value="com.mysql.jdbc.Driver"></property> </properties> <settings> <!--設置是否允許緩存--> <setting name="cacheEnabled" value="true"/> <!--設置日誌輸出的目標--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
結果:
2.3、typeAiases(別名)
在mapper.xml中,定義很多的statement,statement需要parameterType指定輸入參數的類型、需要resultType指定輸出結果的映射類型。
如果在指定類型時輸入類型全路徑,不方便進行開發,可以針對parameterType或resultType指定的類型定義一些別名,在mapper.xml中通過別名定義,方便開發。
如下所示類型com.zhangguo.mybatis02.entities.Student會反覆出現,冗餘:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zhangguo.mybatis02.mapper.studentMapper"> <select id="selectStudentById" resultType="com.zhangguo.mybatis02.entities.Student"> SELECT id,name,sex from student where id=#{id} </select> <select id="selectStudentsByName" parameterType="String" resultType="com.zhangguo.mybatis02.entities.Student"> SELECT id,name,sex from student where name like '%${value}%'; </select> <insert id="insertStudent" parameterType="com.zhangguo.mybatis02.entities.Student"> insert into student(name,sex) VALUES(#{name},'${sex}') </insert> <update id="updateStudent" parameterType="com.zhangguo.mybatis02.entities.Student"> update student set name=#{name},sex=#{sex} where id=#{id} </update> <delete id="deleteStudent" parameterType="int"> delete from student where id=#{id} </delete> </mapper>
2.3.1.MyBatis預設支持的別名
別名 |
映射的類型 |
_byte |
byte |
_long |
long |
_short |
short |
_int |
int |
_integer |
int |
_double |
double |
_float |
float |
_boolean |
boolean |
string |
String |
byte |
Byte |
long |
Long |
short |
Short |
int |
Integer |
integer |
Integer |
double |
Double |
float |
Float |
boolean |
Boolean |
date |
Date |
decimal |
BigDecimal |
bigdecimal |
BigDecimal |
2.3.2.自定義別名
(一)、單個別名定義(在myBatisConfig.xml)
<settings> <!--設置是否允許緩存--> <setting name="cacheEnabled" value="true"/> <!--設置日誌輸出的目標--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!--別名--> <typeAliases> <!--定義單個別名,指定名稱為student,對應的類型為com.zhangguo.mybatis02.entities.Student--> <typeAlias type="com.zhangguo.mybatis02.entities.Student" alias="student"></typeAlias> </typeAliases>
UserMapper.xml引用別名
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zhangguo.mybatis02.mapper.studentMapper"> <select id="selectStudentById" resultType="student"> SELECT id,name,sex from student where id=#{id} </select> <select id="selectStudentsByName" parameterType="String" resultType="student"> SELECT id,name,sex from student where name like '%${value}%'; </select> <insert id="insertStudent" parameterType="student"> insert into student(name,sex) VALUES(#{name},'${sex}') </insert> <update id="updateStudent" parameterType="student"> update student set name=#{name},sex=#{sex} where id=#{id} </update> <delete id="deleteStudent" parameterType="int"> delete from student where id=#{id} </delete> </mapper>
(二)批量定義別名,掃描指定的包
定義單個別名的缺點很明顯,如果項目中有很多別名則需要一個一個定義,且修改類型了還要修改配置文件非常麻煩,可以指定一個包,將下麵所有的類都按照一定的規則定義成別名:
<settings> <!--設置是否允許緩存--> <setting name="cacheEnabled" value="true"/> <!--設置日誌輸出的目標--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!--別名--> <typeAliases> <!--定義單個別名,指定名稱為student,對應的類型為com.zhangguo.mybatis02.entities.Student--> <!--<typeAlias type="com.zhangguo.mybatis02.entities.Student" alias="student"></typeAlias>--> <!--指定包名下所有的類被自動掃描並定義預設別名, mybatis會自動掃描包中的pojo類,自動定義別名,別名就是類名(首字母大寫或小寫都可以)--> <package name="com.zhangguo.mybatis02.entities"></package> </typeAliases>
如果com.zhangguo.mybatis02.entities包下有一個名為Student的類,則使用別名時可以是:student,或Student。
你一定會想到當兩個名稱相同時的衝突問題,可以使用註解解決
解決方法:
2.4、typeHandlers(類型處理器)
mybatis中通過typeHandlers完成jdbc類型和java類型的轉換。
通常情況下,mybatis提供的類型處理器滿足日常需要,不需要自定義.
mybatis支持類型處理器:
類型處理器 |
Java類型 |
JDBC類型 |
BooleanTypeHandler |
Boolean,boolean |
任何相容的布爾值 |
ByteTypeHandler |
Byte,byte |
任何相容的數字或位元組類型 |
ShortTypeHandler |
Short,short |
任何相容的數字或短整型 |
IntegerTypeHandler |
Integer,int |
任何相容的數字和整型 |
LongTypeHandler |
Long,long |
任何相容的數字或長整型 |
FloatTypeHandler |
Float,float |
任何相容的數字或單精度浮點型 |
DoubleTypeHandler |
Double,double |
任何相容的數字或雙精度浮點型 |
BigDecimalTypeHandler |
BigDecimal |
任何相容的數字或十進位小數類型 |
StringTypeHandler |
String |
CHAR和VARCHAR類型 |
ClobTypeHandler |
String |
CLOB和LONGVARCHAR類型 |
NStringTypeHandler |
String |
NVARCHAR和NCHAR類型 |
NClobTypeHandler |
String |
NCLOB類型 |
ByteArrayTypeHandler |
byte[] |
任何相容的位元組流類型 |
BlobTypeHandler |
byte[] |
BLOB和LONGVARBINARY類型 |
DateTypeHandler |
Date(java.util) |
TIMESTAMP類型 |
DateOnlyTypeHandler |
Date(java.util) |
DATE類型 |
TimeOnlyTypeHandler |
Date(java.util) |
TIME類型 |
SqlTimestampTypeHandler |
Timestamp(java.sql) |
TIMESTAMP類型 |
SqlDateTypeHandler |
Date(java.sql) |
DATE類型 |
SqlTimeTypeHandler |
Time(java.sql) |
TIME類型 |
ObjectTypeHandler |
任意 |
其他或未指定類型 |
EnumTypeHandler |
Enumeration類型 |
VARCHAR-任何相容的字元串類型,作為代碼存儲(而不是索引)。 |
2.5、mappers(映射配置)
映射配置可以有多種方式,如下XML配置所示:
<!-- 將sql映射註冊到全局配置中--> <mappers> <!-- mapper 單個註冊(mapper如果多的話,不太可能用這種方式) resource:引用類路徑下的文件 url:引用磁碟路徑下的資源 class,引用介面 package 批量註冊(基本上使用這種方式) name:mapper介面與mapper.xml所在的包名 --> <!-- 第一種:註冊sql映射文件--> <mapper resource="com/zhangguo/mapper/UserMapper.xml" /> <!-- 第二種:註冊介面sql映射文件必須與介面同名,並且放在同一目錄下--> <mapper class="com.zhangguo.mapper.UserMapper" /> <!-- 第三種:註冊基於註解的介面 基於註解 沒有sql映射文件,所有的sql都是利用註解寫在介面上--> <mapper class="com.zhangguo.mapper.TeacherMapper" /> <!-- 第四種:批量註冊 需要將sql配置文件和介面放到同一目錄下--> <package name="com.zhangguo.mapper" /> </mappers>
2.5.1、通過resource載入單個映射文件
<mappers> <!--根據路徑註冊一個基於XML的映射器--> <mapper resource="mapper/studentMapper.xml"/> </mappers>
註意位置
2.5.2:通過mapper介面載入單個映射文件
<!-- 通過mapper介面載入單個映射配置文件 遵循一定的規範:需要將mapper介面類名和mapper.xml映射文件名稱保持一致,且在一個目錄中; 上邊規範的前提是:使用的是mapper代理方法; --> <mapper class="com.mybatis.mapper.UserMapper"/>
按照上邊的規範,將mapper.java和mapper.xml放在一個目錄 ,且同名。
註意:
對於Maven項目,IntelliJ IDEA預設是不處理src/main/java中的非java文件的,不專門在pom.xml中配置<resources>是會報錯的,參考處理辦法:
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources>
所以src/main/java中最好不要出現非java文件。實際上,將mapper.xml放在src/main/resources中比較合適。
2.5.3、批量載入mapper
<!-- 批量載入映射配置文件,mybatis自動掃描包下麵的mapper介面進行載入 遵循一定的規範:需要將mapper介面類名和mapper.xml映射文件名稱保持一致,且在一個目錄中; 上邊規範的前提是:使用的是mapper代理方法; --> <package name="com.mybatis.mapper"/>
最後的配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--導入db.properties文件中的所有key-value數據-->