SORU
31 EKİM 2010, Pazar


Android birden fazla Tablo SQLite DB Adaptörü(ler)?

DB ve tablo oluşturma access DB Adaptörü bir sınıf oluşturma başvurulan Android SQLite Not Defteri öğretici okuyordum. Çoklu masa SQLite Veritabanı ile uğraşırken, her tablo için farklı bir Adaptör Sınıf oluşturmak veya tüm Android Uygulaması için tek DB Adaptörü bir sınıf oluşturmak için bir uygulamadır.

Benim uygulama birden fazla tablo kullanır ve tek büyük bağdaştırıcı sınıfı için değil umuyordum. sorun, ancak, her adaptör içinde Not Defteri Örnek başına SQLiteOpenHelper iç içe geçmiş bir alt sınıf var. İlk tablo erişildiğinde, her şey gayet iyi çalışıyor. Ben daha sonra ikinci tble(farklı bir aktivite) erişmeye çalıştığınızda benim app çöküyor.

İlk başta, kaza sürüm bir sorunu neden olduğunu düşündüm, ama şimdi her iki bağdaştırıcı aynı Veritabanı Sürümü var ve hala kaybediyoruz.

İşte bu tablo için DB Adaptörleri gereken bir örnektir. Diğer adaptörleri farklı uygulamaları ile aynı biçimi uygulayın.

public class InfoDBAdapter {
    public static final String ROW_ID = "_id";
    public static final String NAME = "name";

    private static final String TAG = "InfoDbAdapter";
    private static final String DATABASE_NAME = "myappdb";
    private static final String DATABASE_TABLE = "usersinfo";
    private static final int DATABASE_VERSION = 1;


    private static final String DATABASE_CREATE = "create table usersinfo (_id integer primary key autoincrement, "
              NAME
              " TEXT,"   ");";

    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;

    private final Context mCtx;

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            db.execSQL(DATABASE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version "   oldVersion   " to " //$NON-NLS-1$//$NON-NLS-2$
                      newVersion   ", which will destroy all old data"); //$NON-NLS-1$
            //db.execSQL("DROP TABLE IF EXISTS usersinfo"); //$NON-NLS-1$
            onCreate(db);
        }
    }


    public InfoDBAdapter(Context ctx) {
        this.mCtx = ctx;
    }


    public InfoDBAdapter open() throws SQLException {
        this.mDbHelper = new DatabaseHelper(this.mCtx);
        this.mDb = this.mDbHelper.getWritableDatabase();
        return this;
    }

    /**
     * close return type: void
     */
    public void close() {
        this.mDbHelper.close();
    }


    public long createUser(String name) {
        ContentValues initialValues = new ContentValues();
        initialValues.put(NAME, name);
        return this.mDb.insert(DATABASE_TABLE, null, initialValues);
    }


    public boolean deleteUser(long rowId) {

        return this.mDb.delete(DATABASE_TABLE, ROW_ID   "="   rowId, null) > 0; //$NON-NLS-1$
    }


    public Cursor fetchAllUsers() {

        return this.mDb.query(DATABASE_TABLE, new String[] { ROW_ID,
                NAME}, null, null, null, null, null);
    }


    public Cursor fetchUser(long rowId) throws SQLException {

        Cursor mCursor =

        this.mDb.query(true, DATABASE_TABLE, new String[] { ROW_ID, NAME}, ROW_ID   "="   rowId, null, //$NON-NLS-1$
                null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }


    public boolean updateUser(long rowId, String name) {
        ContentValues args = new ContentValues();
        args.put(NAME, name);
        return this.mDb
                .update(DATABASE_TABLE, args, ROW_ID   "="   rowId, null) > 0; //$NON-NLS-1$
    }
}

