3、mybatis配置解析
核心配置文件
configuration:配置,配置文件的根节点
properties:属性
settings:设置
typeAliases:类型别名
typeHandlers:类型处理器
objectFactory:对象工厂
plugins:插件
environments:环境
environment:环境变量
transactionManager:事务管理器
dataSource:数据源
mappers:映射器
environments
<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://localhost:3306/mybatis?useSSL=true&characterEncoding=utf8&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="mysql"/>
</dataSource>
</environment>
</environments>
- 配置Mybatis的多套运行环境,将sql映射到多个不同的数据库上,必须制定其中一个为默认运行环境,通过default制定
- 子元素节点:environment
- dataSource元素使用标准的JDBC数据源接口来配置JDBC连接对象的资源
- 数据必须配置
- 有三中内建的数据类型
type="[UNPOOLED|POOLED|JNDI]"
- unpooled:这个数据源的实现只是每次被请求时打开和关闭连接
- pooled:这种数据源的实现利用池的概念将JDBC连接对象组织起来,这使得并发Web应用快速响应请求的流行处理方式
- jndi:为了能在如spring或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文应用
- 数据源也有很多其他第三方的实现,如dbcp,c3p0,druid等
- 具体的一套环境,通过设置id进行区分,id保证唯一
- 子元素节点:transactionManager事务管理
<transactionManager type="[JDBC|MANAGED]"/>
- 子元素节点:dataSource数据源
mappers
- 映射器:定义映射sql的语句
引入资源的方式:
<!--使用相对类路径引入-->
<mappers>
<mapper resource="com/test/dao/UserDao.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<!--
将包内的映射器接口实现全部注册为映射器
但是需要配置文件名称和接口名称一致,并且位于同一目录下
-->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
Mapper文件
<?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.test.dao.UserDao">
</mapper>
- namespace,命名空间
- namespace的命名必须为某个接口的全限定名
- 接口中的方法与映射文件中sql语句的id一一对应
properties文件
数据库连接的一些属性可以通过外部配置动态替换,就可以在典型的java属性文件中配置,也可以通过properties元素的子元素来配置
- 资源目录下引入db.properties文件
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8 username=root password=123456
- 将上述文件导入properties配置文件
<configuration> <!--导入properties文件--> <properties resource="db.properties"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <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> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers> </configuration>
注:properties文件不识别'''&'''字符,应替换为'''&'''符号
typeAliases
类别名设置,用于减少类全限定名称的冗余
<!--单独配置-->
<typeAliases>
<typeAlias type="com.test.po.User" alias="User"/>
</typeAliases>
<!--包配置-->
<typeAliases>
<package name="com.test.po"/>
</typeAliases>
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>
- cacheEnabled 全局性开启或关闭所有映射器配置文件已配置的任何缓存 true/false
- lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。 true/false
- aggressiveLazyLoading 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。否则,每个延迟加载苏醒会按需加载。 true/false
- multipleResultSetsEnabled 是否允许单个语句返回多结果集,需要数据库驱动支持。 true/false
- useColumnLabel 使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档。 true/fasle
- useGeneratedKeys 允许JDBC支持自动生成主键,需要数据库驱动支持。如果设置为true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作。 true/false
- autoMappingBehavior 指定Mybatis应如何自动映射列到字段或属性。NONE表示关闭自动映射;PARTIAL只会自动映射没有定义嵌套结果映射的字段。FULL会自动映射任何复杂的结果集。 NONE|PARTIAL|FULL
- autoMappingUnknownColumnBehavior 指定发现自动映射目标未知列或未知属性类型的行为。 NONE|WARNING|FAILING
- NONE 不做任何反应
- WARNING 输出警告日志
'org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN - FAILING 映射失败
抛出 SqlSessionException
- defaultExecutorType 配置默认的执行器。 SIMPLE|REUSE|BATCH
- SIMPLE 普通的执行器
- REUSE 执行器会重用预处理语句PreparedStatement
- BATCH 执行器不仅重用语句还会执行批量更新。
- defaultStatementTimeout 设置超时时间,决定数据库驱动等待数据库响应的秒数。 任意正整数
- defaultFetchSize 为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数还可以在查询设置中被覆盖。 任意正整数
- defaultResultSetType 指定语句默认的滚动策略。 FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE|DEFAULT(等同于未设置)
- safeRowBoundsEnabled 是否允许嵌套语句中使用分页(RowBounds)。如果允许使用则设置为false。 true/false
- safeResultHandlerEnabled 是否允许在嵌套语句中使用结果处理器。如果允许使用则设置为false。 true/false
- mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从A_B映射到aB。 true/false
- localCacheScope Mybatis利用本地缓存机制防止循环引用和加速重复的嵌套查询。默认值为SESSION,会缓存一个会话中执行的所有查询。若设置值为STATEMENT,本地缓存将仅用于执行语句,对相同SqlSession的不同查询将不会进行缓存。 SESSION/STATEMENT
- jdbcTypeForNull 当没有为参数指定特定的JDBC类型时,空值的默认JDBC类型。某些数据库驱动需要指定列的JDBC类型,多数情况直接用一般类型即可,比如NULL,VARCHAR或OTHER。
- lazyLoadTriggerMethods 指定对象的哪些方法触发一次延迟加载。 值为用逗号隔开的方法列表
- defaultScriptingLanguage 指定动态sql生成使用的默认脚本语言。 值为一个类型别名或全限定类名
- defaultEnumTypeHandler 指定Enum使用的默认TypeHandler。 值为一个类型别名或全限定类名
- callSettersOnNulls 指定当结果集中为null的时候是否调用映射对象的setter(map对象时为put)方法,这在依赖于Map.keySet()或null值进行初始化时比较有用。注意基本类型(int,boolean等)是不能设置成null的。 true/false
- returnInstanceForEmptyRow 当返回的所有列都为空时,Mybatis默认返回null。当开启这个设置时,Mybatis会返回一个空实例。请注意,它也适用于嵌套结果集。 true/false
- logPrefix 指定Mybatis增加日志名称的前缀。 值为任意字符串
- logImpl 指定Mybatis所用日志的具体实现,未指定时自动查找。 SLF4J|LOG4J|LOG4J2|JDK_LOGGING|COMMONS_LOGGING|STDOUT_LOGGING|NO_LOGGING
- proxyFactory 指定Mybatis创建可延迟加载对象所用到的代理工具。 CGLIB|JAVASSIST
- vfsImpl 指定VFS的实现。 值为自定义VFS的实现的类全限定名,以逗号分隔
- useActualParamName 允许使用方法标签中的名称作为语句参数名称。为了使用该特性,项目必须采用Java8变异,并加上 -parameters选项。 true/false
- configurationFactory 指定一个提供Configuration实例的类。这个被回的Configuration实例用来加载被反序列化对象的延迟加载属性值。这个类必须包含一个签名为static Configuration getConfiguration()的方法。 值为一个类型别名或完全限定类名
生命周期
- SqlSessionFactoryBuilder的作用在于创建SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder就失去了作用,所以它只能存在于创建SqlSessionFactory的方法中,而不要让其长期存在。因此SqlSessionFactoryBuilder实例的最佳作用域是方法作用域(也就是局部方法变量)。
- SqlSessionFactory可以被认为是一个数据库连接池,它的作用是创建SqlSession接口对象。因为MyBatis的本质就是 Java 对数据库的操作,所以SqlSessionFactory的生命周期存在于整个MyBatis的应用之中,所以一旦创建了SqlSessionFactory,就要长期保存它,直至不再使用MyBatis应用,所以可以认为SqlSessionFactory的生命周期就等同于MyBatis的应用周期。
- 由于SqlSessionFactory是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。
- 因此在一般的应用中我们往往希望SqlSessionFactory作为一个单例,让它在应用中被共享。所以说SqlSessionFactory的最佳作用域是应用作用域。
- 如果说SqlSessionFactory相当于数据库连接池,那么SqlSession就相当于一个数据库连接(Connection对象),你可以在一个事务里面执行多条 SQL,然后通过它的commit、rollback等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用try...catch...finally...语句来保证其正确关闭。
注:该部分内容转自狂神说的Mybatis系列教程