【mybatis】objectwrapper解读

news2024/11/27 16:41:12

简介

在 MyBatis 中,ObjectWrapper 是一个关键的接口,用于详细封装了对象的属性信息。ObjectWrapper 主要用于内部操作,它抽象了对象的属性操作,使得 MyBatis 能够统一处理原生类型、Bean 对象以及 Map 集合等。

类图展示

ObjectWrapper.png

主要功能

  1. 属性的获取与设置ObjectWrapper 提供了方法来获取和设置对象的属性值。这对于 MyBatis 在执行 SQL 语句时,动态地插入参数值或者将查询结果映射回对象是非常有用的。
  2. 集合操作的支持:对于 Map 类型或者集合类型的对象,ObjectWrapper 提供了方法来操作集合内的元素,包括获取指定键的值等。
  3. 复杂属性的处理ObjectWrapper 还能处理复杂的属性路径。例如,如果有一个属性路径是 someBean.somePropertyObjectWrapper 能够解析这个路径并获取或设置相应的属性值。

实现类

MyBatis 提供了几个 ObjectWrapper 的实现类,用于处理不同类型的对象:

  • **BeanWrapper**:用于处理 Java Bean 对象的包装器,通过反射机制访问对象的属性。
  • **MapWrapper**:用于处理 Map 类型对象的包装器,通过键值对来访问数据。
  • **CollectionWrapper**:尽管不直接实现 ObjectWrapper 接口,但 MyBatis 处理集合类型时有相关的机制,以支持集合的处理。

应用场景

ObjectWrapper 的设计主要是为了内部使用,以提供一种统一的方式来访问对象的属性,无论这些对象是普通的 Java Beans、Map 集合还是其他复杂的数据结构。这种机制极大地简化了 MyBatis 的参数映射和结果映射逻辑,使得开发者可以更加专注于 SQL 语句的编写,而不是数据的封装和解析过程。

在自定义类型处理器(Type Handler)或是高级映射配置时,了解 ObjectWrapper 的工作原理可以帮助开发者更好地控制 MyBatis 的行为,实现更加灵活和强大的数据操作。

ObjectWrapper 接口类的设计理念

封装性(Encapsulation)

ObjectWrapper 封装了对对象属性的操作,隐藏了具体的实现细节。这意味着,不论是操作 Java Bean、Map 还是其他任何复杂对象,对于使用者来说,都是通过一个统一的接口进行。这种封装性使得 MyBatis 的其余部分可以不用关心对象属性是如何被访问和修改的,从而降低了各个模块间的耦合度。

抽象性(Abstraction)

ObjectWrapper 作为一个高层次的抽象,定义了一套操作对象属性的通用方法。这种抽象使得 MyBatis 能够支持广泛的数据类型,而无需为每种数据类型编写特定的代码。通过抽象出一个统一的接口,MyBatis 可以轻松地扩展以支持新的对象类型,只需添加相应类型的 ObjectWrapper 实现即可。

单一职责原则(Single Responsibility Principle)

ObjectWrapper 的设计遵循了单一职责原则,即一个类应该只有一个引起变化的原因。ObjectWrapper 接口专注于对象属性的访问和操作,而不涉及其他逻辑,如 SQL 语句的构建、数据库连接的管理等。这使得 ObjectWrapper 及其实现类易于理解和维护。

开闭原则(Open/Closed Principle)

根据开闭原则,软件实体应该对扩展开放,对修改关闭。ObjectWrapper 接口的设计允许 MyBatis 在不修改已有代码的基础上扩展框架的功能。通过添加新的 ObjectWrapper 实现,可以支持新的数据类型或自定义的对象处理逻辑,而无需改动框架的核心部分。

策略模式(Strategy Pattern)

ObjectWrapper 的设计体现了策略模式的应用,其中 ObjectWrapper 接口定义了一组算法家族(在这里是对象属性的操作方法),而它的实现类则封装了这些算法的具体实现。这使得 ObjectWrapper 在运行时可以根据对象的类型选择合适的实现,从而改变对象属性的访问和操作行为。这种模式提高了代码的灵活性和可重用性。

