public class MyDatabaseHelper extends SQLiteOpenHelper { //把數據庫建表指令弄成一個字符串CREATE_BOOK常量 public static final String CREATE_BOOK = "create table book (" + "id integer primary key autoincrement, " + "author text, " + "price real, " + "pages integer, " + "name text)"; public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context,name,factory,version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK);//執行建表 Log.d(TAG,"數據庫初始化完成"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
private MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1); //新建一個MyDatabaseHelper對象,上下文;數據庫名;第三個參數容許咱們在查詢數據的時候返回一個自定義的 Cursor,通常都是傳入 null;數據庫版本號 dbHelper.getWritableDatabase();
因爲數據庫BookStore.db已經存在,onCreate()方法不會再次執行,直接在onCreate()方法中,添加table不能被更新。數據庫
添加表格常量;在onCreate()方法中建表;在upGreate()方法中刪去存在表格,並從新執行onCreate()方法;在引用數據庫時更改數據庫版本號ide
public class MyDatabaseHelper extends SQLiteOpenHelper { //把數據庫建表指令弄成一個字符串CREATE_BOOK常量 public static final String CREATE_BOOK = "create table book (" + "id integer primary key autoincrement, " + "author text, " + "price real, " + "pages integer, " + "name text)"; //integer 表示整型,real 表示浮點型,text 表示文本類型,blob 表示二進制類型。另外,上述建表語句中咱們還 //使用了 primary key 將 id 列設爲主鍵,並用 autoincrement 關鍵字表示 id 列是自增加的 public static final String CREATE_CATEGORY = "create table category(" + "id integer primary key autoincrement, " + "category_name text, " + "category_code integer)"; public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context,name,factory,version); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK);//執行建表 db.execSQL(CREATE_CATEGORY); Log.d(TAG,"數據庫初始化完成"); } //當檢測到數據庫版本變化,就會執行onUpgrade()中的代碼 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //調用SQL語句,若存在表格則刪去,以後在從新調用onCreate()方法 db.execSQL("drop table if exists Book"); db.execSQL("drop table if exists Category"); onCreate(db); } }
因爲覆蓋式更新數據庫的方法會重置數據庫,致使用戶數據丟失,不能在產品中使用函數
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //調用SQL語句,若存在表格則刪去,以後在從新調用onCreate()方法 /** * 註釋時間:20170117 * 代碼做用:覆蓋式更新數據庫,刪除以前的數據庫再新建庫 * 註釋緣由:學習新的數據庫更新方法 db.execSQL("drop table if exists Book"); db.execSQL("drop table if exists Category"); onCreate(db); */ switch (newVersion) { case 2:db.execSQL(CREATE_CATEGORY); //!!!注意,無break; case 3:db.execSQL("alter table Book add column category_id integer"); //!!!注意,無break; //由於不管覆蓋哪個版本安裝,都須要安裝其餘更新,從第二版安裝第三版時,只須要更新case3,確保數據庫最新 Log.d(TAG,"第3版數據庫更新成功"); break; default: Log.d(TAG,"數據庫更新失敗"); break; } }
對數據進行的操做也就無非四種,即CRUD。其中 C 表明添加(Create) ,R 表明查詢(Retrieve) ,U 表明更新(Update) ,D 表明刪除(Delete)學習
SQLiteDatabase db = dbBookStoreHelper.getWritableDatabase(); //新建兩個數據 db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" }); db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "The Lost Symbol", "Dan Brown", "510", "19.95" }); //查詢全部數據 db.rawQuery("select * from Book", null); //把《The Da Vinci Code》這本書改爲10.99 db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99","The Da Vinci Code" }); //把500頁以上的書刪了 db.execSQL("delete from Book where pages > ?", new String[] { "500" });
insert()方法,1.表名;2.未指定添加數據的狀況下給某些可爲空的列自動賦值 NULL;3.ContentValues 對象,它提供了一系列的 put()方法重載,用於向 ContentValues 中添加數據,只須要將表中的每一個列名以及相應的待添加數據傳入便可
this
//!!!先組裝數據,再插入數據 SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); // 開始組裝第一條數據 values.put("name", "The Da Vinci Code"); values.put("author", "Dan Brown"); values.put("pages", 454); values.put("price", 16.96); db.insert("Book", null, values); // 插入第一條數據 values.clear(); // 開始組裝第二條數據 values.put("name", "The Lost Symbol"); values.put("author", "Dan Brown"); values.put("pages", 510); values.put("price", 19.95); db.insert("Book", null, values); // 插入第二條數據
update()方法,1.表名;2.ContentValues 對象,要把更新數據在這裏組裝進去;第3、第四個參數用於去約束更新某一行或某幾行中的數據,不指定的話默認就是更新全部行spa
SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("price", 10.99); db.update("Book", values, "name = ?", new String[] { "The DaVinci Code" }); values.clean();
delete()方法,1.表名;第2、第三個參數用於去約束刪除某一行或某幾行的數據,不指定的話默認就是刪除全部行code
db.delete("Book","pages > ?",new String[] {"300"});
query()方法,1.表名;2.指定去查詢哪幾列,若是不指定則默認查詢全部列;3.第3、第四個參數用於去約束查詢某一行或某幾行的數據,不指定則默認是查詢全部行的數據;5.指定須要去 group by 的列,不指定則表示不對查詢結果進行 group by 操做;6. group by 以後的數據進行進一步的過濾,不指定則表示不進行過濾;7,指定查詢結果的排序方式,不指定則表示使用默認的排序方式。對象
query()方法參數 | 對應 SQL 部分 | 描述 |
table | from table_name | 指定查詢的表名 |
columns | select column1, column2 | 指定查詢的列名 |
selection | where column = value | 指定 where 的約束條件 |
selectionArgs | - | 爲 where 中的佔位符提供具體的值 |
groupBy | group by column | 指定須要 group by 的列 |
having | having column = value | 對 group by 後的結果進一步約束 |
orderBy | order by column1, column2 | 指定查詢結果的排序方式 |
Cursor cursor = db.query("Book",null,"1",null,null,null,null); if (cursor != null) { if(cursor.moveToFirst()) { do {//直到型循環 String name = cursor.getString(cursor.getColumnIndex("name")); String author = cursor.getString(cursor.getColumnIndex("author")); Double price = cursor.getDouble(cursor.getColumnIndex("price")); int pages = cursor.getInt(cursor.getColumnIndex("pages")); Log.d(TAG,"name = " + name); Log.d(TAG,"author = " + author); Log.d(TAG,"price = " + price); Log.d(TAG,"pages = " + pages); }while (cursor.moveToNext()); } } cursor.close();
事情要善始善終,就像轉帳,錢沒到達對方帳戶就會退回原始帳戶blog
db.beginTransaction();//開始事務 try { db.delete("Book", null, null); if (true) { // 在這裏手動拋出一個異常,讓事務失敗 throw new NullPointerException(); } db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)", new String[]{"馬克思主義2", "中國**黨", "1000", "100.00"});//竟然和諧 db.setTransactionSuccessful(); // 事務已經執行成功 } catch (Exception e) { e.printStackTrace(); } finally { db.endTransaction(); // 結束事務 }