MyBatis3源码深度解析(十一)MyBatis常用工具类(四)ObjectFactoryProxyFactory

news2024/11/17 23:34:12

文章目录

    • 前言
    • 3.6 ObjectFactory
    • 3.7 ProxyFactory
    • 3.8 小结

前言

本节研究ObjectFactory和ProxyFactory的基本用法,因为它们在MyBatis的源码中比较常见。这里不深究ObjectFactory和ProxyFactory的源码,而是放到后续章节再展开。

3.6 ObjectFactory

ObjectFactory是MyBatis中的对象工厂,主要作用是实例化目标类。它只有一个默认的实现,即DefaultObjectFactory。

MyBatis在每次创建Mapper映射结果对象的新实例时,均会使用ObjectFactory对象工厂来完成。

下面是使用ObjectFactory创建新对象的示例:

@Test
public void testObjectFactory() {
    ObjectFactory objectFactory = new DefaultObjectFactory();
    Order order = objectFactory.create(Order.class);
    order.setOrderNo("NO.1986");
    order.setGoodsName("《西游记》");
    System.out.println(order.toString());
}

控制台输出执行结果:

Order{orderNo='NO.1986', goodsName='《西游记》'}

需要注意的是,ObjectFactory支持通过接口的方式创建对象,例如指定要创建java.util.List的实例时,实际上会创建java.util.ArrayList对象。List、Map、Set接口对应的实现分别是ArrayList、HashMap、HashSet。

ObjectFactory实际上是MyBatis的一种扩展机制。某些情况下,在得到Mapper映射结果之前需要处理一些额外的逻辑,或者在执行该类的有参构造方法之前,要对参数进行一些处理,则可以通过自定义的ObjectFactory来实现。

下面通过一个简单的SpringBoot整合MyBatis项目,演示自定义的ObjectFactory如何影响目标对象的创建:

(1)在pom.xml中导入SpringBoot和MyBatis的依赖
(2)创建自定义ObjectFactory:需要继承DefaultObjectFactory类并重写create()方法

public class UserObjectFactory extends DefaultObjectFactory {

    @Override
    public <T> T create(Class<T> type) {
        System.out.println("自定义UserObjectFactory执行了...");
        return super.create(type);
    }

}

(3)创建ObjectFactory转换器:程序读取到UserObjectFactory类后会使用该转换器将其转换为ObjectFactory类

@Component
@ConfigurationPropertiesBinding
public class ObjectFactoryConverter implements Converter<String, ObjectFactory> {