BaseWrapper类解读

MyBatis 中的 BaseWrapper 类并不是直接暴露给终端用户的一个类,而是作为一个内部使用的基础类,提供了一些共通的功能和工具,供其子类如 BeanWrapperMapWrapperObjectWrapper 的实现类使用。BaseWrapper 主要是实现了 ObjectWrapper 接口的一些公共逻辑,以避免在每一个实现中重复相同的代码。它是一个抽象类,为处理对象属性的读取和设置提供了基础设施。

主要功能
  1. 属性表达式解析BaseWrapper 提供了解析复杂属性表达式的功能,例如嵌套属性和集合/数组元素的访问。这允许 MyBatis 在运行时动态地访问和修改对象的属性,即使这些属性是通过复杂的路径访问的。
  2. 通用属性访问:通过封装对反射 API 的调用,BaseWrapper 提供了一种相对简单的方式来读取和设置对象的属性值。这包括处理 Java Beans、Map 以及集合类型的对象。
  3. 缓存机制:为了提高性能,BaseWrapper 可能会实现一些缓存机制,例如缓存反射操作的结果(如方法、字段访问)。这样可以减少对相同属性的重复解析和访问开销。
  4. 类型转换和处理BaseWrapper 提供了类型转换的基础设施,以便在设置属性值时,能够将输入数据转换为目标属性的适当类型。这是通过 MyBatis 的类型处理器(TypeHandler)来实现的。
  5. 延迟加载支持:在一些情况下,BaseWrapper 可能会参与支持延迟加载(Lazy Loading)的逻辑,尽管这通常是在更高层次上处理的,但 BaseWrapper 提供的基础设施使得这种功能的实现变得可能。
应用场景

BaseWrapper 主要在 MyBatis 内部使用,作为一个工具类来支持更高层次的抽象,如 ObjectWrapper 的实现。它通过提供一组通用的工具和方法简化了对不同类型对象的操作,提高了 MyBatis 在处理复杂映射和动态 SQL 时的灵活性和效率。用户通常不需要直接与 BaseWrapper 交互,但理解其功能和作用可以帮助更好地理解 MyBatis 是如何在内部处理对象映射的。

类定义和构造函数
  • BaseWrapper 是一个抽象类,它实现了 ObjectWrapper 接口。
  • 它包含一个 protectedMetaObject 类型的成员变量 metaObjectMetaObject 是 MyBatis 中用于反射操作的核心类,提供了对对象属性的访问和修改功能。
  • 构造函数 BaseWrapper(MetaObject metaObject) 用于初始化 metaObject 成员变量。
方法解读
  • **resolveCollection(PropertyTokenizer prop, Object object)**** 方法**:用于处理集合对象。如果 PropertyTokenizername 属性为空字符串,表示直接返回输入对象;否则,通过 metaObject.getValue(prop.getName()) 获取属性值。这里的 PropertyTokenizer 是用于分析属性表达式的工具类。
  • **getCollectionValue(PropertyTokenizer prop, Object collection)**** 方法**:根据 PropertyTokenizer 中的索引,从集合对象中获取元素值。这个方法能够处理 MapList、数组以及基本类型数组(如 int[], char[] 等)。如果集合对象不是这些类型之一,则抛出 ReflectionException 异常。
  • **setCollectionValue(PropertyTokenizer prop, Object collection, Object value)**** 方法**:根据 PropertyTokenizer 中的索引,向集合对象中设置元素值。这个方法同样能够处理 MapList、数组以及基本类型数组。它根据集合的类型,将值 value 插入或替换到正确的位置。如果操作的目标不是这些集合类型之一,同样会抛出 ReflectionException 异常。

CollectionWrapper类解读

