MyBatis配置文件要素
<?xml version="1.0" encoding="UTF-8"?>
<configuration><!--配置-->
<properties/><!--属性-->
<settings/><!--设置-->
<typeAliases/><!--类型命名-->
<typeHandlers/><!--类型处理器-->
<objectFactory/><!--对象工厂-->
<plugins/><!--插件-->
<environments><!--配置环境-->
<environment><!--环境变量-->
<transactionManager/><!--事务管理器-->
<dataSource/><!--数据源-->
</environment>
</environments>
<databaseIdProvider/><!--数据库厂商标识-->
<mappers/><!--映射器-->
</configuration>
<!--MyBatis配置项的顺序不能颠倒,如果颠倒他们的顺序,会导致MyBatis启动阶段发生异常,程序无法运行-->
properties属性
properties属性可以给系统配置运行参数,可以放在XML文件或者properties文件中,而不是放在Java编码中,这样的好处在于方便参数修改,而不会引起代码的重新编译,
一般而言,MyBatis提供了三种方式让我们使用properties,他们是:
property子元素
properties文件
程序代码传递
使用property子元素将数据库连接的相关配置进行改写如下:
<?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>
<properties>
<property name="database.driver" value="com.mysql.jdbc.Driver"/>
<property name="database.url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="database.username" value="root"/>
<property name="database.password" value="123456"/>
</property>
<typeAliases><!--别名-->
<typeAlias alias="role" type="com.learn.ssm.chapter3.pojo.Role"/>
</typeAliases>
<!--数据库环境-->
<environments default="development">
<environment id="developent">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</dataSource>
</environment>
</environments>
<!--映射文件-->
<mapper>
<mapper resource="com/learn/ssm/chapter3/mapper/RoleMapper.xml"/>
</mapper>
</configuration>
<!--这里用了元素<properties>下的子元素<property>定义,用字符串database.username定义数据库用户名,然后就可以在数据库定义中引入这个已经定义好的属性参数,如${database.username},这样定义一次就可以到处引用了,但是如果属性参数有成百上千个用这种方式就不是很好的选择,这个时候就可以使用properties文件-->
使用properties文件
使用properties文件是比较普遍达到方法,一方面这个文件十分简单,其逻辑就是键值对应,我们可以配置多个键值放在一个properties文件中,也可以把多个键值放在多个properties文件中,这些都是可以允许的,它方便日后维护和修改
我们创建一个jdbc.properties放到classpath的路径下,如下:
database.driver=com.mysql.Driver
database.url=jdbc:mysql://localhost:3306/ssm
database.username=root
database.password=123456
在MyBatis中通过<properties>的属性resource来引入properties文件
<properties resource="jdbc.properties"/>
也可以按${database.username}的方法引入properties文件的属性参数到MyBatis配置文件中,通过维护properties文件就可以维护我们的配置内容了.
使用程序传递方式传递参数
String resource = "mybatis-config.xml";
InputStream inputStream;
InputStream in = Resources.getResourceAsStream("jdbc.properties");
properties props = new Properties();
props.load(in);
String username = props.getProperty("database.username");
String password = props.getProperty("database.password");
//解密用户和密码,并在属性中重置
props.put("database.username",CodeUtils.decode(username));
props.put("database.password",CodeUtils.decode(password));
inputStream = Resources.getResourceAsStream(resource);
//使用程序传递的方式覆盖原有的properties属性参数
SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,props);
首先使用Resources对象读取了一个jdbc.propertiesprize配置文件,然后获取了它原来配置的用户和密码,进行解密重置,最后使用SqlSessionFactoryBuilder的build方法,传递多个properties参数来完成.这将覆盖之前配置的秘文,这样就能连接数据库了,同时也满足了运维人员对数据库用户和密码安全的要求.
MyBatis使用properties的三种方式,这三种方式是有优先级的,最优先的是使用程序传递的方式,其次是使用properties的文件的方式,最后是properties子元素的方式,MyBatis会根据优先级来覆盖原先配置的属性值.
settings设置
settings是MyBatis中最复杂的配置,它能深刻影响MyBatis底层的运行,但是在大部分情况下使用默认值便可以运行,所以大部分情况下不需要大量配置它,只需要修改一些常用的规则即可,比如自动映射,驼峰命名映射,级联规则,是否启动缓存,执行器(Executor)类型等.settings配置项说明如下:
配置项 | 作用 | 配置选项说明 | 默认值 |
cacheEnabled | 该i配置影响所有映射器中配置缓存的全局开关 | true|false | true |
lazyLoadingEnabled | 延迟加载的全局开关.开启时,所以关联对象都会延迟加载.在特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 | true|false | false |
aggressiveLoading | 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载,反之,每种属性将会按需加载 | true|false | 版本3.4.1(不包括)true |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动) | true|false | true |
useColmnLabel | 使用列标签代替列名.不同的驱动会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用的驱动的结果 | true|false | true |
useGeneratedKeys | 允许JDBC支持自动生成主建,需要驱动兼容.如果设置为true,则这个设置强制使用自动生成主建,尽管一些驱动不能兼容但仍可正常工作(比如Derby) | true|false | false |
autoMappingBehavior | 指定MyBatis应如何自动映射列到字段或属性.NONE表示取消自动映射,PARTIAL表示只会自动映射,没有定义嵌套结果集和映射结果集.FULL会自动映射任意复杂结果集(无论是否嵌套) | NONE,PARTIAL,FULL | PARTIAL |
autoMappingUnKnownColumnBehavior | 指定自动映射当中未知列(或未知属性类型)时的行为.默认是不处理,只有当日志级别达到WARN级别或者以下,才显示相关日志,如果处理失败会抛出SqlSessionException异常 | NONE,WARNING,FAILING | NONE |
defaultExecutorType | 配置默认的执行器.SIMPLE是普通的执行器,REUSE会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 | SIMPLE,REUSE,BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数 | 任何正整数 | Not Set(null) |
defaultFetchSize | 设置数据库驱动程序默认返回的条数限制,此参数可以重新设置 | 任何正整数 | Not Set(null) |
safaRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds).如果允许,设置false | true|false | false |
safeResultHandlerEnabled | 允许在嵌套语句中使用分页(ResultHandler).如果允许,设置false | true|false | true |
mapUnderscoreToCamelCase | 是否开启驼峰命名规则映射,即从经典数据库列名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 | NULL,VARCHAR,OTHER | OTHER |
lazyLoadTriggerMethods | 指定那个对象的方法触发一次延迟加载 | - | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定动态sql生成的默认语言 | - | org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver |
callSettersOnNulls | 指定当结果集中值为null时,是否调用映射对象的setter(map对象为put)方法,这对于有Map.keySet()依赖或null值初始化时是有用的.注意,基本类型(int,boolean等)不能设置成null | true|false | false |
logPrefix | 指定MyBatis增加到日志名称的前缀 | 任何字符串 | Not set |
logImpl | 指定MyBatis所用日志的具体实现,未指定时将自动查找 | SLF4|LOG4J|LOG4J2|JDK_LOGGING|COMMONS_LOGGING|STDOUT_LOGGING|NO_LOGGING | Not set |
proxyFactory | 指定MyBatis创建具有延迟加载能力的对象所用到的代理工具 | CGLIB|JAVASSIST | JAVASSIST(MyBatis版本为3.3及以上的) |
vfsImpl | 指定VFS的实现类 | 提供VFS类的全限定名,如果存在多个,可以使用逗号分隔 | Not set |
useActualParamName | 允许用方法参数中声明的实际名称引用参数.要使用此功能,项目必须被编译为Java8参数的选择.(从版本3.4.1开始可以使用) | true|false | true |
settings的配置样例
<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别名
由于类的全限定名称很长,需要大量使用的时候,总写这么长的名称很不方便.在MyBatis中允许一个简写来代表这个类,这就是别名,别名分别为系统定义别名和自定义别名.在MyBatis中别名由类TypeAliasRegistry(org.apache.ibatis.type.TypeAliasRegistry)去定义.在MyBatis中不分大小写.
别名 | java类型 | 是否支持数组 |
_byte | byte | 是 |
_long | long | 是 |
_short | short | 是 |
_int | int | 是 |
_integer | integer | 是 |
_double | double | 是 |
_float | float | 是 |
_booleam | booleam | 是 |
string | String | 是 |
byte | byte | 是 |
long | long | 是 |
short | short | 是 |
int | Integer | 是 |
integer | Integer | 是 |
double | Double | 是 |
date | Date | 是 |
arraylist
ArrayList否collectionCollection否iteratorIterator否ResultSetResultSet否如果需要使用对应类型的数字型,要看能否支持数据,如果支持只需要使用别名加[]即可,比如_int数组的别名就是_int[].而类似list这样不支持数组的别名,则不能那么写.有时需要通过代码来注册别名.
TypeAliasRegistry初始化别名
public TypeAliasRegistry(){
registerAlias("string",String.class);
registerAlias("byte",Byte.class);
registerAlias("long",long.class);
registerAlias("byte[]",Byte[].class);
registerAlias("long[]",long[].class);
}
Configuration配置的别名
//事务的别名
typeAliasRegistry.registerAlias("JDBC",JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED"mANAGEDtRANSACTIONfACTORY.CLASS);
//数据源类型别名
typeAliasRegistry.registerAlias("JNDI",JndiDataSourceFactory.class);
typeAliasRegistry.registerAlias("POOLED",PooledDataSourceFactory.class);
typeAliasRegistry.registerAlias("UNPOOLED",UnpooledDataSourceFactory.class);
//缓存策略别名
typeAliasRegistry.registerAlias("PERPETUAL",PerpetualCache.class);
typeAliasRegistry.registerAlias("FIFO",FifoCache.class);
typeAliasRegistry.registerAlias("LRU",LruCache.class);
typeAliasRegistry.registerAlias("SOFT",SoftCache.class);
typeAliasRegistry.registerAlias("WEAK",WeakCache.class);
//数据库标识别名
typeAliasRegistry.registerAlias("DB_VENDOR",VendorDatabaseIdProvider.class);
未完待续!!!