如何使用 DataNucleus JDOQL API 查询集合中的对象?
How can I use DataNucleus JDOQL API to Query Object within Collection?
我正在尝试弄清楚如何使用 RDBMS 和 DataNucleus 查询持久对象集合中的对象。我有一个用户、一个 ObjectAttribute 和一个 ObjectAttributeDefinition。
用户可能有多个 ObjectAttribute,每个 ObjectAttribute 都有一个 ObjectAttributeDefinition。这个想法是一些定义可以定义一大堆 ObjectAttributes。
我想检查是否存在一个 ObjectAttribute,其值字段与指定字段一致,并且其 ObjectAttributeDefinition 包含字段 attributeName,其值设置为我指定的 attributeName。
换句话说:
for (ObjectAttribute attribute : userAttributeCollection)
{
if(attribute.value == myValue && attribute.definition.attributeName == myName)
return success;
}
我有以下三个class:
用户
@Component
@PersistenceCapable
public class User implements Serializable
{
@Persistent(table="USER_ATTRIBUTES")
@Join(column="USER_ID")
@Element(column = "ATTRIBUTE_ID")
private List<ObjectAttribute> userAttributeCollection;
///... Constructors, getters and setters, Primary Key definition below
}
对象属性
@Component
@PersistenceCapable
public class ObjectAttribute implements Serializable
{
@Persistent(table="ATTRIBUTE_DEFINITION_JOIN")
@Join(column="ATTRIBUTE_ID")
@Element(column="DEFINITION_ID")
private ObjectAttributeDefinition definition;
private String value;
//...
@Override
public boolean equals(Object obj)
{
ObjectAttribute testObject = (ObjectAttribute) obj;
if (this.value.equals(testObject.getValue()) && this.definition.getAttributeName().equals(testObject.getDefinition().getAttributeName())) {
return true;
}
else {
return false;
}
}
}
对象属性定义
public class ObjectAttributeDefinition implements Serializable
{
public enum ATTRIBUTE_NAMES
{
//Google Search Page Attribute (https://cloud.google.com/appengine/docs/java/search/)
SEARCH_PAGE("SEARCH_PAGE");
private final String text;
ATTRIBUTE_NAMES(String type)
{
this.text = type;
}
@Override
public String toString()
{
return text;
}
}
private ATTRIBUTE_NAMES attributeName;
//...
@Override
public boolean equals(Object obj)
{
ObjectAttributeDefinition definition = (ObjectAttributeDefinition) obj;
return this.attributeName.equals(definition.attributeName);
}
}
进一步说明
我有一个 DAO class 和为访问这些持久对象定义的方法列表。整体基础设施似乎设置正确,因为持久对象和再次检索它们似乎工作正常。
我确保对象属性唯一性的方法是查询 ObjectAttribute 的值和 ObjectAttributeDefinition 的名称。
我试过的
基本查询
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val & att.definition.attributeName == :def");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.us.orm.general.models.ObjectAttributeDefinition; import com.us.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue(), myAtt.getDefinition().getAttributeName());
基本查询错误
Query has reference to member "attributeName" of class "com.us.orm.general.models.ObjectAttribute" yet this doesnt exist!
正如 JDO Specification 所暗示的那样,一切都应该非常 Java。但是,出于某种原因,我似乎无法访问低于第一层的对象。
所以我试图破解比较。
在 ObjectAttribute 中使用 equals() 覆盖
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att == :val");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.us.orm.general.models.ObjectAttributeDefinition; import com.us.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt);
在 ObjectAttribute 结果中使用 equals() 覆盖
我收到零结果。查看为此对象生成的实际 SQL,我得到以下信息:
SELECT DISTINCT 'com.us.orm.user.models.User' AS NUCLEUS_TYPE,`A0`.`CREATED`,`A0`.`EMAIL`,`A0`.`FIRSTNAME`,`A0`.`ISACTIVE`,`A0`.`LASTMODIFIED`,`A0`.`LASTNAME`,`A0`.`PASSWORD`,`A0`.`PROFILEBANNERBUCKET`,`A0`.`PROFILEBANNERFILENAME`,`A0`.`PROFILEIMAGEBUCKET`,`A0`.`PROFILEIMAGEFILENAME`,`A0`.`USERID`,`A0`.`USERNAME` FROM `USER` `A0` INNER JOIN `USER_ATTRIBUTES` `B0` ON `A0`.`USERID` = `B0`.`USER_ID` INNER JOIN `OBJECTATTRIBUTE` `C0` ON `B0`.`ATTRIBUTE_ID` = `C0`.`ATTRIBUTEID` WHERE `C0`.`ATTRIBUTEID` = null
空引用的 ATTRIBUTEID 检查永远不会 return 结果。所以这是在我的代码与 DataNucleus 的接口方面,但我又不知所措了。
也许我可以覆盖 ObjectAttribute 和 ObjectAttributeDefinition 上的 equals()..
等于覆盖 ObjectAttribute 和 ObjectAttributeDefinition
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val & att.definition == :def");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.up.orm.general.models.ObjectAttributeDefinition; import com.up.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue(), myAtt.getDefinition());
等于重写 ObjectAttribute 和 ObjectAttributeDefinition 结果
rval returns null,不生成数据库查询,不抛异常。
仅使用值比较
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.up.orm.general.models.ObjectAttributeDefinition; import com.up.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue());
仅使用值比较结果
这return是期望值,但没有使用定义比较,只达到了目标的一半。
有什么方法可以查询二级深度的定义及其字段吗?
我找到了解决办法。我可能在文档中错过了这一点,但我不知道声明的变量实际上在 SQL 中执行 "cross join"。这是解决问题的一个非常重要的方面。
查询如下:
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val & definition.attributeName == :name");
query.declareVariables("ObjectAttribute att; ObjectAttributeDefinition definition");
query.declareImports("import com.us.orm.general.models.ObjectAttributeDefinition; import com.us.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue(), name.toString());
我缺少过滤器的 "cross joined" 变量部分(以 ObjectAttributeDefinition 的形式)。现在它就在那里,查询正在提取预期的结果。
我正在尝试弄清楚如何使用 RDBMS 和 DataNucleus 查询持久对象集合中的对象。我有一个用户、一个 ObjectAttribute 和一个 ObjectAttributeDefinition。
用户可能有多个 ObjectAttribute,每个 ObjectAttribute 都有一个 ObjectAttributeDefinition。这个想法是一些定义可以定义一大堆 ObjectAttributes。
我想检查是否存在一个 ObjectAttribute,其值字段与指定字段一致,并且其 ObjectAttributeDefinition 包含字段 attributeName,其值设置为我指定的 attributeName。
换句话说:
for (ObjectAttribute attribute : userAttributeCollection)
{
if(attribute.value == myValue && attribute.definition.attributeName == myName)
return success;
}
我有以下三个class:
用户
@Component
@PersistenceCapable
public class User implements Serializable
{
@Persistent(table="USER_ATTRIBUTES")
@Join(column="USER_ID")
@Element(column = "ATTRIBUTE_ID")
private List<ObjectAttribute> userAttributeCollection;
///... Constructors, getters and setters, Primary Key definition below
}
对象属性
@Component
@PersistenceCapable
public class ObjectAttribute implements Serializable
{
@Persistent(table="ATTRIBUTE_DEFINITION_JOIN")
@Join(column="ATTRIBUTE_ID")
@Element(column="DEFINITION_ID")
private ObjectAttributeDefinition definition;
private String value;
//...
@Override
public boolean equals(Object obj)
{
ObjectAttribute testObject = (ObjectAttribute) obj;
if (this.value.equals(testObject.getValue()) && this.definition.getAttributeName().equals(testObject.getDefinition().getAttributeName())) {
return true;
}
else {
return false;
}
}
}
对象属性定义
public class ObjectAttributeDefinition implements Serializable
{
public enum ATTRIBUTE_NAMES
{
//Google Search Page Attribute (https://cloud.google.com/appengine/docs/java/search/)
SEARCH_PAGE("SEARCH_PAGE");
private final String text;
ATTRIBUTE_NAMES(String type)
{
this.text = type;
}
@Override
public String toString()
{
return text;
}
}
private ATTRIBUTE_NAMES attributeName;
//...
@Override
public boolean equals(Object obj)
{
ObjectAttributeDefinition definition = (ObjectAttributeDefinition) obj;
return this.attributeName.equals(definition.attributeName);
}
}
进一步说明
我有一个 DAO class 和为访问这些持久对象定义的方法列表。整体基础设施似乎设置正确,因为持久对象和再次检索它们似乎工作正常。
我确保对象属性唯一性的方法是查询 ObjectAttribute 的值和 ObjectAttributeDefinition 的名称。
我试过的
基本查询
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val & att.definition.attributeName == :def");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.us.orm.general.models.ObjectAttributeDefinition; import com.us.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue(), myAtt.getDefinition().getAttributeName());
基本查询错误
Query has reference to member "attributeName" of class "com.us.orm.general.models.ObjectAttribute" yet this doesnt exist!
正如 JDO Specification 所暗示的那样,一切都应该非常 Java。但是,出于某种原因,我似乎无法访问低于第一层的对象。
所以我试图破解比较。
在 ObjectAttribute 中使用 equals() 覆盖
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att == :val");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.us.orm.general.models.ObjectAttributeDefinition; import com.us.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt);
在 ObjectAttribute 结果中使用 equals() 覆盖
我收到零结果。查看为此对象生成的实际 SQL,我得到以下信息:
SELECT DISTINCT 'com.us.orm.user.models.User' AS NUCLEUS_TYPE,`A0`.`CREATED`,`A0`.`EMAIL`,`A0`.`FIRSTNAME`,`A0`.`ISACTIVE`,`A0`.`LASTMODIFIED`,`A0`.`LASTNAME`,`A0`.`PASSWORD`,`A0`.`PROFILEBANNERBUCKET`,`A0`.`PROFILEBANNERFILENAME`,`A0`.`PROFILEIMAGEBUCKET`,`A0`.`PROFILEIMAGEFILENAME`,`A0`.`USERID`,`A0`.`USERNAME` FROM `USER` `A0` INNER JOIN `USER_ATTRIBUTES` `B0` ON `A0`.`USERID` = `B0`.`USER_ID` INNER JOIN `OBJECTATTRIBUTE` `C0` ON `B0`.`ATTRIBUTE_ID` = `C0`.`ATTRIBUTEID` WHERE `C0`.`ATTRIBUTEID` = null
空引用的 ATTRIBUTEID 检查永远不会 return 结果。所以这是在我的代码与 DataNucleus 的接口方面,但我又不知所措了。
也许我可以覆盖 ObjectAttribute 和 ObjectAttributeDefinition 上的 equals()..
等于覆盖 ObjectAttribute 和 ObjectAttributeDefinition
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val & att.definition == :def");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.up.orm.general.models.ObjectAttributeDefinition; import com.up.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue(), myAtt.getDefinition());
等于重写 ObjectAttribute 和 ObjectAttributeDefinition 结果
rval returns null,不生成数据库查询,不抛异常。
仅使用值比较
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val");
query.declareVariables("ObjectAttribute att");
query.declareImports("import com.up.orm.general.models.ObjectAttributeDefinition; import com.up.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue());
仅使用值比较结果
这return是期望值,但没有使用定义比较,只达到了目标的一半。
有什么方法可以查询二级深度的定义及其字段吗?
我找到了解决办法。我可能在文档中错过了这一点,但我不知道声明的变量实际上在 SQL 中执行 "cross join"。这是解决问题的一个非常重要的方面。
查询如下:
Query query = pm.newQuery(User.class, "userAttributeCollection.contains(att) & att.value == :val & definition.attributeName == :name");
query.declareVariables("ObjectAttribute att; ObjectAttributeDefinition definition");
query.declareImports("import com.us.orm.general.models.ObjectAttributeDefinition; import com.us.orm.general.models.ObjectAttribute");
query.setResultClass(User.class);
rval = (List<User>) query.execute(myAtt.getValue(), name.toString());
我缺少过滤器的 "cross joined" 变量部分(以 ObjectAttributeDefinition 的形式)。现在它就在那里,查询正在提取预期的结果。