一 創建數據庫
1.創建一個 “數據庫管理器” 實體類來繼承 SQLiteOpenHelper抽象類。其中需要重寫兩個方法用於創建數據庫和升級數據庫:onCreate()和onUpgrade()。
2.數據庫管理器的構造方法接收四個參數。第一個是context(環境),第二個是數據庫名,第三個是查詢數據返回的自定義的cursor、一般都是null,第四個是數據庫的版本號。
3.數據庫管理器實例的兩種方法,getReadableDatabase()和getWritableDatabase()。這兩個都可以創建或打開一個數據庫,沒有的時候創建,存在的時候直接打開就行操作。(當數據庫不可以寫入的時候read以只讀方式打開,而write方式會出錯。)
- 它會調用並返回一個可以讀寫數據庫的對象
- 在第一次調用時會調用onCreate的方法
- 當數據庫存在時會調用onOpen方法
- 結束時調用onClose方法
總的來說、將管理器傳入四個參數實例化后就可以通過Read或write兩種方法對數據庫進行操作了。
創建一個BookStore.db數據庫,其中新建Book表
1 create table Book( 2 id integer primary key autoincrement, 3 author text, 4 price real, 5 pages integer, 6 name text)
這是SQL語句,代碼如下:
特別注意,在寫SQL語句轉換為字符串常量的時候,一定要記得寫“,”和“()”。
1 public class MyDatabaseHelper extends SQLiteOpenHelper { 2 3 /*建表語句定義成了一個字符串常量*/ 4 public static final String CREATE_BOOK = 5 "create table Book(" 6 + "id integer primary key autoincrement," 7 + "author text," 8 + "price real," 9 + "pages integer," 10 + "name text)"; 11 12 private Context mContext; 13 14 /*數據庫管理器構造方法*/ 15 public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { 16 super(context, name, factory, version); 17 mContext = context; 18 } 19 20 /*創建數據庫,同時創建表*/ 21 @Override 22 public void onCreate(SQLiteDatabase db) { 23 db.execSQL(CREATE_BOOK); 24 Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_LONG).show(); 25 } 26 27 /*升級數據庫*/ 28 @Override 29 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 30 } 31 }
在布局中寫一個創建按鈕,然后MainActivity中的代碼如下:
1 public class MainActivity extends AppCompatActivity { 2 3 private MyDatabaseHelper dbHelper; 4 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 10 dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1); 11 Button createDatabase = (Button) findViewById(R.id.create_database); 12 createDatabase.setOnClickListener(new View.OnClickListener() { 13 @Override 14 public void onClick(View view) { 15 dbHelper.getWritableDatabase(); 16 } 17 }); 18 } 19 }
如上,先實例化數據庫管理器,在構造函數中傳入相關參數,然后在點擊事件中調用實例的 getWritableDatabase()方法。
注,因為需要用android6,0版本才能有root權限,所以用的是android6,0的虛擬機,而如果出現“waiting for target device to come online”的提示並一直打不開虛擬器,則是sdk的版本與虛擬器不適配,通過sdk manager打開。
然后選擇對應虛擬器的 API level。如下: 然后再啟動就成功了。
可以打開命令行來查看數據庫創建情況,
- 步驟 1 adb shell。
- 步驟 2 通過cd 進入到 /data/data/com,example.databasetest/databases/目錄下
- 步驟 3 通過sqlite3 加上數據庫名加入數據庫
- 步驟 4 輸入 .table 查看數據庫中所有的表。
二 升級數據庫
如我們想在數據庫中添加一張新的表 SQL語句如下:
1 create table Category( 2 id integer primary key autoincremet, 3 category_name text, 4 category_code integer)
同樣將這句話加入到數據庫管理器中,作為一個字符串常量,然后在onCreate()中創建這個表。
但是!因為數據庫已經存在了,所以不會再調用onCreate()方法,就無法得到創建,所以需要在更新數據庫的onUpgrade()方法中先將兩張表刪除,再調用onCreate()方法。注意要調用到更新方法時需要在構造函數中將傳入的版本號升級。
數據庫管理器代碼如下:
1 public class MyDatabaseHelper extends SQLiteOpenHelper { 2 3 /*建表語句定義成了一個字符串常量*/ 4 public static final String CREATE_BOOK = 5 "create table Book(" 6 + "id integer primary key autoincrement," 7 + "author text," 8 + "price real," 9 + "pages integer," 10 + "name text)"; 11 12 public static final String CREATE_CATEGORY = 13 "create table Category(" 14 + "id integer primary key autoincrement," 15 + "category_name text," 16 + "category_code integer)"; 17 18 private Context mContext; 19 20 /*數據庫管理器構造方法*/ 21 public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { 22 super(context, name, factory, version); 23 mContext = context; 24 } 25 26 27 /*創建數據庫,同時創建表*/ 28 @Override 29 public void onCreate(SQLiteDatabase db) { 30 db.execSQL(CREATE_BOOK); 31 db.execSQL(CREATE_CATEGORY); 32 Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_LONG).show(); 33 } 34 35 /*升級數據庫*/ 36 @Override 37 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 38 db.execSQL("drop table if exists Book"); 39 db.execSQL("drop table if exists Category"); 40 onCreate(db); 41 } 42 }
查看命令行:證明創建成功。
三 添加數據( insert()方法 )
因為之前說的 getReadableDatabase()方法和 getwritableDatabase()方法會返回一個SQLiteDatabase對象。所以對這個對象用insert()方法即可添加數據。
insert()方法接收三個參數:
- “表名”
- “默認空值”
- “傳入組裝好的數據values”
而其中用到的contentvalues數據類型則是用來組裝傳入內容的。相當於一個map組,用put來壓入數據。用完后要記得clear();代碼如下:
1 /*插入數據,insert方法傳入三個參數,“表名”“默認空值”“傳入組裝好的數據values”*/ 2 Button addData = (Button) findViewById(R.id.add_data); 3 addData.setOnClickListener(new View.OnClickListener() { 4 @Override 5 public void onClick(View view) { 6 SQLiteDatabase db = dbHelper.getWritableDatabase(); 7 /*用contentValues來組裝要插入的數據 未賦值的自動生成默認值*/ 8 ContentValues values = new ContentValues(); 9 // 開始組裝第一組數據 10 values.put("name", "The da vi code"); 11 values.put("author", "Dan"); 12 values.put("pages", 434); 13 values.put("price", 13.33); 14 db.insert("Book", null, values);//輸入第一行數據 15 values.clear();//清空values。 16 17 // 開始組裝第二條數據 18 values.put("name", "The lost"); 19 values.put("author", "mask"); 20 values.put("pages", 12); 21 values.put("price", 999); 22 db.insert("Book", null, values);//輸入第二行數據 23 values.clear();//清空values。 24 } 25 });
四 更新數據 ( update()方法 )
更新方法類似於新增數據的方法,使用的是update()方法,傳入四個參數,分別是:
- “表名”
- “contentvalues值 修改的內容值”
- “SQL語句中的where約束條件”
- “where中的具體限定值”
同樣將要改變的數據壓入contentvalues中,然后傳入。代碼如下:
1 /*更新數據,使用update方法,傳入四個參數, 2 “表名”“修改的內容值”“SQL語句中的where”“where中的具體限定值”*/ 3 Button updateData = (Button) findViewById(R.id.update_data); 4 updateData.setOnClickListener(new View.OnClickListener() { 5 @Override 6 public void onClick(View view) { 7 SQLiteDatabase db = dbHelper.getWritableDatabase(); 8 ContentValues values = new ContentValues(); 9 values.put("price", 1.2); 10 db.update("Book", values, "name=?", new String[]{"The da vi code"}); 11 } 12 });
五 刪除數據 ( delete()方法 )
使用delete()方法,不需要用content數據來傳數據,因為只需要指定相應的數據進行刪除即可。delete()方法傳入三個參數:
- “表名”
- “SQL語句中的where約束條件”
- “where中的具體限定值”
具體的代碼如下:
1 /*刪除數據,使用delete方法,傳入三個參數, 2 * “表名”“SQL語句中的where”“where中的具體限定值”*/ 3 Button deleteButton = (Button) findViewById(R.id.delete_data); 4 deleteButton.setOnClickListener(new View.OnClickListener() { 5 @Override 6 public void onClick(View view) { 7 SQLiteDatabase db = dbHelper.getWritableDatabase(); 8 db.delete("Book", "pages>?", new String[]{"20"}); 9 } 10 });
六 查詢數據( query()方法 )
查詢方法比較復雜,其中要傳入的參數較多,就最短的一個也要傳入七個參數。如下
同時需要用到cursor對象(光標)來輸出查詢結果,將查詢結果賦給cursor對象,得到的cursor對象。
接着調用他的moveToFirst()方法將數據指針移動到第一行開始,然后加入循環,遍歷每一行數據,通過moveToNext()來進行跳轉。
通過cursor的getColumnIndex()方法獲得某一列在表中位置索引,然后將索引傳入相應的取值方法中,得到對應的數據。使用完后需要將cursor通過close關閉。
代碼如下:
1 /*查詢數據,使用query方法,傳入參數較多。*/ 2 Button queryButton = (Button) findViewById(R.id.query_data); 3 queryButton.setOnClickListener(new View.OnClickListener() { 4 @Override 5 public void onClick(View view) { 6 SQLiteDatabase db = dbHelper.getWritableDatabase(); 7 //查詢book中所有數據 8 Cursor cursor = db.query("Book", null, null, null, null, null, null); 9 if (cursor.moveToFirst()) { 10 do { 11 //遍歷cursor對象 取出數據並打印 12 String name = cursor.getString(cursor.getColumnIndex("name")); 13 String author = cursor.getString(cursor.getColumnIndex("author")); 14 int pages = cursor.getInt(cursor.getColumnIndex("pages")); 15 double price = cursor.getDouble(cursor.getColumnIndex("price")); 16 Log.d("MainActivity", "book name is " + name); 17 Log.d("MainActivity", "book author is " + author); 18 Log.d("MainActivity", "book pages is " + pages); 19 Log.d("MainActivity", "book price is " + price); 20 }while (cursor.moveToNext()); 21 } 22 cursor.close(); 23 } 24 });
七 原生方法 (原SQL語句)
1 // 添加數據的方法如下: 2 db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)", new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" }); 3 db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)", new String[] { "The Lost Symbol", "Dan Brown", "510", "19.95" }); 4 5 // 更新數據的方法如下: 6 db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99", "The Da Vinci Code" }); 7 8 // 刪除數據的方法如下: 9 db.execSQL("delete from Book where pages > ?", new String[] { "500" }); 10 11 // 查詢數據的方法如下: 12 db.rawQuery("select * from Book", null);