05-轻松玩转Android数据库框架
现在有的项目开发中,不可避免的使用到数据库框架,不用自己手写SQL语句,可以直接将对象映射到SQLite数据库中。本文介绍的greenDao、LitePal就是轻量且快速的ORM解决方案,大大提升了我们的开发效率,滴滴滴,开车。
一、greenDao使用指南
greenDAO的github地址:
https://github.com/greenrobot/greenDAO
1、需要在AS中配置一下,才能进行使用
首先gradle引入
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
}
接着在项目root的build.gradle加入
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
最后在app的build.gradle加入:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
greendao {
// 当前数据库结构的版本
schemaVersion 1
//生成的DAO,DaoMaster和DaoSession的包名。默认是实体的包名
daoPackage 'com.greendao.gen'
//生成源文件的路径。默认源文件目录是在build目录中的(build/generated/source/greendao)
targetGenDir 'src/main/java'
}
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
// This is only needed if you want to use encrypted databases
//需要加密的时候才引用
compile 'net.zetetic:android-database-sqlcipher:3.5.6'
}
配置完成后,在AS->build->Make Project后,框架会在targetGenDir 的路径下自动生成使用到的文件。
2、配置完成户即可进行开发工作
新建一个实体类:
@Entity
public class Message {
@Id
private Long id;
private String msg;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
新建的实体类,框架会帮我们自动生成MessageDao类
那么接下来我们该如何使用这个MessageDao类呢?
我们可以再全局类中定义一个DaoSession实体,通过这个DaoSession对象去拿各个实体Dao的实例,从而进行相应的操作,具体看代码:
public class App extends Application {
/** A flag to show how easily you can switch from standard SQLite to the encrypted SQLCipher. */
public static final boolean ENCRYPTED = true;
private DaoSession daoSession;
@Override
public void onCreate() {
super.onCreate();
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, ENCRYPTED ? "notes-db-encrypted" : "notes-db");
Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb();
daoSession = new DaoMaster(db).newSession();
}
public DaoSession getDaoSession() {
return daoSession;
}
}
接着在需要使用的地方拿到Dao实例
MessageDao mDao = ((App) getApplication()).getDaoSession().getMessageDao();
添加
mDao.insert(Message)
查找
查询全部数据
List<Message> msgList = mDao.loadAll();
查询一条数据
Message msg= mDao.queryBuilder().where(UserDao.Properties.id.eq(888)).unique();
删除
根据条件删除 举例:比如删除id小于或等于6的数据,删除首先得查找
List<Message> msgList = (List<Message>) mDao.queryBuilder().where(MessageDao.Properties.Id.le(6)).build().list();
for (Message msg: msgList) {
mDao.delete(msg);
}
根据主键删除
mDao.deleteByKey(id);
删除所有数据
mDao.deleteAll();
修改
mDao.update(Message)
数据库升级
修改schemaVersion 2
重新make project下就行
3、介绍greenDao中的一些注解,方便开发
实体注解:
@Entity(
// 如果项目中有超过一个的数据库结构,可以通过这个字段来区分
// 该实体属于哪个数据库结构
//一般一个用对就对应一个
schema = "curschema",
// 实体是否激活的标志,激活的实体有更新,删除和刷新的方法
active = true,
// 确定数据库中表的名称
// 表名称默认是实体类的名称
nameInDb = "table_message",
// Define indexes spanning multiple columns here.
indexes = {
@Index(value = "name DESC", unique = true)
},
// DAO是否应该创建数据库表的标志(默认为true)
// 如果你有多对一的表,将这个字段设置为false
// 或者你已经在GreenDAO之外创建了表,也将其置为false
createInDb = false
)
基础属性注解
@Id :主键 Long型,可以通过@Id(autoincrement = true)设置自增长
@Property:设置一个非默认关系映射所对应的列名,默认是的使用字段名 举例:@Property (nameInDb="name")
@NotNull:设置数据库表当前列不能为空
@Transient :添加次标记之后不会生成数据库表的列
索引注解
@Index:使用@Index作为一个属性来创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束
@Unique:向数据库列添加了一个唯一的约束
关系注解
@ToOne:定义与另一个实体(一个实体对象)的关系
@ToMany:定义与多个实体对象的关系
好了,关于greenDao先介绍到这里,这个库针对android系统进行了优化,内存开销小,API也易于使用,大家自行去研究使用吧。
一、LitePal使用指南
LitePal的github地址:
https://github.com/LitePalFramework/LitePal
1、gradle引入,最新版本,到github上自行查看
dependencies {
compile 'org.litepal.android:core:1.5.1'
}
2、在assets 文件夹中新建并且配置litepal.xml文件
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<!--
Define the database name of your application.
By default each database name should be end with .db.
If you didn't name your database end with .db,
LitePal would plus the suffix automatically for you.
For example:
<dbname value="demo" />
-->
<dbname value="demo" />
<!--
Define the version of your database. Each time you want
to upgrade your database, the version tag would helps.
Modify the models you defined in the mapping tag, and just
make the version value plus one, the upgrade of database
will be processed automatically without concern.
For example:
<version value="1" />
-->
<version value="1" />
<!--
Define your models in the list with mapping tag, LitePal will
create tables for each mapping class. The supported fields
defined in models will be mapped into columns.
For example:
<list>
<mapping class="com.test.model.Reader" />
<mapping class="com.test.model.Magazine" />
</list>
-->
<list>
</list>
<!--
Define where the .db file should be. "internal" means the .db file
will be stored in the database folder of internal storage which no
one can access. "external" means the .db file will be stored in the
path to the directory on the primary external storage device where
the application can place persistent files it owns which everyone
can access. "internal" will act as default.
For example:
<storage value="external" />
-->
</litepal>
3、配置LitePalApplication,可以继承LitePalApplication
public class MyApplication extends LitePalApplication{
@Override
public void onCreate() {
super.onCreate();
LitePal.initialize(this);
}
...
}
配置完成后,即可开始开发工作了,滴滴滴。
1、创建实体类,对应数据库中的表,必须继承DataSupport
public class Album extends DataSupport {
@Column(unique = true, defaultValue = "unknown")
private String name;
private float price;
private byte[] cover;
private List<Song> songs = new ArrayList<Song>();
// generated getters and setters.
...
}
public class Song extends DataSupport {
@Column(nullable = false)
private String name;
private int duration;
@Column(ignore = true)
private String uselessField;
private Album album;
// generated getters and setters.
...
}
实体类需要在litepal.xml中配置
<list>
<mapping class="org.litepal.litepalsample.model.Album" />
<mapping class="org.litepal.litepalsample.model.Song" />
</list>
2、数据库操作
添加
Album album = new Album();
album.setName("album");
album.setPrice(10.99f);
album.setCover(getCoverImageBytes());
album.save();
查找
根据id查找
Song song = DataSupport.find(Song.class, id);
查找所有
List<Song> allSongs = DataSupport.findAll(Song.class);
条件查找
List<Song> songs = DataSupport.where("name like ?", "song%").order("duration").find(Song.class);
删除
根据id删除
DataSupport.delete(Song.class, id);
根据条件删除
DataSupport.deleteAll(Song.class, "duration > ?" , "350");
修改
查找后修改
Album albumToUpdate = DataSupport.find(Album.class, 1);
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.save();
根据id直接修改
Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.update(id);
根据条件修改
Album albumToUpdate = new Album();
albumToUpdate.setPrice(20.99f); // raise the price
albumToUpdate.updateAll("name = ?", "album");
数据库异步操作
findAllAsync异步查找数据库,结果在onFinish中返回
DataSupport.findAllAsync(Song.class).listen(new FindMultiCallback() {
@Override
public <T> void onFinish(List<T> t) {
List<Song> allSongs = (List<Song>) t;
}
});
异步存储数据
Album album = new Album();
album.setName("album");
album.setPrice(10.99f);
album.setCover(getCoverImageBytes());
album.saveAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
}
});
litePal是郭霖郭神写的开源框架,大家有兴趣可以看源码进行学习学习。
总结
除了这两个框架,还有其它框架比如ormLite,Realm等,个人认为这两个框架比较好用,老司机们可以搞起了。框架只是方便开发,提升效率,要想提升能力,不能一味的使用框架,需要自己去了解实现原理,当然数据库知识也是基础,也不能不懂吧。不过作为一名砖家,赶紧完成搬砖要紧,后面有时间有兴趣,再去了解!