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(); } }); } }
基本的配置:

2、配置一下我們的litepal.xml文件,在app/src/main路徑下通過 New - Directory 創建一個assect 目錄, 然后再assect目錄下新建一個 litepal.xml文件。接着編輯里面的內容,內容如下:
3、最后就是修改一下我們的 AndroidMainfest.xml文件了,將我們的項目的application配置為 org.litepal,litePalApplication,這樣才能讓LitePal所有功能正常的使用,之后我們會在補充關於 application的內容的時候會講解一下為什么!

它的使用:


