Android學習--持久化(三) SQLite & LitePal


 

SQLite & LitePal


 

    自己做為一個iOS開發,看到安卓這一塊的時候,那中濃烈的熟悉味道更加強烈,SQLite這種輕量級的關系型數據庫的使用在移動端相差不多,iOS有FMDB,Android有LitePal, 這一篇文章好好總結一下 SQLite & LitePal,由於自己用的是Mac系統,在配置 adb的時候也遇到了一些問題,把這些問題也都說一下,避免大家跳太多的坑吧。這個我們就先說說在Mac系統下配置這個adb,因為這個不管是我們使用原生SQLite還是用LitePal,這東西都是必須的,說以先說說它的一個配置:

 

adb


 

      adb是 Android SDK自帶的一個調試工具,使用這個工具可以直接對連接在電腦上的手機或者模擬器進行調試操作,使用adb shell 可以對數據庫和表的創建情況進行檢查。它存放在SDK的platform-tools目錄下,如果想要在命令行中使用這個工具,就需要先把它的路徑配置到環境變量中。

      Windows系統的我們就不說了,這個自己上網找,相信會有很多很多的教程,就說說在Mac系統下adb的安裝教程:

      先在你的SDK Manager 里面找一下你的SDK的位置,如下圖兩點中需要注意的地方,一個是SDK位置,一個是下載Platform - Tools:

 

 

       然后打開你的終端我們繼續:

       1、檢查一下你是不是有.bash_profile文件,打開終端 ls  -a 查看一下是不是有這個文件,沒有的就到下一步,有的就跳過第二步

      2、沒有上面查看的文件,輸入 touch .bash_profile 創建文件

      3、打開.bash_profile文件,對其內容進行編輯,命令如下:open -e .bash_profile

      4、此時文本編輯器會打開一個文本,編輯內容如下:注意!!!下面ABC就是你在前面看到的SDK的路徑! 

           export PATH=${PATH}:ABC/platform-tools

           export PATH=${PATH}:ABC/tools

      5、更新剛配置的環境變量,輸入: source .bash_profile

      6、檢查一下是否配置成功 輸入: adb

      7、只要不出現command not found,那就說明配置沒問題了!

 

SQLite


     

      一:SQLite的創建      

      Android為了讓我們更加方便的管理數據庫,專門提供了一個SQLiteOpenHelper的抽象類,這意味的我們要是想使用它的話就得我們創建一個類去繼承它,SQLiteOpenHelper中有兩個抽象方法,分別是onCreate()和onUpgrade(),我們也必須在自己的類當中去重寫這兩個方法,分別在這兩個方法中去實現創建和升級數據庫的邏輯。

      SQLiteOpenHelper當中有兩個非常重要的實例化方法,getReadableDatabase()和getWritableDatabase(),這兩個方法都可以創建或者而打開一個現有的數據庫,入伙數據庫已經存在就直接打開,否則會創建一個新的數據庫,並返回一個可以對數據庫進行操作的對象,不同的是,當數據庫不可寫入的時候(比如磁盤已滿)。getReadableDatabase()方法返回的對象將以只讀的方法打開數據庫,而getWritableDatabase()方法則將出現異常。

      SQLiteOpenHelper中有兩個構造方法可供重寫,一般使用參數比較少的那個構造方法即可,這個構造方法中接收四個參數,第一個參數是Context,這個沒什么好說的,第二個參數是數據庫名稱,第三個參數允許我們再查詢數據的時候返回一個自定義的cursor,一般傳入都是null,第四個參數是當前數據庫的版本號,這個額可以對數據庫進行升級操作,構建出SQLiteOpenHelper實例之后再調用前面我們說的getReadableDatabase()或getWritableDatabase()就能夠創建數據庫了,數據庫文件會存放在/data/data/<package name >/database 目錄下。此時重寫的 onCreat()方法也會得到執行。所以通常會在這里做一些創建表的邏輯。

     (具體代碼下面)

 

      二:SQLite的升級

      我們想象這樣一個場景,我們要是需要在數據庫當中添加一張表那我們需要怎么辦呢?簡單啊,我們在創建的表的方法onCreate()里面添加一條創建表的語句就可以了啊,仔細想象這樣真的可以嗎?其實是不行的,因為你已經存在的數據庫是沒辦法在走onCreate方法的, 那怎么辦?把以前的程序刪除了,重新安裝,額。。這樣做不行的,這里就要使用我們的數據庫的升級了。

      我們利用的就是onUpgrade()方法+前面初始化時候的版本號,接着利用上面代碼,我們升級一下我們這個數據庫,給里面再添加一張表。

    (具體代碼下面)

 

      三:SQLite的增刪查改

      下面代碼是上面三點的代碼的總結,代碼是寫在一起的,下面是我們寫的SQManager文件內容:

package SQManager;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

/**
 * Created by skotc on 2018/7/17.
 */
public class SQManager extends SQLiteOpenHelper {

    public static  final String CREATE_BOOK = " create table Book (" +
            "id integer primary key autoincrement" +
            "author text" +
            "price real" +
            "pages integer" +
            "name text)";
    public static  final String CREATE_CATEGORY = " create table Category (" +
            "id integer primary key autoincrement" +
            "category_name text" +
            "category_code integer)";

    private Context mContext;
    public SQManager(Context context,String name, SQLiteDatabase.CursorFactory factory, int version){

        super(context,name,factory,version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

        sqLiteDatabase.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "Create Succeed", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

        // 這兩條drop語句,如果發現數據庫中已經存在表,那就將這兩張表刪除掉,造調用onCreate重新創建
        // 這里我們有一點需要注意的是如果表已經存在,再去創建就會報錯
        sqLiteDatabase.execSQL("drop table if exists Book");
        sqLiteDatabase.execSQL("drop table if exists Category");
        onCreate(sqLiteDatabase);

    }
}

 

      再把MainActivity文件的內容展示出來: 

package com.example.skotc.sqlitetest;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabaseLockedException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import SQManager.SQManager;

public class MainActivity extends AppCompatActivity {

    private SQManager sqManager;
    private SQLiteDatabase sqLiteDatabase;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //
        sqManager = new SQManager(this,"BookStore",null,1);

        //sqManager = new SQManager(this,"BookStore",null,1);

        Button SQButton = (Button)findViewById(R.id.SQButton);
        SQButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // 第一次調用的時候檢測到沒有BookStore這個數據庫就回去創建這個數據庫
                sqLiteDatabase = sqManager.getWritableDatabase();

                ContentValues values = new ContentValues();
                values.put("name","我是中國人");
                values.put("author","zhangxu");
                values.put("pages",500);
                values.put("price",15.4);

                //insert 第一個參數是表的名稱  第二個參數是用於在未指定添加的情況下給某些可為空的列自動復制為NULL
                //第三個參數是我們的ContentValues對象
                sqLiteDatabase.insert("Book",null,values);

                //組裝第二條數據
                values.put("name","我在廣州");
                values.put("author","james");
                values.put("pages",343);
                values.put("price",19.4);
                sqLiteDatabase.insert("Book",null,values);

                //這里有個問題需要我們注意一下
                //為什么我們沒有在ID的哪一列沒有賦值呢?這還少因為在前面創建表的時候,我們將ID設置為了自增
                //它的值會在入庫的時候自動的增加

                //先說這句更新的意思
                //整體語句的意思是把書名叫我在廣州的書的價格修改為10.0
                values.put("price","10.0");
                //說說update方法的參數
                //第一和表名,第二個是修改的values,第三,第四是用於約束更新某一行或者幾行的數據
                //更新所有name = ?的行,而?是一個占位符,在第四個參數提供了一個字符串數組為第三個參數中的每一個占位符
                //提供相應的內容
                sqLiteDatabase.update("Book", values, "name = ?", new String[]{"我在廣州"});


                //delete刪除
                //第一和表名,第二個參數是刪除的條件,第三個參數是給約束條件賦值,沒和前面的更新道理相同
                sqLiteDatabase.delete("Book","page > ?",new String[]{"300"});


                // 查詢
                // 這里需要注意的就是query方法的參數解析
                // 第一個參數是表名稱
                // 第二個參數用於指定查詢那一列,要是沒有至此那個就查詢所有
                // 第三,第四各參數用於約束查詢某一行或者幾行的數據,這個和前面的一樣道理
                // 第五個參數用於指定需要去group by的列,不指定則表示不需要對查詢結果進行 group by操作
                // 第六個參數用於對第五步 group by 之后的數據進行進一步的過濾,不指定就不進行過濾
                // 第七個參數用於指定查詢結果的排序方式,不指定就是默認排序

                Cursor cursor = sqLiteDatabase.query("Book",null,null,null,null,null,null);
                if (cursor.moveToFirst()){

                    do {

                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        String author = cursor.getString(cursor.getColumnIndex("author"));
                        int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        double price = cursor.getDouble(cursor.getColumnIndex("price"));

                        Log.d("MainActivity","name = "+name);
                        Log.d("MainActivity","author = "+author);
                        Log.d("MainActivity","pages = "+pages);
                        Log.d("MainActivity","price = "+price);

                    }while (cursor.moveToNext());
                }
                cursor.close();
            }
        });
    }
}

 

LitePal


 

        LitePal是郭神(郭霖)在2014年的傑作,三年后在github上有了一個更新,故來學習一番,沒想到還挺好用,這里做下筆記。LitePal是一款開源的Android數據庫框架,它采用了對象關系映射(ORM)的模式,並將我們平時開發時最常用到的一些數據庫功能進行了封裝,使得不用編寫一行SQL語句就可以完成各種建表、増刪改查的操作。並且LitePal很“輕”,jar包只有100k不到,而且近乎零配置,這一點和hibernate這類的框架有很大區別。

      基本的配置:
 
      1、引入我么的LitePal包
          由於我們的LitePal也是提交到jcenter的,所以我們可以通過在app/build.gradle 文件中聲明該開源庫的引用就可以了,代碼如下:(LitePal的版本已經來到2.0)

      2、配置一下我們的litepal.xml文件,在app/src/main路徑下通過 New - Directory 創建一個assect 目錄,  然后再assect目錄下新建一個 litepal.xml文件。接着編輯里面的內容,內容如下:

 

      3、最后就是修改一下我們的 AndroidMainfest.xml文件了,將我們的項目的application配置為 org.litepal,litePalApplication,這樣才能讓LitePal所有功能正常的使用,之后我們會在補充關於 application的內容的時候會講解一下為什么!

 

      它的使用:
      關於它的映射類這部分的類容我們和關於它CRUD的操作依據里面的注意事項就直接上代碼,把他們放在代碼中說:
      映射類的創建就不說了,你自己創建一個java類,添加變量重寫get以及set方法就行了,關鍵的點是在進行關於它CRUD的操作的時候,在以前是需要我們把我們的映射類繼承DataSupport的,但現在這個類已經被廢棄了,而是選擇使用 LitePalSupport,這點在代碼中有具體的提現:
 
      看看我們定義的映射類,注意寫的注釋:

 

      最后就是我們關於它的CRUD的操作:
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM