SQLite
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> SQLite

Phòng - Sử dụng SQLites bên ngoài cũng như DB nội bộ

Những gì chúng tôi cần:

Chúng ta cần có khả năng đính kèm cơ sở dữ liệu bên ngoài vào Cơ sở dữ liệu phòng nội bộ mà không thay đổi đường dẫn chúng được lưu trữ. Sau khi thêm chúng, chúng ta muốn có thể sử dụng cơ sở dữ liệu với các đối tượngRoom Entity, Dao và Database. Có cách nào khả thi để đạt được điều này không?

Có thể dễ dàng hơn nếu không đính kèm, lý do là bạn có thể sử dụng một phiên bản Cơ sở dữ liệu phòng riêng biệt. Nếu không, bạn cần phải có các DAO riêng biệt để phục vụ cho tên lược đồ đính kèm (tôi tin là vậy). Nói rằng ví dụ dưới đây (dựa trên thứ mà tôi đang chơi cùng ai đó và do đó có tên cột khá khó hiểu) .

ví dụ. giả sử ATTACH DATABASE .... AS other (lược đồ đính kèm là other ) sau đó thay vì (cho cơ sở dữ liệu chính)

@Query("SELECT * FROM AllUsers")
List<AllUsers> getAllAllUsers();

Bạn sẽ cần một phần thưởng:-

@SkipQueryVerification
@Query("SELECT * FROM other.AllUsers")
List<AllUsers> getOtherAllAllUsers();

vv

Tuy nhiên, nếu thay vào đó bạn có một cái gì đó như (cho chính):-

    mLPDB = Room.databaseBuilder(this,LoanPaymentDatabase.class,"mydb").allowMainThreadQueries().build();
    mLPDB_DAO = mLPDB.mDao();

Cùng với (cho cái khác):-

    mOtherDB = Room.databaseBuilder(this,LoanPaymentDatabase.class,OtherDatabaseHelper.DBNAME).allowMainThreadQueries().build();
    mOtherDAO = mOtherDB.mDao();

Sau đó, bạn có thể truy cập cả hai bằng cách sử dụng cùng một DAO.

  • Lưu ý tất nhiên phần trên giả định rằng lược đồ là bổ sung (không nhất thiết phải chính xác).

Không nhất thiết phải chính xác?

Cũng bao gồm nhận xét:-

Trước tiên, bạn phải di chuyển dữ liệu vào chính phòng.

  • Vui chơi một chút, bạn có thể tránh được việc phải di chuyển bằng cách đánh lừa phòng bằng cách đặt user_version thành 0. Trong trường hợp đó, Room đặt số phiên bản (thử nghiệm giới hạn). Tuy nhiên, tôi không chắc GreenDao hoặc Máy chủ của bạn sẽ làm gì với điều này (bài tập về nhà của bạn).

  • Thử nghiệm giới hạn của tôi là cho một vấn đề phổ biến khi di chuyển một cột có KHÓA CHÍNH CỦA INTEGER, tức là không có AUTOINCREMENT. Phòng nếu di chuyển sẽ phàn nàn rằng lược đồ không khớp. Vì vậy, tôi đã cố ý không viết mã AUTOINCREMENT, đặt user_version thành 0 và không có khiếu nại nào khi truy cập cơ sở dữ liệu qua Room. Cũng đã sử dụng một loại cột rumplestilskin và không có khiếu nại.

Vì vậy, tôi tin rằng bạn có thể giải quyết các vấn đề di chuyển với dự kiến ​​/ tìm thấy đáng sợ bằng cách đặt user_version thành 0 (và do đó tôi tin rằng sẽ tránh được việc di chuyển). Rõ ràng là mặc dù tên cột phải khớp, nếu được xác định trong một Thực thể và không bị bỏ qua.

  • Tôi cũng đã thử thêm một cột không được xác định Đối tượng và sử dụng các kết quả ở trên không có khiếu nại (các thử nghiệm này sẽ rõ ràng trong đoạn mã bên dưới).

(Các) ví dụ

Sau đây là ví dụ về Cơ sở dữ liệu phòng thực thể 2 và nhằm mục đích kiểm tra khác cơ sở dữ liệu được xây dựng bên ngoài phòng đủ khớp với cơ sở dữ liệu của phòng để có thể được sử dụng, tức là tên cột đối tượng được khớp.

Cơ sở dữ liệu khác

Cơ sở dữ liệu không phải phòng khác được tạo qua SQLiteOpenHelper lớp con theo OtherDatabaseHelper.java :-

public class OtherDatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "lpolddb";
    public static final int DBVERSION = 1;
    public static final String ALLUSERS_TBL = "AllUsers";
    public static final String PAIDUNPAID_TBL = "PaidUnpaid";

    /*
        @PrimaryKey(autoGenerate = true)
        private long auid;
        private String Name;
        private int Loan;
        private int TimeInMonths;
     */
    public static final String ALLUSERS_COL_AUID = "auid";
    public static final String ALLUSERS_COL_NAME = "Name";
    public static final String ALLUSERS_COL_LOAN = "Loan";
    public static final String ALLUSERS_COL_TIMEINMONTHS = "TimeInMonths";

    private static final String crt_allusers_table_sql =
            "CREATE TABLE IF NOT EXISTS " + ALLUSERS_TBL + "(" +
                    //ALLUSERS_COL_AUID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    ALLUSERS_COL_AUID + " INTEGER PRIMARY KEY," +
                    ALLUSERS_COL_NAME + " TEXT, " +
                    ALLUSERS_COL_LOAN + " INTEGER, " +
                    "someothercolumnnotdefineinroom TEXT, " + //!!!!!!!!!! not a column in an entity
                    ALLUSERS_COL_TIMEINMONTHS + " INTEGER" +
                    ")";

    /*
        @PrimaryKey(autoGenerate = true)
        private long puid;
        private int TimeInMonths;
        private String PaidUnpaid;
        @ForeignKey(
            entity = AllUsers.class,
            parentColumns = {"auid"},
            childColumns = {"AllUsersReference"},
            onUpdate = ForeignKey.CASCADE, onDelete = ForeignKey.CASCADE)
        private long AllUsersReference;
     */

    public static final String PAIDUNPAID_COL_PUID = "puid";
    public static final String PAIDUNPAID_TIMEINMONTHS = ALLUSERS_COL_TIMEINMONTHS;
    public static final String PAIDUNPAID_COL_PAIDUNPAID = "PaidUnpaid";
    public static final String PAIDUNPAID_COL_ALLUSERSREFERENCE = "AllUsersReference";

    public static final String crt_paidunpaid_table_sql =
            "CREATE TABLE IF NOT EXISTS " + PAIDUNPAID_TBL + "(" +
                    PAIDUNPAID_COL_PUID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                    PAIDUNPAID_TIMEINMONTHS + " rumplestilskin, " + // !!!!!!!!!!!
                    PAIDUNPAID_COL_PAIDUNPAID + " TEXT," +
                    PAIDUNPAID_COL_ALLUSERSREFERENCE + " INTEGER " +
                    " REFERENCES " + ALLUSERS_TBL + "(" + ALLUSERS_COL_AUID + ") " +
                    "ON UPDATE CASCADE ON DELETE CASCADE" +
                    ")";


    SQLiteDatabase mDB;
    public OtherDatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(crt_allusers_table_sql);
        db.execSQL(crt_paidunpaid_table_sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insertAllUsers(String name, int loanamount, int periodofloan) {
        ContentValues cv = new ContentValues();
        cv.put(ALLUSERS_COL_NAME,name);
        cv.put(ALLUSERS_COL_LOAN,loanamount);
        cv.put(ALLUSERS_COL_TIMEINMONTHS,periodofloan);
        return mDB.insert(ALLUSERS_TBL,null,cv);
    }

    public long insertPaidUnpaid(int formonth, String status, long allUserreferenced) {
        ContentValues cv = new ContentValues();
        cv.put(PAIDUNPAID_TIMEINMONTHS,formonth);
        cv.put(PAIDUNPAID_COL_PAIDUNPAID,status);
        cv.put(PAIDUNPAID_COL_ALLUSERSREFERENCE,allUserreferenced);
        return mDB.insert(PAIDUNPAID_TBL,null,cv);
    }
}
  • xem các nhận xét về những điểm kỳ lạ / sự khác biệt được thêm vào có chủ đích
  • điều này được bật lên, được truy cập bởi cơ sở dữ liệu Phòng thay thế và qua DB được đính kèm trong MainActivity.java dưới đây

Cơ sở dữ liệu phòng

2 Thực thể:-

AllUsers.java

