下载什么的,环境配置什么的,就不说了。
输入 :su 获得超级管理员权限
cd /data/data/com.example.项目名称/databases
查看数据库文件,一般出现两个,一个是我们自己创建了的数据库文件,一个是数据文件支持的日志文件。
进入数据库
.table 查看表
.schema 查看创建语句0
select * from …
之前书上讲了Sqlite,我觉得Litepal用的更舒服一点
作者为什么要推荐写LitePal呢,大概是因为他是LitePal的作者把,那个好用,这个仁者见仁智者见智,适合就好。
我们需要在app/build.gradle文件的dependencies闭包中添加:
implementation 'org.litepal.android:core:2.0.0'
后面是版本号我用的2.0.0,现在有3.0.0 。
最新的可以到github上去看。
我不用3.0.0是因为,3.0中创建数据库LitePal.getDatabase();这个方法用不了,我看了github也没找到解决办法。
书上写的是 compile 现在它已经被抛弃,是个孤儿,现在都用implementation了。
< dbname > 指定数据库名称
< version > 指定数据库版本号
< list > 指定所有的映射模型
android:name=“org.litepal.LitePalApplication”
就是加几个CRUD的按钮!
定义一个Book类
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 void setPress(String press) {
this.press = press;
}
public String getPress() {
return press;
}
public int getId() {
return id;
}
public String getAuthor() {
return author;
}
public double getPrice() {
return price;
}
public int getPages() {
return pages;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setAuthor(String author) {
this.author = author;
}
public void setPrice(double price) {
this.price = price;
}
public void setPages(int pages) {
this.pages = pages;
}
public void setName(String name) {
this.name = name;
}
}
接下来将Book类添加到映射模型列表中,修改litepal.xml中的代码如下
< mapping >声明我们要配置的映射模型类
在MainActivity中这样写
@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 view) {
LitePal.getDatabase();
}
});
}
点击Button (cretaDatabase)调用LitePal.getDatabase()方法
就会创建数据库了
在adb中查看如下
这里我们再加一张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中修改
要进行改变数据的话,要记得把version版本号加1
LitePal进行表管理操作时不需要模型类有任何的继承结构,但是进行CRUD操作是就不行了,必须要继承LitePalSupport。书上继承的是DataSupport,这个已经被抛弃了,DataSupport也是一个孤儿。
public class Book extends LitePalSupport {
..........
}
然后来修改Button(addData)
Button addData=(Button)findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
Book book=new Book();
book.setName("The Da Vinci Code");
book.setAuthor("Dan Brown");
book.setPages(454);
book.setPrice(16.96);
book.setPress("Unknown");
book.save();
}
});
首先是创建了一个Book的实例,然后调用Book类中的各种set方法对其进行设置,最后在调用book.save()方法,这个方法是继承来的。
对于Litepal来说,对象是否已存储就是根据调用model.isSaved()方法的结果来判断的,返回true表示已存储,false就是为存储。
当用过modle.save()方法,此时model就会被认为是已存储了的
Button updateData=(Button)findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
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();
}
});
这里就是只会将19.95改成10.99,而不会去创建新的对象了,因为LitePal会发现当前的book对象是已存储了的。
Button updateData=(Button)findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
Book book=new Book();
book.setPrice(14.95);
book.setPress("Anchor");
book.updateAll("name = ? and author = ?","The Lost Symbol","Dan Brown");
}
});
1)我们首先new一个Book的实例,然后直接调用setPrice和setPress方法来设置更新的数据,最后在调用updateAll()方法去执行更新操作。
2)updateAll方法中可以指定约束条件和sql中where差不多,如果不指定约束条件的话,就表示更新所有数据。
3)这里我们指定将所有书名是The Lost Symbol并且作者是Dan Brown的书的价格更新为14.95,出版社更行为Anchor
不过,在使用updateAll()方法时,还有一个非常重要的知识点是你需要知晓的,就是当你想把一个字段的值更新成默认值时,是不可以使用上面的方式来set数据的。我们都知道,在Java中任何一种数据类型的字段都会有默认值,例如int类型的默认值是0,boolean类型的默认值是false,String类型的默认值是null。那么当new出一个Book对象时,其实所有字段都已经被初识化成默认值了,比如说pages字段的值就是0。因此,如果我们想把数据库表中的pages列更新成0,直接调用book.setpages(0)是不可以的,因为即使不调用这行代码,pages字段本身也是0,Litepal此时是不会对这个列进行更新的。对于所有想要将为数据更新成默认值的操作,Litepal统一提供了一个setToDefault()方法,然后传入相应的列名就可以实现了。
比如我们可以这样写
Book book=new Book();
book.setToDefault("Pages");
book.updateAll();
这段代码的意思是,将所有书的页数都更新为0,因为updateAll()方法中没有指定约束条件,因此更新操作对所有数据都有效。
第一种比较简单,就是调用存储对象的delete方法就好了。
LitePal.delete(这里写参数)
看一下delete的原码
This means that the record 1 in person table will be removed.
*
* @param modelClass
* Which table to delete from by class.
* @param id
* Which record to delete.
* @return The number of rows affected. Including cascade delete rows.
*/
public static int delete(Class> modelClass, long id) {
synchronized (LitePalSupport.class) {
int rowsAffected = 0;
SQLiteDatabase db = Connector.getDatabase();
db.beginTransaction();
try {
DeleteHandler deleteHandler = new DeleteHandler(db);
rowsAffected = deleteHandler.onDelete(modelClass, id);
db.setTransactionSuccessful();
return rowsAffected;
} finally {
db.endTransaction();
}
}
}
我们来看另一种方式
Button deleteButton=(Button)findViewById(R.id.delete_data);
deleteButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
LitePal.deleteAll(Book.class,"price < ?","15");
}
});
书上写的是DataSupport现在已经被抛弃了是个孤儿,现在大家都喜欢用LitePal
LitePal.deleteAll(Book.class,“price < ?”,“15”);
指定删除Book表中price<15的数据
我们看一下效果:
看小于15的数据已经被删除了
Button queryButton=(Button) findViewById(R.id.query_data);
queryButton.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
List books= LitePal.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());
}
}
});
LitePal.findAll(Book.class);返回的是一个List对象,LitePal已经帮我们完成么赋值操作
除了findAll方法 Litepal还有许多其他的查询API
查询Book表中第一条数据:
Book firstBook=LitePal.findFirst(Book.class);
查询Book表中最后一条数据:
Book lastBook=LitePal.findLast(Book.class);
select()方法用于指定查询哪几列的数据,对应了SQL当中的select关键字。比如只查name和author着两列的数据
List books=LitePal.select("name","author").find(Book.class);
where()方法用于指定查询的约束条件,对应了SQL当中的where关键字。比如只查页数大于400的数据
List books=LitePal.where("pages > ?","400").find(Book.class);
order()方法用于指定结果的排序方式,对应了SQL当中的order by关键字。比如将查询结果按照书价从高到低排序
List books=LitePal.order("price desc").find(Book.class);
limit()方法用于指定查询结果的数量。比如只查表中的前3条数据
List books=LitePal.limit(3).find(Book.class);
offset()方法用于指定查询结果的偏移量。比如查询表中的第2条,第3条,第4条数据
List books=LitePal.limit(3).offset(1).find(Book.class);
对这5个方法综合运用
List books=LitePal.select("name","author","pages")
.where("pages > ?","400")
.roder("pages")
.limit(10)
.offset(10)
.find(Book.class);
LitePal中也可以用sql
使用LitePal.findBySQL()方法 返回一个Cursor游标对象,然后用Sqlite的方法去访问,这边我就不讲了,有兴趣百度去吧。