objectFactory配置
当使用MyBatis查询结果返回时,在Java程序中将表现为一个POJO对象,ObjectFactory(对象工厂)所做的就是构建这个POJO对象的事情。
在默认情况下,使用的是org.apache.ibatis.reflection.factory.DefaultObjectFactory
类作为对象工厂,这个类实现了和它在同一包下的ObjectFactory
接口(感觉和前几篇学的TypeHandler好像,不过这个类并不是抽象类)。如果要定制特定的对象工厂,可以直接继承DefaultObjectFactory
类,然后覆写其中的四个方法。
下面这个例子,自定的对象工厂里用super
去调用了父类(DefaultObjectFactory
)的实现,仅仅是体现了该怎么去定制。
在配置文件的适当位置注册自定的对象工厂:
<objectFactory type="objectFactory.MyObjectFactory">
<property name="name" value="MyObjectFactory"/>
</objectFactory>
书写自定的对象工厂,这四个方法不是抽象的(DefaultObjectFactory
就不是抽象类),所以要手工提示IDE一下来覆写它们:
package objectFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import java.util.List;
import java.util.Properties;
public class MyObjectFactory extends DefaultObjectFactory {
//处理向对象中设置属性
@Override
public void setProperties(Properties properties) {
System.out.println("调用了setProperties");
super.setProperties(properties);
}
//处理创建单个对象
@Override
public <T> T create(Class<T> type) {
System.out.println("调用了create(1)");
return super.create(type);
}
//处理创建list对象
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
System.out.println("调用了create(2)");
return super.create(type, constructorArgTypes, constructorArgs);
}
//判断是否是Collection集合类型
@Override
public <T> boolean isCollection(Class<T> type) {
System.out.println("调用了isCollection");
return super.isCollection(type);
}
}
运行上篇枚举类型处理器的例子做测试:
至于具体要使用时该怎么实现,可以参考DefaultObjectFactory
下的实现,不算复杂。
environments配置
这个配置总是是必要的,通过environments
的多个environment
子标签可以配置多个数据库环境,其中二级标签transactionManager
表示这个环境使用的数据库事务配置,二级标签dataSource
表示这个环境所使用的数据源。
<!--包含一个或多个数据库环境信息,这里使用里面id=development的数据库环境作为默认-->
<environments default="development">
<!--一个数据库环境-->
<environment id="development">
<!--使用JDBC事务管理-->
<!--还可以使用MANAGED表示容器方式管理事务(JNDI数据源中常用);还可以自定义数据库事务管理办法-->
<transactionManager type="JDBC">
<!--不自动提交-->
<property name="autoCommit" value="false"/>
</transactionManager>
<!--POOLED表示使用连接池方式来获取连接对象-->
<!--还可以使用UNPOOLED表示非连接池数据库;使用JNDI表示JNDI数据源;还可以自定义数据源-->
<dataSource type="POOLED">
<!--数据库驱动-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--连接字符串-->
<property name="url" value="jdbc:mysql://localhost:3306/test_mbts"/>
<!--用户名-->
<property name="username" value="root"/>
<!--密码-->
<property name="password" value="3838438"/>
</dataSource>
</environment>
</environments>
数据库事务大部分情况下都会使用Spring框架来控制,所以更不太会使用自定义的数据库事务管理办法。
使用自定义的数据源则是比较多的,比如上学期J2EE课程项目就用了DBCP2的连接池,不过当时在Hibernate里似乎不太需要配置。在MyBatis下,如果要使用自定义的数据源,需要实现org.apache.ibatis.datasource.DataSourceFactory
接口,实现其中的方法,然后将这个类的全限名写在dataSource
标签的type
属性中。
databaseIdProvider配置
这个标签用来配置数据库厂商标识,可以用来实现MyBatis的多数据库支持。因为在不同的DBMS中,哪怕都是基于T-SQL,也会有很多不同的地方(如聚合函数,时间、字符串的处理函数等),这时就可以给映射文件中增删查改的标签添加上一个databaseId
属性,这个属性标识了这个SQL是用在哪种数据库上的。
而databaseIdProvider
标签配置了这种对应关系,其默认值是:
<!--数据库厂商标识-->
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="MySQL" value="mysql"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle"/>
</databaseIdProvider>
而如果要使用databaseId
属性,还是要显示给出databaseIdProvider
标签,只是在使用默认值时不需要提供内部的property
子标签,即:
<databaseIdProvider type="DB_VENDOR"/>
当配置上了databaseIdProvider
标签后,如果当前数据库能够被这个标签的配置所识别(如MySQL),那么MyBatis只会在映射文件中寻找不带databaseId
属性和databaseId
属性值与当前数据库相同的那些语句,而忽略掉其它databaseId
属性的语句,这样就实现了多数据库支持(只管自己数据库的)。
这个配置标签的属性type="DB_VENDOR"
是指MyBatis内部注册的策略器,如果要自己实现,则可以写一个类去实现org.apache.ibatis.mapping.DatabaseIdProvider
接口,里面具体怎么写没太看懂,以后再深入研究。