查询视图不适用于 DBFlow

Posted

技术标签:

【中文标题】查询视图不适用于 DBFlow【英文标题】:Query a view doesn't works with DBFlow 【发布时间】:2017-08-29 12:29:23 【问题描述】:

我正在使用 DBflow 来查询包含多个表的 SQLite 数据库。由于我的查询包含很多连接,因此使用 DBflow 连接有点难以阅读:

SQLite.select()
.from(Plant.class).as("p0")
                .innerJoin(Definition.class).as("d0")
                    .on(Plant_Table.definitionId.withTable(NameAlias.builder("p0").build()).eq(Definition_Table.definitionId.withTable(NameAlias.builder("d0").build())))
                .innerJoin(Picture.class).as("pi0")
                    .on(Plant_Table.pictureId.withTable(NameAlias.builder("p0").build()).eq(Picture_Table.pictureid.withTable(NameAlias.builder("pi0").build())))
                .innerJoin(SpaceAssociation.class)
                    .on(Plant_Table.pictureId.withTable(NameAlias.builder("p0").build()).eq(SpaceAssociation_Table.plantId1))
                    .innerJoin(Plant.class).as("p1")
                        .on(SpaceAssociation_Table.plantId2.eq(Plant_Table.plantId.withTable(NameAlias.builder("p1").build())))
                        .innerJoin(Definition.class).as("d1")
                            .on(Plant_Table.definitionId.withTable(NameAlias.builder("p1").build()).eq(Definition_Table.definitionId.withTable(NameAlias.builder("d1").build())))
                        .innerJoin(Picture.class).as("pi1")
                            .on(Plant_Table.pictureId.withTable(NameAlias.builder("p1").build()).eq(Picture_Table.pictureid.withTable(NameAlias.builder("pi1").build())))
                    .innerJoin(Flag.class)
                        .on(SpaceAssociation_Table.flagId.eq(Flag_Table.flagId))
                        .innerJoin(FlagDefinition.class)
                            .on(Flag_Table.flagDefinitionId.eq(FlagDefinition_Table.flagDefinitionId));

所以我决定在我的数据库中创建一个 SQL 视图并查询这个视图会更好:

SQLite.select()
    .from(PlantsAssociations.class)
    .queryList();

更具可读性!问题是我收到了这个错误

database.sqlite.SQLiteException: no such table: PlantsAssociations (code 1): , while compile: SELECT * FROM PlantsAssociations

如果我复制并粘贴这个生成的查询并直接在我的数据库上的 SQLite 控制台中执行它,它就可以工作...

我检查了official documentation,上面写着“声明为表格”:

视图:声明为表,支持视图(虚拟表)。

所以我声明我的视图就像一张桌子:

@Table(database = PlantsDatabase.class)
public class PlantsAssociations extends BaseModel 

    @PrimaryKey
    @Column(name = "p0_plant_id")
    private int p0PlantId;

    @Column(name = "p0_definition")
    private String p0Definition;

    @Column(name = "p0_picture")
    private String p0Picture;

    @Column(name = "p1_plant_id")
    private int p1PlantId;

    @Column(name = "p1_definition")
    private String p1Definition;

    @Column(name = "p1_picture")
    private String p1Picture;

    @Column(name = "flag_id")
    private int flagId;

    @Column(name = "flag_definition")
    private String flagDefinition;

    public PlantsAssociations()  

    public PlantsAssociations(int p0PlantId, String p0Definition, String p0Picture, int p1PlantId, String p1Definition, String p1Picture, int flagId, String flagDefinition) 
        this.p0PlantId = p0PlantId;
        this.p0Definition = p0Definition;
        this.p0Picture = p0Picture;
        this.p1PlantId = p1PlantId;
        this.p1Definition = p1Definition;
        this.p1Picture = p1Picture;
        this.flagId = flagId;
        this.flagDefinition = flagDefinition;
    

    public int getP0PlantId() 
        return p0PlantId;
    

    public void setP0PlantId(int p0PlantId) 
        this.p0PlantId = p0PlantId;
    

    public String getP0Definition() 
        return p0Definition;
    

    public void setP0Definition(String p0Definition) 
        this.p0Definition = p0Definition;
    

    public String getP0Picture() 
        return p0Picture;
    

    public void setP0Picture(String p0Picture) 
        this.p0Picture = p0Picture;
    

    public int getP1PlantId() 
        return p1PlantId;
    

    public void setP1PlantId(int p1PlantId) 
        this.p1PlantId = p1PlantId;
    

    public String getP1Definition() 
        return p1Definition;
    

    public void setP1Definition(String p1Definition) 
        this.p1Definition = p1Definition;
    

    public String getP1Picture() 
        return p1Picture;
    

    public void setP1Picture(String p1Picture) 
        this.p1Picture = p1Picture;
    

    public int getFlagId() 
        return flagId;
    

    public void setFlagId(int flagId) 
        this.flagId = flagId;
    

    public String getFlagDefinition() 
        return flagDefinition;
    

    public void setFlagDefinition(String flagDefinition) 
        this.flagDefinition = flagDefinition;
    

