2013-07-03 9 views
26

jestem trochę zdezorientowany, bo nie wiem, w jaki sposób należy interpretować tutorial tutaj: http://developer.android.com/training/basics/data-storage/databases.html#DbHelperJak korzystać z klasy kontraktowej w systemie Android?

Mój kod do tej pory wygląda następująco:

public final class DatabaseContract { 
// To prevent someone from accidentally instantiating the contract class, 
// give it an empty constructor. 
public DatabaseContract() {} 

public static abstract class Table1 implements BaseColumns { 
    public static final String TABLE_NAME  = "nameOfTable"; 
    public static final String COLUMN_NAME_COL1 = "column1"; 
    public static final String COLUMN_NAME_COL2 = "column2"; 
    public static final String COLUMN_NAME_COL3 = "column3"; 
} 

public class DatabaseHelper extends SQLiteOpenHelper { 
    // If you change the database schema, you must increment the database version. 
    public static final int DATABASE_VERSION = 1; 
    public static final String DATABASE_NAME  = "database.db"; 
    private static final String TEXT_TYPE   = " TEXT"; 
    private static final String COMMA_SEP   = ","; 
    private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " + 
      Table1.TABLE_NAME + " (" + 
      Table1._ID + " INTEGER PRIMARY KEY," + 
      Table1.COLUMN_NAME_COL1 + TEXT_TYPE + COMMA_SEP + 
      Table1.COLUMN_NAME_COL2 + TEXT_TYPE + COMMA_SEP + 
      Table1.COLUMN_NAME_COL3 + TEXT_TYPE + COMMA_SEP + ")"; 
    private static final String SQL_DELETE_ALL_ENTRIES = "DROP TABLE IF EXISTS " + Table1.TABLE_NAME; 

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

    // Method is called during creation of the database 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(SQL_CREATE_ENTRIES); 
    } 

    // Method is called during an upgrade of the database 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(DatabaseHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); 

     db.execSQL(SQL_DELETE_ALL_ENTRIES); 
     onCreate(db); 
    } 
} 
} 

Czy ja interpretować go w prawo lub mieć pierwsze 6 zmiennych w klasie pomocnika na zewnątrz w klasie kontraktowej? Czy klasa pomocnicza nie powinna być klasą wewnętrzną klasy kontraktowej?

Spodziewać się można mi pomóc

+0

Klasa pomocnika nie jest częścią businessobjects ... –

+0

, więc powinienem utworzyć własny plik dla klasy Pomocnika? – maysi

Odpowiedz

91

Twoja umowa w zasadzie definiuje bazy danych i jak ludzie powinni współpracować z nim przez dostawcę treści.

Klasa umowa definiuje stałe, które pomagają aplikacje działają z URI treści, nazwy kolumn, działania intencji, i inne cechy dostawca treści. Klasy kontraktowe nie są automatycznie dostarczane z dostawcą; twórca dostawcy musi je zdefiniować, a następnie udostępnić je innym programistom.

Powiedziawszy to, niekoniecznie potrzebujesz Dostawcy Treści, aby użyć klasy Kontrakt. Mój przykład zawiera stałe, które są używane przez dostawcę treści (części MIME i URI). Jeśli nie korzystasz z dostawcy treści, nie potrzebujesz tych sekcji.

Lubię myśleć o klasie kontraktu jako schemacie bazy danych lub innymi słowy o czymś, co definiuje konfigurację bazy danych. Możesz zauważyć, że wszystko w klasie kontraktowej jest zadeklarowane jako statyczne. Dzieje się tak dlatego, że nigdy nie tworzysz instancji klasy Contract, a jedynie odnosząc się do zdefiniowanych w niej stałych. W moim przykładzie widać, że moja klasa kontraktowa ma tylko kilka statycznych zmiennych końcowych. Ta klasa kontraktu może być własnym plikiem, np. mój plik nazywa się TransitContract.java.

Załóżmy na przykład, że chcesz zmienić nazwę jednej ze swoich kolumn. Zamiast dokonywania zmian w wielu plikach, wystarczy zmienić wartość kolumny w klasie kontraktu. Nie wykonujesz żadnych operacji obliczeniowych w klasie kontraktu.