核心功能
  • 构造函数:接受一个 CustomCollection 类型的对象作为参数,并将其存储在 collection 成员变量中。这表明 CustomObjectWrapper 是专门为操作 CustomCollection 设计的。
  • **isCollection**** 方法**:返回 true,表明这个包装器封装的是一个集合对象。这是对 ObjectWrapper 接口的具体实现,指示 MyBatis 这个包装器处理的是集合类型的数据。
  • **add**** 方法和 **addAll** 方法**:这两个方法允许向 collection 成员变量中添加单个元素或多个元素。这表明 CustomObjectWrapper 提供了基本的集合操作功能,使得可以通过这个包装器修改底层集合。
未实现的方法

代码中有多个方法标记为 “Not Implemented”,包括 getsetfindPropertygetGetterNamesgetSetterNamesgetSetterTypegetGetterTypehasSetterhasGetterinstantiatePropertyValue。这些方法的空实现表明 CustomObjectWrapper 在当前形态下不支持这些操作。这可能是因为这些操作对于 CustomCollection 类型的数据不是必需的,或者开发者打算在未来根据需要实现它们。

设计意图

CustomObjectWrapper 的设计意图是提供一个机制,通过它 CustomCollection 类型的对象可以在 MyBatis 中使用,同时提供了一种方式来扩展 MyBatis 默认的对象包装行为。通过实现 ObjectWrapper 接口,CustomObjectWrapper 使得 MyBatis 能够对 CustomCollection 进行操作,如添加元素,而不必担心其他更复杂的属性操作。

使用场景

这种自定义包装器的一个潜在使用场景是在 MyBatis 的 ORM 映射中,当需要处理非标准集合类型时。例如,如果 CustomCollection 提供了一些特殊的行为或优化,那么使用 CustomObjectWrapper 可以确保这些特性能够在 MyBatis 操作中得到支持和利用。
总的来说,CustomObjectWrapper 提供了一个框架,用于将自定义集合类型集成到 MyBatis 中,尽管它需要进一步的实现来支持所有的 ObjectWrapper 接口方法。这种设计允许开发者根据特定需求定制 MyBatis 的行为,从而提高框架的灵活性和可用性。

MapWrapper类解读

这段代码定义了 类,它继承自 BaseWrapper 并实现了 ObjectWrapper 接口,专门用于处理 Java Map 类型的对象。MapWrapper 类提供了一系列操作,使得 MyBatis 能够通过反射机制访问和修改 Map 对象的内容。以下是对该类关键功能和方法的详细解释:

构造函数
  • MapWrapper(MetaObject metaObject, Map<String, Object> map):接受一个 MetaObject 和一个 Map<String, Object> 作为参数。metaObject 用于访问对象的元数据,map 是这个 MapWrapper 实例将要操作的 Map 对象。
方法实现
  • **get(PropertyTokenizer prop)**:如果属性名(prop)带有索引,则解析并返回集合中的相应元素;如果没有索引,则直接从 Map 中获取对应的值。
  • **set(PropertyTokenizer prop, Object value)**:如果属性名(prop)带有索引,则在集合中设置相应的元素;如果没有索引,则在 Map 中设置对应的值。
  • **findProperty(String name, boolean useCamelCaseMapping)**:直接返回属性名,因为 Map 的属性查找不需要转换或处理。
  • **getGetterNames()**** 和 ****getSetterNames()**:返回 Map 中所有键的数组,表示所有可用的getter和setter方法名。
  • **getSetterType(String name)**** 和 ****getGetterType(String name)**:返回给定属性名对应值的类型。如果 Map 中包含该属性,则返回其值的类类型;否则,默认为 Object 类型。
  • **hasSetter(String name)**hasGetter(String name)**:对于 Map 类型,理论上所有的属性名都可以有setter和getter,因为可以在 Map 中插入或查询任何键。
  • **instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory)**:用于动态创建并初始化一个属性值。在这里,它创建了一个新的 HashMap 并将其设置为指定属性的值。
  • **isCollection()**:返回 false,因为 Map 不被视为 Collection 类型。
  • **add(Object element)**** 和 ****addAll(List<E> element)**:抛出 UnsupportedOperationException,因为对于 Map 类型的数据结构,单独添加元素的操作没有定义。
设计意图

MapWrapper 类的设计主要是为了让 MyBatis 能够更灵活地处理 Map 类型的对象。通过实现 ObjectWrapper 接口,它提供了一种标准化的方式来访问和修改 Map 中的数据,无论是单个值还是集合类型的元素。这种封装使得 MyBatis 在执行 SQL 操作时,能够方便地映射结果集到 Map,或者将 Map 中的数据用作查询的参数。

使用场景

在 MyBatis 中,MapWrapper 被用来处理那些需要动态查询参数或希望将查询结果映射到 Map 对象的场景。通过 MapWrapper,用户可以灵活地操作 Map,无需担心如何将数据库的列映射到 Map 的键上。这在处理动态查询或构建动态响应时尤其有用。

BeanWrapper类解读

这段代码定义了 BeanWrapper 类,它是 MyBatis 反射模块中的一个关键部分,用于封装和操作 Java Bean 对象。BeanWrapper 继承自 BaseWrapper 并实现了 ObjectWrapper 接口,提供了一系列方法来访问和修改 Java Bean 的属性。以下是对该类关键功能和方法的详细解释:

构造函数
  • BeanWrapper(MetaObject metaObject, Object object):构造函数接收一个 MetaObject 和一个 Java 对象。MetaObject 是 MyBatis 反射模块的核心,用于访问对象的元数据,而 object 是被封装的 Java Bean 对象。metaClass 是通过 MetaClass.forClass(object.getClass(), metaObject.getReflectorFactory()) 创建的,用于访问 Java Bean 的元数据,如属性的 getter 和 setter 方法。
主要方法
  • **get(PropertyTokenizer prop)**:根据 PropertyTokenizer 提供的属性名(可能包含索引或嵌套路径)获取属性值。如果属性名带有索引,则处理为集合或数组的访问;否则,通过 getBeanProperty 方法直接访问 Bean 的属性。
  • **set(PropertyTokenizer prop, Object value)**:根据 PropertyTokenizer 设置属性值。如果属性名带有索引,则处理为集合或数组的修改;否则,通过 setBeanProperty 方法修改 Bean 的属性。
  • **getBeanProperty**** 和 ****setBeanProperty**:这两个私有方法分别用于获取和设置 Java Bean 的属性值。它们通过 MetaClass 获取属性的 getter 或 setter Invoker,然后反射调用相应的方法。
  • 属性查找和类型获取方法:如 findPropertygetSetterTypegetGetterType 等方法,这些方法通过 MetaClass 实现,用于查找属性名、获取属性的类型等。
  • **hasSetter**** 和 ****hasGetter**:检查 Java Bean 是否有指定属性的 setter 或 getter 方法。
  • **instantiatePropertyValue**:如果需要,此方法用于实例化属性值。它通过 ObjectFactory 创建属性类型的新实例,并将其设置为属性值。
  • 集合操作相关方法isCollectionaddaddAll 方法在 BeanWrapper 中不支持,因为它封装的是单个 Java Bean 对象而非集合。
设计意图

BeanWrapper 的设计主要目的是封装对 Java Bean 对象的反射操作,提供统一的接口来访问和修改属性,支持嵌套属性和集合属性的操作。通过 MetaClass 和反射,BeanWrapper 能够动态地访问 Java Bean 的属性,这对于 MyBatis 在执行 SQL 语句时动态绑定参数值、映射查询结果到 Java 对象非常重要。

使用场景

在 MyBatis 的 ORM 映射过程中,BeanWrapper 被用于处理 Java Bean 类型的参数和结果对象。它允许 MyBatis 动态地访问和修改对象的属性,支持复杂的嵌套属性和集合属性的操作,从而使得 MyBatis 能够灵活地将数据库查询结果映射到 Java 对象,以及将 Java 对象作为查询参数。

CustomBeanWrapper类解读

