mybatis-config详解5.1 属性,全局设置,别名5.1.1 本章目标
学习使用XML配置文件配置Mybatistis
5.1.2 本节目标详细了解每个属性的作用
5.1.3 mybatis-config.xml介绍以下是mybatis官网关于配置文件的说明
*注:配置项的顺序不能颠倒,如果颠倒了它们的顺序,在MyBatis的自启动阶段就会出现异常,导致程序无法运行。
错误信息为:元素类型 "configuration" 必须匹配内容 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。
5.1.4 properties介绍
这些属性可以在外部配置,也可以动态替换。你可以是典型的 Java 这些属性也可以在xml配置文件中使用 properties property中设置元素的子元素
5.1.5 properties配置数据库参数
<properties > <property name="driver" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/book_system"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </properties>
5.1.6 引用properties,设置默认值
新建db.properties文件,写入以下内容:
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/book_systemusername=rootpassword=123456
<configuration> <properties resource="db.properties"></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> </configuration>
注意这里的要点:
- 默认的环境 ID(比如:default="development")。
- 每个 environment 定义元素的环境 ID(比如:id="development")。
- 事务管理器配置(如:type="JDBC")。
- 数据源配置(例如:type="POOLED")。
默认环境和环境ID是自我解释的,所以一目了然。您可以随意命名环境,但必须确保默认环境 ID 与其中一个环境相匹配 ID。
事务管理器(transactionManager)
在 MyBatis 有两种类型的事务管理器(即 type="[JDBC|MANAGED]”):
- JDBC – 该配置是直接使用的 JDBC 依靠从数据源获得的连接来管理事务功能域的提交和回滚设置。
- MANAGED – 这个配置几乎什么都没做。它从不提交或回滚连接,而是让容器管理整个生命周期(例如 JEE 上下文应用服务器)。 默认情况下,它会关闭连接,但有些容器不想这样做,所以需要 closeConnection 属性设置为 false 阻止其默认关闭。例如:
<transactionManager type="MANAGED"> <property name="closeConnection" value="false"/></transactionManager>
数据源(dataSource)
dataSource 标准元素使用 JDBC 配置数据源接口 JDBC 连接对象的资源。
- 许多 MyBatis 应用程序将根据示例中的例子配置数据源。虽然这是可选的,但必须配置数据源才能使用延迟加载。
内部建设的数据源有三种类型(即 type=[UNPOLED|POOLED|JNDI]”):
UNPOOLED– 这个数据源的实现只是在每次被要求时打开和关闭连接。虽然有点慢,但对于数据库连接可用性要求不高的简单应用程序来说,这是一个不错的选择。 不同数据库的性能也不同。对于一些数据库来说,使用连接池并不重要。这种配置非常适合这种情况。UNPOOLED 只需配置以下类型的数据源 5 种属性:
driver
– 这是 JDBC 驱动的 Java 类别的完全限定名(不是 JDBC 可能包含在驱动中的数据源类)。url
– 这是数据库 JDBC URL 地址。username
– 用户名登录数据库。password
– 登录数据库密码。defaultTransactionIsolationLevel
– 默认连接事务隔离级别。
作为可选项,您还可以将属性传递给数据库驱动。要这样做,属性的前缀是“driver.”,例如:
driver.encoding=UTF8
这将通过 DriverManager.getConnection(url,driverProperties) 方法传递值为 UTF8
的 encoding
属性驱动数据库。
POOLED– 利用“池”的概念实现这种数据源 JDBC 组织连接对象,避免创建新的连接实例所需的初始化和认证时间。 这是并发的一种 Web 应用快速响应请求的流行处理方法。
除上述提到外 UNPOOLED 除了下属性,还有更多的属性用于配置 POOLED 的数据源:
poolMaximumActiveConnections
– 任何时候可以存在的活动(即正在使用)的连接数量,默认值:10poolMaximumIdleConnections
– 空闲连接数可能存在于任何时间。poolMaximumCheckoutTime
– 在被迫返回之前,检测到了池中的连接(checked out)时间,默认值:2万 毫秒(即 20 秒)poolTimeToWait
– 这是一个底层设置。如果需要很长时间才能获得连接,连接池将打印状态日志,并尝试重新获得连接(避免在错误配置的情况下安静失败)。默认值:2万 毫秒(即 20 秒)。poolMaximumLocalBadConnectionTolerance
– 这是关于坏连接容忍度的底层设置, 作用于每个试图从缓存池获得连接的线程. 如果线程获得了一个坏的连接,那么数据源允许线程尝试重新获得一个新的连接,但重新尝试的次数不应该超过poolMaximumIdleConnections
与poolMaximumLocalBadConnectionTolerance
之和。 默认值:3 (新增于 3.4.5)poolPingQuery
– 将检测查询发送到数据库,以检查连接是否正常工作,并准备接受请求。默认情况是“NO PING QUERY SET当大多数数据库驱动失败时,就会出现适当的错误消息。poolPingEnabled
– 是否启用检测查询。如果打开,需要设置poolPingQuery
属性是可执行的 SQL 句子(最好是速度很快的句子) SQL 语句),默认值:false。poolPingConnectionsNotUsedFor
– 配置 poolPingQuery 频率。可以设置为与数据库连接时间相同,以避免不必要的检测。默认值:0(即每时每刻检测所有连接 — 当然仅当 poolPingEnabled 为 true 时适用)。
JNDI – 实现这个数据源的目的是如 EJB 或者使用服务器等容器,容器可以集中或配置外部数据源,然后放置一个 JNDI 引用上下文。这种数据源配置只需要两个属性:
initial_context
– 这个属性是用来在的 InitialContext 中搜上下文(即,initialContext.lookup(initial_context))。这是一个可选的属性,如果被忽略,那么 data_source 属性将直接从 InitialContext 中寻找。data_source
– 这是引用数据源实例位置的上下文路径。它提供了 initial_context 配置将在其返回的上下文中找到,如果不提供,则直接在 InitialContext 中查找。
类似于其他数据源配置,可以添加前缀“env.“直接将属性传递给初始上下文。例如:
env.encoding=UTF8
这将是初始上下文(InitialContext)实例化时,其结构方法的传递值为 UTF8
的 encoding
属性。
从 MyBatis 3.4.2 一开始,你可以为占位符指定一个默认值。例如:
<property name="username" value="${username:root}"/> <!-- 如果属性 'username' 没有配置,"username' 属性值将是 'root' -->
默认情况下,这一特征是关闭的。要使用这一特性,需要添加一个特定的属性来打开这一特性。例如:
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- 使用默认值特性 -->
5.1.7 settings介绍及功能
这是 MyBatis 它们的配置非常重要,因为它们会改变 MyBatis 运行时的行为。
5.1.8 settings中可配置的属性介绍(参考官网)- cacheEnabled
- lazyLoadingEnabled
- aggressiveLazyLoading
- multipleResultSetsEnabled
- useColumnLabel使用列标签代替列。不同的驱动程序在这方面会有不同的性能,可以参考相关的驱动程序文档或通过测试这两种不同的模式来观察驱动程序的结果。
- useGeneratedKeys允许 JDBC 需要驱动兼容性来支持主键的自动生成。如果设置为 true 这个设置强制使用自动生成主键,虽然有些驱动不能兼容,但仍然可以正常工作(例如 Derby)。
- autoMappingBehavior指定 MyBatis 是否以及如何自动映射指定的字段或属性。NONE 表示取消自动映射;PARTIAL 嵌套结果集映射的结果集只能自动映射。FULL 任何复杂的结果集(包括嵌套和其他情况)都会自动映射。
- autoMappingUnknownColumnBehavior
- defaultExecutorType配置默认执行器。SIMPLE 是普通的执行器;REUSE 执行器将重用预处理语句(prepared statements);BATCH 执行器将重用语句并批量更新。
- defaultStatementTimeout设置超时间,它决定驱动等待数据库响应的秒数。
- defaultFetchSize
- safeRowBoundsEnabled
- safeResultHandlerEnabled
- mapUnderscoreToCamelCase自动驼峰命名规则是否打开?(camel case)映射是从经典数据库中排名的 A_COLUMN 到经典 Java 属性名 aColumn 类似映射。开启:
<setting name="mapUnderscoreToCamelCase" value="true"/>
未开启:
- localCacheScope
- jdbcTypeForNull
- lazyLoadTriggerMethods
- defaultScriptingLanguage
- defaultEnumTypeHandler
- callSettersOnNulls
- returnInstanceForEmptyRow
- logPrefix
- logImpl指定 MyBatis 未指定时自动搜索使用日志的具体实现。
<setting name="logImpl" value="STDOUT_LOGGING" />
开启后效果
- proxyFactory
- useActualParamName
- configurationFactory
<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="logImpl" value="STDOUT_LOGGING" /> <setting name="mapUnderscoreToCamelCase" value="true"/> <setting name="localCacheScope" value="SESSION"/> <setting name="jdbcTypeForNull" value="OTHER"/> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/></settings>
5.1.10 设置别名
类型别名是为 Java 类型命名的短名。它只和谐 XML 与配置相关,存在的意义仅在于减少类别完全限定名的冗余。
Mybatis已经定义了别名
5.1.11 演示效果
<typeAliases> <typeAlias type="com.study.pojo.Book" alias="book" /> </typeAliases> <select id="getBookList" resultType="book"> SELECT * FROM book </select>
5.2 5.2类型转换器.1 本节目标
了解Mybatis内置的类型转换器,学习定制Mybatis类型转换器
5.2.1 介绍类型转换器作为ORM框架,mybatis要求java中的对象与数据库中的表记录相对应。因此,java类名-数据库表名、java类属性名-数据库表字段名、java类属性类型-数据库字段类型前两种容易设置,但第三个要求往往是java类型和数据库存储类型不同, 比如java类型是String,存储在数据库中的charr、varchar、text
对于一般常见的类型对应,mybatis已经包含了类型转换器,使String类型的java属性可以直接插入数据库,也可以直接从数据库中取出直接赋值给对象的属性
5.2.2 TypeHandler定义Mybatis系统5.2.2.1 TypeHandler5.2.2.2 mybatis支持的jdbctype转换为javatype对应关系
JDBC Type Java Type
- CHAR String
- VARCHAR String
- LONGVARCHAR String
- NUMERIC java.math.BigDecimal
- DECIMAL java.math.BigDecimal
- BIT boolean
- BOOLEAN boolean
- TINYINT byte
- SMALLINT short
- INTEGER int
- BIGINT long
- REAL float
- FLOAT double
- DOUBLE double
- BINARY byte[]
- VARBINARY byte[]
- LONGVARBINARY byte[]
- DATE java.sql.Date
- TIME java.sql.Time
- TIMESTAMP java.sql.Timestamp
- CLOB Clob
- BLOB Blob
- ARRAY Array
- DISTINCT mapping of underlying type
- STRUCT Struct
- REF Ref
- DATALINK java.net.URL[color=red][/color]
<select id="getBookList_resultMap" resultMap="resultData"> SELECT * FROM book </select> <resultMap id="resultData" type="book" > <result property="bookId" column="book_id" javaType="int" jdbcType="INTEGER"/> <result property="bookName" column="book_name" javaType="string" jdbcType="VARCHAR"/> <result property="publishDate" column="publish_date" javaType="java.sql.Date" jdbcType="DATE"/> <result property="publishHouse" column="publish_house" javaType="string" jdbcType="VARCHAR"/> <result property="author" column="author" javaType="string" jdbcType="VARCHAR"/> <result property="price" column="price" javaType="double" jdbcType="DOUBLE"/> </resultMap>
5.2.5 Mybatis自定义TypeHandler
MyTypeHandler需要创建我们自己的类型转换类型
实现org.apache.ibatis.type.TypeHandler接口或继承org.apache.ibatis.type.Basetypehandler
5.2.6 如何将数据库类型转换为枚举类型?Mybatis默认提供了两种Enum类型的handler:EnumtypeHandlerEnumOrdinalTypeHandler。
- EnumTypeHandler:根据String将enum存入库中,存储为varchar类型;
- EnumOrdinalTypeHandler:根据Integer将enum存储为inter(smallint、tinyint也可以)。
public enum GenderTypeEnum { /** * female */ FEMALE(0,“女”), /** * male */ MALE(1,“男”), /** * unknown */ UNKNOWN(2,“未知”); private int value; private String desc; GenderTypeEnum(int value, String desc) { this.value = value; this.desc = desc; } public int value(){ return this.value; } public String desc(){ return this.desc; }}
5.2.8 编写自定义类型转换器
public class MyTypeHandler implements TypeHandler { /** * 该方法是插入并设置参数 * 参数:PreparedStatement * 当JDBC预编译时,inti为JDBC设置索引值 * Object obj要插入的参数值 * JdbcType JDBC类型的JDBCType插入JDBC */ @Override public void setParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException { if( o == null){ preparedStatement.setInt(i,0); } Boolean par = (Boolean)o; if(par){ preparedStatement.setInt(i, 1); }else{ preparedStatement.setInt(i, 0); } } @Override public Object getResult(ResultSet resultSet, String s) throws SQLException { int flag = resultSet.getInt(s); Boolean b = Boolean.FALSE; if(flag == 1){ b = Boolean.TRUE; } return b; } @Override public Object getResult(ResultSet resultSet, int i) throws SQLException { return null; } @Override public Object getResult(CallableStatement callableStatement, int i) throws SQLException { return null; }}public class MytypeHandler extends BaseTypeHandler { @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException { if( o == null){ preparedStatement.setInt(i,0); } Boolean par = (Boolean)o; if(par){ preparedStatement.setInt(i, 1); }else{ preparedStatement.setInt(i, 0); } } @Override public Object getNullableResult(ResultSet resultSet, String s) throws SQLException { int flag = resultSet.getInt(s); Boolean b = Boolean.FALSE; if(flag == 1){ b = Boolean.TRUE; } return b; } @Override public Object getNullableResult(ResultSet resultSet, int i) throws SQLException { return null; } @Override public Object getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return null; }}
现在我们需要最后一步来注册定制类型转换器(在接口编程中,我们需要注册许多实现或集成人的接口或实现类,这样程序就会知道哪个实现类是运行)。
5.2.9 注册类型转换器在核心配置文件中添加注册类型转换器有两种方式:1、全局注册:
<typeHandlers> <typeHandler handler="com.study.typehandler.MyTypeHandler" javaType="Boolean" jdbcType="BIGINT" /> </typeHandlers>
这种配置的作用域是全局的,也就是说,在我们写的所有Mapper中,当满足Java类型是bolean数据库类型是number或int时(满足这个条件) javaType=“Boolean” jdbcType=“BIGINT” ),这个MyTypeHandler将被执行。
2.将resultmap标签局部注册在相应的Mapper文件中:
<select id="getBorrowInfoList" resultType="borrowInfo" resultMap="borrowInfoMap"> SELECT * FROM borrow_info </select> <resultMap id="borrowInfoMap" type="borrowInfo"> <result property="borrowState" column="borrow_state" typeHandler="com.study.typehandler.MyTypeHandler"/> </resultMap>
如果您注册了TypeHandler。在Mapper.xml只需声明jdbctype和javatype,不需要声明具体的typeHandler。mybatis将自动通过jdbctype、javatype映射到特定注册的TypeHandler上
<result property="borrowState" column="borrow_state" javaType="Boolean" jdbcType="BIGINT"/>
5.2.10 5.2指定类型转换.11 演示