但如前所述,看起来 DBflow 生成了正确的查询,但是通过在 SQLite 端查找视图出现了问题......

所以我检查了官方SQLite documentation,看起来我做得对:

CREATE VIEW PlantsAssociations
as
select  p0.plantid as p0_plant_id,
    d0.definition as p0_definition,
    pi0.picture as p0_picture,
    p1.plantid as p1_plant_id,
    d1.definition as p1_definition,
    pi1.picture as p1_picture,
    flag.flagId as flag_id,
    flagDefinition.definition as flag_definition
from plant p0
  inner join definition d0
    on p0.definitionId = d0.definitionId
  inner join picture pi0
    on p0.pictureId = pi0.pictureId
  inner join spaceAssociation
    on p0.plantId = spaceAssociation.plantId1
    inner join plant p1
      on spaceAssociation.plantId2 = p1.plantid
 inner join definition d1
        on p1.definitionid = d1.definitionid
      inner join flag
        on spaceAssociation.flagId = flag.flagId
        inner join flagDefinition
          on flag.flagDefinitionId = flagDefinition.flagDefinitionId         
      inner join picture pi1
        on p1.pictureid = pi1.pictureid
where d0.definition != d1.definition

我错过了什么吗?

[编辑] 我只是增加了数据库版本号,但现在查询只返回一个空列表...

【问题讨论】:

你继续阅读ModelViews 感谢您的评论。我尝试了 ModelViews 并得到了相同的结果。最大的问题是我没有任何错误消息,只是一个空的结果集,所以很难弄清楚这一点。顺便说一句,我将它与现有数据库一起使用,我创建的视图是为了更好地阅读我的代码,而 ModelViews 类迫使我用我的视图 dbflow 查询声明一个@ModelViewQuery(但这个视图永远不会被创建,因为它已经存在)....所以即使我可以让它工作它也不能解决就绪性问题。也许使用 ORM 不是一个好的选择。 我想我找到了部分解决方案。当我使用 SQLite 查询数据库时,我的 Plant 表中有一个 pictureId 列。但看起来 DBFlow 找不到它SQLiteException: no such column: pictureid。也许它也找不到视图,但什么也不说,只返回一个空结果。但我不知道为什么它找不到存在于数据库和我的模型中的列。 【参考方案1】:

卸载应用程序,然后./gradelw clean 并重新安装应用程序。

它有效...

【讨论】:

以上是关于查询视图不适用于 DBFlow的主要内容,如果未能解决你的问题,请参考以下文章

CSS 媒体查询最近不适用于 iPad

Spring Data:休眠查询缓存不适用于派生查询

媒体查询不适用于 Android

dbflow 批量 增删查改

媒体查询不适用于横向

graphQl突变查询不适用于变量