目录
1.properties标签
2.typeAliases标签
3.Mappers标签
3.1使用mapper映射文件的路径3
3.2使用mapper接口的路径
3.3使用mapper接口的包名批量引入
4.settings(设置)
5.typeHandlers(类型处理器)
6.objectFactory(对象工厂)
7.plugins(插件)
8.environments(环境配置)
9.databaseIdProvider(数据库厂商标识)
mybatis-config.xml 文件中的元素节点是有一定顺序的,节点位置必须按以上位置排序,否则会编译错误。
主要用于配置数据连接和MyBatis运行时所需的各种特性:包含了影响MyBatis行为甚深的设置(settings)和属性(properties)mybatis-config.xml是Mybatis的全局配置文件,名称可以是任意,但是一般命名都为(mybatis-config)
核心配置文件 configuration(配置)作为最顶级节点,其余 9 大属性都嵌套在其内.
接下来为大家介绍几个标签:
我们一般会把数据库配置信息定义在一个独立的配置文件里面,比如db.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=1111
那么我们如何在mybatis的核心配置文件里面加载外部的数据库配置信息呢?
在SqlMapConfig.xml引入数据库配置信息
properties 优先级
1、第一优先级:在 Java 代码中构建的 properties 属性对象;
2、第二优先级:通过属性 resource 或 url 读取到的本地文件或远程文件;
3、第三优先级:直接在 properties 内部子标签元素 property 中设置的属性。
注意,在实际开发中,为了避免给后期维护造成困扰,建议使用单一种配置方式。properties 优先级
类型别名是为Java类型命名一个短的名字。它只和XML配置有关,只用来减少全限定类型的多余部分,便于开发。
使用别名:
mappers 标签用于指定 MyBatis SQL 映射文件的路径。
mapper 是 mappers 的子标签,mapper 中的 resource 属性用于指定 SQL 映射文件的路径(类资源路径)
Mappers标签的作用是用来在核心配置文件里面引入映射文件,引入方式有如下三种:
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同
Mybatis 也内置了一些常用属性的别名,都是不区分大小写的
settings 标签元素,是 MyBatis 中极为重要的调整设置,它们会动态改变 MyBatis 的运行时行为,这些配置就像 Mybatis 内置的许多功能,当你需要使用时可以根据需要灵活调整
<... more .../>
MyBatis 在设置预处理SQL语句(PreparedStatement)中所需要的 参数 或从 结果集 ResultSet 中获取对象时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。
我们可以通过源码查看内置的类型别名的注册信息。
具体源码路径在 org.apache.ibatis.type.TypeHandlerRegistry # TypeHandlerRegistry() :
接口 TypeHandler 定义了四个方法:
public interface TypeHandler {
void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
T getResult(ResultSet rs, String columnName) throws SQLException;
T getResult(ResultSet rs, int columnIndex) throws SQLException;
T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
从方法名 setParameter 和 getResult 我们就可以知道,是发生在预编译时设置参数(增删改查传入参数)与查询结果集后转换为 Java 类型时,类型处理器发挥作用。
具体实现如下,先自定义类型处理器类 MyExampleTypeHandler :
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MyExampleTypeHandler extends BaseTypeHandler {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return rs.getString(columnName);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return rs.getString(columnIndex);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return cs.getString(columnIndex);
}
}
其次,在核心配置文件中设置类型处理器:
或者不使用注解方式的话,取消 @MappedJdbcTypes(JdbcType.VARCHAR) 注解,直接在 xml 配置中指定 jdbcType 与 javaType 映射 :
另外,当我们自定义很多类型处理器时,系统支持配置包扫描的方式查找类型处理器:
每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。
public class ExampleObjectFactory extends DefaultObjectFactory {
public Object create(Class type) {
return super.create(type);
}
public Object create(Class type, List constructorArgTypes, List constructorArgs) {
return super.create(type, constructorArgTypes, constructorArgs);
}
public void setProperties(Properties properties) {
super.setProperties(properties);
}
public boolean isCollection(Class type) {
return Collection.class.isAssignableFrom(type);
}
}
ObjectFactory 接口很简单,它包含两个创建用的方法,一个是处理默认构造方法的,另外一个是处理带参数的构造方法的。 最后,setProperties 方法可以被用来配置 ObjectFactory,在初始化你的 ObjectFactory 实例后, objectFactory 元素体中定义的属性会被传递给 setProperties 方法。
MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的类,方法,参数(由于有多态的情况)即可。
@Intercepts({
@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
private Properties properties = new Properties();
public Object intercept(Invocation invocation) throws Throwable {
// implement pre processing if need
Object returnObject = invocation.proceed();
// implement post processing if need
return returnObject;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
上面的插件将会拦截在 Executor 实例中所有的 “update” 方法调用, 这里的 Executor 是负责执行底层映射语句的内部对象。
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。
不过要记住:尽管可以配置多个环境,但每个 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);
environments 元素定义了如何配置环境。
注意一些关键点:
默认环境和环境 ID 顾名思义。 环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId
属性。 MyBatis 会加载带有匹配当前数据库 databaseId
属性和所有不带 databaseId
属性的语句。 如果同时找到带有 databaseId
和不带 databaseId
的相同语句,则后者会被舍弃。 为支持多厂商特性,只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider
即可:
databaseIdProvider 对应的 DB_VENDOR 实现会将 databaseId 设置为 DatabaseMetaData#getDatabaseProductName()
返回的字符串。 由于通常情况下这些字符串都非常长,而且相同产品的不同版本会返回不同的值,你可能想通过设置属性别名来使其变短:
在提供了属性别名时,databaseIdProvider 的 DB_VENDOR 实现会将 databaseId 设置为数据库产品名与属性中的名称第一个相匹配的值,如果没有匹配的属性,将会设置为 “null”。 在这个例子中,如果 getDatabaseProductName()
返回“Oracle (DataDirect)”,databaseId 将被设置为“oracle”。
你可以通过实现接口 org.apache.ibatis.mapping.DatabaseIdProvider
并在 mybatis-config.xml 中注册来构建自己的 DatabaseIdProvider:
public interface DatabaseIdProvider {
default void setProperties(Properties p) { // 从 3.5.2 开始,该方法为默认方法
// 空实现
}
String getDatabaseId(DataSource dataSource) throws SQLException;
}