// The "Content authority" is a name for the entire content provider, similar to the // relationship between a domain name and its website. A convenient string to use for the // content authority is the package name for the app, which is guaranteed to be unique on the // device. public static final String CONTENT_AUTHORITY = "com.loveqiqi.sy.mysunshine"; // Use CONTENT_AUTHORITY to create the base of all URI's which apps will use to contact // the content provider. public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY); // Possible paths (appended to base content URI for possible URI's) // For instance, content://com.example.android.sunshine.app/weather/ is a valid path for // looking at weather data. content://com.example.android.sunshine.app/givemeroot/ will fail, // as the ContentProvider hasn't been given any information on what to do with "givemeroot". // At least, let's hope not. Don't be that dev, reader. Don't be that dev. public static final String PATH_WEATHER = "weather"; public static final String PATH_LOCATION = "location";
/* Inner class that defines the table contents of the location table Students: This is where you will add the strings. (Similar to what has been done for WeatherEntry) */ public static final class LocationEntry implements BaseColumns { public static final String TABLE_NAME = "location"; public static final String COLUMN_LOCATION_SETTING = "location_setting"; public static final String COLUMN_COORD_LAT = "coord_lat"; public static final String COLUMN_COORD_LONG = "coord_long"; public static final String COLUMN_CITY_NAME="city_name"; public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_LOCATION).build(); public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_LOCATION; public static Uri buildLocationUri(long id) { return ContentUris.withAppendedId(CONTENT_URI, id); } }
/** * Manages a local database for weather data. */ public class WeatherDbHelper extends SQLiteOpenHelper { // If you change the database schema, you must increment the database version. private static final int DATABASE_VERSION = 2; static final String DATABASE_NAME = "weather.db"; public WeatherDbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { final String SQL_CREATE_WEATHER_TABLE = "CREATE TABLE " + WeatherEntry.TABLE_NAME + " (" + // Why AutoIncrement here, and not above? // Unique keys will be auto-generated in either case. But for weather // forecasting, it's reasonable to assume the user will want information // for a certain date and all dates *following*, so the forecast data // should be sorted accordingly. WeatherEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + // the ID of the location entry associated with this weather data WeatherEntry.COLUMN_LOC_KEY + " INTEGER NOT NULL, " + WeatherEntry.COLUMN_DATE + " INTEGER NOT NULL, " + WeatherEntry.COLUMN_SHORT_DESC + " TEXT NOT NULL, " + WeatherEntry.COLUMN_WEATHER_ID + " INTEGER NOT NULL," + WeatherEntry.COLUMN_MIN_TEMP + " REAL NOT NULL, " + WeatherEntry.COLUMN_MAX_TEMP + " REAL NOT NULL, " + WeatherEntry.COLUMN_HUMIDITY + " REAL NOT NULL, " + WeatherEntry.COLUMN_PRESSURE + " REAL NOT NULL, " + WeatherEntry.COLUMN_WIND_SPEED + " REAL NOT NULL, " + WeatherEntry.COLUMN_DEGREES + " REAL NOT NULL, " + // Set up the location column as a foreign key to location table. " FOREIGN KEY (" + WeatherEntry.COLUMN_LOC_KEY + ") REFERENCES " + LocationEntry.TABLE_NAME + " (" + LocationEntry._ID + "), " + // To assure the application have just one weather entry per day // per location, it's created a UNIQUE constraint with REPLACE strategy " UNIQUE (" + WeatherEntry.COLUMN_DATE + ", " + WeatherEntry.COLUMN_LOC_KEY + ") ON CONFLICT REPLACE);"; final String SQL_CREATE_LOACTION_TABLE = "CREATE TABLE " + LocationEntry.TABLE_NAME + "(" + LocationEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + LocationEntry.COLUMN_LOCATION_SETTING + " TEXT UNIQUE NOT NULL," + LocationEntry.COLUMN_COORD_LAT + " REAL NOT NULL,"+ LocationEntry.COLUMN_COORD_LONG + " REAL NOT NULL," + LocationEntry.COLUMN_CITY_NAME + " TEXT NOT NULL); "; sqLiteDatabase.execSQL(SQL_CREATE_WEATHER_TABLE); sqLiteDatabase.execSQL(SQL_CREATE_LOACTION_TABLE); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { // This database is only a cache for online data, so its upgrade policy is // to simply to discard the data and start over // Note that this only fires if you change the version number for your database. // It does NOT depend on the version number for your application. // If you want to update the schema without wiping data, commenting out the next 2 lines // should be your top priority before modifying this method. sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + LocationEntry.TABLE_NAME); sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + WeatherEntry.TABLE_NAME); onCreate(sqLiteDatabase); } }
onCreate(SQLiteDatabase)
,
onUpgrade(SQLiteDatabase, int, int)
and/or
onOpen(SQLiteDatabase)
will be called.所以,
mOpenHelper = new WeatherDbHelper(getContext());然后就是对数据库的增删改查了。
// Gets the data repository in write mode SQLiteDatabase db = mDbHelper.getWritableDatabase(); // Create a new map of values, where column names are the keys ContentValues values = new ContentValues(); values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, id); values.put(FeedEntry.COLUMN_NAME_TITLE, title); values.put(FeedEntry.COLUMN_NAME_CONTENT, content); // Insert the new row, returning the primary key value of the new row long newRowId; newRowId = db.insert( FeedEntry.TABLE_NAME, FeedEntry.COLUMN_NAME_NULLABLE, values);第一个参数是表名,第二个参数是设置哪些列可以为空,如果设置为null,那么系统不会插入一个空行),一般是null吧,这样在定义
SQLiteDatabase db = mDbHelper.getReadableDatabase(); // Define a projection that specifies which columns from the database // you will actually use after this query. String[] projection = { FeedEntry._ID, FeedEntry.COLUMN_NAME_TITLE, FeedEntry.COLUMN_NAME_UPDATED, ... }; // How you want the results sorted in the resulting Cursor String sortOrder = FeedEntry.COLUMN_NAME_UPDATED + " DESC"; Cursor c = db.query( FeedEntry.TABLE_NAME, // The table to query projection, // The columns to return selection, // The columns for the WHERE clause selectionArgs, // The values for the WHERE clause null, // don't group the rows null, // don't filter by row groups sortOrder // The sort order );
This method will return false if the cursor is empty
然后就可以使用了:
cursor.moveToFirst(); long itemId = cursor.getLong( cursor.getColumnIndexOrThrow(FeedEntry._ID) );
// Define 'where' part of query. String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; // Specify arguments in placeholder order. String[] selectionArgs = { String.valueOf(rowId) }; // Issue SQL statement. db.delete(table_name, selection, selectionArgs);
public int delete(String table,String whereClause, String[] whereArgs)
Returns
SQLiteDatabase db = mDbHelper.getWritableDatabase(); // New value for one column ContentValues values = new ContentValues(); values.put(FeedEntry.COLUMN_NAME_TITLE, title); // Which row to update, based on the ID String selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?"; String[] selectionArgs = { String.valueOf(rowId) }; int count = db.update( FeedReaderDbHelper.FeedEntry.TABLE_NAME, values, selection, selectionArgs);