    @Override
    public ObjectFactory convert(String s) {
        try {
            return  (ObjectFactory) Class.forName(s).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

(4)创建Mapper接口与xml文件

@Mapper
public interface UserMapper {
    public List<User> selectAll();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.star.mybatis.test11.UserMapper">
    <select id="selectAll" resultType="User">
        SELECT * FROM USER
    </select>
</mapper>

(5)在application.properties配置文件中配置MyBatis

# datasource等配置省略...

mybatis:
  mapper-locations: classpath*:/mapper/**Mapper.xml
  type-aliases-package: com.star.mybatis.common
  configuration:
    map-underscore-to-camel-case: true
    object-factory: com.star.mybatis.test11.UserObjectFactory

(6)编写主启动类

@SpringBootApplication
public class CustomObjectFactoryApp {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(CustomObjectFactoryApp.class, args);
        UserMapper userMapper = (UserMapper) context.getBean("userMapper");
        List<User> userList = userMapper.selectAll();
        userList.forEach(System.out::println);
    }

}

(7)执行主启动类,得到结果

执行创建User对象的自定义逻辑...
执行创建User对象的自定义逻辑...
User{id=1, name='孙悟空', age=18, phone='18705464523', birthday=Mon Feb 21 10:24:30 CST 2000}
User{id=22, name='user1', age=18, phone='18705464523', birthday=Mon Feb 21 10:24:30 CST 2000}

由执行结果可知,在得到映射结果对象之前执行了自定义的ObjectFactory,那就可以在这个自定义的ObjectFactory中做一些额外的处理。

3.7 ProxyFactory

ProxyFactory是MyBatis中的代理工厂,用于创建动态代理对象。

ProxyFactory接口有两个不同的实现,分别为CglibProxyFactory和JavassistProxyFactory。从实现类的名称就可知道,MyBatis支持两种动态代理策略,分别是Cglib和Javassist动态代理。

ProxyFactory主要用于实现MyBatis的懒加载功能。当开启懒加载后,懒加载创建Mapper映射结果对象后,会通过ProxyFactory创建映射结果对象的代理对象。当调用代理对象的getter方法获取数据时,会执行CglibProxyFactory或JavassistProxyFactory中定义的拦截逻辑。

关于懒加载的细节,放到后面的章节再研究,本节主要了解ProxyFactory的使用。

下面是一个ProxyFactory的使用示例:

@Test
public void testProxyFactory() {
    // 创建ProxyFactory对象
    ProxyFactory proxyFactory = new JavassistProxyFactory();
    Order order = new Order("NO.1986", "《西游记》");
    // 调用ProxyFactory对象的createProxy方法
    Object proxy = proxyFactory.createProxy(order,
            new ResultLoaderMap(),
            new Configuration(),
            new DefaultObjectFactory(),
            Arrays.asList(String.class, String.class),
            Arrays.asList(order.getOrderNo(), order.getGoodsName()));
    System.out.println(proxy.getClass());
    System.out.println(((Order)proxy).getOrderNo());
    System.out.println(((Order)proxy).getGoodsName());
}

控制台输出执行结果:

class com.star.mybatis.common.Order_$$_jvst3c2_0
NO.1986
《西游记》

在示例中,创建了一个Order对象,然后通过JavassistProxyFactory实例创建了一个Order对象的动态代理对象。

动态代理对象创建完毕后,会把原始对象的属性复制到代理对象中。

3.8 小结

第三章到此就梳理完毕了,本章的主题是:MyBatis常用工具类。回顾一下本章的梳理的内容:

(八)SQL工具类
(九)ScriptRunner&SqlRunner
(十)MetaObject&MetaClass
(十一)ObjectFactory&ProxyFactory

这些工具类在MyBatis源码中出现的频率较高,了解这些工具类的使用及实现原理有助于深入研究MyBatis的源码。

  • SQL工具类用于在Java代码中动态构建SQL语句;
  • SqlRunner和ScriptRunner用于执行SQL脚本和SQL语句;
  • MetaObject和MetaClass是MyBatis中的反射工具类,封装了对类和对象的操作;
  • ObjectFactory和ProxyFactory是对象创建相关的工具类,ObjectFactory用于创建Mapper映射实体对象,而ProxyFactory则用于创建Mapper 映射实体对象的动态代理对象,通过动态代理来实现MyBatis 中的懒加载机制。

更多内容请查阅分类专栏:MyBatis3源码深度解析

第四章主要学习:MyBatis核心组件。主要内容包括:

  • 使用MyBatis操作数据库;
  • MyBatis核心组件;
  • Configuration详解;
  • Executor详解;
  • MappedStatement详解;
  • StatementHandler详解;
  • TypeHandler详解;
  • ParameterHander详解;
  • ResultSetHandler详解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1515177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最优算法100例之05-第一个只出现一次的字符

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置。 题解报…

掌握抽象基础之20个必备原则,看完你还不会,你打我

抽象基础之20个必备原则 1. 面向对象编程&#xff08;OOP&#xff09;中抽象原则背后的基本思想是什么&#xff1f;2.抽象和封装的区别&#xff1f;3.提供一个现实生活中说明抽象的例子4.在编程语言中如何实现抽象&#xff1f;5.定义抽象类6.提供一个抽象类的真实世界场景7.解释…

Composer创建ThinkPHP无法获取最新版本的问题

composer安装TP&#xff08;截止目前最新版本为8.0&#xff09; composer create-project topthink/think tp 一开始直接给我安装成TP6了&#xff0c;原因就是我系统的PHP版本不是8.0以上&#xff0c;所以不支持最新的TP版本&#xff0c;就会默认安装之前稳定的版本。解决这个…

25.网络游戏逆向分析与漏洞攻防-网络通信数据包分析工具-利用全新的通信结构传递消息

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;24.根据配置文件…

备考2025年AMC8竞赛:吃透2000-2024年600道真题(免费赠送真题)

我们继续来随机看五道AMC8的真题和解析&#xff0c;根据实践经验&#xff0c;对于想了解或者加AMC8美国数学竞赛的孩子来说&#xff0c;吃透AMC8历年真题是备考最科学、最有效的方法之一。 即使不参加AMC8竞赛&#xff0c;吃透了历年真题600道和背后的知识体系&#xff0c;那么…

18. 查看帖子详情

文章目录 一、建立路由二、开发GetPostDetailHandler三、编写logic四、编写dao层五、编译测试运行 一、建立路由 router/route.go v1.GET("/post/:id", controller.GetPostDetailHandler)二、开发GetPostDetailHandler controller/post.go func GetPostDetailHand…

SpringBoot3学习记录(有ssm基础)

目录 一、SpringBoot3 介绍 SpringBoot3 简介 SpringBoot3 快速入门 入门总结 1.为什么依赖不需要写版本 2.Startrer&#xff08;启动器&#xff09;是什么 3.SpringBootApplication 二、SpringBoot3 配置文件 统一配置管理 使用yaml配置文件&#xff08;推荐&#x…

Vue的渲染原理

列表渲染 列表渲染 v-for指令写在循环项上&#xff1a;v-for“(一个参数或者两个参数) in/of 要遍历的数组、对象、字符串、指定次数” 遍历数组时参数分别是数组中元素(可以是一个对象)和元素所在下标(从0开始)遍历对象时参数分别是属性值和属性名遍历字符串时参数分别是单…

基于SpringCache实现数据缓存

SpringCache SpringCache是一个框架实现了基本注解的缓存功能,只需要简单的添加一个EnableCaching 注解就能实现缓存功能 SpringCache框架只是提供了一层抽象,底层可以切换CacheManager接口的不同实现类即使用不同的缓存技术,默认的实现是ConcurrentMapCacheManagerConcurren…

Redisson分布式锁解决方案

官方地址 官网: https://redisson.org github: https://github.com/redisson/redisson 基于setnx实现的分布式锁存在的问题 redisson分布式锁原理 不可重入: 利用hash结构记录线程id和重入次数不可重试: 利用信号量和PubSub功能实现等待、唤醒, 获取锁失败的重试机制超时释放…

监听抖音直播间的评论并实现存储

监听抖音直播间评论&#xff0c;主要是动态监听dom元素的变化&#xff0c;如果评论是图片类型的&#xff0c;获取alt的值 主要采用的是MutationObserver&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver index.js如下所示:function getPL() {…

29网课交单平台源码最新修复全开源版本

去除论文编辑 去除强国接码 修复上级迁移 修复聚合登录 修复支付不回调 优化支付接口兼容码/易支付 优化MySQL表&#xff0c;提高网页加载速度 下载地址&#xff1a;https://pan.xunlei.com/s/VNstLrJaRtbvDyovPQ-CbISOA1?pwd622t#

数字人基础 | 3D手部参数化模型2017-2023

楔子: 2017年年底的泰国曼谷, SIGGRAPH Asia会议上, 来自马普所的 Javier Romero, Dimitrios Tzionas(两人都是 Michael J. Black的学生)发布了事实性的手部参数化模型标准: MANO [1]。 MANO的诞生意味着 Michael J. Black团队在继人体参数化模型 SMPL后, 事实性的将能够表达人…

【正则表达式】正则表达式里使用变量

码 const shuai No My Name Is ShuaiGe.match(new RegExp(shuai, gi)); //↑↑↑↑↑↑↑↑ //等同于 //↓↓↓↓↓↓↓↓ /No/.test(My Name Is ShuaiGe)用作领域 搜索的字符动态改变&#xff0c;例如↓模糊搜索例&#xff1a; 一个文本宽&#xff0c;输入文本模糊搜索用户…

【哈希映射】【 哈希集合】 381. O(1) 时间插入、删除和获取随机元素 - 允许重复

作者推荐 视频算法专题 本文涉及知识点 哈希映射 哈希集合 LeetCode 381. O(1) 时间插入、删除和获取随机元素 - 允许重复 RandomizedCollection 是一种包含数字集合(可能是重复的)的数据结构。它应该支持插入和删除特定元素&#xff0c;以及删除随机元素。 实现 Randomiz…

【漏洞复现】金和OA viewConTemplate.action RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

XIAO ESP32S3部署Edge Impulse模型

在上一篇文章中我们介绍了如何使用edge impulse训练一个图片分类模型并导出arduino库文件。在这篇文章中我们将介绍如何在esp32s3中部署这个训练好的图片分类模型。 添加进Arduino库 有两种方法将下载的文件添加进Arduino库。 在Arduino IDE程序中&#xff0c;转到项目选项卡…

php apache 后台超时设置

最近在写一个thinkphp项目的时候&#xff0c;发现Ajax从后端请求数据时间比较长&#xff0c;大概需要45秒左右&#xff0c;但是一旦请求时间超过40s&#xff0c;页面就会超时500了&#xff0c;一开始以为是ajax请求时间不能太长&#xff0c;后来将Ajax请求改为同步且timeout设置…

景联文科技:提供行业垂直大模型训练数据

近年来&#xff0c;以大模型为代表的人工智能技术已成为国家科技实力竞争的焦点。其中垂直大模型作为重要方向&#xff0c;在相关政策引导及市场需求的驱动下&#xff0c;已展现出较强的发展活力。 行业垂直大模型是针对特定行业的需求和场景进行深度定制的。这意味着模型在训练…

软考高级:需求变更管理过程概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…