1.介绍
PropertyTokenizer 是 MyBatis 中的一个工具类,主要用于处理属性表达式(property expressions)。在 MyBatis 中,属性表达式是用于访问对象属性的一种语法,类似于 Java 中的点号操作符。例如,对于一个对象 user,可以使用属性表达式 "user.name" 来访问其 name 属性。PropertyTokenizer 类提供了一些方法来解析和处理这样的属性表达式。
2.主要作用
PropertyTokenizer 的主要作用如下:
- 解析属性表达式:PropertyTokenizer 可以将属性表达式字符串解析为对象的属性名和索引信息。例如,对于属性表达式 "user[0].name",PropertyTokenizer 可以解析出属性名为 "user",索引为 0。
- 获取下级属性:PropertyTokenizer 可以获取当前属性的下级属性表达式。例如,对于属性表达式 "user[0].name",通过 PropertyTokenizer 可以获取下级属性表达式 "name"。
- 判断是否有子表达式:PropertyTokenizer 可以判断当前属性是否有下级属性表达式。例如,对于属性表达式 "user[0].name",PropertyTokenizer 可以判断是否存在下级属性表达式。
- 获取索引类型:如果属性是一个数组或集合类型,PropertyTokenizer 可以获取索引的类型。例如,对于属性表达式 "user[0].name",PropertyTokenizer 可以获取索引的类型为 Integer。
3.主要功能测试
// 创建一个 PropertyTokenizer 对象来解析属性表达式
PropertyTokenizer tokenizer = new PropertyTokenizer("user[0].name");
// 获取属性名
String propertyName = tokenizer.getName(); // "user"
// 判断是否有下级属性
boolean hasNestedProperty = tokenizer.hasNext(); // true
// 获取下级属性表达式
String nestedProperty = tokenizer.getChildren(); // "name"
// 获取索引名
String indexedName = tokenizer.getIndexedName(); //user[0]
// 获取索引值
String index = tokenizer.getIndex(); // "0"
4.源码注释
package org.apache.ibatis.reflection.property;
import java.util.Iterator;
/**
* @author Clinton Begin
* 属性标记器
*/
/**
* 假设传入的为student[sId].name
* 则各个属性得到以下结果
*
* 该属性标记器只能处理一级,即点后面的都作为children
*/
public class PropertyTokenizer implements Iterator<PropertyTokenizer> {
// student.name.string
private String name;
// student[sId]
private final String indexedName;
// sId
private String index;
// name
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);
}
}
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.");
}
}