1.0 隨著android編程的版本和工具的不斷更新备恤,一些學(xué)習(xí)內(nèi)容出現(xiàn)失效编整、棄用現(xiàn)象。寫這個同時也是給自己做筆記元镀。
2.0 Android系統(tǒng)內(nèi)置數(shù)據(jù)庫绍填,SQLite輕量級的關(guān)系型數(shù)據(jù)庫,當(dāng)然栖疑,使用起來其實很麻煩讨永,還需要熟練使用SQL語句。
3.0 開源讓Android開發(fā)者收益良多遇革,導(dǎo)致GitHub上有成百上千的優(yōu)秀Android開源項目卿闹,當(dāng)我們使用開源庫LitePal時揭糕,將會特別感受到SQLite數(shù)據(jù)庫使用的容易性。
4.0 LitePal項目主頁當(dāng)然有詳細(xì)的使用文檔锻霎,地址是:GitHub - LitePalFramework/LitePal: 一個Android庫著角,使開發(fā)人員非常容易使用sqlite數(shù)據(jù)庫
5.0 配置LitePal。
編輯app/build.gradle文件旋恼,在dependencies閉包中添加如下內(nèi)容:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
implementation 'org.litepal.android:java:3.0.0'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
添加這行代碼中吏口,“org.litepal.android:java:”是固定的,后面的版本號可以去 LitePal項目主頁上查看蚌铜。
6.0 新建一個項目锨侯,我的目錄結(jié)構(gòu)如下:
當(dāng)然這里也不要忘了,更新下編程環(huán)境冬殃,點這個:
7.0 litepal.xml內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="BookStore"></dbname>
<version value="2"></version>
<list>
<mapping class="com.example.litepaltest.Book"></mapping>
<mapping class="com.example.litepaltest.Category"></mapping>
</list>
</litepal>
dbname 標(biāo)簽用于指定數(shù)據(jù)庫名
version 標(biāo)簽用于指定數(shù)據(jù)庫版本號囚痴,這里我因為已經(jīng)玩了幾輪了,已經(jīng)更新到2审葬。
mapping 標(biāo)簽里面都是全路徑名稱下的具體的表深滚。
8.0 最后還需要配置下LitePalApplication,修改AndroidManifest.xml中的代碼涣觉,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.litepaltest">
<application
android:name="org.litepal.LitePalApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
主要是application標(biāo)簽下增加android:name="org.litepal.LitePalApplication"痴荐,其他都是自動生成的。
這樣LitePal的所有功能都能正常工作了官册,LitePal配置工作完全結(jié)束生兆。
9.0 LitePal最大的好處,就在于她是相當(dāng)于面向?qū)ο蟮南ツ瑖?yán)謹(jǐn)?shù)卣f鸦难,叫做采用的是對象關(guān)系映射(ORM)的模式。
這樣可以用面向?qū)ο蟮乃季S來操作數(shù)據(jù)庫员淫,而不用再和SQL語句打交道合蔽,并且可以直接指定好了數(shù)據(jù)的數(shù)據(jù)類型。
例如在這個項目中介返,再定義一個Book類拴事,代碼如下:
package com.example.litepaltest;
import org.litepal.crud.LitePalSupport;
public class Book extends LitePalSupport {
private int id;
private String author;
private double price;
private int pages;
private String name;
private String press;
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
可見這是一個典型的Java bean。相當(dāng)于對應(yīng)數(shù)據(jù)庫中的Book表圣蝎。
10.0 由于前面已經(jīng)描述了litepal.xml中的代碼刃宵,事實上,坐好Book類徘公,還需要在這個文件中用mapping標(biāo)簽來聲明要配置的映射模型類组去。這里就不再貼代碼了。
11.0修改MainActivity.java中的代碼步淹,創(chuàng)建數(shù)據(jù)庫:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button createDatebase = (Button) findViewById(R.id.create_database);
createDatebase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LitePal.getDatabase();
}
});
這里用了LitePal.getDatabase();創(chuàng)建數(shù)據(jù)庫从隆,運行,可以點擊那個Button控件(最后一次性貼activity_main.xml的代碼缭裆,里面到時候會配置4個按鈕控件)键闺,數(shù)據(jù)庫創(chuàng)建成功。
12.0 怎么可以查看數(shù)據(jù)庫是否真的創(chuàng)建好了澈驼,在我的參考書里面是通過adb.exe辛燥,在命令窗口,通過命令行查看缝其,但是Android6.0以后的版本的模擬器挎塌,這個方法根本進(jìn)不去數(shù)據(jù)庫。
所以我用的第二種方法内边。
12.1 首先你得裝一個Navicat Premium榴都,數(shù)據(jù)庫可視化軟件。
我的是Navicat Premium 12漠其。
12.2 然后運行項目后嘴高,點擊按鈕,創(chuàng)建數(shù)據(jù)庫和屎。然后打開Android studio拴驮,在右下角可以看到Device File Explorer,接下來的操作如圖所示:
當(dāng)然,如果你找不到Device File Explorer,可以到View→Tool Windows→Device File Explorer:
如果這樣都沒有的話柴信,那就涼涼了……
12.3 接下來打開Navicat Premium 套啤,點擊SQLite,操作如圖:
選擇數(shù)據(jù)庫文件随常,
找到保存的目錄潜沦,選擇目錄文件,打開
這樣线罕,就可以查看到相關(guān)的內(nèi)容了(我的因為多寫了別的代碼止潮,導(dǎo)致里面有數(shù)據(jù))
13.0 常說的增刪查改。首先是想添加一個出版社钞楼,直接修改Book代碼喇闸,添加一個press字段即可,上面的代碼询件,已經(jīng)是添加完畢的燃乍。
14.0 如果還想再添加一張Category表,那么只需要添加一個Category類即可:
Category.java
package com.example.litepaltest;
public class Category {
private int id;
private String categoryName;
private int categoryCode;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public int getCategoryCode() {
return categoryCode;
}
public void setCategoryCode(int categoryCode) {
this.categoryCode = categoryCode;
}
}
但別忘了在litepal.xml中增加一個mapping(在上面貼的完整代碼中已添加好):
<mapping class="com.example.litepaltest.Category"></mapping>
15.0 添加數(shù)據(jù)宛琅,LitePal進(jìn)行表管理操作時不需要模型類有任何的繼承結(jié)構(gòu)刻蟹,但是進(jìn)行CRUD操作時就不行,必須繼承LitePalSupport類才行(之前是繼承DataSupport類嘿辟,現(xiàn)在已經(jīng)被棄用)
上面可以看到我們的Book類已經(jīng)被我加上了繼承結(jié)構(gòu)舆瘪,但在創(chuàng)建表時片效,可以不用該繼承。
添加數(shù)據(jù),將數(shù)據(jù)設(shè)置好英古,調(diào)用下save()方法即可淀衣,只需要修改下MainActivity.java中的代碼(當(dāng)然,這里又增加了一個Button按鈕):
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setName("中國古代歷史");
book.setAuthor("睡醒著");
book.setPages(454);
book.setPrice(16.96);
book.setPress("Unknow");
book.save();
}
});
}
}
16.0更新數(shù)據(jù)召调,如下:
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setName("大亨小傳");
book.setAuthor("java著");
book.setPages(329);
book.setPrice(21.96);
book.setPress("Unknow");
book.save();
book.setPrice(51.96);
book.save();
}
});
}
}
當(dāng)然膨桥,還可以更加靈巧的更新數(shù)據(jù):
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setPrice(33.96);
book.setPress("Anchor");
book.updateAll("name= ? and author = ?","中國古代歷史","睡醒著");
}
});
}
}
上面updateAll()方法的意思是匹配Book表中,所有名字叫“中國古代歷史“”唠叛,而且作者是“睡醒著”的所有數(shù)據(jù)只嚣,將他們的價格和出版社給改了。
還可以將某個數(shù)據(jù)恢復(fù)成系統(tǒng)默認(rèn)值:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 下面三句代碼的意思是:把所有書的頁數(shù)設(shè)置為默認(rèn)值0
Book book = new Book();
book.setToDefault("pages");
book.updateAll();
}
});
}
}
17.0 刪除數(shù)據(jù)艺沼,如下:
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button deleteData = (Button) findViewById(R.id.delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 這里之前的DataSupport被棄用册舞,取而代之的是LitePal
LitePal.deleteAll(Book.class,"price < ?","23");
}
});
}
}
上句話的意思是,刪除Book表中所有價格小于23的書的數(shù)據(jù)澳厢。
18.0 查詢數(shù)據(jù)环础,很簡單:
在Button控件監(jiān)控的基礎(chǔ)上,直接增加如下代碼:
18.1 查詢Book表中的所有數(shù)據(jù):
List<Book> book = LitePal.findAll(Book.class);
18.2 查詢Book表中的第一條數(shù)據(jù):
Book firstBook = LitePal.findFirst(Book.class);
18.3 查詢Book表中的最后一條數(shù)據(jù):
Book lastBook = LitePal.findLast(Book.class);
18.4 只查詢Book表中的name和author這兩列數(shù)據(jù)(對應(yīng)SQL中的select關(guān)鍵字):
List<Book> book = LitePal.select("name","author").find(Book.class);
18.5 只查詢Book表中的頁數(shù)大于400的數(shù)據(jù)(對應(yīng)SQL中的where關(guān)鍵字):
List<Book> book = LitePal.where("pages > ?","400").find(Book.class);
18.6 查詢Book表,將查詢結(jié)果按照書價從高到低排序(對應(yīng)SQL中的order by關(guān)鍵字):
List<Book> book = LitePal.order("price desc ").find(Book.class);
其中“desc”表示降序排序剩拢,不寫或者"asc"表示升序排序
18.7 查詢Book表中的前3條數(shù)據(jù):
List<Book> book = LitePal.limit(3).find(Book.class);
18.8 查詢Book表中的第2條线得、第3條、第4條數(shù)據(jù):
List<Book> book = LitePal.limit(3).offset(1).find(Book.class);
limit(3)查詢的是前3條數(shù)據(jù)(第1徐伐、2贯钩、3條),再加一個offset(1)進(jìn)行位置的偏移办素,意味著查詢第2角雷、3、4條數(shù)據(jù)了性穿,這兩個方法相結(jié)合對應(yīng)SQL語句中的limit關(guān)鍵字勺三。
18.9 劃重點的來了,可以把select()需曾、where()吗坚、order()、limit()呆万、offset()五個方法任意組合商源,以完成一個復(fù)雜的查詢操作,比如查詢Book表中第11-20條滿足頁數(shù)大于400這個條件的name谋减、author和pages這3列數(shù)據(jù)牡彻,并將查詢結(jié)果按照頁數(shù)的升序排列:
List<Book> book = LitePal.selcect("name","author","pages")
.where("pages > ?","400")
.order(pages)
.limit(10)
.offset(10)
.find(Book.class);
18.10 最后,如果LitePal這都滿足不了你窮兇極惡的需求出爹,那么它仍然支持使用原生的SQL來查詢:
Cursor c = LitePal.findBySQL("select * from Book where pages > ? and price < ?","400","20");
當(dāng)然庄吼,這樣數(shù)據(jù)需要取出來的話缎除,就得通過Cursor的各種get方法了。
END