數據庫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()就可以直接拿到這個靜態對象。
Java代碼
- 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對象 實現創建與刪除數據庫。
Java代碼
- 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 類型。
Java代碼
- /**創建一張表的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 表名稱 就可以刪除
Java代碼
- /**刪除一張表的SQL語句**/
- private static final String NAME_TABLE_DELETE = "DROP TABLE gameInfo";
在代碼中去執行一條SQL語句 使用SQLiteDatabase對象去調用execSQL() 傳入SQL語句就OK了。
Java代碼
- mDb.execSQL(NAME_TABLE_CREATE);
以創建一張名稱為gameInfo的表為例 給出代碼實現
Java代碼
- 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的例子
Java代碼
- 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
Java代碼
- 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數組角標。
Java代碼
- 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);
- }
- }
最後如果你還是覺得我寫的不夠詳細 看的不夠爽 不要緊我把源代碼的下載地址貼出來 歡迎大家一起討論學習。
下載地址:http://vdisk.weibo.com/s/aacjH