@Entity
public class AllUsers {
    @PrimaryKey(autoGenerate = true)
    private long auid;
    private String Name;
    private int Loan;
    private int TimeInMonths;

    public AllUsers() {
    }

    @Ignore
    public AllUsers(String Name, int Loan, int TimeInMonths) {
        this.Name = Name;
        this.Loan = Loan;
        this.TimeInMonths = TimeInMonths;
    }

    public long getAuid() {
        return auid;
    }

    public void setAuid(long auid) {
        this.auid = auid;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public int getLoan() {
        return Loan;
    }

    public void setLoan(int loan) {
        Loan = loan;
    }

    public int getTimeInMonths() {
        return TimeInMonths;
    }

    public void setTimeInMonths(int timeInMonths) {
        TimeInMonths = timeInMonths;
    }
}

PaidUnpaid.java :-

@Entity
public class PaidUnpaid {
    @PrimaryKey(autoGenerate = true)
    private long puid;
    private int TimeInMonths;
    private String PaidUnpaid;
    @ForeignKey(
            entity = AllUsers.class,
            parentColumns = {"auid"},
            childColumns = {"AllUsersReference"},
            onUpdate = ForeignKey.CASCADE, onDelete = ForeignKey.CASCADE)
    private long AllUsersReference;


    public PaidUnpaid() {
    }

    @Ignore
    public PaidUnpaid(int TimeInMonths, String PaidUnpaid, long AllUsersreference) {
        this.TimeInMonths = TimeInMonths;
        this.PaidUnpaid = PaidUnpaid;
        this.AllUsersReference = AllUsersreference;
    }

    public long getPuid() {
        return puid;
    }

    public void setPuid(long puid) {
        this.puid = puid;
    }

    public int getTimeInMonths() {
        return TimeInMonths;
    }

    public void setTimeInMonths(int timeInMonths) {
        TimeInMonths = timeInMonths;
    }

    public String getPaidUnpaid() {
        return PaidUnpaid;
    }

    public void setPaidUnpaid(String paidUnpaid) {
        PaidUnpaid = paidUnpaid;
    }

    public long getAllUsersReference() {
        return AllUsersReference;
    }

    public void setAllUsersReference(long allUsersReference) {
        AllUsersReference = allUsersReference;
    }
}

Một lớp POJO bổ trợ, AllUsersAndPaidUnpaidsList.java đã được kết hợp và sử dụng như vậy:-

public class AllUsersAndPaidUnpaidsList {

    @Embedded
    AllUsers allUsers;
    @Ignore
    @PrimaryKey
    long auid;

    @Ignore
    @Relation(entity = PaidUnpaid.class,parentColumn = "auid",entityColumn = "puid")
    List<PaidUnpaid> paidUnpaidList;

    @Ignore
    public AllUsersAndPaidUnpaidsList(AllUsers au, List<PaidUnpaid> pulist) {
        this.allUsers = au;
        this.paidUnpaidList = pulist;
    }

    public List<PaidUnpaid> getPaidUnpaidList() {
        return this.paidUnpaidList;
    }


    public void setPaidUnpaidList(List<PaidUnpaid> paidUnpaidList) {
        this.paidUnpaidList = paidUnpaidList;
    }

    public AllUsers getAllUsers() {
        return allUsers;
    }

    public void setAllUsers(AllUsers allUsers) {
        this.allUsers = allUsers;
    }

    public void outputToLog(String tag) {
        StringBuilder sb = new StringBuilder("AllUsersName = ")
                .append(this.allUsers.getName())
                .append(" TimeInMonths = ")
                .append(String.valueOf(this.allUsers.getTimeInMonths()))
                ;
        for (PaidUnpaid pu: this.getPaidUnpaidList()) {
            sb.append("\n\t TimeInMonths = ")
                    .append(String.valueOf(pu.getTimeInMonths()))
                    .append(" Paid/Unpaid = ")
                    .append(pu.getPaidUnpaid());
        }
        Log.d(tag,sb.toString());
    }
}

Một giao diện duy nhất Dao.java :-

@androidx.room.Dao
public interface Dao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    long[] insertAllUsers(AllUsers... allUsers);

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    long insertAllUsers(AllUsers allUsers);

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    long[] insertPaidUnpaid(PaidUnpaid... paidUnpaids);

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    long insertPaidUnpaid(PaidUnpaid paidUnpaid);

