在JAVA对象中,如何进行有效的查询呢,这一直是个很值得探讨的问题.大家知道,在XML中,要找元素如何找呢?没错,通过XPATH
是个不错的办法,同样道理,新近发现原来在JAVA中,也居然有象XPATH里的东西,这就是著名的apache commons库中包含的jxpath包中所提供的功能,这可以在 http://jakarta.apache.org/commons/jxpath/中找到相关下载.下面来简单介绍一下(注:本文内容主要来自
http://today.java.net/pub/a/today/2006/08/03/java-object-querying-using-jxpath.html
,本人有所改动和润色)
什么是JXPATH
首先,JXPATH是通过简单的表达式,可以在JAVA的类对象层次中进行查询.我们还是来看简单的例子来说明问题:
比如,我们的例子中,有一些公司,每间公司有不同的部门,每个不同的雇员,而且当然,公司有它们的CEO.雇员还有比如姓名,电话等属性.
假设我们要查找在California的公司中,有哪些公司的部门中有超过10位员工的话,以前会这样写的
for (Iterator companies = database.getCompanies().iterator(); companies.hasNext();)
{
//获得所有公司
Company company = (Company)companies.next();
//获得在California的公司
if (company.getLocation().equals("CAA")) {
for (Iterator departments =company.getDepartments().iterator();departments.hasNext(); )
{
//获得公司的所有部门
Department department =
(Department)departments.next();
if (department.getEmployees().size() > 10) {
System.out.println(department);
}
}
}
}
而如果用JXPATH的话,可以这样写
Iterator departments = context.iterate(
"/companies[location='CA']" +
"/departments[count(employees) > 10]");
while (departments.hasNext()) {
System.out.println(departments.next());
}
可以看到,用了JXPATH的话,只需要简单指定好表达式,马上就可以了.下面来简单介绍下一些写法
比如:
要多的所有的公司:/companies
获得公司下的部门:/companies/departments
获得在某个地方的公司:/companies[location='CA'],这里,location为companies的属性
要获得位于CA的公司中含有开发部门的公司的话,可以这样:
/companies[location='CA']/departments[contains(name, 'Development')]
要获得某个部门雇员数大于10人的:/companies/departments[count(employees) > 10]
要获得SUN公司下第二个部门:/companies[name='Sun Microsystems']/departments[2]
要注意的是,JXPATH的序号是从1开始,不是从0开始
和XPATH类似,可以象这样
/companies[name='Sun Microsystems']/
departments[last()]
接下来说下如何配合JAVA代码来实现查询
首先,对比如对于company,employee,department这三个类,都必须设置getter,setter方法,
然后,比如要有
public List getCompanies();
后,则可以使用
/Companies来查询了
而每个公司下面要查询所有的部门的话,先设置
public List getDepartments();
方法,
然后再用/companies/departments可以查询了;
提供public String getName();方法,则在下面的场景中会被调用:
/companies/departments[name='Server Development']
又比如,假设已经设置了一个MAP,里面存放某人的电话,比如有工作电话,私人电话:
Map numbers = employee.getTelephoneNumbers();
String workNumber =
(String)numbers.get("work number");
上面是取得某个雇员的工作电话,但必须这样写JXPATH
.../employees[1]/
telephoneNumbers[@name='work number']
@name是用来指定MAP中的KEY的,而不能简单将上面的写成
.../employees[1]/
telephoneNumbers/work number
最后,我们可以结合起来使用jxpath了,首先先声明根对象,也就是说,你要先构造出一个类层次出来,比如已经构造出一个类层次,叫
database类,则:
JXPathContext context = JXPathContext.
newContext(database);
其中database类里面已经有所有的公司的实例了,这里先取出其上下文context;然后,
Iterator departments = context.iterate("/companies[location='WA']" +
"/departments[count(employees) > 10]");
则取出所有在WA的那些部门人数>10的所有公司的集合了
最后输出:
while (departments.hasNext()) {
Department dept = (Department)i.next();
}
看,多简单呀.
最后,强烈大家去下载本文的例子去看看,在ECLIPSE里跑一下就可以了,写的很清晰
代码: http://today.java.net/today/2006/08/03/source_code.tar.gz
是个不错的办法,同样道理,新近发现原来在JAVA中,也居然有象XPATH里的东西,这就是著名的apache commons库中包含的jxpath包中所提供的功能,这可以在 http://jakarta.apache.org/commons/jxpath/中找到相关下载.下面来简单介绍一下(注:本文内容主要来自
http://today.java.net/pub/a/today/2006/08/03/java-object-querying-using-jxpath.html
,本人有所改动和润色)
什么是JXPATH
首先,JXPATH是通过简单的表达式,可以在JAVA的类对象层次中进行查询.我们还是来看简单的例子来说明问题:
比如,我们的例子中,有一些公司,每间公司有不同的部门,每个不同的雇员,而且当然,公司有它们的CEO.雇员还有比如姓名,电话等属性.
假设我们要查找在California的公司中,有哪些公司的部门中有超过10位员工的话,以前会这样写的
for (Iterator companies = database.getCompanies().iterator(); companies.hasNext();)
{
//获得所有公司
Company company = (Company)companies.next();
//获得在California的公司
if (company.getLocation().equals("CAA")) {
for (Iterator departments =company.getDepartments().iterator();departments.hasNext(); )
{
//获得公司的所有部门
Department department =
(Department)departments.next();
if (department.getEmployees().size() > 10) {
System.out.println(department);
}
}
}
}
而如果用JXPATH的话,可以这样写
Iterator departments = context.iterate(
"/companies[location='CA']" +
"/departments[count(employees) > 10]");
while (departments.hasNext()) {
System.out.println(departments.next());
}
可以看到,用了JXPATH的话,只需要简单指定好表达式,马上就可以了.下面来简单介绍下一些写法
比如:
要多的所有的公司:/companies
获得公司下的部门:/companies/departments
获得在某个地方的公司:/companies[location='CA'],这里,location为companies的属性
要获得位于CA的公司中含有开发部门的公司的话,可以这样:
/companies[location='CA']/departments[contains(name, 'Development')]
要获得某个部门雇员数大于10人的:/companies/departments[count(employees) > 10]
要获得SUN公司下第二个部门:/companies[name='Sun Microsystems']/departments[2]
要注意的是,JXPATH的序号是从1开始,不是从0开始
和XPATH类似,可以象这样
/companies[name='Sun Microsystems']/
departments[last()]
接下来说下如何配合JAVA代码来实现查询
首先,对比如对于company,employee,department这三个类,都必须设置getter,setter方法,
然后,比如要有
public List getCompanies();
后,则可以使用
/Companies来查询了
而每个公司下面要查询所有的部门的话,先设置
public List getDepartments();
方法,
然后再用/companies/departments可以查询了;
提供public String getName();方法,则在下面的场景中会被调用:
/companies/departments[name='Server Development']
又比如,假设已经设置了一个MAP,里面存放某人的电话,比如有工作电话,私人电话:
Map numbers = employee.getTelephoneNumbers();
String workNumber =
(String)numbers.get("work number");
上面是取得某个雇员的工作电话,但必须这样写JXPATH
.../employees[1]/
telephoneNumbers[@name='work number']
@name是用来指定MAP中的KEY的,而不能简单将上面的写成
.../employees[1]/
telephoneNumbers/work number
最后,我们可以结合起来使用jxpath了,首先先声明根对象,也就是说,你要先构造出一个类层次出来,比如已经构造出一个类层次,叫
database类,则:
JXPathContext context = JXPathContext.
newContext(database);
其中database类里面已经有所有的公司的实例了,这里先取出其上下文context;然后,
Iterator departments = context.iterate("/companies[location='WA']" +
"/departments[count(employees) > 10]");
则取出所有在WA的那些部门人数>10的所有公司的集合了
最后输出:
while (departments.hasNext()) {
Department dept = (Department)i.next();
}
看,多简单呀.
最后,强烈大家去下载本文的例子去看看,在ECLIPSE里跑一下就可以了,写的很清晰
代码: http://today.java.net/today/2006/08/03/source_code.tar.gz