###0.前言
记录MyBatis的配置以及对应的说明
《Java EE互联网轻量级框架整合开发——SSM框架(Spring MVC+Spring+MyBatis)和Redis实现》
MyBatis配置元素:
<configuration> //配置
<properties /> //属性
<settings /> //设置
<typeAliases /> //别名
<typeHandlers /> //类型处理器
<objectFactory /> //对象工厂
<plugins /> //插件
<environments> //环境配置
<environment> //环境变量
<transactionManaager /> //事务管理器
<dataSource /> //数据源
</environment>
</environments>
<databaseIdProvider /> //数据库标识
<mappers /> //映射器
</configuration>
###1.配置节点说明
- configuration:配置顶级节点
- properties:配置运行参数(xml的上下文使用)
- MyBaits的properties节点中(property子元素)
- 外置properties文件
- 代码传入
- settings:MyBatis全局设置
- typeAliases:别名设置,主要是简写类的全限定名称。不区分大小写
- typeHandlers:类型转换器,javaType <=> typeHandler <=> jdbcType(java类型和数据库类型之间的转化)
- objectFactory:对象工厂,创建结果集实例
- plugins:插件
- environments:运行环境配置,配置数据库信息
- environment:单个环境配置实例
- transactionManaager:事务管理器(JDBC、MANAGED)
- dataSource:数据源配置,配置数据库连接策略(POOLED、UNPOOLED、JNDI),连接参数(驱动、url、用户名和密码等)
- databaseIdProvider:数据库标识,多数据库兼容
- mappers:映射器,维护SQL语句,并返回SQL执行后的java对象的结果集。
###2.properties 属性
属性主要是给系统配置一些运行参数,可以放在外部配置文件中,以便参数的修改而不会引起代码的重新编译。
MyBaits的properties节点中(property子元素)
//mybatis-config.xml <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="root"/> </properties> //...省略... <!-- 数据库环境 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="com.learn.ssm.chapter4.datasource.DbcpDataSourceFactory"> <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> //...省略... </configuration>
外置properties文件
//jdbc.properties文件 database.driver=com.mysql.jdbc.Driver database.url=jdbc:mysql://localhost:3306/ssm database.username=root database.password=root //mybatis-config.xml <configuration> <properties resource="jdbc.properties"/> //...省略... <!-- 数据库环境 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="com.learn.ssm.chapter4.datasource.DbcpDataSourceFactory"> <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> //...省略... </configuration>
代码传入
//SqlSessionFactory创建传入,此例子为动态解密数据库用户名和密码 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);
配置优先级:
代码配置 > properties文件 > property子元素
###3.settings 设置
全量配置样例:
<settings>
<setting name="cacheEnabled" value="true" /> <!--映射器缓存开启 -->
<setting name="lazyLoadingEnabled" value="true" /> <!--延时加载开启 -->
<setting name="multipelResultSetsEnabled" value="true" /> <!--单一语句返回多结果集,需兼容驱动 -->
<setting name="useColumnLabel" value="true" /> <!--使用列标签代替列名 -->
<setting name="useGeneratedKeys" value="false" /> <!--允许JDBC自动生成主键,需要驱动兼容 -->
<setting name="autoMappingBehavior" value="PARTIAL" /> <!--指定自动映射行为(NONE、PARTIAL、FULL) -->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING" /> <!--自动映射未知列的行为,WARNING以上有日志 -->
<setting name="defaultExecutorType" value="SIMPLE" /> <!--执行器(SIMPLE、REUSE、BATCH) -->
<setting name="defaultStatementTimeout" value="25" /> <!--驱动等待数据库响应的超时时间 -->
<setting name="defaultFetchSize" value="100" /> <!--数据库驱动默认返回条数限制 -->
<setting name="safeRowBoundsEnabled" value="false" /> <!--允许嵌套语句中使用分页,允许为false -->
<setting name="mapUnderscoreToCamelCase" value="false" /> <!--数据库A_COLUMN自动转java中的驼峰aColumn -->
<setting name="localCacheScope" value="SESSION" /> <!--缓存查询(SESSION、STATEMENT) -->
<setting name="jdbcTypeForNull" value="OTHER" /> <!--为空值指定jdbc类型(OTHER、NULL、VARCHAR)-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" /> <!--指定触发延时加载的方法 -->
</settings>
部分设置属性说明:
- autoMappingBehavior:指定自动映射行为(resultMap、association、collection中的autoMapping可覆盖)
- NONE:取消自动映射
- PARTIAL:只会自动映射没有定义嵌套结果集映射的结果集(如果没有显式定义result标签,不会帮你把结果映射到pojo上)。<默认值>
- FULL:自定映射任意复杂结果集
- autoMappingUnknownColumnBehavior:自动映射未知列时的行为
- NONE:不处理。 <默认值>
- WARNING:显示相关日志
- FAILING:抛出异常SqlSessionException
- defaultExecutorType:默认执行器
- SIMPLE:普通执行器,每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。 <默认值>
- REUSE:重用预处理执行器,执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。
- BATCH:重用语句并执行批量更新。执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
- localCacheScope:利用本地缓存机制防止循环引用和加速重复嵌套查询
- SESSION:会话作用域。<默认值>
- STATEMENT:语句作用域。
- jdbcTypeForNull:当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。
- NULL
- VARCHAR
- OTHER:<默认值>
缓存相关问题(cacheEnabled和localCacheScope的设置问题):
MyBatis缓存 和
MyBatis 缓存机制深度解剖 / 自定义二级缓存
jdbcType对照表
JdbcType | MySql | Oracle | JavaType |
---|---|---|---|
ARRAY | Array | ||
BIGINT | BIGINT | long | |
BINARY | BINARY | byte[] | |
BIT | BIT | BIT | boolean |
CLOB | CLOB | CLOB | Clob |
BLOB | BLOB | BLOB | Blob |
BOOLEAN | boolean | ||
CHAR | CHAR | CHAR | String |
DATE | DATE | DATE | java.sql.Date |
DECIMAL | DECIMAL | DECIMAL | java.math.BigDecimal |
DOUBLE | DOUBLE | NUMBER | double |
FLOAT | FLOAT | FLOAT | double |
INTEGER | INTEGER | INTEGER | int |
LONGVARBINARY | byte[] | ||
LONGVARCHAR | VARCHAR | LONG | String |
NCHAR | NCHAR | String | |
NCLOB | NCLOB | ||
NULL | |||
NUMERIC | NUMERIC | NUMERIC/NUMBER | java.math.BigDecimal |
NVARCHAR | |||
OTHER | ANY | ||
REAL | REAL | REAL | float |
SMALLINT | SMALLINT | SMALLINT | short |
STRUCT | Struct | ||
TIME | TIME | TIME | java.sql.Time |
TIMESTAMP | TIMESTAMP/DATETIME | TIMESTAMP | java.sql.Timestamp |
TINYINT | TINYINT | TINYINT | byte |
UNDEFINED | |||
VARBINARY | VARBINARY | byte[] | |
VARCHAR | VARCHAR | VARCHAR | String |
DATALINK | java.net.URL[color=red][/color] | ||
REF | Ref | ||
DISTINCT | mapping of underlying type |
记录原文地址:
mybatis的jdbcType和javaType、oracle,MySQL的对应类型
###4.typeAliases 别名设置
通过简写来代替类名,有TypeAliasRegistry定义。
注意:
- 别名不区分大小写。
- 系统定义的别名中,数组和Map类型基本不支持数组(即后面加[]声明为数组)
别名的使用:
方法一:
<typeAliases><!-- 别名:单个声明 -->
<typeAlias alias="role" type="com.nowy.mybatissample.pojo.Role"/>
</typeAliases>
方法二:
<typeAliases><!-- 别名:整个包扫描 -->
<package name="com.nowy.mybatissample.pojo" />
</typeAliases>
其中整个包扫描定义的别名规则为: Role => role
可以通过类名上方的注解(@Alias(“name”))重命名
例如:
@Alias("role")
public class Role {
//...
}
###5.typeHnadler 类型转化器
- 主要作用是java类型与jdbc类型的相互转化处理。
- MyBatis会自动探测匹配类型,大部分情况下默认提供的typeHandler已经足够使用。
- 但在类似枚举类型时候需要自定义typeHandler处理转换。
事例:
//SexEnumTypeHandler类
public class SexEnumTypeHandler implements TypeHandler<SexEnum> {
@Override
public void setParameter(PreparedStatement ps, int i, SexEnum parameter,
JdbcType jdbcType) throws SQLException {
ps.setInt(i, parameter.getId());
}
@Override
public SexEnum getResult(ResultSet rs, String columnName)
throws SQLException {
int id = rs.getInt(columnName);
return SexEnum.getSexById(id);
}
@Override
public SexEnum getResult(ResultSet rs, int columnIndex) throws SQLException {
int id = rs.getInt(columnIndex);
return SexEnum.getSexById(id);
}
@Override
public SexEnum getResult(CallableStatement cs, int columnIndex)
throws SQLException {
int id = cs.getInt(columnIndex);
return SexEnum.getSexById(id);
}
}
配置文件注册:
<typeHandlers>
<!--方式一:单个注册-->
<typeHandler jdbcType="VARCHAR" javaType="string" handler="com.nowy.mybatissample.typehandler.MyTypeHandler"
/>
<!--方式二:包名扫描-->
<package name="com.nowy.mybatissample.typehandler" />
</typeHandlers>
Mapper中结果集引用:
<resultMap id="userMapper" type="user">
<!--方式一,类型匹配-->
<result property="name" column="name" jdbcType="VARCHAR" javaType="string"/>
<!--方式二,直接指定typeHandler-->
<result property="sex" column="sex"
typeHandler="com.nowy.mybatissample.typehandler.SexEnumTypeHandler"/>
</resultMap>
使用包扫描注册typeHandler,可以通过注解配置javaType和jdbcType的匹配规则
//启用扫描注册的时候需要注解
@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MyTypeHandler implements TypeHandler<String> {
//...
}
###6.environments 环境配置
主要配置数据库的连接策略和数据库连接的各种参数
- environment:单个环境配置实例
- transactionManaager:事务管理器
- JDBC:以JDBC的方式进行数据库的提交和回滚操作
- MANAGED:把事务交给容器处理,提交和回滚不做任何操作
- dataSource:数据源配置,
- 配置数据库连接策略(POOLED(连接池)、UNPOOLED(非连接池)、JNDI(JNDI上下文))
- 连接参数(驱动、url、用户名和密码等)
###7.databaseIdProvider 数据库厂商标识
主要作用是支持多个数据库厂商进行开发,用于指定SQL执行在哪个数据库中,对应Mapper中的sql语句的databaseId属性,当databaseId被设置,系统会优先获取与数据库配置一致的SQL,如果没有,则获取没有设置databaseId的默认语句。如果最后还是获取不到,则抛出异常。
<databaseIdProvider type="DB_VENDOR">
<property name="Oracle" value="oracle" />
<property name="MySQL" value="mysql" />
<property name="DB2" value="db2" />
</databaseIdProvider>
###8.ObjectFactory 对象工厂
MyBatis通过对象工厂完成结果集的创建(DefaultObjectFactory)。可以通过自定义objectFactory对返回结果集进行监听。
###9.总结
本文主要对MyBatis的学习进行记录和归纳,以便使用时的快速回忆。学习的书本为《Java EE互联网轻量级框架整合开发——SSM框架(Spring MVC+Spring+MyBatis)和Redis实现》,同时对不理解的知识点进行了进一步的查找和学习。
Mapper将会进行单独记录。
END
–Nowy
– 2018.12.04