Android学习--持久化(三) SQLite LitePal
?
SQLite & LitePal
?
? ? 自己做為一個(gè)iOS開發(fā),看到安卓這一塊的時(shí)候,那中濃烈的熟悉味道更加強(qiáng)烈,SQLite這種輕量級(jí)的關(guān)系型數(shù)據(jù)庫的使用在移動(dòng)端相差不多,iOS有FMDB,Android有LitePal, 這一篇文章好好總結(jié)一下?SQLite & LitePal,由于自己用的是Mac系統(tǒng),在配置 adb的時(shí)候也遇到了一些問題,把這些問題也都說一下,避免大家跳太多的坑吧。這個(gè)我們就先說說在Mac系統(tǒng)下配置這個(gè)adb,因?yàn)檫@個(gè)不管是我們使用原生SQLite還是用LitePal,這東西都是必須的,說以先說說它的一個(gè)配置:
?
adb
?
? ? ? adb是 Android SDK自帶的一個(gè)調(diào)試工具,使用這個(gè)工具可以直接對(duì)連接在電腦上的手機(jī)或者模擬器進(jìn)行調(diào)試操作,使用adb shell 可以對(duì)數(shù)據(jù)庫和表的創(chuàng)建情況進(jìn)行檢查。它存放在SDK的platform-tools目錄下,如果想要在命令行中使用這個(gè)工具,就需要先把它的路徑配置到環(huán)境變量中。
? ? ? Windows系統(tǒng)的我們就不說了,這個(gè)自己上網(wǎng)找,相信會(huì)有很多很多的教程,就說說在Mac系統(tǒng)下adb的安裝教程:
? ? ? 先在你的SDK Manager 里面找一下你的SDK的位置,如下圖兩點(diǎn)中需要注意的地方,一個(gè)是SDK位置,一個(gè)是下載Platform - Tools:
?
?
? ? ? ?然后打開你的終端我們繼續(xù):
? ? ? ?1、檢查一下你是不是有.bash_profile文件,打開終端 ls ?-a 查看一下是不是有這個(gè)文件,沒有的就到下一步,有的就跳過第二步
? ? ? 2、沒有上面查看的文件,輸入?touch .bash_profile 創(chuàng)建文件
? ? ? 3、打開.bash_profile文件,對(duì)其內(nèi)容進(jìn)行編輯,命令如下:open -e .bash_profile
? ? ? 4、此時(shí)文本編輯器會(huì)打開一個(gè)文本,編輯內(nèi)容如下:注意!!!下面ABC就是你在前面看到的SDK的路徑!?
? ? ? ? ? ?export PATH=${PATH}:ABC/platform-tools
? ? ? ? ? ?export PATH=${PATH}:ABC/tools
? ? ? 5、更新剛配置的環(huán)境變量,輸入:?source .bash_profile
? ? ? 6、檢查一下是否配置成功 輸入: adb
? ? ? 7、只要不出現(xiàn)command not found,那就說明配置沒問題了!
?
SQLite
? ? ?
? ? ? 一:SQLite的創(chuàng)建? ? ??
? ? ? Android為了讓我們更加方便的管理數(shù)據(jù)庫,專門提供了一個(gè)SQLiteOpenHelper的抽象類,這意味的我們要是想使用它的話就得我們創(chuàng)建一個(gè)類去繼承它,SQLiteOpenHelper中有兩個(gè)抽象方法,分別是onCreate()和onUpgrade(),我們也必須在自己的類當(dāng)中去重寫這兩個(gè)方法,分別在這兩個(gè)方法中去實(shí)現(xiàn)創(chuàng)建和升級(jí)數(shù)據(jù)庫的邏輯。
? ? ??SQLiteOpenHelper當(dāng)中有兩個(gè)非常重要的實(shí)例化方法,getReadableDatabase()和getWritableDatabase(),這兩個(gè)方法都可以創(chuàng)建或者而打開一個(gè)現(xiàn)有的數(shù)據(jù)庫,入伙數(shù)據(jù)庫已經(jīng)存在就直接打開,否則會(huì)創(chuàng)建一個(gè)新的數(shù)據(jù)庫,并返回一個(gè)可以對(duì)數(shù)據(jù)庫進(jìn)行操作的對(duì)象,不同的是,當(dāng)數(shù)據(jù)庫不可寫入的時(shí)候(比如磁盤已滿)。getReadableDatabase()方法返回的對(duì)象將以只讀的方法打開數(shù)據(jù)庫,而getWritableDatabase()方法則將出現(xiàn)異常。
? ? ??SQLiteOpenHelper中有兩個(gè)構(gòu)造方法可供重寫,一般使用參數(shù)比較少的那個(gè)構(gòu)造方法即可,這個(gè)構(gòu)造方法中接收四個(gè)參數(shù),第一個(gè)參數(shù)是Context,這個(gè)沒什么好說的,第二個(gè)參數(shù)是數(shù)據(jù)庫名稱,第三個(gè)參數(shù)允許我們?cè)俨樵償?shù)據(jù)的時(shí)候返回一個(gè)自定義的cursor,一般傳入都是null,第四個(gè)參數(shù)是當(dāng)前數(shù)據(jù)庫的版本號(hào),這個(gè)額可以對(duì)數(shù)據(jù)庫進(jìn)行升級(jí)操作,構(gòu)建出SQLiteOpenHelper實(shí)例之后再調(diào)用前面我們說的getReadableDatabase()或getWritableDatabase()就能夠創(chuàng)建數(shù)據(jù)庫了,數(shù)據(jù)庫文件會(huì)存放在/data/data/<package name >/database 目錄下。此時(shí)重寫的 onCreat()方法也會(huì)得到執(zhí)行。所以通常會(huì)在這里做一些創(chuàng)建表的邏輯。
? ? ?(具體代碼下面)
?
? ? ? 二:SQLite的升級(jí)
? ? ? 我們想象這樣一個(gè)場(chǎng)景,我們要是需要在數(shù)據(jù)庫當(dāng)中添加一張表那我們需要怎么辦呢?簡(jiǎn)單啊,我們?cè)趧?chuàng)建的表的方法onCreate()里面添加一條創(chuàng)建表的語句就可以了啊,仔細(xì)想象這樣真的可以嗎?其實(shí)是不行的,因?yàn)槟阋呀?jīng)存在的數(shù)據(jù)庫是沒辦法在走onCreate方法的, 那怎么辦?把以前的程序刪除了,重新安裝,額。。這樣做不行的,這里就要使用我們的數(shù)據(jù)庫的升級(jí)了。
? ? ? 我們利用的就是onUpgrade()方法+前面初始化時(shí)候的版本號(hào),接著利用上面代碼,我們升級(jí)一下我們這個(gè)數(shù)據(jù)庫,給里面再添加一張表。
? ? (具體代碼下面)
?
? ? ? 三:SQLite的增刪查改
? ? ? 下面代碼是上面三點(diǎn)的代碼的總結(jié),代碼是寫在一起的,下面是我們寫的SQManager文件內(nèi)容:
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;}@Overridepublic void onCreate(SQLiteDatabase sqLiteDatabase) {sqLiteDatabase.execSQL(CREATE_BOOK);Toast.makeText(mContext, "Create Succeed", Toast.LENGTH_LONG).show();}@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {// 這兩條drop語句,如果發(fā)現(xiàn)數(shù)據(jù)庫中已經(jīng)存在表,那就將這兩張表刪除掉,造調(diào)用onCreate重新創(chuàng)建// 這里我們有一點(diǎn)需要注意的是如果表已經(jīng)存在,再去創(chuàng)建就會(huì)報(bào)錯(cuò)sqLiteDatabase.execSQL("drop table if exists Book");sqLiteDatabase.execSQL("drop table if exists Category");onCreate(sqLiteDatabase);} }?
? ? ? 再把MainActivity文件的內(nèi)容展示出來:?
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;@Overrideprotected 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() {@Overridepublic void onClick(View view) {// 第一次調(diào)用的時(shí)候檢測(cè)到?jīng)]有BookStore這個(gè)數(shù)據(jù)庫就回去創(chuàng)建這個(gè)數(shù)據(jù)庫sqLiteDatabase = sqManager.getWritableDatabase();ContentValues values = new ContentValues();values.put("name","我是中國人");values.put("author","zhangxu");values.put("pages",500);values.put("price",15.4);//insert 第一個(gè)參數(shù)是表的名稱 第二個(gè)參數(shù)是用于在未指定添加的情況下給某些可為空的列自動(dòng)復(fù)制為NULL//第三個(gè)參數(shù)是我們的ContentValues對(duì)象sqLiteDatabase.insert("Book",null,values);//組裝第二條數(shù)據(jù)values.put("name","我在廣州");values.put("author","james");values.put("pages",343);values.put("price",19.4);sqLiteDatabase.insert("Book",null,values);//這里有個(gè)問題需要我們注意一下//為什么我們沒有在ID的哪一列沒有賦值呢?這還少因?yàn)樵谇懊鎰?chuàng)建表的時(shí)候,我們將ID設(shè)置為了自增//它的值會(huì)在入庫的時(shí)候自動(dòng)的增加//先說這句更新的意思//整體語句的意思是把書名叫我在廣州的書的價(jià)格修改為10.0values.put("price","10.0");//說說update方法的參數(shù)//第一和表名,第二個(gè)是修改的values,第三,第四是用于約束更新某一行或者幾行的數(shù)據(jù)//更新所有name = ?的行,而?是一個(gè)占位符,在第四個(gè)參數(shù)提供了一個(gè)字符串?dāng)?shù)組為第三個(gè)參數(shù)中的每一個(gè)占位符//提供相應(yīng)的內(nèi)容sqLiteDatabase.update("Book", values, "name = ?", new String[]{"我在廣州"});//delete刪除//第一和表名,第二個(gè)參數(shù)是刪除的條件,第三個(gè)參數(shù)是給約束條件賦值,沒和前面的更新道理相同sqLiteDatabase.delete("Book","page > ?",new String[]{"300"});// 查詢// 這里需要注意的就是query方法的參數(shù)解析// 第一個(gè)參數(shù)是表名稱// 第二個(gè)參數(shù)用于指定查詢那一列,要是沒有至此那個(gè)就查詢所有// 第三,第四各參數(shù)用于約束查詢某一行或者幾行的數(shù)據(jù),這個(gè)和前面的一樣道理// 第五個(gè)參數(shù)用于指定需要去group by的列,不指定則表示不需要對(duì)查詢結(jié)果進(jìn)行 group by操作// 第六個(gè)參數(shù)用于對(duì)第五步 group by 之后的數(shù)據(jù)進(jìn)行進(jìn)一步的過濾,不指定就不進(jìn)行過濾// 第七個(gè)參數(shù)用于指定查詢結(jié)果的排序方式,不指定就是默認(rèn)排序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上有了一個(gè)更新,故來學(xué)習(xí)一番,沒想到還挺好用,這里做下筆記。LitePal是一款開源的Android數(shù)據(jù)庫框架,它采用了對(duì)象關(guān)系映射(ORM)的模式,并將我們平時(shí)開發(fā)時(shí)最常用到的一些數(shù)據(jù)庫功能進(jìn)行了封裝,使得不用編寫一行SQL語句就可以完成各種建表、増刪改查的操作。并且LitePal很“輕”,jar包只有100k不到,而且近乎零配置,這一點(diǎn)和hibernate這類的框架有很大區(qū)別。? ? ? 基本的配置: 1、引入我么的LitePal包 由于我們的LitePal也是提交到j(luò)center的,所以我們可以通過在app/build.gradle 文件中聲明該開源庫的引用就可以了,代碼如下:(LitePal的版本已經(jīng)來到2.0)
? ? ? 2、配置一下我們的litepal.xml文件,在app/src/main路徑下通過 New - Directory 創(chuàng)建一個(gè)assect 目錄, ?然后再assect目錄下新建一個(gè) litepal.xml文件。接著編輯里面的內(nèi)容,內(nèi)容如下:
?
? ? ? 3、最后就是修改一下我們的 AndroidMainfest.xml文件了,將我們的項(xiàng)目的application配置為 org.litepal,litePalApplication,這樣才能讓LitePal所有功能正常的使用,之后我們會(huì)在補(bǔ)充關(guān)于 application的內(nèi)容的時(shí)候會(huì)講解一下為什么!?
? ? ? 它的使用: 關(guān)于它的映射類這部分的類容我們和關(guān)于它CRUD的操作依據(jù)里面的注意事項(xiàng)就直接上代碼,把他們放在代碼中說: 映射類的創(chuàng)建就不說了,你自己創(chuàng)建一個(gè)java類,添加變量重寫get以及set方法就行了,關(guān)鍵的點(diǎn)是在進(jìn)行關(guān)于它CRUD的操作的時(shí)候,在以前是需要我們把我們的映射類繼承DataSupport的,但現(xiàn)在這個(gè)類已經(jīng)被廢棄了,而是選擇使用 LitePalSupport,這點(diǎn)在代碼中有具體的提現(xiàn): 看看我們定義的映射類,注意寫的注釋:?
最后就是我們關(guān)于它的CRUD的操作:?
轉(zhuǎn)載于:https://www.cnblogs.com/zhangxiaoxu/p/7337655.html
總結(jié)
以上是生活随笔為你收集整理的Android学习--持久化(三) SQLite LitePal的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: weblogic漏洞复现(CVE-202
- 下一篇: poj3187 穷竭搜索 挑战程序设计大