本篇主要介绍mybatis反射工具中用到的三个属性工具类:PropertyTokenizer、PropertyNamer、PropertyCopier。

PropertyTokenizer:

主要用来解析Mybatis使用过程中遇到的类似"order[0].items[0].name"这种由"."和"[ ]"组成的表达式:

public class PropertyTokenizer implements Iterator<PropertyTokenizer> {

    /** ________________________
* |order[0]|.items[0].name|
* —————————————————————————
*
* 第一级表达式:name=order;indexName=order[0];index=0;children=item[0].name
*/
/**
* 当前表达式的名称
*/
private String name;
/**
* 当前表达式的索引名
*/
private String indexedName;
/**
* 当前表达式的索引
*/
private String index;
/**
* 子表达式
*/
private String children; /**
* 初始化上述属性
*/
public PropertyTokenizer(String fullname) {
int delim = fullname.indexOf('.');
if (delim > -1) {
name = fullname.substring(0, delim);
children = fullname.substring(delim + 1);
} else {
name = fullname;
children = null;
}
indexedName = name;
delim = name.indexOf('[');
if (delim > -1) {
index = name.substring(delim + 1, name.length() - 1);
name = name.substring(0, delim);
}
} public String getName() {
return name;
} public String getIndex() {
return index;
} public String getIndexedName() {
return indexedName;
} public String getChildren() {
return children;
} @Override
public boolean hasNext() {
return children != null;
} @Override
public PropertyTokenizer next() {
return new PropertyTokenizer(children);
} @Override
public void remove() {
throw new UnsupportedOperationException("Remove is not supported, as it has no meaning in the context of properties.");
}
}

PropertyNamer:

主要是用于实体类中getter、setter方法与相应属性的名称转换和相应的一些检测判断操作:

public final class PropertyNamer {

    private PropertyNamer() {
// Prevent Instantiation of Static Class
} /**
* get/set方法名转换为相应的属性名称
*/
public static String methodToProperty(String name) {
if (name.startsWith("is")) {
name = name.substring(2);
} else if (name.startsWith("get") || name.startsWith("set")) {
name = name.substring(3);
} else {
throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'.");
} if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
} return name;
} /**
* 检测方法名是否get、set方法
*/
public static boolean isProperty(String name) {
return name.startsWith("get") || name.startsWith("set") || name.startsWith("is");
} /**
* 检测方法名是否get方法
*/
public static boolean isGetter(String name) {
return name.startsWith("get") || name.startsWith("is");
} /**
* 检测方法名是否get方法
*/
public static boolean isSetter(String name) {
return name.startsWith("set");
}
}

PropertyCopier:

主要用于相同类型的两个对象之间进行属性值的拷贝:

public final class PropertyCopier {

    private PropertyCopier() {
// Prevent Instantiation of Static Class
} public static void copyBeanProperties(Class<?> type, Object sourceBean, Object destinationBean) {
Class<?> parent = type;
while (parent != null) {
/**
* 获取到parent中所有被声明的字段,包括public、protected、default、private修饰的,除了
* 继承父类的字段
*/
final Field[] fields = parent.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
/**
* 将sourceBean的属性值设置到destinationBean中
            * set方法也不会将所有的属性值复制,有限制,具体限制可查看set源码
*/
field.set(destinationBean, field.get(sourceBean));
} catch (Exception e) {
// Nothing useful to do, will only fail on final fields, which will be ignored.
}
}
parent = parent.getSuperclass();
}
}
}