类定义
  • CustomBeanWrapper 继承自 BeanWrapper 类,这意味着它继承了所有的公共方法和属性,使得可以覆盖(Override)或添加新的行为和功能。
构造函数
  • CustomBeanWrapper(MetaObject metaObject, Object object):构造函数接收两个参数:一个 MetaObject 和一个 Java 对象(object)。这与父类 BeanWrapper 的构造函数签名一致。在构造函数体中,它通过调用 super(metaObject, object) 将这些参数传递给父类的构造函数。
设计意图
  • 扩展 **BeanWrapper** 功能:虽然这个示例中 CustomBeanWrapper 没有实现任何新的功能或覆盖任何父类方法,实际使用时,你可以在这个类中添加新的方法或覆盖现有方法,以实现特定的行为或处理逻辑。例如,可以覆盖 getset 方法来添加日志记录、错误处理、属性值转换等自定义行为。
使用场景
  • 自定义对象包装器:如果你在使用 MyBatis 时有特殊需求,比如需要对某些 Java Bean 的属性访问或修改进行特殊处理,可以通过创建自定义的 BeanWrapper 来实现。这样可以保留 MyBatis 原有的映射和参数处理机制的同时,添加或修改特定的行为。

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

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

相关文章

1、初识JVM

一、JVM是什么&#xff1f; JVM的英文全称是 Java Virtual Machine&#xff0c;其中文译名为Java虚拟机。它在本质上就是是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件。 JVM执行流程如下 二、JVM有哪些功能&#xff1f; 2.1 解释和运行 对字节码文…

vue:功能【xlsx】动态行内合并

场景&#xff1a;纯前端导出excel数据&#xff0c;涉及到列合并、行合并。 注&#xff09;当前数据表头固定&#xff0c;行内数据不固定。以第一列WM为判断条件&#xff0c;相同名字的那几行数据合并单元格。合并的那几行数据&#xff0c;后面的列按需求进行合并。 注&#x…

SpringBoot + Vue项目(显示+删除+回显家居)

文章目录 1.显示家居信息1.com/sun/furn/controller/FurnController.java 添加方法2.postman测试3.src/views/HomeView.vue 修改el-table 并清空数据池tableData4.src/views/HomeView.vue 发送请求并取出数据1.方法池2.created阶段调用list方法3.结果展示 5.src/utils/request.…

【python】flask服务端响应与重定向处理

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

C语言经典算法-8

文章目录 其他经典例题跳转链接41.基数排序法42.循序搜寻法&#xff08;使用卫兵&#xff09;43.二分搜寻法&#xff08;搜寻原则的代表&#xff09;44.插补搜寻法45.费氏搜寻法 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠…

01 JDBC介绍

文章目录 JDBC本质版本使用核心APIDriverDriverManager驱动注册连接对象获取 Connection获取执行对象事务管理 Statement概述 ResultSet概述 JDBC本质 官方&#xff08;sun公司&#xff09;定义的一套操作所有关系型数据库的规则&#xff0c;即接口各个数据库厂商去实现这套接…

爬虫逆向实战(37)-某保险超市(AES,SHA256)

一、数据接口分析 主页地址&#xff1a;某保险超市 1、抓包 通过抓包可以发现数据接口是/tacpc/tiananapp/marketing_product_commodity/commodityList 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现&#xff0c;有一个jsonKey加密参…

Servlet使用

文章目录 简介一、快速入门二、Servlet 执行流程三、Servlet 生命周期四、Servlet 方法介绍五、Servlet 体系结构六、Servlet urlPattern配置七、XML 配置方式编写 Servlet 简介 一、快速入门 <dependencies><dependency><groupId>javax.servlet</groupId…

绝地求生:[更新周报] 3/20 不停机更新:商城无上新、23号七周年HOT TIME!

大家好&#xff0c;我是闲游盒。本周三3月20号&#xff0c;绝地求生不会有停机时间&#xff0c;大家可以随便玩~ ▲本周可选地图池 亚服/东南亚服&#xff1a;艾伦格、米拉玛、泰戈、荣都、卡拉金&#xff1b; 日服/韩服KAKAO服&#xff1a;艾伦格、泰戈、萨诺、荣都、卡拉金&a…

