MyBatis-1.XML映射

Mybatis的配置文件包含了影響MyBatis行為的設(shè)置(setting)和屬性(properties)信息。

properties

properties中配置的屬性都是可外部配置且可動(dòng)態(tài)替換的??梢栽诘湫偷腏ava屬性文件中配置,也可以通過properties元素的子元素來傳遞。

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="root"/>
  <property name="password" value="sa"/>
</properties>

然后其屬性就可以在整個(gè)配置文件中用來替換需要?jiǎng)討B(tài)配置的屬性值:

<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>

屬性也可以被傳遞到SqlSessionFactoryBuilder.build()方法中:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
// ... or ..
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
多個(gè)地方配置屬性

如果屬性不只在一個(gè)地方進(jìn)行了配置,那么MyBatis按照如下順序加載:

  • properties元素內(nèi)指定的元素首先讀取
  • 根據(jù)properties元素中的resource屬性讀取類路徑下屬性文件或者根據(jù)url屬性指定的路徑讀取屬性文件,并覆蓋已讀取的同名屬性
  • 最后讀取作為方法參數(shù)傳遞的屬性,并覆蓋已讀取的同名屬性
屬性默認(rèn)值

可以為屬性指定一個(gè)默認(rèn)值:

<dataSource type="POOLED">
  <!-- ... -->
  <!-- If 'username' property not present, username become 'ut_user' -->
  <property name="username" value="${username:ut_user}"/> 
</dataSource>

該功能默認(rèn)關(guān)閉,需要指定一個(gè)屬性來開啟:

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <!-- Enable this feature -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
</properties>

可以使用 ":" 作為屬性鍵(e.g. db:username) 或者你也可以在sql定義中使用 OGNL 表達(dá)式的三元運(yùn)算符(e.g. ${tableName != null ? tableName : 'global_constants'}), 你應(yīng)該通過增加一個(gè)指定的屬性來改變分隔鍵和默認(rèn)值的字符。例如:

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <!-- Change default value of separator -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> 
</properties>
<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${db:username?:ut_user}"/>
</dataSource>

setting

改變MyBatis運(yùn)行時(shí)的行為。

設(shè)置參數(shù) 描述 有效值 默認(rèn)值
cachedEnable 全局地開啟或關(guān)閉配置文件中所有映射器已經(jīng)配置的任何緩存 true|false true
lazyLoadingEnable 延遲加載的全局開關(guān)。開啟時(shí),所有關(guān)聯(lián)對象將會(huì)延遲加載。特定關(guān)聯(lián)關(guān)系中可以通過設(shè)置fetchType屬性來覆蓋該項(xiàng)的開關(guān)狀態(tài) true|false false
aggressiveLazyLoading 當(dāng)開啟時(shí),任何方法的調(diào)用都會(huì)加載該對象的所有屬性,否則,每個(gè)屬性都會(huì)按需加載(參考 lazyLoadingTriggerMethods true|false false
multiResultSetsEnable 是否允許單一語句返回多結(jié)果集(需要兼容驅(qū)動(dòng)) true|false false
useColumnLabel 使用列標(biāo)簽代替列名。不同的驅(qū)動(dòng)在這方面會(huì)有不同的表現(xiàn), 具體可參考相關(guān)驅(qū)動(dòng)文檔或通過測試這兩種不同的模式來觀察所用驅(qū)動(dòng)的結(jié)果。 true|false true
useGeneratedKeys 允許 JDBC 支持自動(dòng)生成主鍵,需要驅(qū)動(dòng)兼容。 如果設(shè)置為 true 則這個(gè)設(shè)置強(qiáng)制使用自動(dòng)生成主鍵,盡管一些驅(qū)動(dòng)不能兼容但仍可正常工作(比如 Derby)。 true|false False
autoMappingBehavior 指定 MyBatis 應(yīng)如何自動(dòng)映射列到字段或?qū)傩浴?br>NONE 表示取消自動(dòng)映射;
PARTIAL 只會(huì)自動(dòng)映射沒有定義嵌套結(jié)果集映射的結(jié)果集。
FULL 會(huì)自動(dòng)映射任意復(fù)雜的結(jié)果集(無論是否嵌套)。
NONE, PARTIAL, FULL PARTIAL
autoMappingUnknownColumnBehavior 指定發(fā)現(xiàn)自動(dòng)映射目標(biāo)未知列(或者未知屬性類型)的行為。
NONE: 不做任何反應(yīng)
WARNING: 輸出提醒日志 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior'的日志等級必須設(shè)置為 WARN)
FAILING: 映射失敗 (拋出 SqlSessionException)
NONE, WARNING,FAILING NONE
defaultExecutorType 配置默認(rèn)的執(zhí)行器。
SIMPLE就是普通的執(zhí)行器;
REUSE 執(zhí)行器會(huì)重用預(yù)處理語句(prepared statements);
BATCH 執(zhí)行器將重用語句并執(zhí)行批量更新。
SIMPLE,REUSE,BATCH SIMPLE
defaultStatementTimeout 設(shè)置超時(shí)時(shí)間,它決定驅(qū)動(dòng)等待數(shù)據(jù)庫響應(yīng)的秒數(shù)。 任意正整數(shù) Not Set (null)
defaultFetchSize 為驅(qū)動(dòng)的結(jié)果集獲取數(shù)量(fetchSize)設(shè)置一個(gè)提示值。此參數(shù)只可以在查詢設(shè)置中被覆蓋。 任意正整數(shù) Not Set (null)
safeRowBoundsEnabled 允許在嵌套語句中使用分頁(RowBounds)。如果允許使用則設(shè)置為false。 true|false False
safeResultHandlerEnabled 允許在嵌套語句中使用分頁(ResultHandler)。如果允許使用則設(shè)置為false。 true|false True
mapUnderscoreToCamelCase 是否開啟自動(dòng)駝峰命名規(guī)則(camel case)映射,即從經(jīng)典數(shù)據(jù)庫列名 A_COLUMN 到經(jīng)典 Java 屬性名 aColumn 的類似映射。 true|false False
localCacheScope MyBatis 利用本地緩存機(jī)制(Local Cache)防止循環(huán)引用(circular references)和加速重復(fù)嵌套查詢。 默認(rèn)值為 SESSION,這種情況下會(huì)緩存一個(gè)會(huì)話中執(zhí)行的所有查詢。 若設(shè)置值為 STATEMENT,本地會(huì)話僅用在語句執(zhí)行上,對相同 SqlSession 的不同調(diào)用將不會(huì)共享數(shù)據(jù)。 SESSION|STATEMENT SESSION
jdbcTypeForNull 當(dāng)沒有為參數(shù)提供特定的 JDBC 類型時(shí),為空值指定 JDBC 類型。 某些驅(qū)動(dòng)需要指定列的 JDBC 類型,多數(shù)情況直接用一般類型即可,比如 NULL、VARCHAR 或 OTHER。 JdbcType 常量. 大多都為: NULL, VARCHAR and OTHER OTHER
lazyLoadTriggerMethods 指定哪個(gè)對象的方法觸發(fā)一次延遲加載。 用逗號(hào)分隔的方法列表。 equals,clone,hashCode,toString
defaultScriptingLanguage 指定動(dòng)態(tài) SQL 生成的默認(rèn)語言。 一個(gè)類型別名或完全限定類名。 org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
defaultEnumTypeHandler 指定 Enum 使用的默認(rèn) TypeHandler 。 一個(gè)類型別名或完全限定類名。 org.apache.ibatis.type.EnumTypeHandler
callSettersOnNulls 指定當(dāng)結(jié)果集中值為 null 的時(shí)候是否調(diào)用映射對象的 setter(map 對象時(shí)為 put)方法,這對于有 Map.keySet() 依賴或 null 值初始化的時(shí)候是有用的。注意基本類型(int、boolean等)是不能設(shè)置成 null 的。 true|false false
returnInstanceForEmptyRow 當(dāng)返回行的所有列都是空時(shí),MyBatis默認(rèn)返回null。 當(dāng)開啟這個(gè)設(shè)置時(shí),MyBatis會(huì)返回一個(gè)空實(shí)例。 請注意,它也適用于嵌套的結(jié)果集 (i.e. collectioin and association)。 true | false false
logPrefix 指定 MyBatis 增加到日志名稱的前綴。 任何字符串 Not set
logImpl 指定 MyBatis 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)查找。 SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING Not set
proxyFactory 指定 Mybatis 創(chuàng)建具有延遲加載能力的對象所用到的代理工具。 CGLIB | JAVASSIST JAVASSIST
vfsImpl 指定VFS的實(shí)現(xiàn) 自定義VFS的實(shí)現(xiàn)的類全限定名,以逗號(hào)分隔。 Not set
useActualParamName 允許使用方法簽名中的名稱作為語句參數(shù)名稱。 為了使用該特性,你的工程必須采用Java 8編譯,并且加上-parameters選項(xiàng)。 true | false true
configurationFactory 指定一個(gè)提供Configuration實(shí)例的類。 這個(gè)被返回的Configuration實(shí)例用來加載被反序列化對象的懶加載屬性值。 這個(gè)類必須包含一個(gè)簽名方法static Configuration getConfiguration(). 類型別名或者全類名. Not set
一個(gè)配置完整的setting元素
<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="autoMappingUnknownColumnBehavior" value="WARNING"/>
    <setting name="defaultExecutorType" value="SIMPLE"/>
    <setting name="defaultStatementTimeout" value="25"/>
    <setting name="defaultFetchSize" value="100"/>
    <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>

