雨松MOMO帶你走進遊戲開發的世界之資料庫SQLite 詳細介紹
雨松MOMO原創文章如轉載,請註明:轉載至我的獨立網域名稱部落格雨松MOMO程式研究院,原文地址:http://www.xuanyusong.com/archives/287
資料庫SQLite介紹
資料庫最經典的四個操作 添加、刪除、修改、尋找,在處理大量資料的時候使用資料庫可以幫我們迅速定位當前須要處理的資料,舉個例子 好比現在要實現一個搜尋功能 用資料庫的話只須要其中一個搜尋條件 一個資料庫語句就可以迅速的在N條資料中找到我們需要的資料,如果不使用資料庫那麼尋找起來會非常麻煩,效率大打折扣,所以在處理大量資料的時候使用資料庫是明確的選擇,在Android的開發中使用的資料庫是SQLite ,它是一個輕量級的資料庫 、非常小 、 移植性好、效率高、可靠 ,嵌入式裝置因為受到硬體條件的限制所以非常適合使用 SQLite 資料庫。
建立與刪除資料庫
封裝一個類去繼承SQLiteOpenHelper 在建構函式中傳入資料庫名稱與資料庫版本號碼,資料庫被建立的時候會調用onCreate(SQLiteDatabase db) 方法,資料庫版本號碼發生改變的時候會調用onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法,可以方便的對軟體遊戲升級後做出相應處理避免覆蓋安裝資料庫發生改變產生的錯誤。調用SQLiteOpenHelper 的getReadableDatabase()方法去建立資料庫,如果資料庫不存在則建立 並且返回SQLiteDatabase對象,如果資料庫存在則不建立只返回SQLiteDatabase對象。調用deleteDatabase(DATABASE_NAME)方法 傳入資料庫名稱則可刪除資料庫。
封裝了一個DatabaseHelper類繼承SQLiteOpenHelper 我使用了設計模式中的單例模式來處理這個類,這裡說一下單例模式 單例模式是常見的代碼設計模式之一 它的好處是在於避免在記憶體中頻繁的執行個體化所以將它的對象寫成static 靜態 這樣它的對象就只有一份存在靜態記憶體區使用的時候只須要通過getInstance()就可以直接拿到這個靜態對象。
public class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper mInstance = null; /** 資料庫名稱 **/ public static final String DATABASE_NAME = "xys.db"; /** 資料庫版本號碼 **/ private static final int DATABASE_VERSION = 1; /**資料庫SQL語句 添加一個表**/ private static final String NAME_TABLE_CREATE = "create table test(" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT,"+"hp INTEGER DEFAULT 100,"+ "mp INTEGER DEFAULT 100," + "number INTEGER);"; DatabaseHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION); } /**單例模式**/ static synchronized DatabaseHelper getInstance(Context context) {if (mInstance == null) { mInstance = new DatabaseHelper(context);}return mInstance; } @Override public void onCreate(SQLiteDatabase db) {/**向資料中添加表**/db.execSQL(NAME_TABLE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {/**可以拿到當前資料庫的版本資訊 與之前資料庫的版本資訊 用來更新資料庫**/ } /** * 刪除資料庫 * @param context * @return */ public boolean deleteDatabase(Context context) {return context.deleteDatabase(DATABASE_NAME); }}
在這個類中使用DatabaseHelper對象 實現建立與刪除資料庫、
public class NewSQLite extends Activity { DatabaseHelper mDbHelper = null; SQLiteDatabase mDb = null; Context mContext = null; @Override protected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.create_sql);mContext = this;//建立DatabaseHelper對象 mDbHelper = DatabaseHelper.getInstance(mContext);//調用getReadableDatabase方法如果資料庫不存在 則建立 如果存在則開啟mDb= mDbHelper.getReadableDatabase(); Button button0 = (Button)findViewById(R.id.createDateBase);button0.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {Toast.makeText(NewSQLite.this, "成功建立資料庫", Toast.LENGTH_LONG).show(); }});Button button1 = (Button)findViewById(R.id.deleteDateBase);button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {mDbHelper = DatabaseHelper.getInstance(mContext);// 調用getReadableDatabase方法如果資料庫不存在 則建立 如果存在則開啟mDb = mDbHelper.getReadableDatabase();// 關閉資料庫mDbHelper.close();// 刪除資料庫mDbHelper.deleteDatabase(mContext);Toast.makeText(NewSQLite.this, "成功刪除資料庫", Toast.LENGTH_LONG).show(); }});super.onCreate(savedInstanceState); }}
建立的資料庫會被儲存在當前項目中 databases 路徑下 具體
添加與刪除資料庫中的表
資料庫是可以由多張資料表組成的 如果添加一張資料庫的表的話 可以使用 資料庫語句 create table 名稱(內容) 來進行添加 。這裡給出一條建立資料庫的語句 。 意思是建立一張表 名稱為gameInfo 表中包含的欄位 為 _id 為INTEGER 類型 並且遞增 name 為Text類型 hp mp 為INTEGER 預設數值為100 number 為INTEGER 類型。
/**建立一張表的SQL語句**/ private static final String NAME_TABLE_CREATE = "create table gameInfo(" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT,"+ "hp INTEGER DEFAULT 100,"+ "mp INTEGER DEFAULT 100," + "number INTEGER);";
資料庫中刪除一張表 直接使用DROP TABLE 表名稱 就可以刪除
/**刪除一張表的SQL語句**/ private static final String NAME_TABLE_DELETE = "DROP TABLE gameInfo";
在代碼中去執行一條SQL語句 使用SQLiteDatabase對象去調用execSQL() 傳入SQL語句就OK了。
mDb.execSQL(NAME_TABLE_CREATE);
以建立一張名稱為gameInfo的表為例 給出代碼實現
public class NewTable extends Activity { DatabaseHelper mDbHelper = null; SQLiteDatabase mDb = null; Context mContext = null; /**建立一張表的SQL語句**/ private static final String NAME_TABLE_CREATE = "create table gameInfo(" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT,"+ "hp INTEGER DEFAULT 100,"+ "mp INTEGER DEFAULT 100," + "number INTEGER);"; /**刪除一張表的SQL語句**/ private static final String NAME_TABLE_DELETE = "DROP TABLE gameInfo"; @Override protected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.create_table);mContext = this;mDbHelper = DatabaseHelper.getInstance(mContext);mDb= mDbHelper.getReadableDatabase(); Button button0 = (Button)findViewById(R.id.createTable);button0.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {try { mDb.execSQL(NAME_TABLE_CREATE); Toast.makeText(NewTable.this, "成功添加資料表", Toast.LENGTH_LONG).show(); }catch(SQLiteException e) { Toast.makeText(NewTable.this, "資料庫中已存此表", Toast.LENGTH_LONG).show(); } }});Button button1 = (Button)findViewById(R.id.deleteTable);button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {try { mDb.execSQL(NAME_TABLE_DELETE); Toast.makeText(NewTable.this, "成功刪除資料表", Toast.LENGTH_LONG).show(); }catch(SQLiteException e) { Toast.makeText(NewTable.this, "資料庫中已無此表", Toast.LENGTH_LONG).show(); } }});super.onCreate(savedInstanceState); }}
增加 刪除 修改 查詢 資料庫中的資料
使用SQLiteDatabase對象調用 insert()方法 傳入標的名稱與ContentValues 添加的內容 則可以向資料庫表中寫入一條資料 delete ()為刪除一條資料 update()為更新一條資料。
我詳細說一下尋找一條資料使用的方法 query 中 跟了8個參數
public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
參數說明:
table:資料庫表的名稱
columns:資料庫列名稱數組 寫入後最後返回的Cursor中只能查到這裡的列的內容
selection:查詢條件
selectionArgs:查詢結果
groupBy:分組列
having:分組條件
orderBy:排序列
limit:分頁查詢限制
Cursor:傳回值,將查詢到的結果都存在Cursor
Cursor是一個遊標介面,每次查詢的結果都會儲存在Cursor中 可以通過遍曆Cursor的方法拿到當前查詢到的所有資訊。
Cursor的方法
moveToFirst() //將Curor的遊標移動到第一條
moveToLast()///將Curor的遊標移動到最後一條
move(int offset)//將Curor的遊標移動到指定ID
moveToNext()//將Curor的遊標移動到下一條
moveToPrevious()//將Curor的遊標移動到上一條
getCount() //得到Cursor 總記錄條數
isFirst() //判斷當前遊標是否為第一條記錄
isLast()//判斷當前遊標是否為最後一條資料
getInt(int columnIndex) //根據列名稱獲得列索引ID
getString(int columnIndex)//根據索引ID 拿到表中存的欄位
這裡給出一個例子遍曆Cursor的例子
private void query(SQLiteDatabase db) {// 把整張表的所有資料query到cursor中Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null);//判斷cursor不為空白 這個很重要if (cursor != null) { // 迴圈遍曆cursor while (cursor.moveToNext()) {// 拿到每一行name 與hp的數值String name = cursor.getString(cursor.getColumnIndex("name"));String hp = cursor.getString(cursor.getColumnIndex("hp"));Log.v("info", "姓名是 " + name + "hp為 " + hp); } // 關閉 cursor.close();} }
向大家推薦一個查看資料庫的軟體非常好用, 名稱是SQLiteSpy.exe 開啟xys.db 檔案 可以清晰的看見資料庫表中儲存的內容並且該軟體支援執行SQL語句 可以直接在軟體中操作,我給出這款軟體的。
:http://download.csdn.net/source/3481140
public class Newdate extends Activity { DatabaseHelper mDbHelper = null; SQLiteDatabase mDb = null; Context mContext = null; /** 資料庫欄位 **/ public final static String TABLE_NAME = "test"; public final static String ID = "_id"; public final static String NAME = "name"; public final static String HP = "hp"; public final static String MP = "mp"; @Override protected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.create_date);mContext = this;// 建立DatabaseHelper對象mDbHelper = DatabaseHelper.getInstance(mContext);// 調用getReadableDatabase方法如果資料庫不存在 則建立 如果存在則開啟mDb = mDbHelper.getReadableDatabase();// 初始化 給資料庫表寫入一些資訊for (int i = 0; i < 10; i++) { insert(NAME, "雨松MOMO" + i);}// 增加Button button0 = (Button) findViewById(R.id.add);button0.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {insert(NAME, "新添加小可愛");Toast.makeText(Newdate.this, "添加一條資料名稱為小可愛", Toast.LENGTH_LONG).show(); }});// 刪除Button button1 = (Button) findViewById(R.id.delete);button1.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {delete(ID, "1");Toast.makeText(Newdate.this, "刪除一條_id=1的資料", Toast.LENGTH_LONG).show(); }});// 修改Button button2 = (Button) findViewById(R.id.modify);button2.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {update(NAME, "雨松MOMO3", "小可愛3");Toast.makeText(Newdate.this, "更新名稱雨松MOMO3 為小可愛3",Toast.LENGTH_LONG).show(); }});// 尋找Button button3 = (Button) findViewById(R.id.find);button3.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) {Cursor cursor = find(ID, "5");String name = cursor.getString(cursor.getColumnIndex(NAME));Toast.makeText(Newdate.this, "尋找ID為5資料的名稱是 " + name,Toast.LENGTH_LONG).show(); }});super.onCreate(savedInstanceState); } /** * 插入一條資料 * * @param key * @param date */ public void insert(String key, String date) {ContentValues values = new ContentValues();values.put(key, date);mDb.insert(TABLE_NAME, null, values); } /** * 刪除一掉資料 * * @param key * @param date */ public void delete(String key, String date) {mDb.delete(TABLE_NAME, key + "=?", new String[] { date }); } /** * 更新一條資料 * * @param key * @param oldDate * @param newDate */ public void update(String key, String oldDate, String newDate) {ContentValues values = new ContentValues();values.put(key, newDate);mDb.update(TABLE_NAME, values, key + "=?", new String[] { oldDate }); } /** * 尋找一條資料 * * @param key * @param date * @return */ public Cursor find(String key, String date) {Cursor cursor = mDb.query(TABLE_NAME, null, key + "=?",new String[] { date }, null, null, null);if (cursor != null) { cursor.moveToFirst();}return cursor; }}
這裡我在強調一下query中的第二個參數String [] columns , 舉個例子 當前在資料中query 數值 如果我只想要資料中符合條件資料每一行的name欄位和hp 欄位 那麼第二個參數就不要寫成null了。
第二個參數我寫成了new String[] {"name","hp"} 這樣的話得到的Cursor 中的資料只會存有 資料庫表中"name " 與 "hp"兩個欄位 因為其它欄位我們根本不需要所以著麼寫可以大大提高代碼的效率。如果寫成null的話 Cursor 中的資料就會把資料庫表中所以的欄位都儲存進去這樣在計算Cursor 的時候代碼就會消耗更多沒用的時間。
cursor.getString(0); 的意思就是拿到對應new String[] {"name","hp"} 數組中的一個欄位的內容 意思就是拿到 資料庫欄位"name"的值, cursor.getString(1);的意思就是拿到資料庫欄位"hp"的值 。cursor.getString()中的ID 是完全對應第二個參數String [] columns數組角標。
public void find() {Cursor cursor = mDb.query(TABLE_NAME, new String[] {"name","hp"}, null,null, null, null, null);while(cursor.moveToNext()) { String name = cursor.getString(0); String hp = cursor.getString(1); Log.v("info", "name is "+name); Log.v("info", "hp is "+hp);} }
最後如果你還是覺得我寫的不夠詳細 看的不夠爽 不要緊我把原始碼的貼出來 歡迎大家一起討論學習雨松MOMO希望可以和大家一起進步。
:http://www.xuanyusong.com/archives/287