zoukankan      html  css  js  c++  java
  • android-SQLite 和 Content

    SQLite

    游标(Cursor)相当于指向底层数据中结果集的指针,而不是提取和返回结果值的副本,是在结果集中对位置(行)进行控制的管理方式。

    moveToFirst:把游标移动到查询结果的第一行

    moveToNext:把游标移动到下一行

    moveToPrevious:把游标移动到前一行

    getCount:返回结果集中的行数

    getColumnIndexOrThrow:返回具有指定名称的列的索引

    getColumnName:返回指定索引的列的名称

    getColumnNames:返回当前游标中的所有列名的字符串数组

    moveToPosition:移动到特定的行的游标

    getPosition:返回当前的游标位置

    Adapter类负责管理数据库交互(数据模型,更具对象属性设置增删改查的逻辑),使用SQLiteOpenHelper的扩展类协助创建数据表,获取SQLiteDatabase对象进行增删改查。

    扩展SQLiteOpenHelper,由扩展类完成数据表的创建,数据库的更新。

    package com.paad.todolist;
    
    import java.util.Date;
    
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.database.sqlite.SQLiteDatabase.CursorFactory;
    import android.util.Log;
    
    public class ToDoDBAdapter {
      private static final String DATABASE_NAME = "todoList.db";
      private static final String DATABASE_TABLE = "todoItems";
      private static final int DATABASE_VERSION = 1;
     
      public static final String KEY_ID = "_id";
      public static final String KEY_TASK = "task";
      public static final String KEY_CREATION_DATE = "creation_date";
      
      private SQLiteDatabase db;
      private final Context context;
      private toDoDBOpenHelper dbHelper;
    
      public ToDoDBAdapter(Context _context) {
        this.context = _context;
        dbHelper = new toDoDBOpenHelper(context, DATABASE_NAME, 
                                        null, DATABASE_VERSION);
      }
      
      public void close() {
        db.close();
      }
      
      public void open() throws SQLiteException {  
        try {
          db = dbHelper.getWritableDatabase();
        } catch (SQLiteException ex) {
          db = dbHelper.getReadableDatabase();
        }
      }  
      
      //Insert a new task
      public long insertTask(ToDoItem _task) {
        // Create a new row of values to insert.
        ContentValues newTaskValues = new ContentValues();
        // Assign values for each row.
        newTaskValues.put(KEY_TASK, _task.getTask());
        newTaskValues.put(KEY_CREATION_DATE, _task.getCreated().getTime());
        // Insert the row.
        return db.insert(DATABASE_TABLE, null, newTaskValues);
      }
    
      // Remove a task based on its index
      public boolean removeTask(long _rowIndex) {
        return db.delete(DATABASE_TABLE, KEY_ID + "=" + _rowIndex, null) > 0;
      }
    
      // Update a task
      public boolean updateTask(long _rowIndex, String _task) {
        ContentValues newValue = new ContentValues();
        newValue.put(KEY_TASK, _task);
        return db.update(DATABASE_TABLE, newValue, KEY_ID + "=" + _rowIndex, null) > 0;
      }
      
      public Cursor getAllToDoItemsCursor() {
        return db.query(DATABASE_TABLE, 
                        new String[] { KEY_ID, KEY_TASK, KEY_CREATION_DATE}, 
                        null, null, null, null, null);
      }
    
      public Cursor setCursorToToDoItem(long _rowIndex) throws SQLException {
        Cursor result = db.query(true, DATABASE_TABLE, 
                                   new String[] {KEY_ID, KEY_TASK},
                                 KEY_ID + "=" + _rowIndex, null, null, null, 
                                 null, null);
        if ((result.getCount() == 0) || !result.moveToFirst()) {
          throw new SQLException("No to do items found for row: " + _rowIndex);
        }
        return result;
      }
    
      public ToDoItem getToDoItem(long _rowIndex) throws SQLException {
        Cursor cursor = db.query(true, DATABASE_TABLE, 
                                 new String[] {KEY_ID, KEY_TASK},
                                 KEY_ID + "=" + _rowIndex, null, null, null, 
                                 null, null);
        if ((cursor.getCount() == 0) || !cursor.moveToFirst()) {
          throw new SQLException("No to do item found for row: " + _rowIndex);
        }
    
        String task = cursor.getString(cursor.getColumnIndex(KEY_TASK));
        long created = cursor.getLong(cursor.getColumnIndex(KEY_CREATION_DATE));
              
        ToDoItem result = new ToDoItem(task, new Date(created));
        return result;  
      }
      
      private static class toDoDBOpenHelper extends SQLiteOpenHelper {
    
          public toDoDBOpenHelper(Context context, String name,
                                  CursorFactory factory, int version) {
            super(context, name, factory, version);
          }
    
          // SQL Statement to create a new database.
          private static final String DATABASE_CREATE = "create table " + 
            DATABASE_TABLE + " (" + KEY_ID + " integer primary key autoincrement, " +
            KEY_TASK + " text not null, " + KEY_CREATION_DATE + " long);";
    
          @Override
          public void onCreate(SQLiteDatabase _db) {
            _db.execSQL(DATABASE_CREATE);
          }
    
          @Override
          public void onUpgrade(SQLiteDatabase _db, int _oldVersion, int _newVersion) {
            Log.w("TaskDBAdapter", "Upgrading from version " + 
                                   _oldVersion + " to " +
                                   _newVersion + ", which will destroy all old data");
    
            // Drop the old table.
            _db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
            // Create a new one.
            onCreate(_db);
          }
        }
    }

    Content

    ContentProvider可使用SQLiteOpenHelper辅助操作数据(用数据库持久化)。由ContentProvider的扩展类完成数据交互,ContentProvider扩展类的对象则是通过获取到应用上下文中的ContentResolver对象,根据其方法及URI,由系统内部执行ContentProvider扩展类对象中重写的方法。

    ContentProvider扩展类的实现:

    public class EarthquakeProvider extends ContentProvider {
    
      public static final Uri CONTENT_URI = Uri.parse("content://com.paad.provider.earthquake/earthquakes");
      
      @Override
      public boolean onCreate() {
        Context context = getContext();
    
        earthquakeDatabaseHelper dbHelper = new earthquakeDatabaseHelper(context,  
                                                                       DATABASE_NAME, 
                                                                       null, 
                                                                       DATABASE_VERSION);
        earthquakeDB = dbHelper.getWritableDatabase();
        return (earthquakeDB == null) ? false : true;
      }
        
      @Override
      public Cursor query(Uri uri, 
                          String[] projection, 
                          String selection, 
                          String[] selectionArgs, 
                          String sort) {
            
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    
        qb.setTables(EARTHQUAKE_TABLE);
    
        // If this is a row query, limit the result set to the passed in row. 
        switch (uriMatcher.match(uri)) {
          case QUAKE_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
                         break;
          default      : break;
        }
    
        // If no sort order is specified sort by date / time
        String orderBy;
        if (TextUtils.isEmpty(sort)) {
          orderBy = KEY_DATE;
        } else {
          orderBy = sort;
        }
    
        // Apply the query to the underlying database.
        Cursor c = qb.query(earthquakeDB, 
                            projection, 
                            selection, selectionArgs, 
                            null, null, 
                            orderBy);
    
        // Register the contexts ContentResolver to be notified if
        // the cursor result set changes. 
        c.setNotificationUri(getContext().getContentResolver(), uri);
        
        // Return a cursor to the query result.
        return c;
      }
    
      @Override
      public Uri insert(Uri _uri, ContentValues _initialValues) {
        // Insert the new row, will return the row number if 
        // successful.
        long rowID = earthquakeDB.insert(EARTHQUAKE_TABLE, "quake", _initialValues);
              
        // Return a URI to the newly inserted row on success.
        if (rowID > 0) {
          Uri uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
          getContext().getContentResolver().notifyChange(uri, null);
          return uri;
        }
        throw new SQLException("Failed to insert row into " + _uri);
      }
    
      @Override
      public int delete(Uri uri, String where, String[] whereArgs) {
        int count;
        
        switch (uriMatcher.match(uri)) {
          case QUAKES:
            count = earthquakeDB.delete(EARTHQUAKE_TABLE, where, whereArgs);
            break;
    
          case QUAKE_ID:
            String segment = uri.getPathSegments().get(1);
            count = earthquakeDB.delete(EARTHQUAKE_TABLE, KEY_ID + "="
                                        + segment
                                        + (!TextUtils.isEmpty(where) ? " AND (" 
                                        + where + ')' : ""), whereArgs);
            break;
    
          default: throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
      }
    
      @Override
      public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
        int count;
        switch (uriMatcher.match(uri)) {
          case QUAKES: count = earthquakeDB.update(EARTHQUAKE_TABLE, values, 
                                                   where, whereArgs);
                       break;
    
          case QUAKE_ID: String segment = uri.getPathSegments().get(1);
                         count = earthquakeDB.update(EARTHQUAKE_TABLE, values, KEY_ID 
                                 + "=" + segment 
                                 + (!TextUtils.isEmpty(where) ? " AND (" 
                                 + where + ')' : ""), whereArgs);
                         break;
    
          default: throw new IllegalArgumentException("Unknown URI " + uri);
        }
    
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
      }
      
      @Override
      public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
          case QUAKES: return "vnd.android.cursor.dir/vnd.paad.earthquake";
          case QUAKE_ID: return "vnd.android.cursor.item/vnd.paad.earthquake";
          default: throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
      }
      
      // Create the constants used to differentiate between the different URI 
      // requests.
      private static final int QUAKES = 1;
      private static final int QUAKE_ID = 2;
    
      private static final UriMatcher uriMatcher;
    
      // Allocate the UriMatcher object, where a URI ending in 'earthquakes' will
      // correspond to a request for all earthquakes, and 'earthquakes' with a 
      // trailing '/[rowID]' will represent a single earthquake row.
      static {
       uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
       uriMatcher.addURI("com.paad.provider.Earthquake", "earthquakes", QUAKES);
       uriMatcher.addURI("com.paad.provider.Earthquake", "earthquakes/#", QUAKE_ID);
      }
      
      //The underlying database
      private SQLiteDatabase earthquakeDB;
    
      private static final String TAG = "EarthquakeProvider";
      private static final String DATABASE_NAME = "earthquakes.db";
      private static final int DATABASE_VERSION = 1;
      private static final String EARTHQUAKE_TABLE = "earthquakes";
    
      // Column Names
      public static final String KEY_ID = "_id";
      public static final String KEY_DATE = "date";
      public static final String KEY_DETAILS = "details";
      public static final String KEY_LOCATION_LAT = "latitude";
      public static final String KEY_LOCATION_LNG = "longitude";
      public static final String KEY_MAGNITUDE = "magnitude";
      public static final String KEY_LINK = "link";
    
      // Column indexes
      public static final int DATE_COLUMN = 1;
      public static final int DETAILS_COLUMN = 2;
      public static final int LONGITUDE_COLUMN = 3;
      public static final int LATITUDE_COLUMN = 4;
      public static final int MAGNITUDE_COLUMN = 5;
      public static final int LINK_COLUMN = 6;
          
      // Helper class for opening, creating, and managing database version control
      private static class earthquakeDatabaseHelper extends SQLiteOpenHelper {
        private static final String DATABASE_CREATE =
          "create table " + EARTHQUAKE_TABLE + " (" 
          + KEY_ID + " integer primary key autoincrement, "
          + KEY_DATE + " INTEGER, "
          + KEY_DETAILS + " TEXT, "
          + KEY_LOCATION_LAT + " FLOAT, "
          + KEY_LOCATION_LNG + " FLOAT, "
          + KEY_MAGNITUDE + " FLOAT), "
          + KEY_LINK + " TEXT);";
            
        public earthquakeDatabaseHelper(Context context, String name,
                                        CursorFactory factory, int version) {
          super(context, name, factory, 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 "
                      + newVersion + ", which will destroy all old data");
                  
          db.execSQL("DROP TABLE IF EXISTS " + EARTHQUAKE_TABLE);
          onCreate(db);
        }
      }
    }

    ContentProvider扩展类的使用:

    private void loadQuakesFromProvider() {
          // Clear the existing earthquake array
          earthquakes.clear();
    
          ContentResolver cr = getContentResolver();
    
          // Return all the saved earthquakes
          Cursor c = cr.query(EarthquakeProvider.CONTENT_URI, null, null, null, null);
             
          if (c.moveToFirst()) {
            do { 
              // Extract the quake details.
              Long datems = c.getLong(EarthquakeProvider.DATE_COLUMN);
              String details = c.getString(EarthquakeProvider.DETAILS_COLUMN);
              Float lat = c.getFloat(EarthquakeProvider.LATITUDE_COLUMN);
              Float lng = c.getFloat(EarthquakeProvider.LONGITUDE_COLUMN);
              Double mag = c.getDouble(EarthquakeProvider.MAGNITUDE_COLUMN);
              String link = c.getString(EarthquakeProvider.LINK_COLUMN);
    
              Location location = new Location("dummy");
              location.setLongitude(lng);
              location.setLatitude(lat);
    
              Date date = new Date(datems);
    
              Quake q = new Quake(date, details, location, mag, link);
              addQuakeToArray(q);
            } while(c.moveToNext());
          }
     }
    
    
    private void addNewQuake(Quake _quake) {
          ContentResolver cr = getContentResolver();
          // Construct a where clause to make sure we don�t already have this 
          // earthquake in the provider.
          String w = EarthquakeProvider.KEY_DATE + " = " + _quake.getDate().getTime();
    
          // If the earthquake is new, insert it into the provider.
          if (cr.query(EarthquakeProvider.CONTENT_URI, null, w, null, null).getCount()==0){
            ContentValues values = new ContentValues();    
    
            values.put(EarthquakeProvider.KEY_DATE, _quake.getDate().getTime());
            values.put(EarthquakeProvider.KEY_DETAILS, _quake.getDetails());
    
            double lat = _quake.getLocation().getLatitude();
            double lng = _quake.getLocation().getLongitude();
            values.put(EarthquakeProvider.KEY_LOCATION_LAT, lat);
            values.put(EarthquakeProvider.KEY_LOCATION_LNG, lng);
            values.put(EarthquakeProvider.KEY_LINK, _quake.getLink());
            values.put(EarthquakeProvider.KEY_MAGNITUDE, _quake.getMagnitude());
    
            cr.insert(EarthquakeProvider.CONTENT_URI, values);
            earthquakes.add(_quake);
    
            addQuakeToArray(_quake);
          }
    }
  • 相关阅读:
    (转)把hadoop源码关联到eclipse工程
    windows 系统下git 的使用
    windows 系统下git 的安装
    windows 系统下TortoiseGit 的安装
    windows 安装 mysql
    windows 下 mySQL 镜像安装文件下载
    vs2012 有效产品密钥
    mac 安装 visual studio 配置
    mac 安装 nodeJs&npm 配置
    macOS Sierra 如何打开任何来源
  • 原文地址:https://www.cnblogs.com/mingfung-liu/p/4535520.html
Copyright © 2011-2022 走看看