mybatis底层组件-property常用工具

Property常用工具

PropertyTokenizer

PropertyTokenizer主要用来解析类似users[0].age 这样由.和[]组成的表达式
先看一个解析的例子

public static void main(String[] args) {
    PropertyTokenizer tokenizer = new PropertyTokenizer("users[0].age");
    printInfo(tokenizer);
    while (tokenizer.hasNext()) {
      tokenizer = tokenizer.next();
      printInfo(tokenizer);
    }
  }
  public static void printInfo(PropertyTokenizer tokenizer) {
    System.out.println(tokenizer.indexedName);
    System.out.println(tokenizer.name);
    System.out.println(tokenizer.index);
  }

输出结果为

users[0]
users
0
age
age
null

看下源码,以fullname为users[0].age为例

public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
	// users
	private String name;
	// users[0]
	private final String indexedName;
	// 0
	private String index;
	// age
	private final 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);
	  }
	}
	@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.");
  }
}

PropertyTokenizer以.进行分割,并且实现了Iterator接口,可以对.分割的字符串进行迭代解析

PropertyNamer

PropertyNamer主要就是将方法名解析为属性名

public final class PropertyNamer {

  private PropertyNamer() {
    // Prevent Instantiation of Static Class
  }

  public static String methodToProperty(String name) {
  	// 去除方法名前面的get is set
    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'.");
    }
	// 将去除get set is的剩余内容,第一个字符大写,并且如果第二个字符也是大写字符,那么不会将第一个字符转换成小写字符,比如getUUID,解析出来的属性名称就是UUID
    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;
  }

  public static boolean isProperty(String name) {
    return isGetter(name) || isSetter(name);
  }

  public static boolean isGetter(String name) {
    return (name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2);
  }

  public static boolean isSetter(String name) {
    return name.startsWith("set") && name.length() > 3;
  }

}

PropertyCopier

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) {
      // 获取在当前类中声明的属性
      final Field[] fields = parent.getDeclaredFields();
      for (Field field : fields) {
        try {
          try {
            field.set(destinationBean, field.get(sourceBean));
          } catch (IllegalAccessException e) {
            if (Reflector.canControlMemberAccessible()) {
              field.setAccessible(true);
              field.set(destinationBean, field.get(sourceBean));
            } else {
              throw e;
            }
          }
        } catch (Exception e) {
          // Nothing useful to do, will only fail on final fields, which will be ignored.
        }
      }
      parent = parent.getSuperclass();
    }
  }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值