MyBatis之ObjectFactory
关于在MyBatis中的ObjectFactory有什么用,在官方文档中有这样的描述(大多数网上的博客都是直接引用这一描述):MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。对于像我这种水平的来说,完全就是一脸蒙逼,这到底有啥用?可以说这个对象工厂就是用来创建实体类的,MyBatis有一个DefaultObjectFactory默认对象工厂类,就像上面所说的默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。它不做其他任何的处理。如果我们想在创建实例化一个目标类的时候做点啥其他的动作,可以继承DefaultObjectFactory,覆写父类方法,并在mybatis-config.xml中注册配置这个对象工厂类。
自己实现一个对象工厂如下所示:
package day_8_mybatis.util; import java.util.Collection;
import java.util.Iterator;
import java.util.Properties; import org.apache.ibatis.reflection.factory.DefaultObjectFactory; import day_8_mybatis.pojo.People; /**
* @author turbo
*
* 2016年10月24日
*/
public class ExampleObjectFactory extends DefaultObjectFactory { @Override
public Object create(Class type) {
if (type.equals(People.class)){
People p = (People)super.create(type);
p.setAge(22);
p.setName("keven");
return p;
}
return super.create(type);
} @Override
public void setProperties(Properties properties) {
Iterator iterator = properties.keySet().iterator();
while (iterator.hasNext()){
String keyValue = String.valueOf(iterator.next());
System.out.println(properties.getProperty(keyValue));
}
super.setProperties(properties);
} @Override
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type);
} }
我们可以先看下第30行这个setProperties方法,发现有一个Properties参数传递进来,这个参数在哪儿传递的呢?就是在我们的mybatis-config.xml的第18行。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>
<!-- 注意configuration中各个属性配置的顺序应为:properties,settings,typeAliases,typeHandlers,objectFactory,objectWrapperFactory,reflectorFactory,plugins,environments,databaseIdProvider,mappers)-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="0000"/>
</properties>
<typeHandlers>
<typeHandler handler="day_8_mybatis.util.ExampleTypeHandler" javaType="java.util.Date" jdbcType="VARCHAR"/>
</typeHandlers>
<objectFactory type="day_8_mybatis.util.ExampleObjectFactory">
<property name="someProperty" value="100"/>
</objectFactory>
<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="day_8_mybatis/mapper/UserMapper.xml"/>
<mapper resource="day_8_mybatis/mapper/NoteMapper.xml"/>
</mappers> </configuration>
选择性忽略14-16行的typeHandlers配置,那是在上一节将typeHandlers用到的配置。
我们就实现了这么个自定义对象工厂,在客户端代码中测试一下。
package day_8_mybatis; import java.io.IOException; import org.apache.ibatis.session.SqlSession; import day_8_mybatis.util.SessionFactory; /**
* 客户端
* @author turbo
*
* 2016年9月11日
*/
public class Main { /**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws Exception {
String resource = "day_8_mybatis/mybatis-config.xml"; //获取mybatis配置文件路径
SqlSession sqlSession = SessionFactory.getSqlSession(resource); //通过SessionFactory工具类(此工具类为自己构造即util包中的SessionFactory)构造SqlSession } }
会发现控制台会有一个100的输出,那正是我们传递进去的参数。但似乎疑问在我们好像并没有调用任何方法啊,其实不然,mybatis的配置文件就是mybatis初始化首先要做的。我们在第22、23行做的工作就是加载configuration配置文件初始化mybatis,用于我们配置了ObjectFactory中的property当然实际上也就调用了ExampleObjectFactory中的setProperties。很多很多框架做的第一件事就是加载配置文件,根据配置初始化各种类各种服务,当然这也可以用代码来实现,不过框架的好处就是它已经为我们做了一些事情,使得我们仅仅需要通过一些配置就能实现我们想要的结果。那么至于create方法呢?我们可以上面说了对象工厂就是用来创建实例的,我们可以传递一个class类型的类,就可以通过对象工厂的create方法得到这个类的实例。
package day_8_mybatis; import java.io.IOException; import org.apache.ibatis.session.SqlSession; import day_8_mybatis.pojo.People;
import day_8_mybatis.util.ExampleObjectFactory;
import day_8_mybatis.util.SessionFactory; /**
* 客户端
* @author turbo
*
* 2016年9月11日
*/
public class Main { /**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws Exception {
String resource = "day_8_mybatis/mybatis-config.xml"; //获取mybatis配置文件路径
SqlSession sqlSession = SessionFactory.getSqlSession(resource); //通过SessionFactory工具类(此工具类为自己构造即util包中的SessionFactory)构造SqlSession
ExampleObjectFactory e = new ExampleObjectFactory();
People p = (People) e.create(People.class);
System.out.println(p.getName());
} }
最后记住上面提到的MyBatis初始化过程就是解析配置文件创建Configuration对象的过程。这也会为我们在了解MyBatis之后学习其源码所要知道的一点。
MyBatis之ObjectFactory的更多相关文章
- mybatis精讲(四)--ObjectFactory
目录 前言 mybatis的ObjectFactory 源码 setProperties create instantiateClass 使用场景 # 加入战队 微信公众号 前言 ObjectFact ...
- MyBatis配置文件(五)--objectFactory对象工厂
我们在使用MyBatis执行查询语句的时候,通常都会有一个返回类型,这个是在mapper文件中给sql增加一个resultType(或resultMap)属性进行控制.resultType和resul ...
- IBatis 2.x 和 MyBatis 3.0.x 的区别(从 iBatis 到 MyBatis)
从 iBatis 到 MyBatis,你准备好了吗? 对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate.JPA 这样的一站式对象 / 关系 ...
- iBatis 和MyBatis区别
从 iBatis 到 MyBatis ,你准备好了吗? 对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate.JPA 这样的一站式对象 ...
- ibatis 到 MyBatis区别
http://blog.csdn.net/techbirds_bao/article/details/9235309 简介: 本文主要讲述了 iBatis 2.x 和 MyBatis 3.0.x 的区 ...
- Mybatis笔记三:iBatis与MyBatis区别
转载:http://www.tuicool.com/articles/auaAru iBatis 框架的主要优势: 1.iBatis 封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL ...
- Mybatis源码学习之反射工具(三)
简述 MyBatis在进行参数处理.结果映射等操作时,会涉及大量的反射操作.Java中的反射虽然功能强大,但是代码编写起来比较复杂且容易出错,为了简化反射操作的相关代码,MyBatis提供了专门的反射 ...
- Mybatis 属性配置
properties 定义配置,配置的属性可以在整个配置文件中的其他位置进行引用 <properties resource="db.properties"></ ...
- (一) Mybatis源码分析-解析器模块
Mybatis源码分析-解析器模块 原创-转载请说明出处 1. 解析器模块的作用 对XPath进行封装,为mybatis-config.xml配置文件以及映射文件提供支持 为处理动态 SQL 语句中的 ...
随机推荐
- STM32位带操作总结---浅显易懂
正在准备做毕业设计,配置LED_Config()的时候,又看到了位带操作的宏定义,我又嘀咕了,什么是位带操作,一年前在使用位带操作的时候,就查阅过好多资料,Core-M3也看过,但是对于博主这种“低能 ...
- [SinGuLaRiTy] 高精度算法代码库
[SinGuLaRiTy-1001] Copyrights (c) SinGuLaRiTy 2017. All Rights Reserved. 加法: #include<stdio.h> ...
- 老李推荐:第14章5节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态
老李推荐:第14章5节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态 poptest是国内唯一 ...
- Angularjs 动态添加指令并绑定事件
先说使用场景,动态生成DOM元素并绑定事件,非常常见的一种场景,用jq实现效果: http://jsbin.com/gajizuyuju/edit?html,js,output var count=0 ...
- hdoj_2546饭卡(强忍悲痛,好好写题解)
Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即在购买之前判断余额.如果购买一个商品之前,卡上的剩余金额大于或等于5元,就一定可以购买成功(即使购买后卡上余额为负) ...
- cocoapods安装好后repo换源
1.pod repo 然后会出现以下内容,如下是我已经换了之后的,而你的URL还是github的 master - Type: git (master) - URL: https://git.cod ...
- 线段树(hdu 1754 i hate it)
I Hate It Time Limit: 3000MS Memory Limit: 32768 K Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分 ...
- KVO 模式详解
KVO:观察者模式.当指定的被观察对象属性被修改时,允许对象接收到通知的机制. p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; ...
- JavaEE开发之SpringMVC中的自定义拦截器及异常处理
上篇博客我们聊了<JavaEE开发之SpringMVC中的路由配置及参数传递详解>,本篇博客我们就聊一下自定义拦截器的实现.以及使用ModelAndView对象将Controller的值加 ...
- Java 8 Lambda 表达式
Lambda 是啥玩意 简单来说,Lambda 就是一个匿名的方法,就这样,没啥特别的.它采用一种非常简洁的方式来定义方法.当你想传递可复用的方法片段时,匿名方法非常有用.例如,将一个方法传递给另外一 ...