我不知道如何在实体的属性中绑定子查询选择,我只需要将“main_game”子查询绑定到我的实体的 mainGame String 属性中:
我的道:
@Dao
public interface GamesDao {
@Query("SELECT *, (SELECT g_nested._id FROM games as g_nested, game_groups as gg WHERE g_nested._id = gg._game_group AND g_nested.is_main = 1 AND gg._game = g._id) as main_game FROM games as g")
List<GameEntity> getAll();
}
我的游戏实体:
@Entity(tableName = "games")
public class GameEntity extends GenericIndexEntity {
@NonNull
@ColumnInfo(name = "gen")
private Integer gen;
@NonNull
@ColumnInfo(name = "is_main")
private Integer isMain;
@Ignore
@ColumnInfo(name = "main_game")
private String mainGame;
public GameEntity(@NonNull String indexNumber, String name, String nameEs, String nameIt, String nameFr, String nameDe, String namePt, String nameRu, @NonNull Integer gen, @NonNull Integer isMain, String mainGame) {
super(indexNumber, name, nameEs, nameIt, nameFr, nameDe, namePt, nameRu);
this.gen = gen;
this.isMain = isMain;
this.mainGame = mainGame;
}
@NonNull
public Integer getGen() {
return gen;
}
public void setGen(@NonNull Integer gen) {
this.gen = gen;
}
@NonNull
public Integer getIsMain() {
return isMain;
}
public void setIsMain(@NonNull Integer isMain) {
this.isMain = isMain;
}
public String getMainGame() {
return mainGame;
}
public void setMainGame(String mainGame) {
this.mainGame = mainGame;
}
}
我尝试使用@Ignore、@ColumnInfo 的多种组合删除它们,但它根本不绑定值:
@Ignore
@ColumnInfo(name = "main_game")
private String mainGame;
这种方式就是扔
Tried the following constructors but they failed to match: ... param:mainGame -> matched field:unmatched]
如果我从查询有效的属性中删除所有标签,但不会填充值。
我错过了什么吗?
如果您
@Ignore
一个成员变量,那么 Room 会将该成员变量视为一列。如果您不这样做@Ignore
成员变量,它将成为表中的一列。
假设您不希望成员变量成为表中的一列,但在某个时候您想要检索并分配一个值,那么您将需要使用一个 POJO,它的成员变量可能不是
@Ignored
在您的情况下,一个额外的成员变量(由于扩展类的复杂性)。
由于表的明显复杂性,即 GameEntity 扩展 GenericIndexEntity 并且可能扩展其他类,硬编码所有涉及的列可能是一场噩梦。
因此,您可能希望在 POJO 中使用
@Embedded
注释来简化工作。但是,这样做将包括@Ignore
d main_game 列。所以你需要使用另一个成员变量。
所以像:-
public class GameWithMainGamePOJO {
@Embedded
GameEntity gameEntity;
private String mg;
public void setGameEntity(GameEntity gameEntity) {
this.gameEntity = gameEntity;
}
public String getMg() {
return mg;
}
public void setMg(String mainGame) {
this.mg = mainGame;
}
/* Perhaps what you want */
public GameEntity getGameEntity() {
gameEntity.setMainGame(this.mg);
return gameEntity;
}
}
在这种情况下,您可能希望输出一个名为 mg 的列,然后可能使用 getGameEntity 方法,该方法应该返回一个 GameEntity,其中 main_game 集具有提取的值。
演示
这是一个基于可用代码的演示,由其他代码组成,重要的是查询 a) 获取 GameEntity 列(包括来自扩展 GenericIndexEntity *(我拼凑的版本) 的列)。
为了演示这个,使用了一个简化的查询,
@Dao
带注释的界面是:-
@Dao
public interface GamesDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
long insert(GameEntity gameEntity);
@Query("SELECT *, (SELECT 'MG1'||g.gen) as mg FROM games as g")
List<GameWithMainGamePOJO> getAll();
}
完整的、经常拼凑在一起的用于演示的代码(减去上面的 GamesDao 接口):-
GenericIndexEntity(拼凑在一起)
class GenericIndexEntity {
private String indexNumber;
private String name;
private String nameEs;
private String nameIt;
private String nameFr;
private String nameDe;
private String namePt;
private String nameRu;
GenericIndexEntity(
String indexNumber, String name, String nameEs, String nameIt, String nameFr, String nameDe, String namePt, String nameRu
) {
this.indexNumber = indexNumber;
this.name = name;
this.nameEs = nameEs;
this.nameIt = nameIt;
this.nameFr = nameFr;
this.nameDe = nameDe;
this.namePt = namePt;
this.nameRu = nameRu;
}
public String getIndexNumber() {
return indexNumber;
}
public String getName() {
return name;
}
public String getNameDe() {
return nameDe;
}
public String getNameEs() {
return nameEs;
}
public String getNameFr() {
return nameFr;
}
public String getNameIt() {
return nameIt;
}
public String getNamePt() {
return namePt;
}
public String getNameRu() {
return nameRu;
}
public void setIndexNumber(String indexNumber) {
this.indexNumber = indexNumber;
}
public void setName(String name) {
this.name = name;
}
public void setNameDe(String nameDe) {
this.nameDe = nameDe;
}
public void setNameEs(String nameEs) {
this.nameEs = nameEs;
}
public void setNameFr(String nameFr) {
this.nameFr = nameFr;
}
public void setNameIt(String nameIt) {
this.nameIt = nameIt;
}
public void setNamePt(String namePt) {
this.namePt = namePt;
}
public void setNameRu(String nameRu) {
this.nameRu = nameRu;
}
}
GameEntity(调整以克服一些未知数/猜测):-
@Entity(tableName = "games")
public class GameEntity extends GenericIndexEntity {
@NonNull
@PrimaryKey
@ColumnInfo(name = "gen")
private Integer gen;
@NonNull
@ColumnInfo(name = "is_main")
private Integer isMain;
@Ignore
@ColumnInfo(name = "main_game")
private String mainGame;
public GameEntity(@NonNull String indexNumber, String name, String nameEs, String nameIt, String nameFr, String nameDe, String namePt, String nameRu){
super(indexNumber,name,nameEs,nameIt,nameFr,nameDe,namePt,nameRu);
}
public GameEntity(@NonNull String indexNumber, String name, String nameEs, String nameIt, String nameFr, String nameDe, String namePt, String nameRu, @NonNull Integer gen, @NonNull Integer isMain, String mainGame) {
super(indexNumber, name, nameEs, nameIt, nameFr, nameDe, namePt, nameRu);
this.gen = gen;
this.isMain = isMain;
this.mainGame = mainGame;
}
@NonNull
public Integer getGen() {
return gen;
}
public void setGen(@NonNull Integer gen) {
this.gen = gen;
}
@NonNull
public Integer getIsMain() {
return isMain;
}
public void setIsMain(@NonNull Integer isMain) {
this.isMain = isMain;
}
public String getMainGame() {
return mainGame;
}
public void setMainGame(String mainGame) {
this.mainGame = mainGame;
}
}
GameWithMainGamePOJO(如上)
TheDatabase
@Database
注解抽象类:-
@Database(entities = {GameEntity.class},exportSchema = false,version = 1)
abstract class TheDatabase extends RoomDatabase {
abstract GamesDao getGamesDao();
private static volatile TheDatabase instance;
public static TheDatabase getInstance(Context context) {
if (instance==null) {
instance= Room.databaseBuilder(context,TheDatabase.class,"the_games_database.db")
.allowMainThreadQueries() /* for brevity of the demo */
.build();
}
return instance;
}
}
MainActivity演示原理:-
public class MainActivity extends AppCompatActivity {
TheDatabase db;
GamesDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = TheDatabase.getInstance(this);
dao = db.getGamesDao();
long g1Id = dao.insert(
new GameEntity("ix1","G1","G1ES","G1IT","G1FR","G1DE","G1PT","G1RU",1,2,"G1MG"));
GameEntity ge2 = new GameEntity("ix2","G2","G2ES","G2IT","G2FR","G2DE","G2PT","G2RU");
ge2.setMainGame("GM2MG");
ge2.setIsMain(0);
ge2.setGen(2);
long g2id = dao.insert(ge2);
List<GameWithMainGamePOJO> debug = dao.getAll();
for (GameWithMainGamePOJO gwmgpojo: dao.getAll()) {
Log.d(
"DBINFO","IXN = " + gwmgpojo.gameEntity.getIndexNumber()
+ "NAME = " + gwmgpojo.gameEntity.getName()
+ "NAMEDE = " + gwmgpojo.gameEntity.getNameDe()
+ "NAMEES = " + gwmgpojo.gameEntity.getNameEs()
+ "NAMEFR = " + gwmgpojo.gameEntity.getNameFr()
+ "NAMEIT = " + gwmgpojo.gameEntity.getNameIt()
+ " ETC .... "
+ "MGFROMGE = " + (gwmgpojo.getGameEntity()).getMainGame()
+ "MGFROMPOJO = " + gwmgpojo.getMg()
);
}
}
}
RESULT输出到日志:-
D/DBINFO: IXN = ix1NAME = G1NAMEDE = G1DENAMEES = G1ESNAMEFR = G1FRNAMEIT = G1IT ETC .... MGFROMGE = MG11MGFROMPOJO = MG11
D/DBINFO: IXN = ix2NAME = G2NAMEDE = G2DENAMEES = G2ESNAMEFR = G2FRNAMEIT = G2IT ETC .... MGFROMGE = MG12MGFROMPOJO = MG12
可以看出 MG11/MG12 已动态生成和应用,并且 getGameEntity 方法返回预期的 HameEntity,并且 mainGame 设置正确。