这是我学习的第一个开源库——LitePal。LitePal是一款开源的Android数据库框架,它采用对象关系映射(ORM)的模式,并将我们平时开发的最常用的一些数据库功能进行了封装.GitHub:Click me
他在readme.md文件中写了Quick setup。不妨看看。
首先在闭包中添加
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
compile 'org.litepal.android:core:1.5.1'
}
配置litepal.xml文件。右键app/src/main目录→New→Directory,创建一个assets目录,然后在assets目录下新建一个litepal.xml文件
new一个File→litepal.xml的文件
<litepal>
<dbname value="Bookstore2" />
<version value="1" />
<list>
list>
litepal>
This is the only configuration file, and the properties are simple.
- dbname configure the database name of project.
- version configure the version of database. Each time you want to upgrade database, plus the value here.
- list configure the mapping classes.
- storage configure where the database file should be stored. internal and external are the only valid options.
显而易见:标签用于指定数据库名,标签用于指定数据库版本号,标签用于指定所有的映射模型。
配置LitePalApplication,修改AndroidMainfest.xml:
<manifest>
<application
android:name="org.litepal.LitePalApplication"
...
>
...
application>
manifest>
配置好了。
先创建一个类继承SQLiteOpenHelper,然后在onCreate()方法来编写建表语句来实现,而使用LitePal就方便多了。
我们使用的编程语言是面向对象编程语言,而使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射。
我们可以用面向对象的四维来操作数据库。
新建Book2类
package com.example.wrjjrw.litepaltest;
import org.litepal.crud.DataSupport;
/**
* Created by wrjjrw on 2017/4/12.
*/
public class Book extends DataSupport{
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;
}
}
Tips:可以alt+insert快速补全
添加litepal.xml:
<litepal>
<dbname value = "Bookstore"> dbname>
<version value = '1'>version>
<list>
<mapping class = "com.example.wrjjrw.litepaltest.Book">mapping>
list>
litepal>
标签来声明我们要配置的映射模型类,注意一定要使用完整的类名。
xml不再贴代码了:
Button createLitepalDatabase = (Button) findViewById(R.id.create_litepal);
createLitepalDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Connector.getDatabase();
}
});
调用Connector.getDatabase()方法就是一次最简单的数据库操作,只要点击一下,就可以创建了.
若你想添加一个列(比如press),就可以直接修改Book里的代码,记得要generate他的getter和setter()函数。
如果你还想添加一张表,只需要新建一个类即可。
比如Category:
public class Category extends DataSupport{
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就可以了(别忘记了版本号。)
<litepal>
<dbname value = "Bookstore"> dbname>
<version value = '2'>version>
<list>
<mapping class = "com.example.wrjjrw.litepaltest.Book">mapping>
<mapping class="com.example.wrjjrw.litepaltest.Category" />
list>
litepal>
在MainActivity:
java
Button addData = (Button) findViewById(R.id.Lite_add_database);
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();
}
});
可以看到这样的存储数据更简单。
Button updateData = (Button) findViewById(R.id.Lite_update_database);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setAuthor("The Lost Symbol");
book.setPages(510);
book.setPress("Unknow");
book.save();
book.setPrice(19.95);
book.save();
}
});
对,没错,就这样。。。。
另外一种方式:
Button updateData = (Button) findViewById(R.id.Lite_update_database);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book();
book.setAuthor("The Lost Symbol");
book.setPages(510);
book.setPress("Unknow");
book.save();
book.setPrice(19.95);
book.save();
Book book2 = new Book();
book2.setPrice(14.95);
book2.setPress("Anchor");
book2.updateAll("name = ? and author = ?", "The Lost Symbol", "Dan Brown");
}
});
我们调用了updateAll()的方法执行更新操作。(where参数更加简洁了,但是如果不指定条件语句的话,就是默认所有数据了)
可以看看他的源码:
/**
* Updates all records with details given if they match a set of conditions
* supplied. This method constructs a single SQL UPDATE statement and sends
* it to the database.
*
*
* Person person = new Person();
* person.setName("Jim");
* person.updateAll("name = ?", "Tom");
*
*
* This means that all the records which name is Tom will be updated into
* Jim.
*
* Note: 1. If you set a default value to a field, the corresponding
* column won't be updated. Use {@link #setToDefault(String)} to update
* columns into default value. 2. This method couldn't update foreign key in
* database. So do not use setXxx to set associations between models.
*
* @param conditions
* A string array representing the WHERE part of an SQL
* statement. First parameter is the WHERE clause to apply when
* updating. The way of specifying place holders is to insert one
* or more question marks in the SQL. The first question mark is
* replaced by the second element of the array, the next question
* mark by the third, and so on. Passing empty string will update
* all rows.
* @return The number of rows affected.
*/
public synchronized int updateAll(String... conditions) {
try {
UpdateHandler updateHandler = new UpdateHandler(Connector.getDatabase());
int rowsAffected = updateHandler.onUpdateAll(this, conditions);
getFieldsToSetToDefault().clear();
return rowsAffected;
} catch (Exception e) {
throw new DataSupportException(e.getMessage(), e);
}
}
* Note: 1. If you set a default value to a field, the corresponding
* column won't be updated. Use {@link #setToDefault(String)} to update
* columns into default value. 2. This method couldn't update foreign key in
* database. So do not use setXxx to set associations between models.
有没有看到上面这句话,如果我们想把值改成默认值的话,就需要使用
book.setToDefault("pages");
book.updateAll();
上面这句话,我们更新了所有的书的页数,都是0了。
Button deleteButton = (Button) findViewById(R.id.Lite_delete_database);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DataSupport.deleteAll(Book.class, "price < ?", "15");
}
});
删除和跟新差不多是一个道理
讲道理,这里应该是最复杂的。在这里,问题就不大了。
这里只要用泛型就可以了findAll了,炒鸡方便
Button queryBotton = (Button) findViewById(R.id.Lite_query_database);
queryBotton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List books = DataSupport.findAll(Book.class);
for(Book book:books){
Log.d(Tag, "Book name is " + book.getName());
Log.d(Tag, "Book author is " + book.getAuthor());
Log.d(Tag, "Book pages is " + book.getPages());
Log.d(Tag, "Book price is " + book.getPrice());
Log.d(Tag, "Book press is " + book.getPress());
Toast.makeText(MainActivity.this, book.getName()+"costs"+book.getPrice(),
Toast.LENGTH_LONG).show();
}
}
});
除此之外还有以下语句:
Book firstBook = DataSupport.findFirst(Book.class);
Book lastBook = DataSupport.findLast(Book.class);
//只查询几列的数据
List books2 = DataSupport.select("name", "author").find(Book.class);
//指定查询的约束条件
List books3 = DataSupport.where("pages > ?", "400").find(Book.class);
//指定结果的排序 desc降序, asc或者默认即升序
List books4 = DataSupport.order("price desc").find(Book.class);
//指定查询结果的数量
List books5 = DataSupport.limit(3).find(Book.class);
// 指定结果的偏移量,比如要查询表中的第2,3,4条数据
List books6 = DataSupport.limit(3).offset(1).find(Book.class);
//将以上方法组合
List books7 = DataSupport.select("name", "author", "pages")
.where("pages > ?", "400")
.order("pages")
.limit(3)
.offset(1)
.find(Book.class);
//LitePal也同样支持原生的SQL来查询
Cursor c = DataSupport.findBySQL("select * from Book where pages > " +
"? and price < ?","400","20");
//但原生的查询也需要原生的读取,因为上面的是Cursor对象。
数据库基础知识不扎实,需要好好巩固一下。
总共有三部分知识,文件储存,IO编程不熟练
SharedPreferences存储以及数据库知识,需要勤加练习呐。。
Error:Execution failed for task ‘:app:transformClassesWithDexForDebug’.
com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lorg/litepal/LitePal;
答:依赖包重复了。
答:Click me