数据分析-Pandas序列滑动窗口配置参数

数据分析-Pandas序列滑动窗口配置参数 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

【保姆级】VsCode 安装GitHub Copilot实操教程

0. 前言 GitHub Copilot&#xff0c;俗称“副驾驶”&#xff0c;是GitHub携手OpenAI共同打造的一款革命性的人工智能代码辅助工具。通过将其插件化集成至编辑器&#xff08;如VS Code&#xff09;&#xff0c;Copilot能够为用户提供强大的代码自动补全功能&#xff0c;并根据用…

图神经网络实战(5)——常用图数据集

图神经网络实战&#xff08;5&#xff09;——常用图数据集 0. 前言0. 图数据集介绍2. Cora 数据集3. Facebook Page-Page 数据集小结系列链接 0. 前言 图数据集往往比单纯的连接集合更丰富&#xff0c;节点和边也可以具有表示分数、颜色、单词等的特征。在输入数据中包含这些…

get_local_ip.bat:快速获取IPv4地址

批处理脚本&#xff0c;用于在Windows命令提示符下获取本地计算机的IPv4地址。 echo off ipconfig | findstr IPv4 pause - echo off&#xff1a;这会关闭命令提示符窗口中的命令回显&#xff0c;使得在运行脚本时不会显示每条命令的执行结果。 - ipconfig&#xff1a;这是一…

IDEA 配置阿里规范检测

IDEA中安装插件 配置代码风格检查规范 使用代码风格检测 在代码类中&#xff0c;右键 然后会给出一些不符合规范的修改建议&#xff1a; 保存代码时自动格式化代码 安装插件&#xff1a; 配置插件&#xff1a;

探索未来教育:在线教育微服务的革新之路

随着互联网技术的不断发展&#xff0c;在线教育已经成为现代教育领域的重要组成部分。而在在线教育的发展过程中&#xff0c;微服务架构的应用正逐渐引起人们的关注和探讨。本文将深入探讨在线教育微服务的概念、优势以及未来发展趋势。 ## 什么是在线教育微服务&#xff1f; …

【how2j练习题】JS部分阶段练习

练习一 <!--练习&#xff0c;做一个简单的加法计算器--><html><input type"text" size "2" id "num1" ><input type"text" size "2" id "num2" ><input type"text" siz…

FSP40罗德与施瓦茨FSP40频谱分析仪

181/2461/8938产品概述&#xff1a; 频率范围:9千赫至40千兆赫 分辨率带宽:1赫兹至10兆赫 显示的平均噪音水平:-155分贝&#xff08;1赫兹&#xff09; 相位噪声:10 kHz时为-113 dB&#xff08;1Hz&#xff09; 附加滤波器:100 Hz至5 MHz的通道滤波器和RRC滤波器、1 Hz至3…

html5cssjs代码 029 CSS计数器

html5&css&js代码 029 CSS计数器 一、代码二、解释 该HTML代码定义了一个网页的结构和样式。在头部&#xff0c;通过CSS样式定义了body和h1-h2元素的样式。body元素的样式包括文本居中、计数器重置、字体颜色和背景颜色。h2元素的样式使用了CSS计数器来自动在标题前添加…

Visio 2003简体中文版软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; Visio 2003简体中文版是一款独立的专业绘图软件&#xff0c;适用于复制、可视化处理、分析和交流信息、系统和流程。不论是哪个版本的Visio&#xff…

石油炼化5G智能制造工厂数字孪生可视化平台,推进行业数字化转型

石油炼化5G智能制造工厂数字孪生可视化平台&#xff0c;推进行业数字化转型。在石油炼化行业&#xff0c;5G智能制造工厂数字孪生可视化平台的出现&#xff0c;为行业的数字化转型注入了新的活力。石油炼化行业作为传统工业的重要领域&#xff0c;面临着资源紧张、环境压力、安…