1. 程式人生 > >檔案儲存之SQLite資料庫儲存

檔案儲存之SQLite資料庫儲存

參考連結

http://blog.csdn.net/liuhe688/article/details/6715983

學習SQLite資料庫之前,先去學習資料庫中的增刪改查語句,以前用工具建立表,表字段,那麼請重新學習SQLite,它是和資料庫操作差不多,不過它輕量級的,很多事情是做不了的。下面事幾個簡單的語句:

create table user(id INTEGER primary key autoincrement,username char(20),userpwd char(20));
select * from user where id = 2;
update user set username = 'ice' where id = 2;
insert into(username,userpwd) values('li','123456');
delete from user where id = 2;

上面事一些基本的語句,需要詳細瞭解的,可以去網路上查詢相關知識。

接下來介紹一些如何操作資料庫呢?

第一點,SQLite嵌入式的,輕量級的資料庫,它已經放在了android手機上,並不是像後臺需要去連結資料庫。SQLite將儲存的資訊放入到指定的路徑下data/<專案資料夾>/databases/。

像要使用SQLite,那麼就需要去繼承SQLiteOpenHelper,它來執行建立,增刪改查相關的操作。繼承SQLiteOpenHelper後,必須要實現兩個方法,和實現一個建構函式。兩個方法分別事onCreate(SQLiteDatabase db) 和 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 。一個事建立表,一個是用來升級資料庫的。

建構函式中,需要去些指出資料庫名和資料庫版本。

public class DBOpenHelper extends SQLiteOpenHelper{

    private static final String DATABASENAME = "test.db"; //資料庫名稱
    private static final int DATABASEVERSION = 2;//資料庫版本,大於0

    //資料庫的建立
    public DBOpenHelper(Context context) {
        super(context, DATABASENAME, null, DATABASEVERSION);
    }

    //建立表
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "create table user(id INTEGER primary key autoincrement,username char(20),userpwd char(20))";
        db.execSQL(sql);

    }

    //資料庫的升級
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "DROP TABLE IF EXISTS user";
        db.execSQL(sql);

        onCreate(db);
    }
}
OnCreate()方法只調用一次,onUpgrade(),當資料庫版本改變的時候,就會呼叫。我在程式碼中在呼叫時,重新去刪除到表後重新執行onCreate(db)。可以像到,為了獲取db(db是用來操作資料庫的),需要去建立一次,這樣就不用每次建立的時候都去呼叫建構函式。下面事會實現的。

接下來就是如何操作資料庫,操作資料庫有兩種方式,一種是執行sql語句,還有一個事db來執行,只需要去呼叫物件的方法,並將引數傳過去。

這裡將一個類建立起來,並獲取到DBOpenHelper。

public class DataHelper {
    private DBOpenHelper mDBOpenHelper;


    private DataHelper(Context context){
        if (mDBOpenHelper == null){
            mDBOpenHelper = new DBOpenHelper(context);
        }
    }
    private static DataHelper mDataHelper;


    public static DataHelper getDataHelper(Context context){
        if (mDataHelper == null){
            mDataHelper = new DataHelper(context);
        }
        return mDataHelper;
    }
}

1.插入

首先事插入。表建立了,如何去建立資料。

execSQL(str);

insert(table,null,values);

第一個是執行sql語句,例如:insert into user(username,userpwd) values(' + "ice“+"','" + "123456"+"')";放入到execSQL引數中。可以執行在函式中些上要執行的語句,其中ice和12345用形參來代替,如insert into user(username,userpwd) values(' + username+"','" + password+"')"來代替。

insert()方法中第一個引數事表名,第二個引數一般設定為null,第三個引數事要插入的值,這個值事ContentValues。

下面來看程式碼,放入在DataHelper中的程式碼:

 /**
     * 執行sql語句
     * @param sql
     */
    public void insert(String sql){
        bdOpenHelper.getWritableDatabase().execSQL(sql);
    }

    /**
     * 插入資料
     * @param username      插入的使用者名稱
     * @param password      插入的密碼
     */
    public void insert1(String username,String password){
        String str = "insert into user(username,userpwd) values('" + username + "','" + password + "')";
        bdOpenHelper.getWritableDatabase().execSQL(str);
    }

    /**
     * 插入資料
     * @param values
     */
    public void insert2(ContentValues values){
        bdOpenHelper.getWritableDatabase().insert("user",null,values);
    }

接下來看它的實現
private DataHelper dataHelper;
dataHelper = DataHelper.getDataHelper(SQLTestActivity.this);

 /**
     * 儲存資料
     */
    public void save(){
        String sql = "insert into user(username,userpwd) values('ice','123456')";
        try {
            dataHelper.insert(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void save1(){
        try {
            dataHelper.insert1("ice","123456");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void save2(){
        ContentValues values = new ContentValues();
        values.put("username","ice");            //key值需要和建立表的欄位名是一樣的
        values.put("userpwd","123456");
        dataHelper.insert2(values);
    }

2.查詢

查詢相對與其它會複雜一些,先來介紹有哪幾種方法
1 db.rawQuery(Stringsql, String[] selectionArgs); 

2 db.query(Stringtable, String[] columns, String selection, String[] selectionArgs, StringgroupBy, String having, String orderBy); 

3 db.query(Stringtable, String[] columns, String selection, String[] selectionArgs, StringgroupBy, String having, String orderBy, String limit); 

4 db.query(Stringdistinct, String table, String[] columns, String selection, String[] selectionArgs,String groupBy, String having, String orderBy, String limit); 
還是有兩種方式,一個rawQuery(),兩個引數分別事sql語句,和查詢的條件。

query()查詢,傳入的引數表明,獲取的欄位,查詢的條件,查詢條件的值。後面的引數用於分組,排序,分頁(這裡暫不考慮)。

/**
     * 查詢
     * @param sql
     */
    public Cursor query(String sql,String[] selectionArgs){
        return bdOpenHelper.getWritableDatabase().rawQuery(sql, selectionArgs);
    }

    public Cursor query1(String table, String[] columns,String selection,String[] selectionArgs){
        return bdOpenHelper.getWritableDatabase().query(table,columns,selection,selectionArgs,null,null,null);
    }

實現:
public void query(){
        String sql = "select * from user where id = ?";     //?是佔位符
        Cursor cursor = dataHelper.query(sql, new String[]{"1"});
        if (cursor.moveToFirst()){          //判斷是游標移動到第一個位置時是否有值
            String username = cursor.getString(1);
            String password = cursor.getString(2);          //這裡沒有從0開始,因為0是id的值
        }
        cursor.close();                         //使用完後需要關閉
    }

    public void query1(){
        Cursor cursor = dataHelper.query1("user", new String[]{"username", "userpwd"}, "id = ?", new String[]{"1"});
        while (cursor.moveToNext()){         //判斷是游標移動到第一個位置時是否有值
            String username = cursor.getString(cursor.getColumnIndex("username"));
            String password = cursor.getString(cursor.getColumnIndex("userpwd"));          //這裡沒有從0開始,因為0是id的值
        }

        cursor.close();
    }
下面事Cursor的一些函式操作,有解釋就不多說了。
1.c.move(int offset); //以當前位置為參考,移動到指定行 
 2 c.moveToFirst();    //移動到第一行 
 3 c.moveToLast();     //移動到最後一行 
 4 c.moveToPosition(int position); //移動到指定行 

 5 c.moveToPrevious(); //移動到前一行 
 6 c.moveToNext();     //移動到下一行 
 7 c.isFirst();        //是否指向第一條 
 8 c.isLast();     //是否指向最後一條 
 9 c.isBeforeFirst();  //是否指向第一條之前 
10c.isAfterLast();    //是否指向最後一條之後 
11 c.isNull(int columnIndex);  //指定列是否為空(列基數為0) 
12 c.isClosed();       //遊標是否已關閉 

13 c.getCount();       //總資料項數 
14c.getPosition();    //返回當前遊標所指向的行數 
15c.getColumnIndex(String columnName);//返回某列名對應的列索引值 
16 c.getString(int columnIndex);   //返回當前行指定列的值

3.修改

插入也事有兩個方法: execSQL(sql); insert(String table,ContentValues values,String where,String[] where); 和上面的很相識,這裡不詳細介紹
 /**
     * 修改
     * @param sql
     */
    public void update(String sql){
        try {
            bdOpenHelper.getWritableDatabase().execSQL(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public void update1(ContentValues values,String where,String[] whereArgs){
        try {
            bdOpenHelper.getWritableDatabase().update("user",values,where,whereArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

實現:
public void update(){
        String sql = "update user set username = '" + "li" + "' where id = '" + "1" + "'";
        dataHelper.update(sql);
    }

    public void update1(){
        ContentValues values = new ContentValues();
        values.put("username","li");
        String where = "id = ?";
        String[] whereArgs = new String[]{"1"};
        dataHelper.update1(values,where,whereArgs);
    }

4.刪除

因為和上面很相似,這裡就直接給出程式碼
/**
     * 刪除資料
     * @param sql
     */
    public void delete(String sql){
        try {
            bdOpenHelper.getWritableDatabase().execSQL(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public void delete(String where,String[] whereArgs){
        try {
            bdOpenHelper.getWritableDatabase().delete("user",where,whereArgs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
實現
/**
     * 刪除資料
     */
    public void delete(){
        String sql = "delete from user where id = '" + "1" + "'";
        dataHelper.delete(sql);
    }
    public void delete1(){
        dataHelper.delete1("id = ?",new String[]{"1"});
    }

上面是介紹原生的SQLite資料查詢,如果對資料操作不是很大的話,原生的語句就可以了,但有時候需要一些框架來輔助自己完成。下面介紹一個框架。要說一點的是,採用框架,就會增大apk的體積,如果對資料操作不多,建議不要使用。
框架名字GreenDAO
GreenDAO
參考連結: http://www.open-open.com/lib/view/open1438065400878.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1127/2069.html
http://greenrobot.org/greendao/documentation//introduction/
三步走 新增grandl 直接給出配置檔案 Android ORM 框架之 greenDAO 使用心得
(抄)
sourceSets {
        main {
            java.srcDirs = ['src/main/java', 'src/main/java-gen']
        }
    }

compile 'org.greenrobot:greendao:2.2.1'
compile 'org.greenrobot:greendao-generator:2.2.0'
上面兩個compile都放在dependecies中。
然後在java res同文件中中建立java-gen資料夾,用於放生成的檔案。 建立一個類來生成一些檔案。
public class Test {
    private static Schema schema;

//    public static void main(String args[]) throws Exception{
//        schema = new Schema(1,"com.ice.bean");
//        schema.setDefaultJavaPackageDao("com.ice.dao");
//        addAircle();
//        new DaoGenerator().generateAll(schema,"../ProjectDemo/app/src/main/java-gen");
//    }

    private static void addAircle(){
        Entity aircle = schema.addEntity("Aircle");
        aircle.addIdProperty();     //主鍵
        aircle.addStringProperty("title").notNull();//其他屬性,非空
    }
}
註釋掉的部分是用來生成一些檔案,這些檔案被放在java-gen中 講解註釋掉的程式碼 首先建立Schema,它的構造方法有兩個引數,一個版本資訊,一個是生成的包名,這個包名可以在java-gen中看到,bean是實體,就是將javabean對映成資料能夠操作的實體,同時在來建立一個dao,該dao是用來做一些操作的,比如增刪改查。然後呼叫addAircle方法,該方法就是用來生成實體類,生成資料庫能夠操作的實體類,aschema.addEntity(),建立Aircle這個類(該類在java-gen中),給這個類新增屬性,需要一個主鍵ID,和一個其他屬性。
new DaoGenerator().generateAll(schema,"../ProjectDemo/app/src/main/java-gen");這句程式碼就是告訴GreenDAO,我的java-gen的位置在哪裡,ProjectDemo就是專案名。
執行起來就能夠在java-gen看到com.ice.bean和com.ice.dao資料夾該資料夾下放了GreenDAO自動配置的檔案。
具體操作
在繼承了Application的類中的onCreate()方法中添上
<pre name="code" class="html">// 通過 DaoMaster 的內部類 DevOpenHelper,你可以得到一個便利的 SQLiteOpenHelper 物件。
    // 可能你已經注意到了,你並不需要去編寫「CREATE TABLE」這樣的 SQL 語句,因為 greenDAO 已經幫你做了。
    // 注意:預設的 DaoMaster.DevOpenHelper 會在資料庫升級時,刪除所有的表,意味著這將導致資料的丟失。
    // 所以,在正式的專案中,你還應該做一層封裝,來實現資料庫的安全升級。
    private void setupDatabase(){
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
        db = helper.getWritableDatabase();
        // 注意:該資料庫連線屬於 DaoMaster,所以多個 Session 指的是相同的資料庫連線。
        daoMaster = new DaoMaster(db);
        daoSession = daoMaster.newSession();
    }
具體實現如下:
private static DaoSession daoSession;
public static DaoSession getDaoSession() {
        return daoSession;
    }

    public static void setDaoSession(DaoSession daoSession) {
        App.daoSession = daoSession;
    }


    private void initData(){
        Aircle aircle = new Aircle();
        aircle.setTitle("ice");
        getAircleDao().insert(aircle);          //插入資料
        List<Aircle> ice = getAircleDao().queryBuilder().where(AircleDao.Properties.Title.eq("ice"))
//                .orderAsc(AircleDao.Properties.Id)    //進行排序
                .list();
        for (int i = 0; i < ice.size();i++){
            System.out.println(ice.get(i).getTitle());
        }
    }
    private AircleDao getAircleDao(){
        return App.getDaoSession().getAircleDao();
    }
獲取到到DAOsession,通過session,連線資料庫,並對其操作。 具體看上面給出的三個連結。