我试试房间图书馆,顺便说一句,这是一个令人印象深刻的图书馆!
所以我有两个@Entity和一个由两个实体组成的POJO。
我的第一个实体=>
@Entity(tableName = "colis")
public class ColisEntity {
@PrimaryKey
private String idColis;
private String label;
}
我的第二个实体带有外键=>
@Entity(tableName = "step",
foreignKeys = @ForeignKey(entity = ColisEntity.class,
parentColumns = "idColis",
childColumns = "idColis",
onDelete = CASCADE))
public class StepEntity {
@PrimaryKey(autoGenerate = true)
private Integer idStep;
private String idColis;
private Long date;
}
我的POJO与@Relation
public class ColisWithSteps {
@Embedded
public ColisEntity colisEntity;
@Relation(parentColumn = "idColis", entityColumn = "idColis")
public List<StepEntity> stepEntityList;
}
所有这些东西都适用于我的@Dao和Repositories。
但我希望我的@Relation列表按日期排序,我不希望StepEntity实现Comparable并制作Collections.sort()。
因为我认为排序应该由数据库完成,而不是在查询之后。
有什么想法吗?
感谢。
答案 0 :(得分:2)
documentation for Relationships提示了它的工作方式
此方法需要Room运行两个查询,因此请向该方法添加@Transaction批注,以确保整个操作都是原子执行的。
这有效地消除了关系正在做什么的整个过程。您必须为每个实体编写一个查询,然后是一个事务查询,但是最终结果与使用关系所得到的结果是无法区分的(至少据我所知)。
您的(Kotlin)代码如下:
@Query("SELECT * FROM colis WHERE idColis = :id")
fun getColisEntity(id : Int) :
@Query("SELECT * FROM step WHERE idColis = :id ORDER BY date")
fun getStepEntities(id : Int) : List<StepEntity>
@Transaction
fun getColisWithSteps(id : Int) : ColisWithSteps{
return ColisWithSteps(getColisEntity(id), getStepEntities(id))
}
getColisWithSteps(id : Int)
会完全返回您要查找的内容,其结果与Relation所提供的内容相同,只是订购的自由度更高。
答案 1 :(得分:1)
以下是在房间v1.0.0中使用Relation进行排序的工作解决方案。
我写过kotlin
@Query("SELECT * FROM colis INNER JOIN step ON colis.idColis= step.idColis ORDER BY date DESC")
fun getAllColisWithSteps():Flowable<List<ColisWithSteps>>
这是jave版本:
@Query("SELECT * FROM colis INNER JOIN step ON colis.idColis= step.idColis ORDER BY date DESC")
public List<ColisWithSteps> getAllColisWithSteps()
更新了ColisWithSteps类:
public class ColisWithSteps {
@Embedded
public ColisEntity colisEntity;
@Relation(parentColumn = "idColis", entityColumn = "idColis",entity = StepEntity.class)
public List<StepEntity> stepEntityList;
}
答案 2 :(得分:0)
我认为在当前版本的Room中有一种内置的方法可以做到这一点。
我可以建议两种可能的解决方案。
@Relation
的POJO。这样您就可以按照自己喜欢的方式订购StepEntity
个实例。当您获得ColisEntity
和所有已排序的相应StepEntity
条记录时,您可以在回购图层中构建ColisWithSteps
对象并将其返回。StepEntity
条记录,然后使用此答案Views in Room即可使用它。我认为选项1在您的情况下是最好的 - 是的,它将涉及使用两个查询,但至少它不会破坏您的数据库迁移,您将能够利用Room来发挥优势。 / p>
答案 3 :(得分:0)
我知道OP对Collection.Sort()说不,但考虑到情况,这似乎是最干净的方法。正如我上面所说,我认为最好避免每次需要访问数据时都要进行单独的查询。首先实现Comparable。
public class StepEntity implements Comparable<StepEntity >{
@PrimaryKey(autoGenerate = true)
private Integer idStep;
private String idColis;
private Long date;
@Override
public int compareTo(@NonNull StepEntity stepEntity ) {
int dateOther = stepEntity.date;
//ascending order
return this.date - dateOther;
//descending order
//return dateOther - this.date;
}
}
现在使用它在现有的@Relation POJO
中添加一个方法包装器public class ColisWithSteps {
@Embedded
public ColisEntity colisEntity;
@Relation(parentColumn = "idColis", entityColumn = "idColis")
public List<StepEntity> stepEntityList;
//add getter method
public List<StepEntity> getSortedStepEntityList(){
Collections.Sort(stepEntityList);
return stepEntityList;
}
}
答案 4 :(得分:0)
我遇到了同样的问题,这是一个解决方案:
@Query("SELECT * FROM step INNER JOIN colis ON step.idColis = colis.idColis ORDER BY date DESC")
fun getAllColisWithSteps():LiveData<List<ColisWithSteps>>
下面是一个示例,解释了INNER JOIN的作用:
要从多个表中查询数据,请使用INNER JOIN子句。的 INNER JOIN子句组合了相关表中的列。
假设您有两个表:A和B。
A具有a1,a2和f列。 B具有b1,b2和f列。 A表 使用名为f的外键列链接到B表。 对于A表中的每一行,INNER JOIN子句将f列的值与B表中f列的值进行比较。如果A表中的f列的值等于B表中的f列的值,则它将a1,a2,b1,b2列中的数据合并,并将该行包括在结果集中。