    @Update(onConflict = OnConflictStrategy.IGNORE)
    int updateAllUsers(AllUsers... allUsers);

    @Update(onConflict =  OnConflictStrategy.IGNORE)
    int updateAllUsers(AllUsers allUsers);

    @Update(onConflict = OnConflictStrategy.IGNORE)
    int updatePaidUnpaid(PaidUnpaid... paidUnpaids);

    @Update(onConflict = OnConflictStrategy.IGNORE)
    int updatePaidUnpaid(PaidUnpaid paidUnpaid);

    @Delete
    int deleteAllUsers(AllUsers... allUsers);

    @Delete
    int deleteAllUsers(AllUsers allUsers);

    @Delete
    int deletePaidUnpaid(PaidUnpaid... paidUnpaids);

    @Delete
    int deletePaidUnpaid(PaidUnpaid paidUnpaid);

    @Query("SELECT * FROM AllUsers")
    List<AllUsers> getAllAllUsers();

    @Query("SELECT * FROM AllUsers WHERE auid = :id")
    List<AllUsers> getOneAllUsersById(long id);

    @Query("SELECT * FROM PaidUnpaid")
    List<PaidUnpaid> getAllPaidUnpaids();

    @Query("SELECT * FROM PaidUnpaid WHERE puid = :id")
    List<PaidUnpaid> getOnePaidUnpaidById(long id);

    @Query("SELECT * FROM PaidUnpaid WHERE AllUsersReference = :allUsersid")
    List<PaidUnpaid> getPaidUnpaidsForAllUsersId(long allUsersid);

    /*************
     * Some Additional DAO's for attached not required for alternative helper
     * in practice you would likely need attached versions of all
     ************/

    @Query("SELECT * FROM other.PaidUnpaid WHERE AllUsersReference = :allUsersid")
    @SkipQueryVerification
    List<PaidUnpaid> getOtherPaidUnpaidForAllUsersId(long allUsersid);

    @SkipQueryVerification
    @Query("SELECT * FROM other.AllUsers")
    List<AllUsers> getOtherAllAllUsers();
}

Lớp Cơ sở dữ liệu phòng LoanPaymentDatabase.java

@Database(entities = {AllUsers.class,PaidUnpaid.class},exportSchema = false,version = 1)
public abstract class LoanPaymentDatabase extends RoomDatabase {
    public abstract Dao mDao();
}

Kết hợp tất cả lại với nhau

Cuối cùng là một hoạt động:-

  1. Tạo và điền khác (không có phòng) cơ sở dữ liệu (nếu nó không tồn tại) để thử nghiệm. Đặt user_version (phiên bản cơ sở dữ liệu trong Android talk) thành 0.

  2. Tạo phiên bản Room của cơ sở dữ liệu, nếu cần.

  3. Thêm một vài hàng vào phiên bản Phòng.
  4. Xuất dữ liệu trong phiên bản Phòng vào nhật ký.
  5. Tạo một RoomDatabase thay thế bằng cách sử dụng other cơ sở dữ liệu.
  6. Xuất dữ liệu trong other cơ sở dữ liệu thông qua Phòng.
  7. Đính kèm khác cơ sở dữ liệu cho phiên bản Phòng.
  8. Xuất dữ liệu từ cả hai thông qua Roomdatabase ban đầu truy cập vào other đính kèm cơ sở dữ liệu thông qua các giao diện DAO bổ sung bao gồm khác. ???? .

MainActivity.java

public class MainActivity extends AppCompatActivity {

    LoanPaymentDatabase mLPDB;
    Dao mLPDB_DAO;

    LoanPaymentDatabase mOtherDB;
    Dao mOtherDAO;
    Random rnd = new Random();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        manageOtherDatabase();

        mLPDB = Room.databaseBuilder(this,LoanPaymentDatabase.class,"mydb").allowMainThreadQueries().build();
        mLPDB_DAO = mLPDB.mDao();
        // Add some(2) AllUsers
        mLPDB_DAO.insertAllUsers(new AllUsers("Fred",5000,5));
        mLPDB_DAO.insertAllUsers(new AllUsers("Mary", 4000,6));