typeAliases

類別名是為Java類型設(shè)置一個(gè)短的名字,只與XML配置有關(guān),存在的意義僅在于減少類完全限定名的冗余。

<typeAliases>
    <typeAlias alias="Author" type="domain.blog.Author"/>
    <typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>

也可以指定包名,MyBatis會(huì)在包名下面搜索需要的Java Bean:

<typeAliases>
    <package name="domain.blog"/>
</typeAliases>

每一個(gè)在包 domain.blog 中的 Java Bean,在沒有注解的情況下,會(huì)使用 Bean 的首字母小寫的非限定類名來作為它的別名。 比如 domain.blog.Author 的別名為 author;若有注解,則別名為其注解值。例如:

@Alias("author")
public class Author {
    ...
}
內(nèi)建別名

這是一些為常見的 Java 類型內(nèi)建的相應(yīng)的類型別名。它們都是大小寫不敏感的,需要注意的是由基本類型名稱重復(fù)導(dǎo)致的特殊處理。

別名 映射的類型
_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
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

typeHandlers

MyBatis 在預(yù)處理語句(PreparedStatement)中設(shè)置一個(gè)參數(shù),或者從結(jié)果集中取出一個(gè)值, 都會(huì)用類型處理器將獲取的值以合適的方式轉(zhuǎn)換成 Java 類型。下表描述了一些默認(rèn)的類型處理器:

類型處理器 Java 類型 JDBC 類型
BooleanTypeHandler java.lang.Boolean, boolean 數(shù)據(jù)庫兼容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 數(shù)據(jù)庫兼容的 NUMERIC 或 BYTE
ShortTypeHandler java.lang.Short, short 數(shù)據(jù)庫兼容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler java.lang.Integer, int 數(shù)據(jù)庫兼容的 NUMERIC 或 INTEGER
LongTypeHandler java.lang.Long, long 數(shù)據(jù)庫兼容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler java.lang.Float, float 數(shù)據(jù)庫兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler java.lang.Double, double 數(shù)據(jù)庫兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler java.math.BigDecimal 數(shù)據(jù)庫兼容的 NUMERIC 或 DECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR
ClobReaderTypeHandler java.io.Reader -
ClobTypeHandler java.lang.String CLOB, LONGVARCHAR
NStringTypeHandler java.lang.String NVARCHAR, NCHAR
NClobTypeHandler java.lang.String NCLOB
BlobInputStreamTypeHandler java.io.InputStream -
ByteArrayTypeHandler byte[] 數(shù)據(jù)庫兼容的字節(jié)流類型
BlobTypeHandler byte[] BLOB, LONGVARBINARY
DateTypeHandler java.util.Date TIMESTAMP
DateOnlyTypeHandler java.util.Date DATE
TimeOnlyTypeHandler java.util.Date TIME
SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP
SqlDateTypeHandler java.sql.Date DATE
SqlTimeTypeHandler java.sql.Time TIME
ObjectTypeHandler Any OTHER 或未指定類型
EnumTypeHandler Enumeration Type VARCHAR-任何兼容的字符串類型,存儲(chǔ)枚舉的名稱(而不是索引)
EnumOrdinalTypeHandler Enumeration Type 任何兼容的 NUMERIC 或 DOUBLE 類型,存儲(chǔ)枚舉的索引(而不是名稱)。
InstantTypeHandler java.time.Instant TIMESTAMP
LocalDateTimeTypeHandler java.time.LocalDateTime TIMESTAMP
LocalDateTypeHandler java.time.LocalDate DATE
LocalTimeTypeHandler java.time.LocalTime TIME
OffsetDateTimeTypeHandler java.time.OffsetDateTime TIMESTAMP
OffsetTimeTypeHandler java.time.OffsetTime TIME
ZonedDateTimeTypeHandler java.time.ZonedDateTime TIMESTAMP
YearTypeHandler java.time.Year INTEGER
MonthTypeHandler java.time.Month INTEGER
YearMonthTypeHandler java.time.YearMonth VARCHAR or LONGVARCHAR
JapaneseDateTypeHandler java.time.chrono.JapaneseDate DATE
重寫/創(chuàng)建類型處理器

