上一篇文章中介紹了手工拼寫sql語句進行數據庫的CRUD操做,本文將介紹調用sqlite內置的方法實現CRUD操做,其實質也是經過拼寫sql語句.java
MyDBHelper.java(建立數據庫的操做)android
package com.amos.android_db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by amosli on 14-6-12. */ public class MyDBHelper extends SQLiteOpenHelper{ /** * * @param context */ public MyDBHelper(Context context) { super(context, "sqlitedb", null, 1); } /** * 數據庫第一次建立的時候調用此方法 * @param db */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table if not exists person (personid integer primary key autoincrement ,name varchar(30) ,age integer(3) )"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
AndroidManifest.xmlgit
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.amos.android_db" android:versionCode="1" android:versionName="1.0"> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.amos.android_db"/> <uses-sdk android:minSdkVersion="7"/> <application android:label="@string/app_name"> <uses-library android:name="android.test.runner"/> <activity android:name="MyActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
package com.amos.android_db.dao; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import com.amos.android_db.MyDBHelper; import java.util.ArrayList; import java.util.List; /** * Created by amosli on 14-6-12. */ public class PersonDao { private Context context; MyDBHelper dbHelper; public PersonDao(Context context) { this.context = context; dbHelper = new MyDBHelper(context); } /** * 添加一條記錄 */ public void add(String name, int age) { SQLiteDatabase db = dbHelper.getWritableDatabase(); if (db.isOpen()) { ContentValues values = new ContentValues(); values.put("age", age); values.put("name", name); //不容許插入一個空值,若是contentvalue,通常第二個參 db.insert("person", null, values);//經過組拼完成的添加的操做 } db.close(); } }
package com.amos.android_db.test; import android.test.AndroidTestCase; import com.amos.android_db.dao.PersonDao; /** * Created by amosli on 14-6-13. */ public class TestPersonDao extends AndroidTestCase{ public void testAdd() throws Exception{ PersonDao personDao = new PersonDao(this.getContext()); personDao.add("amosli",10); personDao.add("amosli",10); for(int i=0;i<10;i++){ personDao.add("amos"+i,10+i); } } }
查看結果:github
打開新建立的數據庫sqlitedbsql
./adb shell #cd /data/data/com.amos.android_db/databases # ls sqlitedb # sqlite3 sqlitedb SQLite version 3.6.22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .database seq name file --- --------------- ---------------------------------------------------------- 0 main /data/data/com.amos.android_db/databases/sqlitedb sqlite> .table android_metadata person
查看寫入的值:shell
sqlite> select * from person; 1|amosli|10 2|amosli|10 3|amos0|10 4|amos1|11 5|amos2|12 6|amos3|13 7|amos4|14 8|amos5|15 9|amos6|16 10|amos7|17 11|amos8|18 12|amos9|19
delete方法,主要是調用了SQLiteDatabase的delete方法.其實質上也是在拼sql語句.數據庫
public void delete(String name) { SQLiteDatabase db = dbHelper.getWritableDatabase(); if (db.isOpen()) { db.delete("person", "name=?", new String[]{name}); db.close(); } }
測試delete方法:app
public void testDelete() throws Exception{ PersonDao personDao = new PersonDao(this.getContext()); personDao.delete("amosli"); }
查看結果:ide
sqlite> select * from person; 3|amos0|10 4|amos1|11 5|amos2|12 6|amos3|13 7|amos4|14 8|amos5|15 9|amos6|16 10|amos7|17 11|amos8|18 12|amos9|19
public void update(String name, String newname, int newage) { SQLiteDatabase db = dbHelper.getWritableDatabase(); if (db.isOpen()) { ContentValues contentValues = new ContentValues(); contentValues.put("name", newname); contentValues.put("age", newage); db.update("person", contentValues, "name=?", new String[]{name}); db.close(); } }
測試方法:工具
public void testUpdate() throws Exception{ PersonDao personDao = new PersonDao(this.getContext()); personDao.update("amos0","0amos",35); }
查看結果:
sqlite> select * from person; 3|0amos|35 4|amos1|11 5|amos2|12 6|amos3|13 7|amos4|14 8|amos5|15 9|amos6|16 10|amos7|17 11|amos8|18 12|amos9|19
public boolean find(String name) { boolean status_result = false; SQLiteDatabase db = dbHelper.getReadableDatabase(); // public android.database.Cursor query( // String table, // String[] columns, // String selection, // String[] selectionArgs, // String groupBy, // String having, // String orderBy) if (db.isOpen()) { Cursor cursor = db.query("person", null, "name=?", new String[]{name}, null, null, null); if (cursor.moveToFirst()) { status_result = true; } cursor.close(); db.close(); } return status_result; }
測試方法:
public void testFind() throws Exception{ PersonDao personDao = new PersonDao(this.getContext()); assertEquals(true,personDao.find("amos1")); }
5)查找全部數據
public List<Person> findAll(){ List<Person> persons = null; SQLiteDatabase db = dbHelper.getReadableDatabase(); if(db.isOpen()){ persons = new ArrayList<Person>(); Cursor cursor = db.query("person", null, null, null, null, null, null); while(cursor.moveToNext()){ Person person = new Person(); person.setName(cursor.getString(cursor.getColumnIndex("name"))); person.setAge(cursor.getInt(cursor.getColumnIndex("age"))); persons.add(person); } cursor.close(); db.close(); } return persons; }
測試方法:
public void testFindAll() throws Exception{ PersonDao personDao = new PersonDao(getContext()); List<Person> personList = personDao.findAll(); for(Person person:personList){ Log.d("person:",person.toString()); } }
輸出結果:
這裏以amos1向amos2轉錢200元爲例:
1),amos1帳戶初始1000元,amos2帳戶初始0元.
2),從amos1中減去200元,amos2中加上200元,這兩個步驟要麼同時成功,要麼同時失敗,不能一方成功,另外一主失敗,這就是事務.
代碼實現:
package com.amos.android_db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by amosli on 14-6-12. */ public class MyDBHelper extends SQLiteOpenHelper{ public MyDBHelper(Context context) { super(context, "sqlitedb", null, 2); } /** * 數據庫第一次建立的時候調用此方法 * @param db */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table if not exists person (personid integer primary key autoincrement ,name varchar(30) ,age integer(3) )"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("alter table person add account integer null"); } }
在初始化時更新表的結構,添加account一列,用來表示帳戶餘額.
在PersonDao中添加以下方法:
public void transferMoney() { SQLiteDatabase db = dbHelper.getWritableDatabase(); if(db.isOpen()){ try{ db.beginTransaction(); //給amos1帳戶裏設置1000元,amost account=0; db.execSQL("update person set account=? where name = ?",new Object[]{1000,"amos1"}); db.execSQL("update person set account=? where name = ?",new Object[]{0,"amos2"}); //從amos1帳戶里扣除200元 db.execSQL("update person set account=account-? where name = ?",new Object[]{200,"amos1"}); //把amos1的錢轉給amos2 db.execSQL("update person set account=account+? where name=?",new Object[]{200,"amos2"}); }catch(Exception e){ e.printStackTrace(); }finally{ //顯示的設置數據事務是否成功 db.setTransactionSuccessful(); db.endTransaction(); db.close(); } } }
和hibernate裏的事務調用很相似,這裏先beginTransaction,而後要注意的是setTransactionSuccessful和endTransaction.
測試方法:
public void testTransaction() throws Exception{ PersonDao personDao = new PersonDao(getContext()); personDao.transferMoney(); }
測試結果:
sqlite> select * from person; 3|0amos|35| 4|amos1|11|800 5|amos2|12|200 6|amos3|13| 7|amos4|14| 8|amos5|15| 9|amos6|16| 10|amos7|17| 11|amos8|18| 12|amos9|19|
本文源碼:https://github.com/amosli/android_basic/tree/android_db