使用泛型 return RavenDB StreamResult
Using generics to return a RavenDB StreamResult
我努力保持我的代码紧凑,最重要的是,在处理 RavenDB 的 querydsl 类型(即我存储在数据库中的类型)时坚持 "don't repeat yourself" 原则。
我有两种情况迫使我使用 copy/paste 方法或用 if 语句乱扔代码:
- 我想将 generic querydsl 类型作为参数传递给方法
- 我想 return 来自方法的通用 querydsl 类型
第一种情况:类似这样
public int RetrieveStuff(<myGenericType>)
{
QGenericType qgt= QGenericType.GenericType;
IRavenQueryable<GenericType> query = session.query(GenericType.class, "GenericType/ByName");
}
第二种情况:
public CloseableIterator<StreamResult<GenericType>> RetrieveMoreStuff(String id)
{
doSomething();
return Session.advanced().stream(query); //type depends on the operation
}
由于我无法编译上述方法,我不得不为每种类型创建一个单独的(但功能相同的)方法!像这样:
private CloseableIterator<StreamResult<supertype>> retrieveStuff();
private CloseableIterator<StreamResult<subtype1>> retrieveStuff1();
private CloseableIterator<StreamResult<subtype2>> retrieveStuff2();
等等
我不清楚以下内容:
- 这是一个 Java 泛型相关的问题,还是 Querydsl 类型强 "bind" 到它们在创建时给定的类型?换句话说,Querydsl 类型 "maps" 与 Querydsl 类型不可分割链接的类型是什么?
- 为什么我不能这样做:
IRavenQueryable<supertype> query = session.query(subtype.class, "Something/ByName")
?
- 是否有可能完全以这种方式对 querydsl 类型和存储在 RavenDB 中的类型应用多态性?如果我在 RavenDB 中存储超类型及其子类型,我能否以某种方式在查询代码中与通用集合进行交互?
如果有可能原则上,我将非常感谢有效的方法签名和最少的内部代码以使查询正常工作。
非常感谢您的帮助。
您可以使用:
IRavenQueryable<? extends Animal> query = session.query(Dog.class)
然而,要对多态查询建模,您应该在索引中使用 WhereEntityIs
:
示例:https://github.com/ravendb/ravendb-jvm-client/blob/7845a881d917e1be56aa6913aa5aba85cedd7190/Raven.Client.Java/src/test/java/net/ravendb/client/connection/WhereEntityIsTest.java#L16
QueryDSL 的唯一目的是避免在查询中使用字符串(类型安全)。它可以用于寻址简单的属性,也可以用于嵌套。例子:
https://github.com/ravendb/ravendb-jvm-client/blob/68ca05f0f3e158ec1702d64eca11d1e6b5dc8a17/Raven.Client.Java/src/test/java/net/ravendb/tests/querying/UsingDynamicQueryWithRemoteServerTest.java#L127
我努力保持我的代码紧凑,最重要的是,在处理 RavenDB 的 querydsl 类型(即我存储在数据库中的类型)时坚持 "don't repeat yourself" 原则。 我有两种情况迫使我使用 copy/paste 方法或用 if 语句乱扔代码:
- 我想将 generic querydsl 类型作为参数传递给方法
- 我想 return 来自方法的通用 querydsl 类型
第一种情况:类似这样
public int RetrieveStuff(<myGenericType>)
{
QGenericType qgt= QGenericType.GenericType;
IRavenQueryable<GenericType> query = session.query(GenericType.class, "GenericType/ByName");
}
第二种情况:
public CloseableIterator<StreamResult<GenericType>> RetrieveMoreStuff(String id)
{
doSomething();
return Session.advanced().stream(query); //type depends on the operation
}
由于我无法编译上述方法,我不得不为每种类型创建一个单独的(但功能相同的)方法!像这样:
private CloseableIterator<StreamResult<supertype>> retrieveStuff();
private CloseableIterator<StreamResult<subtype1>> retrieveStuff1();
private CloseableIterator<StreamResult<subtype2>> retrieveStuff2();
等等
我不清楚以下内容:
- 这是一个 Java 泛型相关的问题,还是 Querydsl 类型强 "bind" 到它们在创建时给定的类型?换句话说,Querydsl 类型 "maps" 与 Querydsl 类型不可分割链接的类型是什么?
- 为什么我不能这样做:
IRavenQueryable<supertype> query = session.query(subtype.class, "Something/ByName")
? - 是否有可能完全以这种方式对 querydsl 类型和存储在 RavenDB 中的类型应用多态性?如果我在 RavenDB 中存储超类型及其子类型,我能否以某种方式在查询代码中与通用集合进行交互?
如果有可能原则上,我将非常感谢有效的方法签名和最少的内部代码以使查询正常工作。
非常感谢您的帮助。
您可以使用:
IRavenQueryable<? extends Animal> query = session.query(Dog.class)
然而,要对多态查询建模,您应该在索引中使用 WhereEntityIs
:
示例:https://github.com/ravendb/ravendb-jvm-client/blob/7845a881d917e1be56aa6913aa5aba85cedd7190/Raven.Client.Java/src/test/java/net/ravendb/client/connection/WhereEntityIsTest.java#L16
QueryDSL 的唯一目的是避免在查询中使用字符串(类型安全)。它可以用于寻址简单的属性,也可以用于嵌套。例子: https://github.com/ravendb/ravendb-jvm-client/blob/68ca05f0f3e158ec1702d64eca11d1e6b5dc8a17/Raven.Client.Java/src/test/java/net/ravendb/tests/querying/UsingDynamicQueryWithRemoteServerTest.java#L127