pqv*_*vst 46 android android-room android-architecture-components
比方说,我想要做的INNER JOIN两个实体之间Foo和Bar:
@Query("SELECT * FROM Foo INNER JOIN Bar ON Foo.bar = Bar.id")
List<FooAndBar> findAllFooAndBar();
Run Code Online (Sandbox Code Playgroud)
是否可以强制这样的返回类型?
public class FooAndBar {
Foo foo;
Bar bar;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试这样做时,我收到此错误:
error: Cannot figure out how to read this field from a cursor.
Run Code Online (Sandbox Code Playgroud)
我也尝试使表名称别名来匹配字段名称,但这也不起作用.
如果这不可能,我应该如何干净地构建包含两个实体的所有字段的兼容返回类型?
小智 47
道
@Query("SELECT * FROM Foo")
List<FooAndBar> findAllFooAndBar();
Run Code Online (Sandbox Code Playgroud)
类 FooAndBar
public class FooAndBar {
@Embedded
Foo foo;
@Relation(parentColumn = "Foo.bar_id", entityColumn = "Bar.id")
//Relation is designed to return a list
List<Bar> bar;
// If we are sure it returns only one entry
// Bar bar;
//Getter and setter...
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案似乎有效,但我并不为此感到自豪.你怎么看待这件事?
编辑:另一种解决方案
Dao,我更喜欢明确选择,但"*"会做的工作:)
@Query("SELECT Foo.*, Bar.* FROM Foo INNER JOIN Bar ON Foo.bar = Bar.id")
List<FooAndBar> findAllFooAndBar();
Run Code Online (Sandbox Code Playgroud)
类 FooAndBar
public class FooAndBar {
@Embedded
Foo foo;
@Embedded
Bar bar;
//Getter and setter...
}
Run Code Online (Sandbox Code Playgroud)
试试这种方式.例如,我有之间M2M(许多一对多)的关系Product和Attribute.许多产品都有很多属性,我需要通过排序记录来获取所有属性.Product.idPRODUCTS_ATTRIBUTES.DISPLAY_ORDERING
|--------------| |--------------| |-----------------------|
| PRODUCT | | ATTRIBUTE | | PRODUCTS_ATTRIBUTES |
|--------------| |--------------| |-----------------------|
| _ID: Long | | _ID: Long | | _ID: Long |
| NAME: Text | | NAME: Text | | _PRODUCT_ID: Long |
|______________| |______________| | _ATTRIBUTE_ID: Long |
| DISPLAY_ORDERING: Int |
|_______________________|
Run Code Online (Sandbox Code Playgroud)
所以,模型如下:
@Entity(
tableName = "PRODUCTS",
indices = [
Index(value = arrayOf("NAME"), unique = true)
]
)
class Product {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_ID")
var _id: Long = 0
@ColumnInfo(name = "NAME")
@SerializedName(value = "NAME")
var name: String = String()
}
@Entity(
tableName = "ATTRIBUTES",
indices = [
Index(value = arrayOf("NAME"), unique = true)
]
)
class Attribute {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_ID")
var _id: Long = 0
@ColumnInfo(name = "NAME")
@SerializedName(value = "NAME")
var name: String = String()
}
Run Code Online (Sandbox Code Playgroud)
而"加入"表将是:
@Entity(
tableName = "PRODUCTS_ATTRIBUTES",
indices = [
Index(value = ["_PRODUCT_ID", "_ATTRIBUTE_ID"])
],
foreignKeys = [
ForeignKey(entity = Product::class, parentColumns = ["_ID"], childColumns = ["_PRODUCT_ID"]),
ForeignKey(entity = Attribute::class, parentColumns = ["_ID"], childColumns = ["_ATTRIBUTE_ID"])
]
)
class ProductAttribute {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "_ID")
var _id: Long = 0
@ColumnInfo(name = "_PRODUCT_ID")
var _productId: Long = 0
@ColumnInfo(name = "_ATTRIBUTE_ID")
var _attributeId: Long = 0
@ColumnInfo(name = "DISPLAY_ORDERING")
var displayOrdering: Int = 0
}
Run Code Online (Sandbox Code Playgroud)
在,AttributeDAO为了获得所有属性Product._ID,您可以执行以下操作:
@Dao
interface AttributeDAO {
@Query("SELECT ATTRIBUTES.* FROM ATTRIBUTES INNER JOIN PRODUCTS_ATTRIBUTES ON PRODUCTS_ATTRIBUTES._ATTRIBUTE_ID = ATTRIBUTES._ID INNER JOIN PRODUCTS ON PRODUCTS._ID = PRODUCTS_ATTRIBUTES._PRODUCT_ID WHERE PRODUCTS._ID = :productId ORDER BY PRODUCTS_ATTRIBUTES.DISPLAY_ORDERING ASC")
fun getAttributesByProductId(productId: Long): LiveData<List<Attribute>>
}
Run Code Online (Sandbox Code Playgroud)
如果您有任何疑问,请告诉我.
另一个选择是只编写一个新的POJO来表示JOIN查询的结果结构(它甚至支持列重命名以避免冲突):
@Dao
public interface FooBarDao {
@Query("SELECT foo.field1 AS unique1, bar.field1 AS unique2 "
+ "FROM Foo INNER JOIN Bar ON Foo.bar = Bar.id")
public List<FooBar> getFooBars();
static class FooBar {
public String unique1;
public String unique2;
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅:room / accessing-data.html#query-multiple-tables
是否可以强制这样的返回类型?
您可以尝试对和@Embedded进行注释。这将告诉 Room 尝试从查询中获取列并将它们倒入和实例中。我只对实体进行了尝试,但文档表明它也应该适用于 POJO。foobarfoobar
但是,如果两个表具有相同名称的列,则这可能无法正常工作。
| 归档时间: |
|
| 查看次数: |
25134 次 |
| 最近记录: |