        // Add Some PaidUnpaid's for each AllUsers
        // Random amount with random paid or unpaid
        // This is just for demonstration and doesn't reflect what would typically be done
        List<AllUsers> allusers =  mLPDB_DAO.getAllAllUsers();
        for (AllUsers au: allusers) {
            int lc = rnd.nextInt(4) + 1;
            int month = 1;
            for (int i=0; i < lc; i++) {
                String paid = "Paid";
                if((rnd.nextInt(2) % 2) > 0 ) {
                    paid = "Unpaid";
                }
                mLPDB_DAO.insertPaidUnpaid(new PaidUnpaid(month++, paid, au.getAuid()));
            }
        }

        //Extract all AllUsersAndPaidUnpaid (i.e  each AllUsers with the related PaidUnpaid for the AllUsers)
        ArrayList<AllUsersAndPaidUnpaidsList> aupulist = new ArrayList<>();
        for (AllUsers au: allusers) {
            List<PaidUnpaid> pulist = mLPDB_DAO.getPaidUnpaidsForAllUsersId(au.getAuid());
            aupulist.add(new AllUsersAndPaidUnpaidsList(au,pulist));
        }

        // Output the results
        for (AllUsersAndPaidUnpaidsList aupu: aupulist) {
            aupu.outputToLog("INITALAUPU");
        }

        //Use separate openHelper rather than ATTACH
        mOtherDB = Room.databaseBuilder(this,LoanPaymentDatabase.class,OtherDatabaseHelper.DBNAME).allowMainThreadQueries().build();
        mOtherDAO = mOtherDB.mDao();
        ArrayList<AllUsersAndPaidUnpaidsList> otheraupulist = new ArrayList<>();
        for (AllUsers oau: mOtherDAO.getAllAllUsers() ) {
            otheraupulist.add(new AllUsersAndPaidUnpaidsList(oau,mOtherDAO.getPaidUnpaidsForAllUsersId(oau.getAuid())));
        }
        for (AllUsersAndPaidUnpaidsList aupu: otheraupulist) {
            aupu.outputToLog("ALTDBAUPU");
        }

        // User Attach
        SupportSQLiteDatabase main_sdb = mLPDB.getOpenHelper().getWritableDatabase();
        SupportSQLiteDatabase other_sdb = mOtherDB.getOpenHelper().getWritableDatabase();
        main_sdb.execSQL("ATTACH DATABASE '" + other_sdb.getPath() + "' AS other");
        ArrayList<AllUsersAndPaidUnpaidsList> attachaupulist = new ArrayList<>();
        for (AllUsers aau: mLPDB_DAO.getAllAllUsers()) {
            attachaupulist.add(new AllUsersAndPaidUnpaidsList(aau,mLPDB_DAO.getPaidUnpaidsForAllUsersId(aau.getAuid())));
        }
        for (AllUsers aauother: mLPDB_DAO.getOtherAllAllUsers()) {
            attachaupulist.add(new AllUsersAndPaidUnpaidsList(aauother,mLPDB_DAO.getOtherPaidUnpaidForAllUsersId(aauother.getAuid())));
        }
        for (AllUsersAndPaidUnpaidsList aupu: attachaupulist) {
            aupu.outputToLog("ATTACHEDAUPU");
        }

        mLPDB.close();
    }

    /*********
     *  For testing purposes - Populate the OTHER database to be used
     *********/
    private void manageOtherDatabase() {
        OtherDatabaseHelper mODBHlpr = new OtherDatabaseHelper(this);
        SQLiteDatabase db = mODBHlpr.getWritableDatabase();
        db.execSQL("PRAGMA user_version = 0");
        if (DatabaseUtils.queryNumEntries(db,OtherDatabaseHelper.ALLUSERS_TBL) > 0) {
            db.close();
            mODBHlpr.close();
            return;
        }
        db.beginTransaction();
        for (int i= 0; i < 5; i++) {
            long auid = mODBHlpr.insertAllUsers("AU" + String.valueOf(i),10000 + 1,5 + i);
            for(int ii = 0; ii < 5; ii++) {
                mODBHlpr.insertPaidUnpaid(ii,"Paid",auid);
            }
        }
        db.setTransactionSuccessful();
        db.endTransaction();
        db.close();
        mODBHlpr.close();
    }
}



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ListView không hiển thị các hình ảnh chính xác trong có thể vẽ theo tên của chúng trong sqlite

  2. Cách hoạt động của SQLite Count ()

  3. Cách cập nhật bảng với activeandroid sau khi thêm cột mới

  4. Đặt giá trị mặc định của một cột số nguyên SQLite

  5. Xóa nhiều hàng bằng cách sử dụng ID?