可以重寫類型處理器或創(chuàng)建類型處理器來處理不支持的或非標(biāo)準(zhǔn)的類型。 具體做法為:

  • 實(shí)現(xiàn) org.apache.ibatis.type.TypeHandler 接口
  • 繼承一個(gè)很便利的類 org.apache.ibatis.type.BaseTypeHandler,
    然后可以選擇性地將它映射到一個(gè) JDBC 類型。比如:
// ExampleTypeHandler.java
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
    ps.setString(i, parameter);
  }

  @Override
  public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
    return rs.getString(columnName);
  }

  @Override
  public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    return rs.getString(columnIndex);
  }

  @Override
  public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    return cs.getString(columnIndex);
  }
}
<!-- mybatis-config.xml -->
<typeHandlers>
  <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>
</typeHandlers>

處理枚舉類型

若想映射枚舉類型 Enum,則需要從 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中選一個(gè)來使用。

對象工廠(objectFactory)

MyBatis 每次創(chuàng)建結(jié)果對象的新實(shí)例時(shí),它都會(huì)使用一個(gè)對象工廠(ObjectFactory)實(shí)例來完成。
默認(rèn)的對象工廠需要做的僅僅是實(shí)例化目標(biāo)類,要么通過默認(rèn)構(gòu)造方法,要么在參數(shù)映射存在的時(shí)候通過參數(shù)構(gòu)造方法來實(shí)例化。 如果想覆蓋對象工廠的默認(rèn)行為,則可以通過創(chuàng)建自己的對象工廠來實(shí)現(xiàn)。

。。。

插件(plugins)

MyBatis 允許你在已映射語句執(zhí)行過程中的某一點(diǎn)進(jìn)行攔截調(diào)用。默認(rèn)情況下,MyBatis 允許使用插件來攔截的方法調(diào)用包括:

  • Executor(update,query,flushStatements,commit,rollback,getTransaction, close,isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

使用插件,只需要實(shí)現(xiàn) Interceptor 接口,并指定想要攔截的方法簽名即可。

// ExamplePlugin.java
@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  public Object intercept(Invocation invocation) throws Throwable {
    return invocation.proceed();
  }
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }
  public void setProperties(Properties properties) {
  }
}
<!-- mybatis-config.xml -->
<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>

上面的插件將會(huì)攔截在 Executor 實(shí)例中所有的 “update” 方法調(diào)用, 這里的 Executor 是負(fù)責(zé)執(zhí)行低層映射語句的內(nèi)部對象。

配置環(huán)境(environment)

盡管可以配置多個(gè)環(huán)境,每個(gè) SqlSessionFactory 實(shí)例只能選擇其一。每個(gè)數(shù)據(jù)庫對應(yīng)一個(gè) SqlSessionFactory 實(shí)例
為了指定創(chuàng)建哪種環(huán)境,只要將它作為可選的參數(shù)傳遞給 SqlSessionFactoryBuilder 即可。可以接受環(huán)境配置的兩個(gè)方法簽名是:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);

如果忽略了環(huán)境參數(shù),那么默認(rèn)環(huán)境將會(huì)被加載,如下所示:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);

