Android Room 子查询不匹配字段错误

问题描述 投票:0回答:1

我不知道如何在实体的属性中绑定子查询选择,我只需要将“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]

如果我从查询有效的属性中删除所有标签,但不会填充值。

我错过了什么吗?

android android-jetpack-compose android-room android-jetpack android-room-relation
1个回答
0
投票

如果您

@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 设置正确。

© www.soinside.com 2019 - 2024. All rights reserved.