In essence, cursors iterate over result sets and provide access to data one row at a time.
first,We’ll want simple model objects,second,we need create table class with static methods and OpenSqliteHelper to create our database.third, a simple interface and DAOs for our model objects.last,create a data manager layer to wrap around those DAOs.
Designing a data access layer:
design table relations:
In general, if you need to share your data with other applications you must create a ContentProvider.if you don’t need to share data, it’s usually simpler to use a
database directly.if we want to use a ContentProvider to expose our tables later, must have an _id column,which is the primary key.e
now the src code is:
create Model objects
ModelBase class:
- /The ModelBase class, which both Movie and Category extend, contains only a long id.
- public class ModelBase {
- protected long id;
- public long getId() {
- return this.id;
- }
- public void setId(long id) {
- this.id = id;
- }
- @Override
- public String toString() {
- return "ModelBase [id=" + this.id + "]";
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (int) (this.id ^ (this.id >>> 32));
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof ModelBase)) {
- return false;
- }
- ModelBase other = (ModelBase) obj;
- if (this.id != other.id) {
- return false;
- }
- return true;
- }
- }
Movie model:
- public class Movie extends ModelBase {
- private String providerId;
- private String name;
- private int year;
- private double rating;
- private String url;
- private String homepage;
- private String trailer;
- private String tagline;
- private String thumbUrl;
- private String imageUrl;
- private Set<Category> categories;
-
- // note, in the real-world making these model beans immutable would be a better approach
- // (that is to say, not making them JavaBeans, but makign immutable model classes with Builder)
-
- public Movie() {
- this.categories = new LinkedHashSet<Category>();
- }
-
- public String getProviderId() {
- return this.providerId;
- }
-
- public void setProviderId(String providerId) {
- this.providerId = providerId;
- }
-
- public String getName() {
- return this.name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getYear() {
- return this.year;
- }
-
- public void setYear(int year) {
- this.year = year;
- }
-
- public double getRating() {
- return this.rating;
- }
-
- public void setRating(double rating) {
- this.rating = rating;
- }
-
- public String getUrl() {
- return this.url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getHomepage() {
- return this.homepage;
- }
-
- public void setHomepage(String homepage) {
- this.homepage = homepage;
- }
-
- public String getTrailer() {
- return this.trailer;
- }
-
- public void setTrailer(String trailer) {
- this.trailer = trailer;
- }
-
- public String getTagline() {
- return this.tagline;
- }
-
- public void setTagline(String tagline) {
- this.tagline = tagline;
- }
-
- public String getThumbUrl() {
- return this.thumbUrl;
- }
-
- public void setThumbUrl(String thumbUrl) {
- this.thumbUrl = thumbUrl;
- }
-
- public String getImageUrl() {
- return this.imageUrl;
- }
-
- public void setImageUrl(String imageUrl) {
- this.imageUrl = imageUrl;
- }
-
- public Set<Category> getCategories() {
- return this.categories;
- }
-
- public void setCategories(Set<Category> categories) {
- this.categories = categories;
- }
-
- @Override
- public String toString() {
- return "Movie [categories=" + this.categories + ", homepage=" + this.homepage + ", name=" + this.name
- + ", providerId=" + this.providerId + ", rating=" + this.rating + ", tagline=" + this.tagline
- + ", thumbUrl=" + this.thumbUrl + ", imageUrl=" + this.imageUrl + ", trailer=" + this.trailer + ", url="
- + this.url + ", year=" + this.year + "]";
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + ((this.categories == null) ? 0 : this.categories.hashCode());
- result = prime * result + ((this.homepage == null) ? 0 : this.homepage.hashCode());
- // upper name so hashCode is consistent with equals (equals ignores case)
- result = prime * result + ((this.name == null) ? 0 : this.name.toUpperCase().hashCode());
- result = prime * result + ((this.providerId == null) ? 0 : this.providerId.hashCode());
- long temp;
- temp = Double.doubleToLongBits(this.rating);
- result = prime * result + (int) (temp ^ (temp >>> 32));
- result = prime * result + ((this.tagline == null) ? 0 : this.tagline.hashCode());
- result = prime * result + ((this.thumbUrl == null) ? 0 : this.thumbUrl.hashCode());
- result = prime * result + ((this.imageUrl == null) ? 0 : this.imageUrl.hashCode());
- result = prime * result + ((this.trailer == null) ? 0 : this.trailer.hashCode());
- result = prime * result + ((this.url == null) ? 0 : this.url.hashCode());
- result = prime * result + this.year;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Movie)) {
- return false;
- }
- Movie other = (Movie) obj;
- if (this.categories == null) {
- if (other.categories != null) {
- return false;
- }
- } else if (!this.categories.equals(other.categories)) {
- return false;
- }
- if (this.homepage == null) {
- if (other.homepage != null) {
- return false;
- }
- } else if (!this.homepage.equals(other.homepage)) {
- return false;
- }
- if (this.name == null) {
- if (other.name != null) {
- return false;
- // name check ignores case
- }
- } else if (!this.name.equalsIgnoreCase(other.name)) {
- return false;
- }
- if (this.providerId == null) {
- if (other.providerId != null) {
- return false;
- }
- } else if (!this.providerId.equals(other.providerId)) {
- return false;
- }
- if (Double.doubleToLongBits(this.rating) != Double.doubleToLongBits(other.rating)) {
- return false;
- }
- if (this.tagline == null) {
- if (other.tagline != null) {
- return false;
- }
- } else if (!this.tagline.equals(other.tagline)) {
- return false;
- }
- if (this.thumbUrl == null) {
- if (other.thumbUrl != null) {
- return false;
- }
- } else if (!this.thumbUrl.equals(other.thumbUrl)) {
- return false;
- }
- if (this.imageUrl == null) {
- if (other.imageUrl != null) {
- return false;
- }
- } else if (!this.imageUrl.equals(other.imageUrl)) {
- return false;
- }
- if (this.trailer == null) {
- if (other.trailer != null) {
- return false;
- }
- } else if (!this.trailer.equals(other.trailer)) {
- return false;
- }
- if (this.url == null) {
- if (other.url != null) {
- return false;
- }
- } else if (!this.url.equals(other.url)) {
- return false;
- }
- if (this.year != other.year) {
- return false;
- }
- return true;
- }
- }
Category model:
- public class Category extends ModelBase implements Comparable<Category> {
- // NOTE in real-world android app you might want a CategoryFactory
- // or factory method here, to cut down on number of objects created
- private String name;
- public Category() {
- }
-
- public Category(long id, String name) {
- this.id = id;
- this.name = name;
- }
-
- public String getName() {
- return this.name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- @Override
- public String toString() {
- return this.name;
- }
-
- @Override
- public int compareTo(Category another) {
- if (another == null) {
- return -1;
- }
- if (this.name == null) {
- return 1;
- }
- return this.name.compareTo(another.name);
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- // upper name so hashCode is consistent with equals (equals ignores case)
- result = prime * result + ((this.name == null) ? 0 : this.name.toUpperCase().hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (!(obj instanceof Category)) {
- return false;
- }
- Category other = (Category) obj;
- if (this.name == null) {
- if (other.name != null) {
- return false;
- // name check ignores case
- }
- } else if (!this.name.equalsIgnoreCase(other.name)) {
- return false;
- }
- return true;
- }
- }
predefine Constant class:Constants、DataConstants:
- public class Constants {
- public static final String LOG_TAG = "MyMovies";
- private Constants() {
- }
- }
- public class DataConstants {
- private static final String APP_PACKAGE_NAME = "example.mymoviesdatabases";
- private static final String EXTERNAL_DATA_DIR_NAME = "mymoviesdata";
- public static final String EXTERNAL_DATA_PATH =
- Environment.getExternalStorageDirectory() + "/" + DataConstants.EXTERNAL_DATA_DIR_NAME;
-
- public static final String DATABASE_NAME = "mymovies.db";
- public static final String DATABASE_PATH =
- Environment.getDataDirectory() + "/data/" + DataConstants.APP_PACKAGE_NAME + "/databases/"
- + DataConstants.DATABASE_NAME;
-
- private DataConstants() {
- }
- }
MovieTable table class:
The MovieTable class with static methods and inner class MovieColumns.
- public final class MovieTable {
- public static final String TABLE_NAME = "movie";
- //BaseColumns is provided by Android, and it defines the _id column
- public static class MovieColumns implements BaseColumns{
- public static final String HOMEPAGE = "homepage";
- public static final String NAME = "movie_name";
- public static final String RATING = "rating";
- public static final String TAGLINE = "tagline";
- public static final String THUMB_URL = "thumb_url";
- public static final String IMAGE_URL = "image_url";
- public static final String TRAILER = "trailer";
- public static final String URL = "url";
- public static final String YEAR = "year";
- }
-
- public static void onCreate(SQLiteDatabase db) {
- StringBuilder sb=new StringBuilder();
- // movie table
- sb.append("CREATE TABLE"+MovieTable.TABLE_NAME+"(");
- sb.append(BaseColumns._ID+"INTEGER PRIMARY KEY,");
- sb.append(MovieColumns.HOMEPAGE + " TEXT, ");
- sb.append(MovieColumns.NAME + " TEXT UNIQUE NOT NULL, ");
- // movie names aren't unique, but for simplification we constrain
- sb.append(MovieColumns.RATING + " INTEGER, ");
- sb.append(MovieColumns.TAGLINE + " TEXT, ");
- sb.append(MovieColumns.THUMB_URL + " TEXT, ");
- sb.append(MovieColumns.IMAGE_URL + " TEXT, ");
- sb.append(MovieColumns.TRAILER + " TEXT, ");
- sb.append(MovieColumns.URL + " TEXT, ");
- sb.append(MovieColumns.YEAR + " INTEGER");
- sb.append(");");
- db.execSQL(sb.toString());
- }
- public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + MovieTable.TABLE_NAME);
- MovieTable.onCreate(db);
- }
- }
CategoryTable table class,
with static methods and inner class CategoryColumns:
- public class CategoryTable {
- public static final String TABLE_NAME = "category";
- public static class CategoryColumns implements BaseColumns {
- public static final String NAME = "name";
- }
-
- public static void onCreate(SQLiteDatabase db) {
- StringBuilder sb = new StringBuilder();
- // category table
- sb.append("CREATE TABLE " + CategoryTable.TABLE_NAME + " (");
- sb.append(BaseColumns._ID + " INTEGER PRIMARY KEY, ");
- sb.append(CategoryColumns.NAME + " TEXT UNIQUE NOT NULL");
- sb.append(");");
- db.execSQL(sb.toString());
- }
-
- public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + CategoryTable.TABLE_NAME);
- CategoryTable.onCreate(db);
- }
- }
MovieCategoryTable table class
The MovieCategoryTable class showing the declaration of foreign key references
- public class MovieCategoryTable {
- public static final String TABLE_NAME = "movie_category";
- public static class MovieCategoryColumns {
- public static final String MOVIE_ID = "movie_id";
- public static final String CATEGORY_ID = "category_id";
- }
-
- public static void onCreate(SQLiteDatabase db) {
- StringBuilder sb = new StringBuilder();
-
- // movie_category mapping table
- sb.append("CREATE TABLE " + MovieCategoryTable.TABLE_NAME + " (");
- sb.append(MovieCategoryColumns.MOVIE_ID + " INTEGER NOT NULL, ");
- sb.append(MovieCategoryColumns.CATEGORY_ID + " INTEGER NOT NULL, ");
-
- sb.append("FOREIGN KEY(" + MovieCategoryColumns.MOVIE_ID + ") REFERENCES " + MovieTable.TABLE_NAME + "("
- + BaseColumns._ID + "), ");
- sb.append("FOREIGN KEY(" + MovieCategoryColumns.CATEGORY_ID + ") REFERENCES " + CategoryTable.TABLE_NAME + "("
- + BaseColumns._ID + ") , ");
- sb.append("PRIMARY KEY ( " + MovieCategoryColumns.MOVIE_ID + ", " + MovieCategoryColumns.CATEGORY_ID + ")");
- sb.append(");");
- db.execSQL(sb.toString());
- }
-
- public static void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + MovieCategoryTable.TABLE_NAME);
- MovieCategoryTable.onCreate(db);
- }
- }
last,The SQLiteOpenHelper used for creating and updating databases.
we need to somehow tell Android to build those tables,This is done by extending SQLiteOpenHelper.
- public class OpenHelper extends SQLiteOpenHelper {
-
- private static final int DATABASE_VERSION = 1;
- private Context context;
- public OpenHelper(final Context context){
- super(context, DataConstants.DATABASE_NAME, null, DATABASE_VERSION);
- this.context = context;
- }
- public void onOpen(final SQLiteDatabase db){
- super.onOpen(db);
- if(!db.isReadOnly()){
- // versions of SQLite older than 3.6.19 don't support foreign keys
- // make sure foreign key support is turned on if it's there
- db.execSQL("PRAGMA foreign_keys=ON;");
- // then we check to make sure they're on
- Cursor c=db.rawQuery("PRAGMA foreign_keys", null);
- if(c.moveToFirst()){
- int result=c.getInt(0);
- Log.i(Constants.LOG_TAG, "SQLite foreign key support (1 is on, 0 is off): " + result);
- }else{
- Log.i(Constants.LOG_TAG, "SQLite foreign key support NOT AVAILABLE");
- }
- if(!c.isClosed()){
- c.close();
- }
- }
- }
-
- @Override
- public void onCreate(final SQLiteDatabase db) {
- // TODO Auto-generated method stub
- Log.i(Constants.LOG_TAG, "DataHelper.OpenHelper onCreate creating database " + DataConstants.DATABASE_NAME);
-
- CategoryTable.onCreate(db);
- // populate initial categories (one way, there are several, this works ok for small data set)
- CategoryDao categoryDao = new CategoryDao(db);
- String[] categories = context.getResources().getStringArray(R.array.tmdb_categories);
- for (String cat : categories) {
- categoryDao.save(new Category(0, cat));
- }
- MovieTable.onCreate(db);
- MovieCategoryTable.onCreate(db);
- }
-
- @Override
- public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
- // TODO Auto-generated method stub
- Log.i(Constants.LOG_TAG, "SQLiteOpenHelper onUpgrade - oldVersion:" + oldVersion + " newVersion:"
- + newVersion);
-
- MovieCategoryTable.onUpgrade(db, oldVersion, newVersion);
- MovieTable.onUpgrade(db, oldVersion, newVersion);
- CategoryTable.onUpgrade(db, oldVersion, newVersion);
- }
-
- }
Each table object has a static method for onCreate and onUpgrade that’s called from OpenHelper’s methods.
To supply initial data of Category,we do this:
create arrays.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
-
- <string-array name="tmdb_categories">
- <item>Action</item>
- <item>Adventure</item>
- <item>Animation</item>
- <item>Comedy</item>
- <item>Crime</item>
- <item>Disaster</item>
- <item>Documentary</item>
- <item>Drama</item>
- <item>Eastern</item>
- <item>Erotic</item>
- <item>Family</item>
- <item>Fan Film</item>
- <item>Fantasy</item>
- <item>Film Noir</item>
- <item>History</item>
- <item>Holiday</item>
- <item>Horror</item>
- <item>Indie</item>
- <item>Music</item>
- <item>Musical</item>
- <item>Mystery</item>
- <item>Neo Noir</item>
- <item>Road Movie</item>
- <item>Romance</item>
- <item>Science Fiction</item>
- <item>Short</item>
- <item>Sport</item>
- <item>Suspense</item>
- <item>Thriller</item>
- <item>War</item>
- <item>Western</item>
- </string-array>
- </resources>
in the SqliteOpenHelper class onCreate method:
- // populate initial categories (one way, there are several, this works ok for small data set)
- CategoryDao categoryDao = new CategoryDao(db);
- String[] categories = context.getResources().getStringArray(R.array.tmdb_categories);
- for (String cat : categories) {
- categoryDao.save(new Category(0, cat));
- }
For small amounts of data this works fine.
for large volumes of data,you can create your SQLite db file ahead of time (each SQLite database is stored as a single file).At runtime each application database is stored in a file at the /data/data/<packagename>/databases/ internal storage location.
database:
Once we have a SQLiteOpenHelper, we can use it from anywhere in our application to create a SQLiteDatabase object. The SQLiteDatabase object is the keystone of
Android SQLite database operations. This is where we’ll create connections and perform data operations such as select, update, insert, and delete.
here’s an example of using our OpenHelper to obtain a SQLiteDatabase reference:
SQLiteOpenHelper openHelper = new OpenHelper(this.context);
SQLiteDatabase db = openHelper.getWritableDatabase();
The getWritableDatabase method of SQLiteOpenHelper will call onCreate the first time it’s called, and thereafter will call onOpen.
We have model objects for working with the data in our application’s Java code and table objects to keep the details for each table separate from one another. We also
have a SQLiteOpenHelper implementation that can be used to create and update our database, and to provide references to the SQLiteDatabase objects we’ll later use to
store and retrieve data
原blog:
http://blog.csdn.net/kaixinbingju/article/details/8468178