İlk adaptör, bu durumda usersinfo, erişildiğinde, her şeyin beklendiği gibi çalışır. Diyelim ki ben başka bir adaptör için arkadaş bilgileri aşağıdaki aynı yapı olarak yukarıda, ne zaman erişilen bir farklı etkinlik, öyle görünüyor bana o iç içe geçmiş alt sınıf SQLiteOpenHelper ki girişim oluşturmak için veritabanını yeniden. Belli ki bir senaryo çünkü yanlış olduğunu, benim app çöküyor.

Yani standart bir uygulama her tablo için tek tek adaptörleri yerine tek mamut db bağdaştırıcısı oluşturmak için içinde Android mi?

CEVAP
5 Mayıs 2011, PERŞEMBE


İşte sonunda uygulama sona erdi çözüm. Karışım info Commonsware kitapları elde gelen bir şey, ve bazı kredi vermek istiyorum çünkü ben sık keşke bu web şeyler:

Db çekmek için ihtiyacım olan her veri türü için bir "sınıf (her şeyi alt sınıfı). adaptör yaratırım Bu adaptörü sınıflar bilgi parçası için db erişim yöntemleri gerekli tüm tutun. Eğer benim db üç masa vardı, örneğin:

  1. Araba
  2. Tekneler
  3. Motosiklet

Aşağıdaki(sadece bir demo olarak bir tane koyuyorum, ama fikir her aynıdır) benzer üç adaptörleri olurdu:

public class CarsDBAdapter {
    public static final String ROW_ID = "_id";
    public static final String NAME = "name";
    public static final String MODEL = "model";
    public static final String YEAR = "year";

    private static final String DATABASE_TABLE = "cars";

    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;

    private final Context mCtx;

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DBAdapter.DATABASE_NAME, null, DBAdapter.DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        }

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

    /**
     * Constructor - takes the context to allow the database to be
     * opened/created
     * 
     * @param ctx
     *            the Context within which to work
     */
    public CarsDBAdapter(Context ctx) {
        this.mCtx = ctx;
    }

    /**
     * Open the cars database. If it cannot be opened, try to create a new
     * instance of the database. If it cannot be created, throw an exception to
     * signal the failure
     * 
     * @return this (self reference, allowing this to be chained in an
     *         initialization call)
     * @throws SQLException
     *             if the database could be neither opened or created
     */
    public CarsDBAdapter open() throws SQLException {
        this.mDbHelper = new DatabaseHelper(this.mCtx);
        this.mDb = this.mDbHelper.getWritableDatabase();
        return this;
    }

    /**
     * close return type: void
     */
    public void close() {
        this.mDbHelper.close();
    }

    /**
     * Create a new car. If the car is successfully created return the new
     * rowId for that car, otherwise return a -1 to indicate failure.
     * 
     * @param name
     * @param model
     * @param year
     * @return rowId or -1 if failed
     */
    public long createCar(String name, String model, String year){
        ContentValues initialValues = new ContentValues();
        initialValues.put(NAME, name);
        initialValues.put(MODEL, model);
        initialValues.put(YEAR, year);
        return this.mDb.insert(DATABASE_TABLE, null, initialValues);
    }

    /**
     * Delete the car with the given rowId
     * 
     * @param rowId
     * @return true if deleted, false otherwise
     */
    public boolean deleteCar(long rowId) {

        return this.mDb.delete(DATABASE_TABLE, ROW_ID   "="   rowId, null) > 0; //$NON-NLS-1$
    }

    /**
     * Return a Cursor over the list of all cars in the database
     * 
     * @return Cursor over all cars
     */
    public Cursor getAllCars() {

        return this.mDb.query(DATABASE_TABLE, new String[] { ROW_ID,
                NAME, MODEL, YEAR }, null, null, null, null, null);
    }

    /**
     * Return a Cursor positioned at the car that matches the given rowId
     * @param rowId
     * @return Cursor positioned to matching car, if found
     * @throws SQLException if car could not be found/retrieved
     */
    public Cursor getCar(long rowId) throws SQLException {

        Cursor mCursor =

        this.mDb.query(true, DATABASE_TABLE, new String[] { ROW_ID, NAME,
                MODEL, YEAR}, ROW_ID   "="   rowId, null, null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }

    /**
     * Update the car.
     * 
     * @param rowId
     * @param name
     * @param model
     * @param year
     * @return true if the note was successfully updated, false otherwise
     */
    public boolean updateCar(long rowId, String name, String model,
            String year){
        ContentValues args = new ContentValues();
        args.put(NAME, name);
        args.put(MODEL, model);
        args.put(YEAR, year);

        return this.mDb.update(DATABASE_TABLE, args, ROW_ID   "="   rowId, null) >0; 
    }

}

