Greedao官方文档 查询 翻译

时间:2021-08-10 05:40:23

查询
1 QueryBuilder
2限制,偏移和分页
3自定义类型作为参数
4查询和LazyList
4.1多次执行查询
5在多个线程中执行查询
6原始查询
7删除查询
8疑难解答查询

查询返回符合特定条件的实体。在greenDAO中,您可以使用原始SQL来制定查询,或者使用QueryBuilder。

此外,查询支持延迟加载结果,当在大结果集上操作时,可以节省内存和性能。

QueryBuilder

编写SQL可能很困难,并且容易出现错误,这些错误仅在运行时被察觉。该QueryBuilder的类,您可以建立您的实体没有SQL自定义查询,并有助于在编译时已检测错误。

简单条件示例:查询所有名为“Joe”的用户,按姓氏排序:
List joes = userDao.queryBuilder()
.where(Properties.FirstName.eq(“Joe”))
.orderAsc(Properties.LastName)
.list();

嵌套条件示例:获取1970年10月或之后出生的名为“Joe”的用户。

假设我们有一个用户的生日作为年,月和日的单独属性。然后,我们可以表达的条件以更正式的方式: 一是名称为“乔” AND (每年的出生是更大的比1970年OR (每年的出生是1970年和月的诞生是等于给或大于比10 )) (该10月,10月)。
QueryBuilder qb = userDao.queryBuilder();
qb.where(Properties.FirstName.eq(“Joe”),
qb.or(Properties.YearOfBirth.gt(1970),
qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
List youngJoes = qb.list();

限制,偏移和分页
有时候,您只需要一个查询的子集,例如在用户界面中显示的前10个元素。当您拥有大量实体时,这是非常有用的(和资源),并且您不能仅使用“where”语句来限制结果。 QueryBuilder < T >有定义限制和偏移的方法:

limit(int):限制查询返回的结果数。

offset(int):结合limit (int )设置查询结果的偏移量 。将跳过第一个 偏移结果,并且结果的总数将受 limit (int )限制。你不能使用offset 无限制(int )。

自定义类型作为参数

通常,greenDAO以透明方式映射查询中使用的类型。例如, boolean被映射到 INTEGER,具有0或1个值,并且 Date被映射到 (long )INTEGER 值。
自定义类型是一个例外:在构建查询时,总是必须使用数据库值类型。例如,如果使用转换器将枚举类型映射到 int值,则应在查询中使用 int值。

查询和LazyList

该查询类表示可以被执行多次的查询。当您使用QueryBuilder中的一个方法 来获取结果(如 list ())时, QueryBuilder < T >在内部使用 Query < T >类。如果要多次运行同一个查询,应该在QueryBuilder < T >上 调用 build() 来创建查询而不执行它。

greenDAO支持唯一结果(0或1个结果)和结果列表。如果您期望在Query < T >(或 QueryBuilder < T > )上 有唯一的结果调用 unique (),这将为您提供单个结果或null,如果没有找到匹配的实体。如果你的用例禁止null作为结果,调用 uniqueOrThrow ()将保证返回一个非空的实体(否则会抛出一个 DaoException)。

如果希望多个实体作为查询结果,请使用以下方法之一:

list ()所有实体都加载到内存中。结果通常是一个ArrayList。最方便使用。
listLazy ()实体按需加载到内存中。一旦列表中的元素第一次被访问,它将被加载并缓存以备将来使用。必须关闭。
listLazyUncached ()一个“虚拟”实体列表:对列表元素的任何访问都导致从数据库加载其数据。必须关闭。
listIterator ()让我们通过按需加载数据(lazily)来遍历结果。数据未缓存。必须关闭。
方法 listLazy (), listLazyUncached ()和 listIterator ()使用greenDAO的LazyList类。要按需加载数据,它保存对数据库游标的引用。这就是为什么你必须确保关闭惰性列表和迭代器(通常在try / finally块)。

从缓存的懒惰列表 listLazy (),并从懒惰迭代 的ListIterator ()自动关闭的光标,一旦所有的元素被访问或运行。调用 close ()如果列表处理过早停止。

多次执行查询

使用QueryBuilder构建查询后,可以重新使用 Query对象以稍后执行查询。这比总是创建新的Query对象更有效。如果查询参数不更改,可以再次调用。
但是,可以更改参数:为每个更改的参数调用 setParameter方法。当前,通过基于零的参数索引来寻址各个参数。索引基于将参数传递给QueryBuilder的顺序。例如:

Java

// fetch users with Joe as a first name born in 1970
Query query = userDao.queryBuilder().where(
Properties.FirstName.eq(“Joe”), Properties.YearOfBirth.eq(1970)
).build();
List joesOf1970 = query.list();

// using the same Query object, we can change the parameters
// to search for Marias born in 1977 later:
query.setParameter(0, “Maria”);
query.setParameter(1, 1977);
List mariasOf1977 = query.list();

在多个线程中执行查询

如果在多个线程中使用查询,则必须调用 forCurrentThread ()获取当前线程的Query实例。Query的对象实例绑定到构建查询的自己的线程。

这使您可以安全地设置Query对象上的参数,而其他线程不能干扰。如果其他线程尝试在查询上设置参数或执行查询绑定到另一个线程,将抛出异常。像这样,你不需要一个synchronized语句。实际上,你应该避免锁定,因为如果并发事务使用相同的Query对象,这可能导致死锁。

每次 调用forCurrentThread ()时,在使用其构建器构建查询时,将参数设置为初始参数。

原始查询

如果QueryBuilder不提供您所需要的,有两种方法来执行仍然返回实体对象的原始SQL。第一种,首选的方法是使用QueryBuilder和 WhereCondition 。StringCondition。这样,您可以将任何SQL片段作为WHERE子句传递给查询构建器。

以下代码是一个理论示例,说明如何运行子选择(使用连接将是更好的解决方案):

Java

Query query = userDao.queryBuilder().where(
new StringCondition(“_ID IN ” +
“(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)”)
).build();

Query query = userDao.queryBuilder().where(
new StringCondition(“_ID IN ” +
“(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)”)
).build();
QueryBuilder之外的第二种方法是使用 queryRaw或 queryRawCreate方法。它们允许您传递一个原始SQL字符串,它附加在SELECT和实体列之后。这样,你可以有任何WHERE和ORDER BY子句来选择实体。可以使用别名T来引用实体表 。

以下示例显示如何创建一个查询,该查询使用连接检索名为“admin”的组的用户(同样,greenDAO 本身支持连接,这只是为了演示):

Query query = userDao.queryRawCreate(
“, GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID”, “admin”
);
注意:可以使用生成的常量引用表和列名称。这是建议避免打字错误,因为编译器将检查名称。在实体的DAO,你会发现 TABLENAME保存数据库表的名称,以及一个内部类 属性与所有属性(场常数 COLUMNNAME)。

删除查询

批量删除不会删除单个实体,但是所有实体都符合一些条件。要执行批量删除,请创建一个QueryBuilder,调用其 buildDelete ()方法,并执行返回的 DeleteQuery。

API的这一部分可以在将来改变,例如可以添加方便的方法。

请注意,大量删除目前不会影响身份范围中的实体,例如,如果已删除的实体先前已经缓存,并且通过其ID(加载方法)访问,您可以“重新激活”已删除实体。请考虑立即清除身份范围,如果这可能会导致您的用例的问题。

疑难解答查询

您的查询不返回预期结果?在QueryBuilder上启用SQL和参数记录有两个静态标志:

Java

QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;

当调用其中一个构建方法时,它们将记录生成的SQL命令和传递的值,并将它们与实际所需的值进行比较。此外,它可能有助于将生成的SQL复制到一些SQLite数据库浏览器,并看看它如何执行。