【问题标题】:Is there a way when Migrating a Room Database to use Variables that are calculated during the Migration?迁移房间数据库时有没有办法使用迁移期间计算的变量?
【发布时间】:2021-06-17 00:26:30
【问题描述】:

我正在用 Java 编写一个 Android 应用程序,并且我已经更改了我的数据库,现在我想将它迁移到新版本,但为此我需要计算一些旧值,然后将它们插入其中一个新表进入数据库但是当我调用时

database.execSQL()

使用我的变量然后访问它们似乎没有设置它们,因为每个值都是 0。

这是不可能的,还是我只是错过了什么?

public void migrate(@NonNull SupportSQLiteDatabase database) {
             database.execSQL("CREATE TABLE 'season' ('id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
                    'spring' INTEGER DEFAULT 0, 'summer' INTEGER DEFAULT 0, 'autumn' INTEGER 
                    DEFAULT 0, 'winter' 
                    INTEGER DEFAULT 0, 'spook' INTEGER DEFAULT 0)");
            database.execSQL("INSERT INTO 'Clothes' (type_of_clothing,clothing_name,description,seasonId,in_laundry,TypeList) " +
                    "SELECT type_of_clothing,clothing_name,description,type_of_clothing,in_laundry,TypeList " +
                    "FROM ClothesNew");
            Cursor cursor = database.query("SELECT * FROM Clothes");
            Cursor secondCursor = database.query("SELECT * FROM ClothesSeason");
            ArrayList<Season> seasonsToBeAdded = new ArrayList<>();
            while (cursor.moveToNext()) {
                secondCursor.moveToNext();
                int Sid = cursor.getInt(0);
                String seasonString = secondCursor.getString(2);
                Season season = new Season(seasonString);
                int tempId = Sid;
                boolean isInList = false;
                for (Season tempSeason : seasonsToBeAdded) {
                    if (tempSeason.equals(season)) {
                        tempId = seasonsToBeAdded.indexOf(tempSeason);
                        isInList = true;
                        break;
                    }
                }
                if (!isInList) {
                    season.setId(seasonsToBeAdded.size());
                    tempId = season.getId();
                    seasonsToBeAdded.add(season);
                }
                if (seasonsToBeAdded.size() == 0) {seasonsToBeAdded.add(season);}
                
                database.execSQL("UPDATE Clothes SET seasonId = :tempId WHERE uid = :Sid");
            }

            int id, spring, summer, autumn, winter, spook;

            for (Season season : seasonsToBeAdded) {
                id = season.getId();
                spring = season.getSpring();
                summer = season.getSummer();
                autumn = season.getAutumn();
                winter = season.getWinter();
                spook = season.getSpook();
                database.execSQL("INSERT INTO season " +
                        "VALUES(:id, :spring, :summer, :autumn, :winter, :spook) ");
            }
            Cursor otherCursor = database.query("SELECT * FROM season");
            ArrayList<Integer> springValues= new ArrayList<>();
            while (otherCursor.moveToNext()) {
                springValues.add(otherCursor.getInt(1));
            }
        }

当我查看存储在 springValues 中的值时,即使我在此查询中添加了正确的值,它们也都是 0

database.execSQL("INSERT INTO season " +
                 "VALUES(:id, :spring, :summer, :autumn, :winter, :spook) ");

我可以不在这里使用 :var 符号吗?

【问题讨论】:

    标签: java android sqlite android-studio android-room


    【解决方案1】:

    我建议使用 SQLiteDatabase Insert 便捷方法和 ContentValues 对象。

    而不是:-

            for (Season season : seasonsToBeAdded) {
                id = season.getId();
                spring = season.getSpring();
                summer = season.getSummer();
                autumn = season.getAutumn();
                winter = season.getWinter();
                spook = season.getSpook();
                database.execSQL("INSERT INTO season " +
                        "VALUES(:id, :spring, :summer, :autumn, :winter, :spook) ");
            }
    

    您的代码可能是:-

        ContentValues cv = new ContentValues(); // Instantiate ContentValues object
        for (Season season : seasonsToBeAdded) {
            cv.clear();
            cv.put("`id`",season.getId());
            cv.put("`spring`",season.getSpring());
            cv.put("`summer`",season.getSummer());
            cv.put("`autumn`",season.getAutumn());
            cv.put("`winter`",season.getWinter());
            cv.put("`spook`",season.getSpook());
            database.insert("season",null,cv); //<<<< Recommended Uses the convenience Insert Method
    
    • 请注意,列名不必像上面使用的那样用重音 `` 括起来。

    • 以上代码为in-principal code,未经测试,可能存在一些错误。

    如您所见,SQL 是为您构建的。 insert 方法返回插入行的 rowid(id 列),如果插入失败则返回 -1,您可能希望利用该值。

    您可能还希望使用其他插入方法,例如insertWithOnConflict 例如database.insertWithOnConflict("season",null,cv,SQLiteDatabase.CONFLICT_IGNORE);

    还建议通过使用适当的 SQLiteDatabase 事务处理方法来利用事务(请参阅beginTransaction

    还建议您对列名使用常量,以便在适当的位置对名称进行编码。列名错误的可能性很小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-13
      • 2021-08-13
      • 2021-12-11
      • 2021-09-02
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      相关资源
      最近更新 更多