本篇主要介绍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. 文件访问时间简记(Modify time 和 Change time)

    [root@77-29-68-bx-core]# stat hql.out File: 'hql.out' Size: 13750 Blocks: 32 IO Block: 4096 regular ...

  2. Batch入门教程丨第一章:部署与Hello World!(下)

    在上期分享的内容中,我们已经掌握了基础理论知识,今天我们将继续了解和学习与Windows Batch有关的知识和编程方法,如何编写和运行Windows Batch程序,脚本语言的入门方式等,从而能够更 ...

  3. Kali学习笔记42:SQL手工注入(4)

    前三篇文章都是在讲发现SQL注入漏洞 如何查询得到所有的信息 那么另一条思路还未尝试过:能否修改数据? 例如这样: '; update users set user='yiqing' where us ...

  4. [Swift]LeetCode13. 罗马数字转整数 | Roman to Integer

    Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 ...

  5. [Swift]LeetCode381. O(1) 时间插入、删除和获取随机元素 - 允许重复 | Insert Delete GetRandom O(1) - Duplicates allowed

    Design a data structure that supports all following operations in averageO(1) time. Note: Duplicate ...

  6. [Swift]LeetCode940. 不同的子序列 II | Distinct Subsequences II

    Given a string S, count the number of distinct, non-empty subsequences of S . Since the result may b ...

  7. Docker 搭建pxc集群 + haproxy + keepalived 高可用(一)

    一.首先需要安装好docker,安装方法可以参考之前一篇博文Centos7安装docker [root@localhost ~]# systemctl start docker [root@local ...

  8. Vue中实现一个无限加载列表

    参考 https://www.jianshu.com/p/0a3aebd63a14 一个需要判断的地方就是加载中再次触发滚动的时候,不要获取数据. <!DOCTYPE html> < ...

  9. SpringBoot配置 druid 数据源配置 慢SQL记录

    spring: datasource: url: jdbc:mysql://127.0.0.12:3306/test?autoReconnect=true&useUnicode=true&am ...

  10. nginx替换响应内容

    因为想要将非业务域名内嵌到微信小程序中,所以用到了nginx的反向代理功能来替换域名实现盗站(缘起:http://www.cnblogs.com/kenwar/p/8288882.html),但是替换 ...