Eğer öyleyse "" her tablo için. adaptörleri bu sınıflardan biri var düşünürseniz

App splash ekranım başladığında tekniği Android For Beginners: Creating multiple SQLite Tables for Android sunulan kullanıyorum

Benim ana DBAdapter tek bir db benim tüm tabloları oluşturmak için sorumlu olan) bu gibi görünüyor:

public class DBAdapter {

    public static final String DATABASE_NAME = "stuffIOwn"; //$NON-NLS-1$

    public static final int DATABASE_VERSION = 1;

    private static final String CREATE_TABLE_CARS =
       "create table cars (_id integer primary key autoincrement, " //$NON-NLS-1$
      CarsDBAdapter.NAME  " TEXT," //$NON-NLS-1$
      CarsDBAdapter.MODEL  " TEXT," //$NON-NLS-1$
      CarsDBAdapter.YEAR  " TEXT"   ");"; //$NON-NLS-1$ //$NON-NLS-2$

    private static final String CREATE_TABLE_BOATS = "create table boats (_id integer primary key autoincrement, " //$NON-NLS-1$
     BoatsDBAdapter.NAME " TEXT," //$NON-NLS-1$
     BoatsDBAdapter.MODEL " TEXT," //$NON-NLS-1$
     BoatsDBAdapter.YEAR " TEXT"  ");"; //$NON-NLS-1$  //$NON-NLS-2$

        private static final String CREATE_TABLE_CYCLES = "create table cycles (_id integer primary key autoincrement, " //$NON-NLS-1$
     CyclesDBAdapter.NAME " TEXT," //$NON-NLS-1$
     CyclesDBAdapter.MODEL " TEXT," //$NON-NLS-1$
     CyclesDBAdapter.YEAR " TEXT"  ");"; //$NON-NLS-1$  //$NON-NLS-2$


    private final Context context; 
    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    /**
     * Constructor
     * @param ctx
     */
    public DBAdapter(Context ctx)
    {
        this.context = ctx;
        this.DBHelper = new DatabaseHelper(this.context);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper 
    {
        DatabaseHelper(Context context) 
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) 
        {
            db.execSQL(CREATE_TABLE_CARS);
            db.execSQL(CREATE_TABLE_BOATS);
            db.execSQL(CREATE_TABLE_CYCLES);           
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, 
        int newVersion) 
        {               
            // Adding any table mods to this guy here
        }
    } 

   /**
     * open the db
     * @return this
     * @throws SQLException
     * return type: DBAdapter
     */
    public DBAdapter open() throws SQLException 
    {
        this.db = this.DBHelper.getWritableDatabase();
        return this;
    }

    /**
     * close the db 
     * return type: void
     */
    public void close() 
    {
        this.DBHelper.close();
    }
}

DBAdapter sınıfı sadece app ilk başlar ve sadece kendi sorumluluk/tablo oluşturmak yükseltmek için çağrılır. Veri tüm diğer erişim bireysel "" sınıf. adaptör ile yapılır Bu mükemmel çalışır buldum ve daha önce bahsettiğim sürüm sorunları oluşturmaz.

Bu yardımcı olur umarım.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Andrea Lewis

    Andrea Lewis

    14 Mart 2013
  • Klemens Torggler

    Klemens Torg

    11 Mart 2008
  • Rugiagialia

    Rugiagialia

    1 Ocak 2008