国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Room Java – Ist es m?glich, Transaktionen in der Schnittstelle auszuführen?
P粉852578075
P粉852578075 2024-01-10 17:15:07
0
1
577

Ich verwende das Room Framework in meinem Android Studio-Projekt. Ich versuche, eine Transaktion innerhalb einer Schnittstelle zu erstellen. Ich habe die Dokumentation hier gelesen: https://developer.android.com/reference/androidx/room/Transaction

Ich wei?, wir sollten Transaktionen in abstrakten Klassen statt in Schnittstellen erstellen. Ich frage mich nur, ob das m?glich ist, da ich in meinem Projekt bereits mehr als ein Dutzend Schnittstellen habe und diese nicht als abstrakte Klassen umschreiben m?chte.

P粉852578075
P粉852578075

Antworte allen(1)
P粉464208937

您所嘗試的操作在接口中是不可能的,因為您不能在接口中使用帶有主體的方法。

更具體地說,您嘗試執(zhí)行多個語句(一條 UPDATE,然后一條 DELETE),但同時只能執(zhí)行一條語句。

您的選擇是定義一個觸發(fā)器(更新后,如果可以從觸發(fā)器內(nèi)確定權(quán)重行)或者可能更可能使用抽象類,從而使用一個函數(shù)來執(zhí)行多個語句或使用利用的方法(傳遞/或檢索)SupportSQliteDatabase(使用抽象類更簡單)。

  • 如果您需要觸發(fā)器,則必須使用回調(diào)來創(chuàng)建觸發(fā)器,因為 Room 不提供觸發(fā)器注釋。

然后,要利用事務(wù),您將在函數(shù)之前有一個虛擬的@Query。例如

@Dao
abstract class TheClassForMethodsWithBodies {

    @Query("UPDATE visits SET date=:date WHERE id=5")
    void testUpdate(Date date);
    @Query("DELETE FROM wieght WHERE id_weight=1")
    void testDelete();

    @Query("")
    void test(Date date) {
        testUpdate(date);
        testDelete();
    }
}
  • 注意 - 代碼本質(zhì)上是代碼,尚未編譯、運行或測試,因此可能包含一些錯誤

附加

這是一個工作演示,設(shè)計為僅運行一次,它使用所有三種方法。

首先是@Entities,基于代碼中可用的內(nèi)容,但已使用 long 來表示日期(而不是使用類型轉(zhuǎn)換器)。

訪問

@Entity
class Visits {
   @PrimaryKey
   Long id=null;
   Long date = System.currentTimeMillis() / 1000;
}

重量

@Entity
class Weight {
    @PrimaryKey
    Long id_weight=null;
}

@Dao 帶注釋的抽象類,具有普通的抽象方法和帶主體的方法(解決方案 1)。 insert 方法允許插入一些數(shù)據(jù)(僅一行)。

@Dao
abstract class AllDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    abstract long insert(Visits visits);

    @Query("UPDATE visits SET date=:date WHERE id=1")
    abstract void resetVisitData(long date);
    @Query("DELETE FROM weight WHERE id_weight=5")
    abstract void deleteFromWeight();
    @Query("")
    void doBoth(long date) {
        resetVisitData(date);
        deleteFromWeight();
    }
}

現(xiàn)在,@Database 帶注釋的類(使用單例)稍微復(fù)雜一些。

這有一個回調(diào)來添加觸發(fā)器,觸發(fā)器過于復(fù)雜,因為它不僅在更新后進行刪除(不是刪除任何內(nèi)容),而且還在訪問表中添加一個新行顯示 TRIGGER 實際上正在被觸發(fā)(解決方案 2)。

此外,由于需要更好的地方(或不取決于風(fēng)格/實踐),包含一個函數(shù)來獲取和使用 SupportSQLiteDatabase(解決方案 3)

@Database(entities = {Weight.class,Visits.class}, version = 1,exportSchema = false)
abstract class TheDatabase extends RoomDatabase {
    abstract AllDao getAllDao();

    private static TheDatabase INSTANCE;
    static TheDatabase getINSTANCE(Context context) {
        if (INSTANCE==null) {
            INSTANCE = Room.databaseBuilder(
                            context,
                            TheDatabase.class,
                            "the_database.db"
                    )
                    .allowMainThreadQueries()
                    .addCallback(cb)
                    .build();
        }
        return INSTANCE;
    }

    /* Solution 2 - via SupportSQLiteDatabase */
    void viaSupportSB(long date) {
        SupportSQLiteDatabase db = this.getOpenHelper().getWritableDatabase();
        db.beginTransaction();
        db.execSQL("UPDATE visits SET date=? WHERE id=1",new String[]{String.valueOf(date)});
        db.execSQL("DELETE FROM weight WHERE id_weight=-600");
        db.setTransactionSuccessful();
        db.endTransaction();
    }


    /* USING a TRIGGER (not intended to make sense/do anything useful just demo) */
    private static final String CREATETRIGGERSQL = "CREATE TRIGGER IF NOT EXISTS theTrigger AFTER UPDATE ON visits BEGIN DELETE FROM weight WHERE id_weight=5; INSERT OR IGNORE INTO visits (date) VALUES(strftime('%s','now')); END";
    static Callback cb  = new Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            db.execSQL(CREATETRIGGERSQL);
        }

        @Override
        public void onDestructiveMigration(@NonNull SupportSQLiteDatabase db) {
            super.onDestructiveMigration(db);
        }

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
            db.execSQL(CREATETRIGGERSQL);
        }
    };
}

要實際利用上面的一些活動代碼MainActivity

public class MainActivity extends AppCompatActivity {

    TheDatabase roomInstance;
    AllDao dao;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        roomInstance = TheDatabase.getINSTANCE(this);
        dao = roomInstance.getAllDao();

        dao.insert(new Visits()); /* Insert a row */

        /* Solution 2 - via Trigger */
        dao.resetVisitData(System.currentTimeMillis() - (24 * 60 * 60 * 7 /* one week ago BUT OOOPS not divided by 1000 */));
        /* Solution 1 - via abstract class aka method with body */
        dao.doBoth(System.currentTimeMillis() / 1000);
        /* Solution 3 - via SupportSQLiteDatabase */
        roomInstance.viaSupportSB(System.currentTimeMillis() + (24 * 60 * 60 * 7 /*week in the future  again OOOPS not divided by 1000*/));
        
        /* Expected result
            1. sinlge row inserted into visits
            2. trigger adds another row into visits (row 2)
            3. doBoth updates so another row added to visits (row 3)
            4. via SupportSQLiteDatabase updates so another row added to visits (row 4)
            
            So 4 rows in visits no rows in weight
         */
    }
}

演示結(jié)果 通過 SppInspection

正如預(yù)期的重量表是空的:-

正如預(yù)期的那樣,訪問表中有 4 行:-

最后,架構(gòu)(即 sqlite_master)顯示觸發(fā)器存在(必須添加額外的 3 行):-

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage