参考书籍:Android第一行代码(第二版).郭霖著
LitePal是一款开源的Android数据库框架,采用对象关系映射(ORM)模式,将开发常用的数据库功能进行封装,不用编写SQL语句就可完成各种建表增删查改操作。项目主页上有详细使用文档:https://github.com/LitePalFramework/LitePal
1、配置LitePal(Android Studio) 现在大多数的开源项目都会提交到jcenter上,所以只需在app/build.gradle文件中声明该开源库的引用就可以了: compile ‘org.litepal.android:core:1.5.1’ 前面部分固定,1.5.1为版本号(最新的去LitePal项目主页上查看)。 接下来需配置litepal.xml文件。右键app/src/main目录->New->Directory,创建一个assets目录,在其中新建一个litepal.xml文件,编辑其中内容:
<?xml version="1.0" encoding="utf-8"?> <litepal> <dbname value="BookStore" /> <version value="1" /> <list> </list> </litepal>指定数据库名、数据库版本号,指定所有映射模型。 最后需配置LitePalApplication,修改AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.jojo.litepaltest"> <application **android:name="org.litepal.LitePalApplication"** android:allowBackup="true" 。。。将项目的application配置为org.litepal.LitePalApplication,才能让LitePal的所有功能正常工作。
2、创建升级数据库
实现与DatabaseTest同样的功能。先将activity_main.xml文件从DatabaseTest项目复制过来。 对象关系映射:将面向对象的语言(我们使用的编程语言)和面向关系的数据库(关系型数据库)之间建立一种映射关系。此模式可以让我们用面向对象的思维操作数据库,不用和SQL语句打交道。 定义一个Book类:
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 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 getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getName() { return name; } public void setName(String name) { this.name = name; } }典型的JavaBean(一段特殊的Java类:有无参构造方法,只有get、set方法的Java类对象)。Book类对应Book表,类中每个字段对应表中每个列(对象关系映射)。 需将Book类添加到映射模型列表中,修改litepal.xml:
<litepal> <dbname value="BookStore" /> <version value="1" /> <list> <mapping class="com.example.jojo.litepaltest.Book"/> </list> </litepal>声明配置的映射模型类,使用完整类名。 所有工作完成,只要进行任意一次数据库操作,BookStore.db数据库就会自动创建出来。修改MainActivity:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button createDatabase = (Button) findViewById(R.id.create_database); createDatabase.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Connector.getDatabase(); } }); } }运行程序,点击创建按钮,通过adb shell查看情况。 打开数据库,通过.schema查看建表语句,有三张表的建表语句,前两张都是内部表不用管。 之前使用SQLiteOpenHelper升级数据库,需要把之前的表drop掉再重新创建(造成数据丢失,升级一次,之前表中数据全丢),可通过复杂逻辑控制避免此问题但维护成本很高。使用LitePal只需修改想改的内容,将版本号加1即可。 如向Book中添加press(出版社)心裂,直接修改该Book类,添加press字段及相应get\set方法即可。同时添加一张Category表,只需创建此类即可:
public class Category { private int id; private String categoryName; private int categoryCode; public void setId(int id) { this.id = id; } public int getId() { return id; } public void setCategoryCode(int categoryCode) { this.categoryCode = categoryCode; } public int getCategoryCode() { return categoryCode; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } public String getCategoryName() { return categoryName; } }将其添加到映射模型列表中,将版本号加1:
<litepal> <dbname value="BookStore" /> <version value="2" /> <list> <mapping class="com.example.jojo.litepaltest.Book"/> <mapping class="com.example.jojo.litepaltest.Category"/> </list> </litepal>重新运行程序,点击创建按钮,查看建表语句:
LitePal会自动保留之前表中的所有数据。
3、添加数据
只需创建出模型类实例,将所有要存储的数据设置好,最后调用一下save()方法就可以了。 现有模型类都没有继承结构(LitePal进行表管理操作时不需要模型类有任何继承结构),但进行CRUD操作必须要继承自DataSupport类才行,所以需给现有类加上此继承:
public class Book extends DataSupport{
向Book中添加数据,修改主程序:
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("The Da Vinci Code"); book.setAuthor("Dan Brown"); book.setPages(454); book.setPrice(16.96); book.setPress("Unknow"); book.save();//从DataSupport类中继承的方法,其中提供了丰富的CRUD方法 } });运行程序,点击添加按钮,查看数据库:
4、更新数据
几种常用更新方式。
最简单的一种:对已存储的对象重新设值,重新调用save()即可。对象是否已存储根据model.isSaved()方法结果判断(两种情况下返回true:已经调用model.save()添加数据了;model对象是通过LitePal提供的查询API查出来的)。先通过第一种情况验证,修改主程序:
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("The Lost Symbol"); book.setAuthor("Dan Brown"); book.setPages(510); book.setPrice(19.95); book.setPress("Unknow"); book.save();//从DataSupport类中继承的方法,其中提供了丰富的CRUD方法 book.setPrice(10.99); book.save(); } });先存后改。运行程序,点击更新按钮,查看结果。 改动生效。这种更新方式只能对已储存的对象进行操作,限制性比较大。另一种更灵巧的方式,修改主程序:
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(14.95); book.setPress("Anchor"); book.updateAll("name = ? and author = ?", "The Lost Symbol", "Dan Brown"); // 如不指定条件语句,则更新所有数据 } });重新运行程序。 在使用updateAll()时,当想把字段的值更新成默认值时不可使用上面的方式来set数据的(Java中任何一种数据类型字段都会有默认值,new出一个Book对象时,所有字段已被初始化成默认值)。LitePal同意提供了setToDefault()方法,传入相应列名即可实现。如: Book book = new Book(); book.setToDefault(“pages”); book.updateAll();
5、删除数据 主要有两种方法:第一种也是直接调用已存储对象的delete()方法(与更新中的第一种方法类似)。 另一种,修改主程序:
Button deleteData = (Button) findViewById(R.id.delete_data); deleteData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DataSupport.deleteAll(Book.class, "price < ?", "15");//不指定约束条件,则删除所有数据 } });运行程序,点击删除按钮,查看结果:
价格低于设置值的那本书已被删除。
6、查询数据
如果希望查询这张表的所有数据。使用LitePal只需这样写: List books = DataSupport.findAll(Book.class); findAll()方法返回的是Book类型的List集合,自动完成了赋值操作。 修改主程序:
Button queryData = (Button) findViewById(R.id.query_data); queryData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { List<Book> books = DataSupport.findAll(Book.class); for (Book book : books){ Log.d("MainActivity", "book name is " + book.getName()); Log.d("MainActivity", "book author is " + book.getAuthor()); Log.d("MainActivity", "book pages is " + book.getPages()); Log.d("MainActivity", "book price is " + book.getPrice()); Log.d("MainActivity", "book press is " + book.getPress()); } } });运行程序,点击查询按钮。
其他查询API: 查询Book表中第一条数据: Book firstBook = DataSupport.findFirst(Book.class); 最后一条: Book lastBook = DataSupport.findLast(Book.class); 通过连缀查询定制更多功能: select()方法指定查询那几列数据,如: List books = DataSupport.select(“name”, “author”).find(Book.class); where()指定查询约束条件,如: List books = DataSupport.where(“pages > ?”, “400”).find(Book.class); order()指定结果的排序方式(默认asc升序),如: List books = DataSupport.order(“price desc”).find(Book.class); limit()指定查询结果数量(行): List books = DataSupport.limit(3).find(Book.class); offset()指定查询结果偏移量,如查询第2、3、4条数据: List books = DataSupport.limit(3).offset(1).find(Book.class); 还可以对着5个方法进行任意连缀组合,形成复杂查询操作: List books = DataSupport.select(“name”, “author”, “pages”).where(“pages > ?”, “400”).order(“pages”).limit(10).offset(10).find(Book.class);
LitePal仍然支持使用原生的SQL进行查询: Cursor c = DataSupport.findBySQL(“select * from Book where pages > ? and price < ?”, “400”, “20”); findBySQL返回的是cursor对象,需将数据一一取出。