本文只论mybatis自己,不涉及与spring整合,文中探讨了mybatis最新版本提供的所有配置项的做用。html
首先要了解都有哪些配置项,mybatis的SqlSession来自SqlSessionFactory,SqlSessionFactory来自SqlSessionFactoryBuilder,从SqlSessionFactoryBuilder切入分析java
... public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } ...
构造SqlSessionFactoryBuilder用到了XMLConfigBuilder,而后看XMLConfigBuildermysql
public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; parseConfiguration(parser.evalNode("/configuration")); return configuration; } private void parseConfiguration(XNode root) { try { //issue #117 read properties first propertiesElement(root.evalNode("properties")); Properties settings = settingsAsProperties(root.evalNode("settings")); loadCustomVfs(settings); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); reflectorFactoryElement(root.evalNode("reflectorFactory")); settingsElement(settings); // read it after objectFactory and objectWrapperFactory issue #631 environmentsElement(root.evalNode("environments")); databaseIdProviderElement(root.evalNode("databaseIdProvider")); typeHandlerElement(root.evalNode("typeHandlers")); mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } } private void settingsElement(Properties props) throws Exception { configuration.setAutoMappingBehavior(AutoMappingBehavior.valueOf(props.getProperty("autoMappingBehavior", "PARTIAL"))); configuration.setAutoMappingUnknownColumnBehavior(AutoMappingUnknownColumnBehavior.valueOf(props.getProperty("autoMappingUnknownColumnBehavior", "NONE"))); configuration.setCacheEnabled(booleanValueOf(props.getProperty("cacheEnabled"), true)); configuration.setProxyFactory((ProxyFactory) createInstance(props.getProperty("proxyFactory"))); configuration.setLazyLoadingEnabled(booleanValueOf(props.getProperty("lazyLoadingEnabled"), false)); configuration.setAggressiveLazyLoading(booleanValueOf(props.getProperty("aggressiveLazyLoading"), false)); configuration.setMultipleResultSetsEnabled(booleanValueOf(props.getProperty("multipleResultSetsEnabled"), true)); configuration.setUseColumnLabel(booleanValueOf(props.getProperty("useColumnLabel"), true)); configuration.setUseGeneratedKeys(booleanValueOf(props.getProperty("useGeneratedKeys"), false)); configuration.setDefaultExecutorType(ExecutorType.valueOf(props.getProperty("defaultExecutorType", "SIMPLE"))); configuration.setDefaultStatementTimeout(integerValueOf(props.getProperty("defaultStatementTimeout"), null)); configuration.setDefaultFetchSize(integerValueOf(props.getProperty("defaultFetchSize"), null)); configuration.setMapUnderscoreToCamelCase(booleanValueOf(props.getProperty("mapUnderscoreToCamelCase"), false)); configuration.setSafeRowBoundsEnabled(booleanValueOf(props.getProperty("safeRowBoundsEnabled"), false)); configuration.setLocalCacheScope(LocalCacheScope.valueOf(props.getProperty("localCacheScope", "SESSION"))); configuration.setJdbcTypeForNull(JdbcType.valueOf(props.getProperty("jdbcTypeForNull", "OTHER"))); configuration.setLazyLoadTriggerMethods(stringSetValueOf(props.getProperty("lazyLoadTriggerMethods"), "equals,clone,hashCode,toString")); configuration.setSafeResultHandlerEnabled(booleanValueOf(props.getProperty("safeResultHandlerEnabled"), true)); configuration.setDefaultScriptingLanguage(resolveClass(props.getProperty("defaultScriptingLanguage"))); @SuppressWarnings("unchecked") Class<? extends TypeHandler> typeHandler = (Class<? extends TypeHandler>)resolveClass(props.getProperty("defaultEnumTypeHandler")); configuration.setDefaultEnumTypeHandler(typeHandler); configuration.setCallSettersOnNulls(booleanValueOf(props.getProperty("callSettersOnNulls"), false)); configuration.setUseActualParamName(booleanValueOf(props.getProperty("useActualParamName"), true)); configuration.setReturnInstanceForEmptyRow(booleanValueOf(props.getProperty("returnInstanceForEmptyRow"), false)); configuration.setLogPrefix(props.getProperty("logPrefix")); @SuppressWarnings("unchecked") Class<? extends Log> logImpl = (Class<? extends Log>)resolveClass(props.getProperty("logImpl")); configuration.setLogImpl(logImpl); configuration.setConfigurationFactory(resolveClass(props.getProperty("configurationFactory"))); }
configuration节点为根节点。git
能够配置10个子节点:properties、settings、typeAliases、plugins、objectFactory、objectWrapperFactory、environments、databaseIdProvider、typeHandlers、mappers。github
这些属性都是可外部配置且可动态替换的,既能够在典型的 Java 属性文件中配置,亦可经过 properties 元素的子元素来传递。例如:spring
<!-- mybatis-config.xml --> <properties resource="jdbc.properties"></properties> <!-- mybatis-config.xml --> <properties> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/a"/> <property name="username" value="root"/> <property name="password" value="root"/> </properties>settings
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。sql
<!-- mybatis-config.xml --> <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>
熟悉配置前须要知道什么是懒加载数据库
public class Order { public Long id; public Long addressId; public Address address; }
public class Address { public Long id; public String name; }
<!-- addressMapper.xml --> <mapper namespace="addressMapperSpace"> <select id="getAddressById" parameterType="Long" resultType="Address"> select id,name from t_address where id = #{id} </select> </mapper>
<!-- orderMapper.xml --> <mapper namespace="..."> <resultMap id="orderMap" type="Order"> <id property="id" column="id" /> <association property="address" column="address_id" select="addressMapperSpace.getAddressById" /> </resultMap> <select id="getOrderById" resultMap="orderMap" parameterType="Long"> select id,address_id from t_order where id = #{id} <select> </mapper>
若是是懒加载,那么访问order的address属性时才会去查询address。apache
参数json |
官方中文描述 |
理解 |
可选值 |
默认值 |
---|---|---|---|---|
cacheEnabled |
全局地开启或关闭配置文件中的全部映射器已经配置的任何缓存。 |
mybatis二级缓存开关,不支持集群环境,设置成false防止意外。 |
true | false |
true |
lazyLoadingEnabled |
延迟加载的全局开关。当开启时,全部关联对象都会延迟加载。 特定关联关系中可经过设置fetchType属性来覆盖该项的开关状态 |
能够不设置 |
true | false |
false |
aggressiveLazyLoading |
当开启时,任何方法的调用都会加载该对象的全部属性。不然,每一个属性会按需加载(参考lazyLoadTriggerMethods). |
当设置为true时,懒加载的对象可能被任何懒属性所有加载;不然,每一个属性按需加载。通常不用。 能够不设置 |
true | false |
false (true in ≤3.4.1) |
lazyLoadTriggerMethods |
指定对象的哪一个方法触发一次延迟加载。 |
在lazyLoadingEnabled=true时有效,调用本方法会使得全部延迟加载属性被加载,若是有多个懒加载属性,可使用这个方法把全部懒加载属性一块儿加载了。 能够不设置 |
用逗号分隔的方法列表。 |
equals,clone,hashCode,toString |
proxyFactory |
指定 Mybatis 建立具备延迟加载能力的对象所用到的代理工具。 |
mybatis延迟加载用的工具,旧版本使用的是CGLIB动态代理技术,新版本支持使用JAVASSIST(Javassist是一个运行时编译库,他能动态的生成或修改类的字节码)来完成。 能够不设置 |
CGLIB | JAVASSIST |
JAVASSIST (MyBatis 3.3 or above) |
multipleResultSetsEnabled |
是否容许单一语句返回多结果集(须要兼容驱动)。 |
sql与ResultSet一对多的用法, 没找到用法。 能够不设置 |
true | false |
true |
useColumnLabel |
使用列标签代替列名。不一样的驱动在这方面会有不一样的表现, 具体可参考相关驱动文档或经过测试这两种不一样的模式来观察所用驱动的结果。 |
在Select字段的时候使用AS,用得上,因为默认true。 能够不设置 |
true | false |
true |
useGeneratedKeys |
容许 JDBC 支持自动生成主键,须要驱动兼容。 若是设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工做(好比 Derby)。 |
咱们使用mysql数据库自增主键,在xml的insert块中若是使用useGeneratedKeys来得到生成的主键,那这个属性必须设置成true。若是使用如下方法,那也能够不设置。 <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long"> SELECT LAST_INSERT_ID() </selectKey> |
true | false |
false |
autoMappingBehavior |
指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(不管是否嵌套)。 |
若是修改为FULL,会因为没及时更新model致使映射失败。 能够不设置 |
NONE, PARTIAL, FULL |
PARTIAL |
autoMappingUnknownColumnBehavior |
指定发现自动映射目标未知列(或者未知属性类型)的行为。
|
能够不设置 |
NONE, WARNING, FAILING |
NONE |
defaultExecutorType |
配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 |
1.设为"SIMPLE", 在执行dao.save()时,就至关于JDBC的stmt.execute(sql); 2.设为"REUSE", 在执行dao.save()时,至关于JDBC重用一条sql,再经过stmt传入多项参数值,而后执行stmt.executeUpdate()或stmt.executeBatch();重用sql的场景不太常见,所以用SIMPLE就能够了。 3.设为"BATCH", 在执行dao.save()时,至关于JDBC语句的 stmt.addBatch(sql),即仅仅是将执行SQL加入到批量计划。 因此此时不会抛出主键冲突等运行时异常,而只有临近commit前执行stmt.execteBatch()后才会抛出异常。 能够不设置 |
SIMPLE REUSE BATCH |
SIMPLE |
defaultStatementTimeout |
设置超时时间,它决定驱动等待数据库响应的秒数。 |
这是以秒为单位的全局sql超时时间设置,当超出了设置的超时时间时,会抛出SQLTimeoutException。建议设置一个合理值。 |
任意正整数 |
Not Set (null) |
defaultFetchSize |
为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只能够在查询设置中被覆盖。 |
mysql不支持fetchSize。 通常使用分页插件便可。 能够不设置 |
任意正整数 |
Not Set (null) |
safeRowBoundsEnabled |
容许在嵌套语句中使用分页(RowBounds)。若是容许使用则设置为false。 |
使用场景:session.select("...", null, new RowBounds(1, 2),resultHandler); 通常使用分页插件便可。 能够不设置 |
true | false |
false |
safeResultHandlerEnabled |
容许在嵌套语句中使用分页(ResultHandler)。若是容许使用则设置为false。 |
使用场景:session.select("...", null, new RowBounds(1, 2),resultHandler); 能够不设置 |
true | false |
true |
mapUnderscoreToCamelCase |
是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的相似映射。 |
驼峰命名映射,手写mapper不去写resultMap时推荐开启。使用mybatis-generator时,不开启也ok。 |
true | false |
false |
localCacheScope |
MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种状况下会缓存一个会话中执行的全部查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不一样调用将不会共享数据。 |
一级缓存在spring中基本也用不上,能够不设置 |
SESSION | STATEMENT |
SESSION |
jdbcTypeForNull |
当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动须要指定列的 JDBC 类型,多数状况直接用通常类型便可,好比 NULL、VARCHAR 或 OTHER。 |
正常状况下咱们都配了。 能够不设置 |
JdbcType 常量. 大多都为: NULL, VARCHAR and OTHER |
OTHER (java.lang.Object) |
defaultScriptingLanguage |
指定动态 SQL 生成的默认语言。 |
虽然官方名称叫作LanguageDriver,其实叫作解析器可能更加合理。MyBatis 从 3.2 开始支持可插拔的脚本语言,所以你能够在插入一种语言的驱动(language driver)以后来写基于这种语言的动态 SQL 查询好比mybatis除了XML格式外,还提供了mybatis-velocity,容许使用velocity表达式编写SQL语句。能够经过实现LanguageDriver接口的方式来插入一种语言。 能够不设置 |
一个类型别名或彻底限定类名。 |
org.apache.ibatis.scripting.xmltags.XMLLanguageDriver |
defaultEnumTypeHandler |
指定 Enum 使用的默认 TypeHandler 。 (从3.4.5开始) |
默认的EnumTypeHandler存入数据库的是枚举的name, mybatis还提供了EnumOrdinalTypeHandler存入数据库的是枚举的位置。 这俩都不太好用,若是想要把数据库查询结果与枚举自动转换,能够自定义typeHandler来实现。在查询或操做数据时以枚举传输优点并不大,只提供对应的枚举也可知足需求。 能够不设置 |
一个类型别名或彻底限定类名。 |
org.apache.ibatis.type.EnumTypeHandler |
callSettersOnNulls |
指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 null 的。 |
假设将数据从DB中查询出来若是将字段映射为Map,而不想封装成Bean。默认状况下,Mybatis对Map的解析生成, 若是值(value)为null的话,那么key也不会被加入到map中. 能够不设置 |
true | false |
false |
returnInstanceForEmptyRow |
当返回行的全部列都是空时,MyBatis默认返回null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集 (i.e. collectioin and association)。(从3.4.2开始) |
查询结果没有的时候,返回null是合理的,返回一个空对象容易引发误会。 不要设置 |
true | false |
false |
logPrefix |
指定 MyBatis 增长到日志名称的前缀。 |
日志前缀,要不要看我的喜爱。 能够不设置 |
任何字符串 |
Not set |
logImpl |
指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 |
不要设置 |
SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING |
Not set |
vfsImpl |
指定VFS的实现 |
VFS主要用来加载容器内的各类资源,好比jar或者class文件。mybatis提供了2个实现 JBoss6VFS 和 DefaultVFS,并提供了用户扩展点,用于自定义VFS实现,加载顺序是自定义VFS实现 > 默认VFS实现 取第一个加载成功的,默认状况下会先加载JBoss6VFS,若是classpath下找不到jboss的vfs实现才会加载默认VFS实现。 |
自定义VFS的实现的类全限定名,以逗号分隔。 |
Not set |
useActualParamName |
容许使用方法签名中的名称做为语句参数名称。 为了使用该特性,你的工程必须采用Java 8编译,而且加上-parameters选项。(从3.4.1开始) |
mybatis的全局配置useActualParamName决定了mapper中参数的写法,默认为true。此时无需再使用@Param。 Order getOrderByCondition (Long id,Long addressId) <select id="getOrderByCondition" resultType="Order" > select * from t_order where id = #{id} and addressId = #{addressId} </select> 若是是false那么可写成 <select id="getOrderByCondition" resultType="Order" > select * from t_order where id = #{0} and addressId = #{1} </select> 使用这个特性必须在jdk1.8场景。这是由于:在Java 8以前的版本,代码编译为class文件后,方法参数的类型是固定的,但参数名称却丢失了,这和动态语言严重依赖参数名称造成了鲜明对比。如今,Java 8开始在class文件中保留参数名,给反射带来了极大的便利。jdk8增长了类Parameter。 能够不设置 |
true | false |
true |
configurationFactory |
指定一个提供Configuration实例的类。 这个被返回的Configuration实例用来加载被反序列化对象的懒加载属性值。 这个类必须包含一个签名方法static Configuration getConfiguration(). (从 3.2.3 版本开始) |
此时mybatis全局的Configuration将被开发者手动指定。 建议不设置 |
类型别名或者全类名. |
Not set |
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,原理是用hashMap关联,存在的意义仅在于用来减小类彻底限定名的冗余。例如:
<!-- mybatis-config.xml --> <typeAliases> <typeAlias alias="OrderMain" type="order.center.domain.OrderMain"/> </typeAliases> <!-- mybatis-config.xml --> <typeAliases> <package name="order.center.domain"/> </typeAliases>
不管是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,仍是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。
能够重写类型处理器或建立你本身的类型处理器来处理不支持的或非标准的类型。 具体作法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 而后能够选择性地将它映射到一个 JDBC 类型。
下面是一个处理javaType=com.alibaba.fastjson.JSON时的例子
public class ExampleTypeHandler extends BaseTypeHandler<JSON> { @Override public void setNonNullParameter(PreparedStatement ps, int i, JSON parameter, JdbcType jdbcType) throws SQLException { ps.setString(i,parameter.toJSONString()); } @Override public JSON getNullableResult(ResultSet rs, String columnName) throws SQLException { return JSON.parseObject(rs.getString(columnName)); } @Override public JSON getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return JSON.parseObject(rs.getString(columnIndex)); } @Override public JSON getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return JSON.parseObject(cs.getString(columnIndex)); } }
<!-- mybatis-config.xml --> <typeHandlers> <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/> </typeHandlers>
<!-- Ordermapper.xml中使用 --> <result column="order_json" typeHandler="org.mybatis.example.ExampleTypeHandle" jdbcType="VARCHAR" property="orderJson" />
MyBatis 每次建立结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂须要作的仅仅是实例化目标类,要么经过默认构造方法,要么在参数映射存在的时候经过参数构造方法来实例化。 若是想覆盖对象工厂的默认行为,则能够经过建立本身的对象工厂来实现。好比:
// ExampleObjectFactory.java public class ExampleObjectFactory extends DefaultObjectFactory { public Object create(Class type) { return super.create(type); } public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) { return super.create(type, constructorArgTypes, constructorArgs); } public void setProperties(Properties properties) { super.setProperties(properties); } public <T> boolean isCollection(Class<T> type) { return Collection.class.isAssignableFrom(type); } }
<!-- mybatis-config.xml --> <objectFactory type="org.mybatis.example.ExampleObjectFactory"> <property name="someProperty" value="100"/> </objectFactory>
通常状况不多会使用到自定义ObjectFactory,若是须要使用的话,建议是在对象建立时须要作一些操做,或前或后,用于改变或者丰富被建立对象。
最新的官方文档中已经找不到这个配置项。原用来提供自定义的ObjectWrapper
MyBatis 容许你在已映射语句执行过程当中的某一点进行拦截调用。默认状况下,MyBatis 容许使用插件来拦截的方法调用包括:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)
这些类中方法的细节能够经过查看每一个方法的签名来发现,或者直接查看 MyBatis 发行包中的源代码。 若是你想作的不只仅是监控方法的调用,那么你最好至关了解要重写的方法的行为。 由于若是在试图修改或重写已有方法的行为的时候,你极可能在破坏 MyBatis 的核心模块。 这些都是更低层的类和方法,因此使用插件的时候要特别小心。
经过 MyBatis 提供的强大机制,使用插件是很是简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名便可。
例如配置pageHelper:
<!-- mybatis-config.xml --> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="mysql"/> <property name="offsetAsPageNum" value="false"/> <property name="rowBoundsWithCount" value="false"/> <property name="pageSizeZero" value="true"/> <property name="reasonable" value="false"/> <property name="supportMethodsArguments" value="false"/> <property name="returnPageInfo" value="none"/> </plugin> </plugins>
MyBatis 能够配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实状况下有多种理由须要这么作。例如,开发、测试和生产环境须要有不一样的配置;或者共享相同 Schema 的多个生产数据库, 想使用相同的 SQL 映射。许多相似的用例。
不过要记住:尽管能够配置多个环境,每一个 SqlSessionFactory 实例只能选择其一。
因此,若是你想链接两个数据库,就须要建立两个 SqlSessionFactory 实例,每一个数据库对应一个。而若是是三个数据库,就须要三个实例,依此类推,记起来很简单:
每一个数据库对应一个 SqlSessionFactory 实例
为了指定建立哪一种环境,只要将它做为可选的参数传递给 SqlSessionFactoryBuilder 便可。能够接受环境配置的两个方法签名是:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
若是忽略了环境参数,那么默认环境将会被加载,以下所示:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
环境元素定义了如何配置环境。
<!-- mybatis-config.xml --> <environments default="development"> <environment id="development"> <!--Mybatis管理事务是分为两种方式: (1)使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事务的提交 (2)使用MANAGED的事务管理机制,这种机制mybatis自身不会去实现事务管理,而是让程序的容器(JBOSS,WebLogic)来实现对事务的管理 --> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!-- 能够直接用properties也能够在这配 --> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> <environment id="test"> <!-- mybatis提供的区分不一样环境的数据库链接配置 --> </environment> </environments>
MyBatis 能够根据不一样的数据库厂商执行不一样的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的全部语句。 若是同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。 为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 便可:
咱们实际使用中,不一样数据库大几率是不一样数据源,很低几率出现同一个mapper两种数据库使用,所以这个配置项几乎不可能用上。
<!-- mybatis-config.xml --> <databaseIdProvider type="DB_VENDOR"> <property name="SQL Server" value="sqlserver"/> <property name="DB2" value="db2"/> <property name="Oracle" value="oracle" /> <property name="Mysql" value="mysql" /> </databaseIdProvider>
<!-- mapper.xml --> <insert id="insertTest" ...> INSERT INTO users(name, age) VALUES('zhangsan', 1), ('wangwu', 2), ('zhaoliu', 3); </insert> <insert id="insertTest" ... databaseId="oracle"> INSERT ALL INTO users VALUES('zhangsan', 1) INTO users VALUES ('wangwu', 2) INTO users VALUES ('zhaoliu', 3); </insert>
既然 MyBatis 的行为已经由上述元素配置完了,咱们如今就要定义 SQL 映射语句了。可是首先咱们须要告诉 MyBatis 到哪里去找到这些语句。 Java 在自动查找这方面没有提供一个很好的方法,因此最佳的方式是告诉 MyBatis 到哪里去找映射文件。你可使用相对于类路径的资源引用, 或彻底限定资源定位符(包括 file:/// 的 URL),或类名和包名等。例如:
<!-- mybatis-config.xml 使用spring后能够在sqlSessionFactory里配置*.xml--> <mappers> <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> <mapper resource="org/mybatis/builder/BlogMapper.xml"/> <mapper resource="org/mybatis/builder/PostMapper.xml"/> </mappers>
<!-- mybatis-config.xml 此方法mapper接口和xml必须同名放在一块儿--> <mappers> <package name="org.mybatis.builder"/> </mappers>
<!-- mybatis-config.xml 绝对路径,不可用--> <mappers> <mapper url="file:///var/mappers/AuthorMapper.xml"/> <mapper url="file:///var/mappers/BlogMapper.xml"/> <mapper url="file:///var/mappers/PostMapper.xml"/> </mappers>