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

 

SQLite & LitePaljava


 

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

 

adbgit


 

      adb是 Android SDK自帶的一個調試工具,使用這個工具能夠直接對鏈接在電腦上的手機或者模擬器進行調試操做,使用adb shell 能夠對數據庫和表的建立狀況進行檢查。它存放在SDK的platform-tools目錄下,若是想要在命令行中使用這個工具,就須要先把它的路徑配置到環境變量中。github

      Windows系統的咱們就不說了,這個本身上網找,相信會有不少不少的教程,就說說在Mac系統下adb的安裝教程:sql

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

 

 

       而後打開你的終端咱們繼續:數據庫

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

      二、沒有上面查看的文件,輸入 touch .bash_profile 建立文件bash

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

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

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

           export PATH=${PATH}:ABC/tools

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

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

      七、只要不出現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這類的框架有很大區別。

      基本的配置:
 
      一、引入我麼的LitePal包
          因爲咱們的LitePal也是提交到jcenter的,因此咱們能夠經過在app/build.gradle 文件中聲明該開源庫的引用就能夠了,代碼以下:(LitePal的版本已經來到2.0)

      二、配置一下咱們的litepal.xml文件,在app/src/main路徑下經過 New - Directory 建立一個assect 目錄,  而後再assect目錄下新建一個 litepal.xml文件。接着編輯裏面的內容,內容以下:

 

      三、最後就是修改一下咱們的 AndroidMainfest.xml文件了,將咱們的項目的application配置爲 org.litepal,litePalApplication,這樣才能讓LitePal全部功能正常的使用,以後咱們會在補充關於 application的內容的時候會講解一下爲何!

 

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

 

      最後就是咱們關於它的CRUD的操做:
 
 
相關文章
相關標籤/搜索