android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project)

android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project)_第1张图片

In essence, cursors iterate over result sets and provide access to data one row at a time.

android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project)_第2张图片

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:

android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project)_第3张图片

design table relations:

android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project)_第4张图片

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:

android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project)_第5张图片

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>
    <!-- Used in View/Spinner1.java -->
    <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.

你可能感兴趣的:(android in practice_create model、table class and sqlitehelper(MyMoviesDataBases project))