本文目录:
1. 配置Litepal
2. 创建数据库
3. 升级数据库
4. 添加数据
5. 更新数据
6. 删除数据
7. 查询数据
分割线
(内容来自《Android第一行代码(第二版)》)
介绍:
作为一款开源的Android数据库框架,它采用对象关系映射
(ORM)的模式,并将我们平时开发最常用的一些数据库功能进行了封装,使得不用编写一行SQL语句就能完成各种数据库操作。
1. 配置Litepal
-
添加此开源库的
引用声明
在app/build.gradle
文件中的dependencies
闭包中添加内容compile 'org.litepal.android:core:1.3.2'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'org.litepal.android:core:1.3.2'
}
-
配置litepal.xml文件
在main目录下新建assets
目录,并在其下新建一个litepal.xml
文件
<!--litepal.xml文件-->
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="BookStore" ></dbname>
<version value="1" ></version>
<list></list>
</litepal>
<dbname>
标签用于指定数据库名;
<version>
标签用于指定数据库版本号;
<list>
标签用于指定所有映射模型
-
修改AndroidMainfest.xml文件
application配置为android:name="org.litepal.LitePalApplication
<?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: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>
2. 创建数据库
开始之前:关于activity_main.xml
文件,我们这里直接复用上一篇文章里的activity_main.xml文件代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/create_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create database"/>
<Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add data"/>
<Button
android:id="@+id/update_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Update data" />
<Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete data"/>
<Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query data" />
</LinearLayout>
对象关系映射模式使我们可以利用面向对象思维来操作数据库,这里为了定义一张Book表,我们定义一个Book类
- 定义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 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;
}
}
Book类中每个字段对应了表中的每一个列
-
修改litepal.xml文件
加入<mapping class="com.example.litepaltest.Book"></mapping>
<mapping>标签用来声明我们要配置的映射模型类
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="BookStore" ></dbname>
<version value="1" ></version>
<list>
<mapping class="com.example.litepaltest.Book"></mapping>
</list>
</litepal>
- 修改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();
}
});
}
}
Connector.getDatabase()
方法就是一次最简单的数据库操作,点击一下按钮,数据库就会自动创建完成。
3. 升级数据库
利用SQLite升级数据库时,需要先将之前的表drop掉,这样会造成数据的丢失。
接下来我们看看Litepal怎样升级数据库避免这些问题的。
例如:我们想在Book表中添加一个press(出版社)列,并想新建一张Category表
-
添加press列
直接修改Book类代码,添加一个press字段和set、get函数。
private String press;
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
-
添加Category表
只需新建一个Category类就好了
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;
}
}
-
修改litepal.xml文件
改完之后,将litepal.xml文件中version版本号加1,并加入新建的模型类Category。
<?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>
重运行程序,点击创建数据库按钮,更新操作就完成了。
4. 添加数据
- 继承DataSupport 类
对数据进行增删查改操作时模型类需要继承自DataSupport
类才行
import org.litepal.crud.DataSupport;
public class Book extends DataSupport {
}
这里我们增加以上语句让Book类继承自DataSupport 类
- 修改MainActivity代码
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();
}
});
onCreate()中添加以上代码实现添加数据功能。
这里内容很简单,创建出Book类之后调用各种set方法对数据进行设置,最后调用save()方法就完成了数据的添加。
5. 更新数据
这里介绍几种常用的更新方式
1.对已存储的对象重新设值
对于LitePal来说,对象是否已存储是根据调用model. isSaved()方法的结果来判断的
- 返回true就表示已存储
- 返回false就表示未存储
那么接下来的问题就是,什么情况下会返回true,什么情况下会返回false呢?
实际上只有在两种情况下model. isSaved()方法才会返回true
- 一种情况是已经调用过model. save()方法去添加数据了,此时model会被认为是已存储的对象。
- 另一种情况是model对象是通过LitePal提供的查询API查出来的,由于是从数据库中查到的对象,因此也会被认为是已存储的对象。
(这里我们先通过第一种情况来进行验证。)
- 修改MainActivity代码
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();
book.setPrice(10.99);
book.save();
}
});
在更新按钮点击事件里,首先添加了一条Book数据,然后调用 setPrice()方法将这本书的价格进行了修改,之后再次调用了save()方法。此时LitePal会发现当前的Book对象是已存储的,因此不会再向数据库中去添加一条新数据,而是会直接更新当前的数据。
2.更灵活的更新方式
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");
}
});
这里new出Book实例后,直接调用setPrice()和setPress()方法设置更新的数据,然后调用updateAll()方法执行更新操作。
updateAll()方法中可以指定一个条件约束,不指定的话表示更新所有数据
这里我们将书名为The Lost Symbol且作者是Dan Brown的书价格更新为14.95,出版社更新为Anchor
6. 删除数据
1.对已存储的对象删除
直接调用已存储对象的delete()方法就可以了。
也就是说,调用过save()方法的对象,或者是通过LitePal提供的查询API查出来的对象,都可以直接使用delete()方法来删除数据。
2.deleteAll()方法
- 修改MainActivity代码
Button deleteButton = (Button) findViewById(R.id.delete_data);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DataSupport.deleteAll(Book.class, "price < ?", "15");
}
});
这里调用deleteAll()
方法来删除数据,这行代码的意思是删除Book表中price小于15的书
7. 查询数据
- 修改MainActivity代码
Button queryButton = (Button) findViewById(R.id.query_data);
queryButton.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());
}
}
});
这里使用语句 List<Book> books = DataSupport.findAll(Book.class);
,就得到一个Book类型的List集合
运行程序可以看到logcat打印的内容
除了findAll()方法外,还有其他一些其他的方法用于查询:
查询第一条数据:
Book firstbook = DataSupport.findFirst(Book.class);
查询最后一条数据:
Book lastbook = DataSupport.findLast(Book.class);
连缀查询:
select():用于指定查询哪几列
List<Book> books = DataSupport.select("name","author").find(Book.class);
where():用于指定查询条件
List<Book> books = DataSupport.where("pages > ?","400").find(Book.class);
order():用于指定结果排序
List<Book> books = DataSupport.order("price desc").find(Book.class);
limit():用于指定查询结果数量
List<Book> books = DataSupport.limit(3).find(Book.class);
(查询表中前三条数据)
offset():用于指定查询结果的偏移量
List<Book> books = DataSupport.limit(3).offset(1).find(Book.class);
(查询表中第2条、第3条和第4条数据,相对前面有了一个位置的偏移)
连缀组合完成复杂查询:
查询表中第11~20条页数大于400的name和author这两列数据,并将结果按照页数升序排列
List<Book> books = DataSupport.select("name","author")
.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");
最后通过以前学习的方法将数据一一取出即可。