Mybatis框架基础支持层——反射工具箱之实体属性Property工具集(6)的更多相关文章

  1. Mybatis框架基础支持层——反射工具箱之Reflector&ReflectorFactory(3)

    说明:Reflector是Mybatis反射工具的基础,每个Reflector对应一个类,在Reflector中封装有该类的元信息, 以及基于类信息的一系列反射应用封装API public class ...

  2. Mybatis框架基础支持层——反射工具箱之对象工厂ObjectFactory&DefaultObjectFactory(5)

    ObjectFactory官方简介:MyBatis每次创建结果集对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成. 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认 ...

  3. Mybatis框架基础支持层——反射工具箱之MetaClass(7)

    简介:MetaClass是Mybatis对类级别的元信息的封装和处理,通过与属性工具类的结合, 实现了对复杂表达式的解析,实现了获取指定描述信息的功能 public class MetaClass { ...

  4. Mybatis框架基础支持层——反射工具箱之泛型解析工具TypeParameterResolver(4)

    简介:TypeParameterResolver是一个工具类,提供一系列的静态方法,去解析类中的字段.方法返回值.方法参数的类型. 在正式介绍TypeParameterResolver之前,先介绍一个 ...

  5. Mybatis框架基础支持层——日志模块(8)

    前言: java开发中常用的日志框架有Log4j,Log4j2,Apache Commons Log,java.util.logging,slf4j等,这些工具对外的接口不尽相同.为了统一这些工具的接 ...

  6. Mybatis框架基础支持层——解析器模块(2)

    解析器模块,核心类XPathParser /** * 封装了用于xml解析的类XPath.Document和EntityResolver */ public class XPathParser { / ...

  7. MyBatis源码分析-基础支持层反射模块Reflector/ReflectorFactory

    本文主要介绍MyBatis的反射模块是如何实现的. MyBatis 反射的核心类Reflector,下面我先说明它的构造函数和成员变量.具体方法下面详解. org.apache.ibatis.refl ...

  8. 精尽 MyBatis 源码分析 - 基础支持层

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  9. MyBatis 框架 基础应用

    1.ORM的概念和优势 概念: 对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据 ...

随机推荐

  1. Git生成ssh密钥指定文件

    ssh-keygen 使用的时候可以直接使用 -f 参数 指定密钥保存文件,省去后面生成成功后再提示选择保存文件: ssh-keygen -t rsa -C "abc@example.com ...

  2. Android Studio 直播弹幕

    我只是搬运:https://blog.csdn.net/HighForehead/article/details/55520199 写的很好很详细,挺有参考价值的 demo直通车:https://do ...

  3. R语言之Apriori算法

    ---恢复内容开始--- 1.概念 关联分析:用于发现隐藏在大型数据集中的有意义的联系 项集:0或多个项的集合.例如:{啤酒,尿布,牛奶,花生} 是一个4-项集,意义想象成爸爸去超市买啤酒和花生,给儿 ...

  4. java 23种设计模式 深入理解【转】

    以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive ...

  5. 平衡二叉树(AVL)介绍及其实现

    一.平衡二叉树 任何一个数据的查找过程都需要从根结点出发,沿某一个路径朝叶子结点前进.因此查找中数据比较次数与树的形态密切相关. 对于二叉树来说,当树中每个结点左右子树高度大致相同时,树高为logN. ...

  6. [Swift]LeetCode215. 数组中的第K个最大元素 | Kth Largest Element in an Array

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  7. [Swift]LeetCode288. 唯一单词缩写 $ Unique Word Abbreviation

    An abbreviation of a word follows the form <first letter><number><last letter>. Be ...

  8. [Swift]LeetCode508. 出现次数最多的子树元素和 | Most Frequent Subtree Sum

    Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a ...

  9. 受到 1 万点暴击,二狗子被 DDoS 攻击的惨痛经历

    二狗子的遭遇 “好消息,好消息,免费 DDoS 攻击软件上线了,性感黑客在线攻击,帮您攻克所有商业难题.”二狗子不知道在看着什么网站,新买的 Mac 中发出热闹的声音. 二狗子想知道“DDoS 是什么 ...

  10. 启动MongoDB shell客户端会什么会一闪而过

    解决办法: 在MongoDB shell客户端根目录下右击选择 "在此处打开命令窗口"; 在命令窗口敲入mongod --dbpath=d:/mongodb/data ; //我的 ...