使用LitePal操作数据库(CRUD增删改查) 项目已上传GitHub
GitHub項目地址:
https://github.com/Skymqq/LitePalSave.git
?
LitePal是一款開源的Android數(shù)據(jù)庫框架,它采用了對象關(guān)系映射(ORM)映射的模式,并將我們平時開發(fā)最常用到的一些數(shù)據(jù)庫進行了封裝,使得不用編寫一行SQL語句就可以完成各種建表和增刪改查的操作。
首先新建一個LitePalSave項目。
配置LitePal
Android中配置開源庫的方法有很多種,第一種(也是優(yōu)先推薦的方法)聲明開源庫的依賴的引用,第二種就是去開源庫的官網(wǎng)下載不同版本的jar包,然后再手動copy到項目的lib文件夾中,再add到本地。這里我們就直接使用第一種添加開源庫依賴的引用的方式來一鍵導入開源庫。
在app/build.gradle文件的dependencies閉包中添加如下內(nèi)容:
//配置LitePalimplementation 'org.litepal.android:core:1.4.1'添加的這一行聲明中,前面部分是固定的,最后的1.4.1是版本號的意思,最新的版本號可以到LitePal的項目主頁上去查看。
這樣我們就把LitePal成功引入到當前項目中了,接下來需要配置litepal.xml文件。右擊app/src/main 目錄 New? Directory,創(chuàng)建一個assets目錄,然后在assets目錄下再新建一個litepal.xml文件,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <litepal><!--數(shù)據(jù)庫名--><dbname value="BookStore" /><!--數(shù)據(jù)庫版本--><version value="1" /><!--映射模型列表--><list></list></litepal>最后還需要在AndroidManifest.xml中的<application>標簽中添加一行代碼:
android:name="org.litepal.LitePalApplication"這里我們將項目的application配置為org.litepal.LitePalApplication,這樣才能讓LitePal的所有功能都可以工作。
創(chuàng)建和升級數(shù)據(jù)庫
我們之前創(chuàng)建數(shù)據(jù)庫時通過自定義一個類繼承自SQLiteDatabase,然后在onCreate()方法中編寫建表語句來實現(xiàn)的,而采用對象關(guān)系映射(ORM)模式的LitePal就很容易實現(xiàn)了。 那么什么是對象關(guān)系映射(ORM)呢?簡單的來說,我們使用的編程語言是面向?qū)ο笳Z言,而使用的數(shù)據(jù)庫則是關(guān)系型數(shù)據(jù)庫,那么將面向?qū)ο蟮恼Z言和面向關(guān)系的數(shù)據(jù)庫之間建立一種映射關(guān)系,這就是對象關(guān)系映射。它賦予了我們一個強大的功能,就是可以用面向?qū)ο蟮乃季S來操作數(shù)據(jù)庫,而不用再去使用SQL語句了。
之前為了創(chuàng)建一張Book表,需要先分析表中應該包含哪些列,然后再編寫出一條建表語句,最后在自定義的SQLiteOpenHelper中去執(zhí)行這條建表語句。但是使用LitePal,你就可以用面向?qū)ο蟮乃季S來實現(xiàn)同樣的功能了,定義一個Book實體類,代碼如下所示:
package com.example.administrator.litepalsave;public class Book {private int id;private String author;private double price;private int pages;private String name;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;} }這是一個典型的JavaBean,在Book類中我們定義了id、author、price、pages、name這幾個字段,并生成了相應的getter和setter方法。Book類中聲明的成員變量分別對應了表中的每一個列,這就是對象關(guān)系映射(ORM)最直觀的體驗。
接下來我們需要將Book類添加到映射模型列表中,修改litepal.xml中的代碼,如下所示:
<?xml version="1.0" encoding="utf-8"?> <litepal><!--數(shù)據(jù)庫名--><dbname value="BookStore" /><!--數(shù)據(jù)庫版本--><version value="1" /><!--映射模型列表--><list><mapping class="com.example.administrator.litepalsave.Book"/></list></litepal>這里使用<mapping>標簽來聲明我們要配置的映射模型類。注意一定要使用完整的類名。不管有多少模型類需要映射,都使用同樣的方式配置<list>標簽下即可。
最后,activity.xml代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btn_create"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Create Database"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_add"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Add Data"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_update"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Update Data"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_delete"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Delete Data"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /><Buttonandroid:id="@+id/btn_query"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Query Data"android:textAllCaps="false"android:textSize="18sp"android:textStyle="bold" /> </LinearLayout>MainActivity.java代碼:
package com.example.administrator.litepalsave;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast;import org.litepal.LitePal;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn_create, btn_add, btn_delete, btn_update, btn_query;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_create = (Button) findViewById(R.id.btn_create);btn_add = (Button) findViewById(R.id.btn_add);btn_delete = (Button) findViewById(R.id.btn_delete);btn_update = (Button) findViewById(R.id.btn_update);btn_query = (Button) findViewById(R.id.btn_query);btn_create.setOnClickListener(this);btn_add.setOnClickListener(this);btn_delete.setOnClickListener(this);btn_update.setOnClickListener(this);btn_query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_create:createDatabase();//創(chuàng)建數(shù)據(jù)庫Toast.makeText(this, "Create Database successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_add:break;case R.id.btn_delete:break;case R.id.btn_update:break;case R.id.btn_query:break;}}private void createDatabase() {LitePal.getDatabase();//通過assets中的litepal.xml文件中的信息,創(chuàng)建BookStore數(shù)據(jù)庫,并根據(jù)對象映射列表中的信息創(chuàng)建Book表}}運行程序,點擊Create Database按鈕之后,Toast提示創(chuàng)建數(shù)據(jù)庫和數(shù)據(jù)庫表成功:
為了驗證創(chuàng)建成功,我們使用adb shell 來查看具體情況:
好了,使用LitePal創(chuàng)建BookStore數(shù)據(jù)庫和創(chuàng)建Book表就完成了,
sqlite3 數(shù)據(jù)庫名? ?用來查看數(shù)據(jù)庫
.table命令? 用來查看數(shù)據(jù)庫表
.schema? 用來查看建表語句
可以看到,這里有3張表的建表語句,其中android_metadata表不用管,table_schema表是LitePal內(nèi)部使用的。我們也可以直接忽視,book表就是根據(jù)我們自定義的Book類以及類中的成員變量來自動生成的。
之前在我們使用SQLiteOpenHelper來升級數(shù)據(jù)之前,必須得先把之前的表drop掉,然后再重新創(chuàng)建才行。這其實是一個非常嚴重的一個問題,因為這樣子會造成數(shù)據(jù)的丟失,每當升級一次數(shù)據(jù)庫,之前表中的數(shù)據(jù)就全部沒有了。
當然如果你是一個非常有經(jīng)驗的程序員,也可以通過復雜的邏輯控制來避免這種情況,但是維護成本很高。而使用LitePal,這就不是什么問題了,操作也很簡單,只需要在修改內(nèi)容之后,將版本號加1就行了。
比如說我們想要向Book表中添加一個press(出版社)列,直接修改Book類中代碼,添加一個press字段即可,如下所示:
private String press;public String getPress() {return press;}public void setPress(String press) {this.press = press;}與此同時,我們還想再添加一張Category表,那么只需要新建一個Category類就可以了,代碼如下所示:
package com.example.administrator.litepalsave;public class Category {private int id;private String categoryName;private int categoryCode;public void setId(int id) {this.id = id;}public void setCategoryName(String categoryName) {this.categoryName = categoryName;}public void setCategoryCode(int categoryCode) {this.categoryCode = categoryCode;} }改完了所有我們想改的東西,只需要記得將版本號加1就行了。當然由于這里還需要添加一個新的模型類,因此也需要將它添加到映射模型列表中。修改assets中的litepal.xml代碼:
<?xml version="1.0" encoding="utf-8"?> <litepal><!--數(shù)據(jù)庫名--><dbname value="BookStore" /><!--數(shù)據(jù)庫版本--><version value="2" /><!--映射模型列表--><list><mapping class="com.example.administrator.litepalsave.Book"/><mapping class="com.example.administrator.litepalsave.Category"/></list></litepal>重新運行一次程序,然后點擊Create Database按鈕,再重新查看一下最新的建表語句,發(fā)現(xiàn)如下所示:
可以看到,book表中新增了一個press列,category表也創(chuàng)建成功了,當然LitePal還自動幫我們做了一項非常重要的工作,就是保留之前表中的所有數(shù)據(jù),這樣也就再也不用擔心數(shù)據(jù)丟失的隱患了。
使用LitePal添加數(shù)據(jù)
首先回顧一下之前添加數(shù)據(jù)的方法,我們需要創(chuàng)建出一個ContentValues對象,然后將所有要添加的數(shù)據(jù)put到這個ContentValues對象當中,然后再調(diào)用SQLiteDatabase的insert()方法將數(shù)據(jù)添加到數(shù)據(jù)庫表中。
而使用LitePal來添加數(shù)據(jù),只需要創(chuàng)建出模型類的實例,再將所有要存儲的數(shù)據(jù)設置好,最后調(diào)用一下save()方法就可以了。
下面手動來實現(xiàn)一下,觀察現(xiàn)有的模型類,你會發(fā)現(xiàn)他們都是沒有繼承結(jié)構(gòu)的。沒錯,因為進行表管理操作時不需要模型類有任何的繼承結(jié)構(gòu),但是進行CRUD操作時就不行了,必須要繼承自DataSupport類才行,因此這里我們需要先把繼承結(jié)構(gòu)給加上,修改Book類中代碼,如下所示:
package com.example.administrator.litepalsave;import org.litepal.crud.DataSupport;public class Book extends DataSupport {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;} }只修改了extends? DataSupport這一句
?
MainActivity.java代碼:
package com.example.administrator.litepalsave;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast;import org.litepal.LitePal;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn_create, btn_add, btn_delete, btn_update, btn_query;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_create = (Button) findViewById(R.id.btn_create);btn_add = (Button) findViewById(R.id.btn_add);btn_delete = (Button) findViewById(R.id.btn_delete);btn_update = (Button) findViewById(R.id.btn_update);btn_query = (Button) findViewById(R.id.btn_query);btn_create.setOnClickListener(this);btn_add.setOnClickListener(this);btn_delete.setOnClickListener(this);btn_update.setOnClickListener(this);btn_query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_create:createDatabase();//創(chuàng)建數(shù)據(jù)庫Toast.makeText(this, "Create Database successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_add:addData();//添加數(shù)據(jù)Toast.makeText(this, "Add Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_delete:break;case R.id.btn_update:break;case R.id.btn_query:break;}}private void createDatabase() {LitePal.getDatabase();//通過assets中的litepal.xml文件中的信息,創(chuàng)建BookStore數(shù)據(jù)庫,并根據(jù)對象映射列表中的信息創(chuàng)建Book表}private void addData() {Book book = new Book();//創(chuàng)建Book實例book.setName("The Da Vinci Code");//設置書名book.setAuthor("Dan Brown");//設置作者book.setPages(454);//設置頁數(shù)book.setPrice(16.96);//設置價格book.setPress("Unknow");//設置出版社book.save();//保存數(shù)據(jù)} }重新運行程序,點擊Add Data按鈕,Toast提示數(shù)據(jù)添加成功:
adb shell 查看Book表中的數(shù)據(jù),輸入SQL語句:select *from Book;
或者;也可以在Device File Explorer中到/data/data/com.example.administrator.litepalsave/databases/路徑下找到BookStore.db文件,將這個文件保存到桌面,然后通過數(shù)據(jù)庫管理工具查看即可。
使用LitePal更新數(shù)據(jù)
學習完了如何使用LitePal添加數(shù)據(jù),接下來我們看看怎樣使用LitePal更新數(shù)據(jù)。更新數(shù)據(jù)要比添加數(shù)據(jù)稍微復雜一點,因為它的API接口比較多,這里我們只介紹最常用的幾種更新方式。首先,最簡單的一種更新方式就是對一存儲的對象重新設值,然后重新調(diào)用save()方法即可。那么這里我們就要了解一個概念,什么是已存儲的對象?
對于LitePal來說,對象是否已存儲就是根據(jù)調(diào)用model.isSaved()方法的結(jié)果來判斷的,返回true就表示已存儲,返回false就表示未存儲。那么接下來的問題就是,什么情況下會返回true,什么情況下會返回false呢?
實際上只有在兩種情況下model.isSaved()方法才會返回true,一種情況是已經(jīng)調(diào)用過model.save()方法去添加數(shù)據(jù)了,此時model會被認為是已存儲的對象。另一種情況是model對象是通過LitePal提供的查詢API查出來的,由于是從數(shù)據(jù)庫中查到的對象,因此也會被認為是已存儲的對象。
這里我們通過第一種情況來進行驗證。修改MainActivity.java代碼:
package com.example.administrator.litepalsave;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast;import org.litepal.LitePal;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn_create, btn_add, btn_delete, btn_update, btn_query;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_create = (Button) findViewById(R.id.btn_create);btn_add = (Button) findViewById(R.id.btn_add);btn_delete = (Button) findViewById(R.id.btn_delete);btn_update = (Button) findViewById(R.id.btn_update);btn_query = (Button) findViewById(R.id.btn_query);btn_create.setOnClickListener(this);btn_add.setOnClickListener(this);btn_delete.setOnClickListener(this);btn_update.setOnClickListener(this);btn_query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_create:createDatabase();//創(chuàng)建數(shù)據(jù)庫Toast.makeText(this, "Create Database successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_add:addData();//添加數(shù)據(jù)Toast.makeText(this, "Add Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_delete:break;case R.id.btn_update:updateData();//更新數(shù)據(jù)Toast.makeText(this, "Update Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_query:break;}}private void createDatabase() {LitePal.getDatabase();//通過assets中的litepal.xml文件中的信息,創(chuàng)建BookStore數(shù)據(jù)庫,并根據(jù)對象映射列表中的信息創(chuàng)建Book表}private void addData() {Book book = new Book();//創(chuàng)建Book實例book.setName("The Da Vinci Code");//設置書名book.setAuthor("Dan Brown");//設置作者book.setPages(454);//設置頁數(shù)book.setPrice(16.96);//設置價格book.setPress("Unknow");//設置出版社book.save();//保存數(shù)據(jù)}private void updateData() {Book book = new Book();//創(chuàng)建Book實例book.setPrice(14.95);//設置價格book.setPress("Anchor");//設置出版社book.updateAll("name=? and author=?", "The Da Vinci Code", "Dan Brown");} }點擊Update Data按鈕,Toast提示成功更新數(shù)據(jù):
使用adb shell查看更新后的數(shù)據(jù)情況
更新前Book表中的數(shù)據(jù):
更新后Book表中的數(shù)據(jù):
?
意料之中,書名為"The Da Vinci Code",作者為"Dan Brown"的這本書的價格由16.96修改成14.95.怎么樣?LitePal的更新API是不是明顯比SQLiteDatabase的update()方法要好用多了?
不過,在使用updateAll()方法時,還有一個非常重要的知識點是你需要知曉的,就是當你想把一個字段的值更新成默認時,是不可以使用上面的方式來set數(shù)據(jù)的。我們都知道,在Java中任何一種數(shù)據(jù)類型的字段都會有默認值,例如int類型的默認值為0,boolean類型的默認值是false,String類型的默認值為null。那么當new出一個Book對象時,其實所有字段都已經(jīng)被初始化成默認值了,比如說pages字段的值就是0,。因此,如果我們想把數(shù)據(jù)庫表中的pages列更新成0,直接調(diào)用book.setPages(0)是不可以的,因為即使不調(diào)用這行代碼,pages字段本身也是0,LitePal此時是不會對這個列進行更新的。對于所有想要將為數(shù)據(jù)更新成默認值的操作,LitePal統(tǒng)一提供了一個setDefault()方法,然后傳入相應的列名就可以實現(xiàn)了。比如我們可以這樣寫:
Book?book=new Book();book.setToDefault("pages");book.updateAll();這段代碼的意思是,將所有的頁數(shù)都更新為0,因此updateAll()方法中沒有指定約束條件,因此更新操作對所有數(shù)據(jù)都生效了。
使用LitePal刪除數(shù)據(jù)
使用LitePal刪除數(shù)據(jù)的方式主要有兩種,第一種比較簡單,就是直接調(diào)用已存儲對象的delete()方法就可以了,第二種就是直接通過DataSupport類調(diào)用deleteAll()靜態(tài)方法來刪除數(shù)據(jù):
例如我們將Book表中pages<500頁的書給刪除就可以這樣子寫:
DataSupport.deleteAll(Book.class, "pages < ?", "500");MainActivity.java代碼:
package com.example.administrator.litepalsave;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast;import org.litepal.LitePal; import org.litepal.crud.DataSupport;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button btn_create, btn_add, btn_delete, btn_update, btn_query;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_create = (Button) findViewById(R.id.btn_create);btn_add = (Button) findViewById(R.id.btn_add);btn_delete = (Button) findViewById(R.id.btn_delete);btn_update = (Button) findViewById(R.id.btn_update);btn_query = (Button) findViewById(R.id.btn_query);btn_create.setOnClickListener(this);btn_add.setOnClickListener(this);btn_delete.setOnClickListener(this);btn_update.setOnClickListener(this);btn_query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_create:createDatabase();//創(chuàng)建數(shù)據(jù)庫Toast.makeText(this, "Create Database successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_add:addData();//添加數(shù)據(jù)Toast.makeText(this, "Add Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_delete:deleteData();//刪除數(shù)據(jù)Toast.makeText(this, "Delete Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_update:updateData();//更新數(shù)據(jù)Toast.makeText(this, "Update Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_query:break;}}private void createDatabase() {LitePal.getDatabase();//通過assets中的litepal.xml文件中的信息,創(chuàng)建BookStore數(shù)據(jù)庫,并根據(jù)對象映射列表中的信息創(chuàng)建Book表}private void addData() {Book book = new Book();//創(chuàng)建Book實例book.setName("The Da Vinci Code");//設置書名book.setAuthor("Dan Brown");//設置作者book.setPages(454);//設置頁數(shù)book.setPrice(16.96);//設置價格book.setPress("Unknow");//設置出版社book.save();//保存數(shù)據(jù)}private void updateData() {Book book = new Book();//創(chuàng)建Book實例book.setPrice(14.95);//設置價格book.setPress("Anchor");//設置出版社book.updateAll("name=? and author=?", "The Da Vinci Code", "Dan Brown");}private void deleteData() {DataSupport.deleteAll(Book.class, "pages < ?", "500");}}點擊Delete Data按鈕,Toast提示刪除數(shù)據(jù)成功:
adb shell查看
刪除前Book表中的數(shù)據(jù):
刪除后Book表中的數(shù)據(jù):
可以看到,我們將Book表中pages<500頁的書給刪除了。
使用LitePal查詢數(shù)據(jù)
之前的查詢數(shù)據(jù)我們都是通過SQLiteDatabase中的query()方法來查詢數(shù)據(jù)的,冗長的參數(shù)列表讓人看得頭疼,即使多數(shù)參數(shù)都用不到,也不得不傳入null,如下所示:
Cursor cursor=db.query("Book",null,null,null,null,null,null);像這樣的代碼恐怕是沒人會喜歡的。為此LitePal在查詢API方面做出了非常多的優(yōu)化,基本上可以滿足絕大多數(shù)場景的查詢需求,并且代碼十分整潔,下面我們就來一起學習一下。
首先分析一下上述代碼,query()方法中使用了第一個參數(shù)指明了查詢哪張表中的數(shù)據(jù),后面的參數(shù)全部為null,這就表示希望查詢這張表中的所有數(shù)據(jù)。那么使用LitePal如何完成同樣的功能呢?非常簡單,只需要這樣寫:
List<Book> books=DataSupport.findAll(Book.class);怎么樣,代碼是不是精簡了許多,沒有冗長的參數(shù)列表,只需要調(diào)用DataSupport類中的findAll()靜態(tài)方法,然后通過Book.class參數(shù)指定查詢Book表就可以。另外,findAll()方法的返回值是一個Book類型的List集合,也就是說,我們不用像之前那樣再通過Cursor對象一行行去取值,再放入集合中。LitePal已經(jīng)幫我們完成了賦值操作。
下面通過一個完整的例子來實踐一下吧,修改MainActivity.java中的代碼:
package com.example.administrator.litepalsave;import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast;import org.litepal.LitePal; import org.litepal.crud.DataSupport;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private static final String TAG = "MainActivity";private Button btn_create, btn_add, btn_delete, btn_update, btn_query;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();//初始化UI控件}private void initView() {btn_create = (Button) findViewById(R.id.btn_create);btn_add = (Button) findViewById(R.id.btn_add);btn_delete = (Button) findViewById(R.id.btn_delete);btn_update = (Button) findViewById(R.id.btn_update);btn_query = (Button) findViewById(R.id.btn_query);btn_create.setOnClickListener(this);btn_add.setOnClickListener(this);btn_delete.setOnClickListener(this);btn_update.setOnClickListener(this);btn_query.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.btn_create:createDatabase();//創(chuàng)建數(shù)據(jù)庫Toast.makeText(this, "Create Database successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_add:addData();//添加數(shù)據(jù)Toast.makeText(this, "Add Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_delete:deleteData();//刪除數(shù)據(jù)Toast.makeText(this, "Delete Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_update:updateData();//更新數(shù)據(jù)Toast.makeText(this, "Update Data successfully", Toast.LENGTH_SHORT).show();break;case R.id.btn_query:queryData();//查詢數(shù)據(jù)Toast.makeText(this, "Query Data successfully", Toast.LENGTH_SHORT).show();break;}}private void createDatabase() {LitePal.getDatabase();//通過assets中的litepal.xml文件中的信息,創(chuàng)建BookStore數(shù)據(jù)庫,并根據(jù)對象映射列表中的信息創(chuàng)建Book表}private void addData() {Book book = new Book();//創(chuàng)建Book實例book.setName("The Da Vinci Code");//設置書名book.setAuthor("Dan Brown");//設置作者book.setPages(454);//設置頁數(shù)book.setPrice(16.96);//設置價格book.setPress("Unknow");//設置出版社book.save();//保存數(shù)據(jù)}private void updateData() {Book book = new Book();//創(chuàng)建Book實例book.setPrice(14.95);//設置價格book.setPress("Anchor");//設置出版社book.updateAll("name=? and author=?", "The Da Vinci Code", "Dan Brown");}private void deleteData() {DataSupport.deleteAll(Book.class, "pages < ?", "500");}private void queryData() {List<Book> books = DataSupport.findAll(Book.class);//獲取Book表中數(shù)據(jù),并且放入一個List集合//增強for遍歷集合數(shù)據(jù),并且打印for (Book book : books) {Log.e(TAG, "book name is " + book.getName());Log.e(TAG, "book author is " + book.getAuthor());Log.e(TAG, "book pages is " + book.getPages());Log.e(TAG, "book price is" + book.getPrice());Log.e(TAG, "book press is " + book.getPress());}}}運行程序之后先點擊一下Add Data按鈕,因為我們剛剛把數(shù)據(jù)給刪除了,所以這里先添加數(shù)據(jù),然后再點擊Query Data按鈕來查詢數(shù)據(jù)。
因Book表中只有一條數(shù)據(jù),所以我們只能查出這一條,如果有很多條其實都可以查出來的。
除了findAll()方法之外,LitePal還提供了很多其他非常有用的查詢API。
比如我們想要查詢Book表中的第一條數(shù)據(jù)就可以這樣子寫:
Book firstBook=DataSupport.findFirst(Book.class);查詢Book表中的最后一條數(shù)據(jù)就可以這樣寫:
Book lastBook=DataSupport.findLast(Book.class);我們還可以通過連綴查詢來定制更多的查詢功能。
select()方法用于指定查詢哪幾列的數(shù)據(jù),對應了SQL當中的select關(guān)鍵字。比如只查name和author這兩列的數(shù)據(jù),就可以這樣子寫:
List<Book> books=DataSupport.select("name","author").find(Book.class);where()方法用于指定查詢的約束條件,對應了SQL當中的where關(guān)鍵字。比如只查頁數(shù)大于400的數(shù)據(jù),就可以這樣子寫:
List<Book> books=DataSupport.where("pages > ?","400").find(Book.class);order()方法用于指定結(jié)果的排序方式,對應了SQL當中的order by關(guān)鍵字。比如將查詢結(jié)果按照書價從高到低排序,就可以這樣子寫:
List<Book> books=DataSupport.order("price desc").find(Book.class);其中desc表示降序排列,asc或者不寫表示升序排列。
limit()方法用于指定查詢結(jié)果的數(shù)量,比如只查表中的前3條數(shù)據(jù),就可以這樣子寫:
List<Book> books=DataSupport.limit(3).find(Book.class);offset()方法用于指定查詢結(jié)果的偏移量,比如查詢表中的第2條、第3條、第4條數(shù)據(jù),就可以這樣寫:
List<Book> books=DataSupport.limit(3).offset(1).find(Book.class);由于limit(3)查詢到的是前3條數(shù)據(jù),這里我們再加上offset(1)進行一個位置的偏移,就能實現(xiàn)查詢第2條、第3條、第4條的功能了。limit()和offset()方法共同對應了SQL當中的limit關(guān)鍵字。
當然,你還可以對這5個方法進行任意的連綴組合,來完成一個比較復雜的查詢操作:
List<Book> books=DataSupport.select("name","author","pages")
.where("pages > ?","400")
.order("pages")
.limit(10)
.offset(10)
.find(Book.class);
?
?
總結(jié)
以上是生活随笔為你收集整理的使用LitePal操作数据库(CRUD增删改查) 项目已上传GitHub的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1897年最早的银行
- 下一篇: (调用系统电话薄)运行时权限的基本使用