環(huán)境元素定義了如何配置環(huán)境變量

    <!--默認(rèn)的環(huán)境ID-->
    <environments default="development">
        <!--各環(huán)境元素自己的ID-->
        <environment id="development">
            <!--事務(wù)管理器的配置-->
            <transactionManager type="JDBC">
                <property name="..." value="..."/>
            </transactionManager>
            <!--數(shù)據(jù)源的配置-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
事務(wù)管理器(transactionManager)

MyBatis中有兩種類型的事務(wù)管理器(type=”[JDBC|MANAGED]”):

  • JDBC – 這個(gè)配置就是直接使用了 JDBC 的提交和回滾設(shè)置,它依賴于從數(shù)據(jù)源得到的連接來管理事務(wù)作用域。
  • MANAGED – 這個(gè)配置幾乎沒做什么。它從來不提交或回滾一個(gè)連接,而是讓容器來管理事務(wù)的整個(gè)生命周期(比如 JEE 應(yīng)用服務(wù)器的上下文)。 默認(rèn)情況下它會(huì)關(guān)閉連接,然而一些容器并不希望這樣,因此需要將 closeConnection 屬性設(shè)置為 false 來阻止它默認(rèn)的關(guān)閉行為。例如:
<transactionManager type="MANAGED">
  <property name="closeConnection" value="false"/>
</transactionManager>

如果你正在使用 Spring + MyBatis,則沒有必要配置事務(wù)管理器, 因?yàn)?Spring 模塊會(huì)使用自帶的管理器來覆蓋前面的配置。

數(shù)據(jù)源(dataSource)

dataSource 元素使用標(biāo)準(zhǔn)的 JDBC 數(shù)據(jù)源接口來配置 JDBC 連接對象的資源。

  • 許多 MyBatis 的應(yīng)用程序會(huì)按示例中的例子來配置數(shù)據(jù)源。雖然這是可選的,但為了使用延遲加載,數(shù)據(jù)源是必須配置的。

有三種內(nèi)建的數(shù)據(jù)源類型(也就type=”[UNPOOLED|POOLED|JNDI]”):

UNPOOLED – 這個(gè)數(shù)據(jù)源的實(shí)現(xiàn)只是每次被請求時(shí)打開和關(guān)閉連接。雖然有點(diǎn)慢,但對于在數(shù)據(jù)庫連接可用性方面沒有太高要求的簡單應(yīng)用程序來說,是一個(gè)很好的選擇。 不同的數(shù)據(jù)庫在性能方面的表現(xiàn)也是不一樣的,對于某些數(shù)據(jù)庫來說,使用連接池并不重要,這個(gè)配置就很適合這種情形。UNPOOLED 類型的數(shù)據(jù)源僅僅需要配置以下 5 種屬性:

  • driver – 這是 JDBC 驅(qū)動(dòng)的 Java 類的完全限定名(并不是 JDBC 驅(qū)動(dòng)中可能包含的數(shù)據(jù)源類)。
  • url – 這是數(shù)據(jù)庫的 JDBC URL 地址。
  • username – 登錄數(shù)據(jù)庫的用戶名。
  • password – 登錄數(shù)據(jù)庫的密碼。
  • defaultTransactionIsolationLevel – 默認(rèn)的連接事務(wù)隔離級別。
    作為可選項(xiàng),你也可以傳遞屬性給數(shù)據(jù)庫驅(qū)動(dòng)。要這樣做,屬性的前綴為“driver.”,例如:
  • driver.encoding=UTF8
    這將通過 DriverManager.getConnection(url,driverProperties) 方法傳遞值為 UTF8 的 encoding 屬性給數(shù)據(jù)庫驅(qū)動(dòng)。

POOLED– 這種數(shù)據(jù)源的實(shí)現(xiàn)利用“池”的概念將 JDBC 連接對象組織起來,避免了創(chuàng)建新的連接實(shí)例時(shí)所必需的初始化和認(rèn)證時(shí)間。 這是一種使得并發(fā) Web 應(yīng)用快速響應(yīng)請求的流行處理方式。

除了上述提到 UNPOOLED 下的屬性外,還有更多屬性用來配置 POOLED 的數(shù)據(jù)源:

  • poolMaximumActiveConnections – 在任意時(shí)間可以存在的活動(dòng)(也就是正在使用)連接數(shù)量,默認(rèn)值:10
  • poolMaximumIdleConnections – 任意時(shí)間可能存在的空閑連接數(shù)。
  • poolMaximumCheckoutTime – 在被強(qiáng)制返回之前,池中連接被檢出(checked out)時(shí)間,默認(rèn)值:20000 毫秒(即 20 秒)
  • poolTimeToWait – 這是一個(gè)底層設(shè)置,如果獲取連接花費(fèi)了相當(dāng)長的時(shí)間,連接池會(huì)打印狀態(tài)日志并重新嘗試獲取一個(gè)連接(避免在誤配置的情況下一直安靜的失敗),默認(rèn)值:20000 毫秒(即 20 秒)。
  • poolMaximumLocalBadConnectionTolerance – 這是一個(gè)關(guān)于壞連接容忍度的底層設(shè)置, 作用于每一個(gè)嘗試從緩存池獲取連接的線程. 如果這個(gè)線程獲取到的是一個(gè)壞的連接,那么這個(gè)數(shù)據(jù)源允許這個(gè)線程嘗試重新獲取一個(gè)新的連接,但是這個(gè)重新嘗試的次數(shù)不應(yīng)該超過 poolMaximumIdleConnections 與 poolMaximumLocalBadConnectionTolerance 之和。 默認(rèn)值:3 (新增于 3.4.5)
  • poolPingQuery – 發(fā)送到數(shù)據(jù)庫的偵測查詢,用來檢驗(yàn)連接是否正常工作并準(zhǔn)備接受請求。默認(rèn)是“NO PING QUERY SET”,這會(huì)導(dǎo)致多數(shù)數(shù)據(jù)庫驅(qū)動(dòng)失敗時(shí)帶有一個(gè)恰當(dāng)?shù)腻e(cuò)誤消息。
  • poolPingEnabled – 是否啟用偵測查詢。若開啟,需要設(shè)置 poolPingQuery 屬性為一個(gè)可執(zhí)行的 SQL 語句(最好是一個(gè)速度非常快的 SQL 語句),默認(rèn)值:false。
  • poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的頻率。可以被設(shè)置為和數(shù)據(jù)庫連接超時(shí)時(shí)間一樣,來避免不必要的偵測,默認(rèn)值:0(即所有連接每一時(shí)刻都被偵測 — 當(dāng)然僅當(dāng) poolPingEnabled 為 true 時(shí)適用)。

JNDI – 這個(gè)數(shù)據(jù)源的實(shí)現(xiàn)是為了能在如 EJB 或應(yīng)用服務(wù)器這類容器中使用,容器可以集中或在外部配置數(shù)據(jù)源,然后放置一個(gè) JNDI 上下文的引用。這種數(shù)據(jù)源配置只需要兩個(gè)屬性:

  • initial_context – 這個(gè)屬性用來在 InitialContext 中尋找上下文(即,initialContext.lookup(initial_context))。這是個(gè)可選屬性,如果忽略,那么 data_source 屬性將會(huì)直接從 InitialContext 中尋找。
  • data_source – 這是引用數(shù)據(jù)源實(shí)例位置的上下文的路徑。提供了 initial_context 配置時(shí)會(huì)在其返回的上下文中進(jìn)行查找,沒有提供時(shí)則直接在 InitialContext 中查找。

和其他數(shù)據(jù)源配置類似,可以通過添加前綴“env.”直接把屬性傳遞給初始上下文。比如:

  • env.encoding=UTF8
    這就會(huì)在初始上下文(InitialContext)實(shí)例化時(shí)往它的構(gòu)造方法傳遞值為 UTF8 的 encoding 屬性。

你可以通過實(shí)現(xiàn)接口 org.apache.ibatis.datasource.DataSourceFactory 來使用第三方數(shù)據(jù)源:

public interface DataSourceFactory {
  void setProperties(Properties props);
  DataSource getDataSource();
}

org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory可被用作父類來構(gòu)建新的數(shù)據(jù)源適配器,比如下面這段插入 C3P0 數(shù)據(jù)源所必需的代碼:

import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
        
public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {

  public C3P0DataSourceFactory() {
    this.dataSource = new ComboPooledDataSource();
  }
}

為了令其工作,記得為每個(gè)希望 MyBatis 調(diào)用的 setter 方法在配置文件中增加對應(yīng)的屬性。下面是一個(gè)可以連接至 PostgreSQL 數(shù)據(jù)庫的例子:

<dataSource type="org.myproject.C3P0DataSourceFactory">
  <property name="driver" value="org.postgresql.Driver"/>
  <property name="url" value="jdbc:postgresql:mydb"/>
  <property name="username" value="postgres"/>
  <property name="password" value="root"/>
</dataSource>

databaseIdProvider

MyBatis 可以根據(jù)不同的數(shù)據(jù)庫廠商執(zhí)行不同的語句,這種多廠商的支持是基于映射語句中的 databaseId 屬性。 MyBatis 會(huì)加載不帶databaseId 屬性和帶有匹配當(dāng)前數(shù)據(jù)庫 databaseId 屬性的所有語句。 如果同時(shí)找到帶有 databaseId 和不帶 databaseId 的相同語句,則后者會(huì)被舍棄。 為支持多廠商特性只要像下面這樣在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:

<databaseIdProvider type="DB_VENDOR" />

這里的 DB_VENDOR 會(huì)通過DatabaseMetaData#getDatabaseProductName()返回的字符串進(jìn)行設(shè)置。 由于通常情況下這個(gè)字符串都非常長而且相同產(chǎn)品的不同版本會(huì)返回不同的值,所以最好通過設(shè)置屬性別名來使其變短,如下:

<databaseIdProvider type="DB_VENDOR">
  <property name="SQL Server" value="sqlserver"/>
  <property name="DB2" value="db2"/>        
  <property name="Oracle" value="oracle" />
</databaseIdProvider>

在提供了屬性別名時(shí),DB_VENDOR databaseIdProvider 將被設(shè)置為第一個(gè)能匹配數(shù)據(jù)庫產(chǎn)品名稱的屬性鍵對應(yīng)的值,如果沒有匹配的屬性將會(huì)設(shè)置為 “null”。 在這個(gè)例子中,如果 getDatabaseProductName() 返回“Oracle (DataDirect)”,databaseId 將被設(shè)置為“oracle”。

你可以通過實(shí)現(xiàn)接口 org.apache.ibatis.mapping.DatabaseIdProvider 并在 mybatis-config.xml 中注冊來構(gòu)建自己的 DatabaseIdProvider:

public interface DatabaseIdProvider {
  void setProperties(Properties p);
  String getDatabaseId(DataSource dataSource) throws SQLException;
}

映射器(mappers)

既然 MyBatis 的行為已經(jīng)由上述元素配置完了,我們現(xiàn)在就要定義 SQL 映射語句了。但是首先我們需要告訴 MyBatis 到哪里去找到這些語句。 Java 在自動(dòng)查找這方面沒有提供一個(gè)很好的方法,所以最佳的方式是告訴 MyBatis 到哪里去找映射文件。你可以使用相對于類路徑的資源引用, 或完全限定資源定位符(包括 file:/// 的 URL),或類名和包名等。例如:

<!-- 使用相對于類路徑的資源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口實(shí)現(xiàn)類的完全限定類名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 將包內(nèi)的映射器接口實(shí)現(xiàn)全部注冊為映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

這些配置會(huì)告訴了 MyBatis 去哪里找映射文件。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲(chǔ)過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,227評論 0 4
  • MyBatis 理論篇 [TOC] 什么是MyBatis ?MyBatis是支持普通SQL查詢,存儲(chǔ)過程和高級映射...
    有_味閱讀 3,174評論 0 26
  • 參考w3c 教程 1.概述 MyBatis 是支持定制化SQL、存儲(chǔ)過程以及高級映射的優(yōu)秀的持久層框架。MyBat...
    王偵閱讀 458評論 0 0
  • 昨天老公回來,接兒子放學(xué),我們一起去跳廣場舞那里散步,兒子一定要一手牽著爸爸一手牽著媽媽,見了人就說,這是我爸爸!...
    心靈深處ye閱讀 289評論 0 0
  • 生活中總會(huì)遇到一些人一些事,教會(huì)你認(rèn)識(shí)這個(gè)世界人性中的惡。一直都覺得自己是被保護(hù)的很好成長起來的女孩,只以為...
    orengesky閱讀 1,217評論 0 1

友情鏈接更多精彩內(nèi)容