我现在正在构建一个带有本地数据库的Android应用程序
表结构如下所示(来自API)
@Entity
data class Person(
name: Name,
... ... ...
... ... ...
)
data class Name(
legalName: String.
common: String
)
这是SQL代码,我试过用法律的的名字
@Query("SELECT * FROM person WHERE name.legalName = :legalName")
suspend fun getPersonByName (legalName: String): Person?
这给了我编译错误,因为我们不能按名称搜索。legalName在房间数据库。此外,我们有静态名单的人(只有法律名称)在主页(没有ID或其他合理的字段来执行搜索)
我们是否有适当的方法来搜索带有legalName字段的用户?
1条答案
按热度按时间tvokkenx1#
Room使用
@Entity
注解来确定底层SQLite表模式。这样注解的类是一个对象,但对象的各个字段/成员存储为表中的列,而不是对象。此类列只能是以下特定类型:-
因此,对象不能直接存储或存储SQLite没有对象的概念/理解,只是将列分组到表中。
在您的情况下,name字段是一个Name对象,而Room将需要2个类型转换器:-
因此,要查询对象的字段/成员,您需要考虑如何相应地表示和搜索它。
不会有name.legalName列,只有name列,并且表示取决于TypConverter,搜索(WHERE子句)也是如此。
现在根据您的代码考虑以下内容:
@Embedded
作为复制字段/成员(legalName和common as字段)的替代方法因此,name列将需要类型转换器,因为每个类的2个注解t中的每一个都带有
@TypeConverter
(注意单数),必须定义定义类型转换器的类(参见下面的***TheDatabase***类)。因此:-实体(在本例中只有一个)必须在
@Database
注解中定义,用于扩展RoomDatabase()的抽象类。所以:-@TypeConverters
注解(复数)除了定义TypeConverter所在的一个或多个类之外,还定义了作用域 (@Database
是最大的作用域)。在这个阶段,可以编译项目(CTRL + F9),注解处理将生成一些代码。重要的是TheDatabase_Impl在java中(生成)* 名称与@Database注解类相同,后缀为_Impl*。这包括一个方法createAllTables,它是创建SQLite表时使用的SQL。person表的SQL是:-
可以看出,id列是主键,name列是name对象的转换表示,然后是法律的和common列,因为name对象通过otherName字段@Embedded。
最后用下面的@Dao注解接口(允许添加一些数据)来完成:
主要活动为:-
项目运行,然后使用App Inspection查看实际数据库,然后:-
名称列包含字符串
{"common":"Fred Bloggs","legalName":"Frederick Bloggs"}
**因此,用于查找以Fred开头的所有法律的名称的WHERE子句可以是
WHERE instr(name,',\"legalName\":\"Fred')
或WHERE name LIKE '%,\"legalName\":\"Fred%'
,"legalName":"Fred
的名称,或者作为公共名称的一部分或整个字符串的某个其他部分的名称,即,可能难以预测将来可能是什么结果。对于替代
@Embedded
Name对象,legalName和common列更容易搜索,以Fred开头的合法名称的等效搜索可以是Fred不可能出现在满足条件的其他地方。搜索只是针对单个列/值,没有其他内容。索引列很可能会提高效率。
将
@Dao
注解接口DAO修改为:-主要活动为:-
然后运行(安装后第一次)日志,日志包含:-
即,在该有限演示中,预期结果为任一方式。
Name.legalName
和Name.common
不是访问数据的方式,它只是用于轻松区分相似值的文本。