Android學習---SQLite數據庫的增刪改查和事務(transaction)調用

上一篇文章中介紹了手工拼寫sql語句進行數據庫的CRUD操做,本文將介紹調用sqlite內置的方法實現CRUD操做,其實質也是經過拼寫sql語句.java

首先,建立一個新的android項目:

其次,查看代碼實現增刪查改:

1.建立DB工具類

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) {
    }
}

2.配置測試環境

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> 

 

3.PersonDao.java(實現增刪查改的方法)

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();
    }

}

1)測試add方法:

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

2)刪除數據

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

3)更新數據

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

4)查找數據

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());
            }

        }

輸出結果:

 

  

4.擴展--SQLite中的事務

這裏以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

相關文章
相關標籤/搜索