Z drugiej strony klasa SQLLiteOpenhelper to coś, co zostało dostarczone przez Google, aby ułatwić pracę z bazami danych. Tutaj wdrażasz metody, które tworzą i konfigurują początkową bazę danych. Zobacz http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html. Po wdrożeniu tych metod, wystarczy utworzyć instancję klasy pomocniczej, a następnie wywołać metodę helperClassInstance.getWriteableDatabase() (lub getReadableDataBase()), a następnie klasa pomocnika automatycznie zajmie się tworzeniem nowej bazy danych w razie potrzeby, lub zwrot tego, który już istnieje itp.

Ten helper jest na ogół implementowany jako wewnętrzna klasa, ale może być samodzielną klasą. Jednak chcesz go zaimplementować.

Gorąco polecam przeglądanie przykładowego Notatnika dostarczonego przez Google, ponieważ jest to dobry przykład tego, jak można ustawić klasę kontraktu. Pamiętaj, że korzystają też z dostawcy treści. Jeśli chcesz dowiedzieć się więcej na temat dostawców treści, zalecamy przeczytanie kilku innych informacji pod numerem http://developer.android.com/guide/topics/providers/content-provider-basics.html. Rozlega się znacznie więcej informacji o dostawcach treści i klasach kontraktów.

Oto przykład użycia Twojego kodu. Tak naprawdę nie przetestowałem tego kodu, aby mógł on zawierać błędy. Jak widać, możesz utworzyć instancję hella pomocniczego wszędzie tam, gdzie uznasz to za konieczne. W tym przykładzie robię to w głównym działaniu onCreate, ale w rzeczywistości jest to zła praktyka.

DatabaseContract.java

public final class DatabaseContract { 

    public static final int DATABASE_VERSION = 1; 
    public static final String DATABASE_NAME  = "database.db"; 
    private static final String TEXT_TYPE   = " TEXT"; 
    private static final String COMMA_SEP   = ","; 

    // To prevent someone from accidentally instantiating the contract class, 
    // give it an empty constructor. 
    private DatabaseContract() {} 

    public static abstract class Table1 implements BaseColumns { 
     public static final String TABLE_NAME  = "nameOfTable"; 
     public static final String COLUMN_NAME_COL1 = "column1"; 
     public static final String COLUMN_NAME_COL2 = "column2"; 
     public static final String COLUMN_NAME_COL3 = "column3"; 


     public static final String CREATE_TABLE = "CREATE TABLE " + 
       TABLE_NAME + " (" + 
       _ID + " INTEGER PRIMARY KEY," + 
       COLUMN_NAME_COL1 + TEXT_TYPE + COMMA_SEP + 
       COLUMN_NAME_COL2 + TEXT_TYPE + COMMA_SEP + 
       COLUMN_NAME_COL3 + TEXT_TYPE + ")"; 
     public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME; 
    } 
} 

DatabaseHelper.java

public class DatabaseHelper extends SQLiteOpenHelper {  
    public DatabaseHelper(Context context) { 
     super(context, DatabaseContract.DATABASE_NAME, null, DatabaseContract.DATABASE_VERSION); 
    } 

    // Method is called during creation of the database 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DatabaseContract.Table1.CREATE_TABLE); 
    } 

    // Method is called during an upgrade of the database 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     db.execSQL(DatabaseContract.Table1.DELETE_TABLE); 
     onCreate(db); 
    } 
} 

MainActivity.java

public class MainActivity extends Activity { 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     // Create new helper 
     DatabaseHelper dbHelper = new DatabaseHelper(getContext()); 
     // Get the database. If it does not exist, this is where it will 
     // also be created. 
     SQLiteDatabase db = dbHelper.getWriteableDatabase(); 

     // Create insert entries 
     ContentValues values = new ContentValues(); 
     values.put(DatabaseContract.Table1.COLUMN_NAME_COL1, "value1"); 
     values.put(DatabaseContract.Table1.COLUMN_NAME_COL2, "value2"); 
     values.put(DatabaseContract.Table1.COLUMN_NAME_COL3, "value3"); 

     // Insert the new row, returning the primary key value of the new row 
     long newRowId; 
     newRowId = db.insert(
       DatabaseContract.Table1.TABLE_NAME, 
       null, 
       values); 
    } 
} 

A mój przykład

public final class TransitContract { 
    public static final String AUTHORITY = "com.example.TransitProvider"; 
    public static final String SCHEME = "content://"; 
    public static final String SLASH = "/"; 
    public static final String DATABASE_NAME = "transit.db"; 

    /* An array list of all the SQL create table statements */ 
    public static final String[] SQL_CREATE_TABLE_ARRAY = { 
     Agency.CREATE_TABLE, 
     CalendarDates.CREATE_TABLE, 
     Calendar.CREATE_TABLE, 
     Routes.CREATE_TABLE, 
     Shapes.CREATE_TABLE, 
     Stops.CREATE_TABLE, 
     StopTimes.CREATE_TABLE, 
     Trips.CREATE_TABLE 
    }; 

    /** 
    * Array of resource ids for each GTFS data file that will be loaded into 
    * database 
    */ 
    public static final int[] RAW_IDS = { 
     R.raw.agency, 
     R.raw.calendar_dates, 
     R.raw.calendar, 
     R.raw.routes, 
     R.raw.shapes, 
     R.raw.stops, 
     R.raw.stop_times, 
     R.raw.trips, 
    }; 

    /* Do not allow this class to be instantiated */ 
    private TransitContract() {} 

    public static final class Agency implements BaseColumns { 
     /* Do not allow this class to be instantiated */ 
     private Agency() {} 

     public static final String TABLE_NAME = "Agency"; 

     public static final String KEY_AGENCY_ID = "AgencyId"; 

     public static final String KEY_NAME = "Name"; 

     public static final String KEY_URL = "Url"; 

     public static final String KEY_TIMEZONE = "Timezone"; 

     public static final String KEY_LANG = "Language"; 

     public static final String KEY_PHONE = "PhoneNumber"; 

     public static final String KEY_FARE_URL = "FareUrl"; 

     /* 
     * URI definitions 
     */ 

     /** 
     * The content style URI 
     */ 
     public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY + SLASH + TABLE_NAME); 

     /** 
     * The content URI base for a single row. An ID must be appended. 
     */ 
     public static final Uri CONTENT_ID_URI_BASE = Uri.parse(SCHEME + AUTHORITY + SLASH + TABLE_NAME + SLASH); 

     /** 
     * The default sort order for this table 
     */ 
     public static final String DEFAULT_SORT_ORDER = KEY_AGENCY_ID + " ASC"; 

     /* 
     * MIME type definitions 
     */ 

     /** 
     * The MIME type of {@link #CONTENT_URI} providing rows 
     */ 
     public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + 
               "/vnd.com.marylandtransitcommuters.agency"; 

     /** 
     * The MIME type of a {@link #CONTENT_URI} single row 
     */ 
     public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + 
               "/vnd.com.marylandtransitcommuters.agency"; 

     /** 
     * SQL Statement to create the routes table 
     */ 
     public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" 
                + _ID + " INTEGER PRIMARY KEY," 
                + KEY_AGENCY_ID + " TEXT," 
                + KEY_NAME + " TEXT," 
                + KEY_URL + " TEXT," 
                + KEY_TIMEZONE + " TEXT," 
                + KEY_LANG + " TEXT," 
                + KEY_PHONE + " TEXT," 
                + KEY_FARE_URL + " TEXT" 
                + ");"; 

     /** 
     * SQL statement to delete the table 
     */ 
     public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME; 

     /** 
     * Array of all the columns. Makes for cleaner code 
     */ 
     public static final String[] KEY_ARRAY = { 
      KEY_AGENCY_ID, 
      KEY_NAME, 
      KEY_URL, 
      KEY_TIMEZONE, 
      KEY_LANG, 
      KEY_PHONE, 
      KEY_FARE_URL 
     }; 
    } 
+0

wow. Dziękuję Ci bardzo. ale nadal nie znam różnic między klasą kontraktową a klasą pomocniczą. Co musi być w umowie, a co w pomocniku. i czy klasy pomocnicze i kontraktowe są różnymi plikami? – maysi

+0

Zaktualizowałem moją odpowiedź. – btse

+0

WOW !!! Dziękuję Ci. właśnie to, czego szukałem. – maysi

Powiązane problemy