最近忙于项目,有差不多一个月没有写博客了,最近空闲下来,打算做一个关于Android数据库框架使用的一系列教程,把目前主流的数据库框架的使用方法以及性能对比做个总结
一、主流数据库框架
greenDao、ormlite、LitePal、Realm…等,这一系列文章就先介绍这几个数据库框架吧
二、特点
关于这几个数据库的特点呢,
首先说下性能方面吧,性能最好的是realm,但它不是在SQLite基础上的ORM,它有自己的数据查询引擎;
如果基于sqlite的话,性能最好的是greendao,其插入和查询的速度远远高于ormlite和litepal;
ormlite胜于其开发文档很齐全,性能也不差,使用起来也很方便,只要不是很大的数据(一万条的话就不如用greenDao了),基本能满足需求;
litepal是郭神开发和维护的一个数据库框架,其博客有很详细的教程,使用起来也简单,如果不考虑性能的话,用起来也很好,关键是有问题可以随时找郭婶不是,O(∩_∩)O哈哈~;
三、greenDao
好了,说了这么多,现在正式开始介绍greenDao使用方法。
1、添加依赖
在3.0以前的版本,使用起来稍显繁琐,3.0以后使用起来爽的飞起啊,本篇主要介绍3.0以后版本的使用方法。
在project的gradle中添加:
dependencies {
...
//添加greenDao依赖
classpath 'org.greenrobot:greendao-gradle-plugin:3.1.0'
}
在module的gradle中添加:
apply plugin: 'org.greenrobot.greendao'
android {
...
greendao{
schemaVersion 1
daoPackage'com.nhsoft.lgy.mytest.dao'
targetGenDir 'src/main/java'
}
}
dependencies {
...
// 添加greenDao依赖
compile 'org.greenrobot:greendao:3.2.2'
compile 'org.greenrobot:greendao-generator:3.2.2'
}
这里有个说明,
greendao{
schemaVersion 1
daoPackage'com.nhsoft.lgy.mytest.dao'
targetGenDir 'src/main/java'
}
schemaVersion 1 是你的数据库版本号,数据库升级的时候用
daoPackage 是你要指定的java文件夹下的哪个目录,比如这里我的包名是“com.nhsoft.lgy.mytest”,我在其下面创建了个文件专门放dao文件,所以这里就是‘com.nhsoft.lgy.mytest.dao’
targetGenDir ‘src/main/java’ 指的是gen目录是src/main/java文件夹下的包路径,是和daoPackage组合起来用的,如果不指定daoPackage,则默认生成的dao路径是当前类下的包
这里我先放一下我的项目结构图
到此依赖完毕
2. 创建DAO
依赖完毕后就可以使用greenDao了,怎么使用呢,首先entity,就是你要创建的数据库表类,
这里我们创建一个user类:
@Entity
public class User {
@Id
private Long id;
@Property(nameInDb = "USER_NAME")
@Unique
private String username;
@Property(nameInDb = "NICKNAME")
private String nickname;
在类的头部添加@Entity,指的是这是一个entity,只有标注了这个标记,才会生成对应的表,表名就是类名大写,如果不希望默认类名为表明,可以自定义表明,方法是@Entity(nameInDb = “MY_USER”),在entity后添加你要的表明
到这里重新build一下,在dao目录下就会生成userDao类,如果是首次生成dao,则会额外生成DaoMaster和DaoSession两个类,后面新加的entity表生成dao时就只会生成对应的dao类了
@Id表明这里是自增主键
@Property(nameInDb = “NICKNAME”)
指明数据库中的列明
@Unique表明唯一值
3、初始化数据库
在application中初始化,初始化过程就会创建表
public class MyApplication extends Application {
public static DaoSession mDaoSession;
@Override
public void onCreate() {
super.onCreate();
initDao();
}
private void initDao() {
DBHelper devOpenHelper = new DBHelper(getApplicationContext());
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
mDaoSession = daoMaster.newSession();
}
}
这里做个说明
public static DaoSession mDaoSession;
这个变量是为了后续拿各个dao方便,全局只持有一个DaoSession,获取dao时这样就可以获取了
userDao = MyApplication.mDaoSession.getUserDao();
另外
DBHelper devOpenHelper = new DBHelper(getApplicationContext());
这里创建的是自己的DBHelper
public class DBHelper extends DaoMaster.OpenHelper {
public static final String DBNAME = "mytestDb.db";
public DBHelper(Context context) {
super(context, DBNAME,null);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
}}
这样做的好处是,可以在数据库升级时做些本地数据迁移的操作,如果使用DaoMaster中的OpenHelper的话,其在数据库升级时删除了所有的表并创建了所有的表,这样原有的数据就会丢失了,我们来看下DaoMaster中的OpenHelper的结构
public static abstract class OpenHelper extends DatabaseOpenHelper {
public OpenHelper(Context context, String name) {
super(context, name, SCHEMA_VERSION);
}
public OpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory, SCHEMA_VERSION);
}
@Override
public void onCreate(Database db) {
Log.i("greenDAO", "Creating tables for schema version " + SCHEMA_VERSION);
createAllTables(db, false);
}
}
/** WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name) {
super(context, name);
}
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");
dropAllTables(db, true);
onCreate(db);
}
}}
其在onUpgrade方法里做了
dropAllTables(db, true);
onCreate(db);
的操作
4、创建dbservice
我们的操作流程是,dao操作数据库,dbservice操作dao,数据使用操作dbservice,达到解耦和封装的目的
首先创建service接口
public interface IUserDbService {
public void insertUser();
public void deleteUser(String userName);
void updateUser();
List<User> queryList();}
实现接口
public class UserDbServiceImpl implements IUserDbService {
private UserDao userDao;
public UserDbServiceImpl() {
userDao = MyApplication.mDaoSession.getUserDao();
}
@Override
public void insertUser() {
Random r = new Random();
Log.i("time", "开始"+DateTimeUtil.format(new Date(),DateTimeUtil.yyyy_MM_dd_HH_mm_ss));
for (int i=0;i<10000;i++){
User user = new User(null, "zhangsan" + r.nextInt(9999), "张三");
userDao.insert(user);
}
Log.i("time", "结束"+DateTimeUtil.format(new Date(),DateTimeUtil.yyyy_MM_dd_HH_mm_ss));
}
@Override
public void deleteUser(String userName) {
User user = userDao.queryBuilder().where(UserDao.Properties.Username.eq(userName)).build().unique();
if (user == null) {
} else {
userDao.delete(user);
}
}
@Override
public void updateUser() {
User user = userDao.queryBuilder().where(UserDao.Properties.Id.le(10), UserDao.Properties.Username.like("%7172")).build().unique();
if (user == null) {
} else {
user.setUsername("王五");
userDao.update(user);
}
}
@Override
public List<User> queryList() {
List<User> list = userDao.queryBuilder().where(UserDao.Properties.Id.between(2, 15)).
limit(5).build().list();
for (int i = 0; i < list.size(); i++) {
Log.d("my_list", "search: "+ new Gson().toJson(list.get(i)));
}
return list;
}}
这里做个说明
首先在构造方法里获取userdao
private UserDao userDao;
public UserDbServiceImpl() {
userDao = MyApplication.mDaoSession.getUserDao();
}
然后我们可以使用userDao做crud操作,
插入操作
User user = new User(null, "zhangsan" + r.nextInt(9999), "张三");
userDao.insert(user);
删除操作
User user = userDao.queryBuilder().where(UserDao.Properties.Username.eq(userName)).build().unique();
if (user == null) {
} else {
userDao.delete(user);
}
我们在删除之前首先要查询这个user,如果不存在,我们可以做一些提示,如果存在再删除
查询中,where组装各种条件,如果查询列表则build之后跟的是.list(),如果查单条则跟的是.unique();
更新操作
User user = userDao.queryBuilder().where(UserDao.Properties.Id.le(10), UserDao.Properties.Username.like("%7172")).build().unique();
if (user == null) {
} else {
user.setUsername("王五");
userDao.update(user);
}
更新也是先查询再更新
查询列表
List<User> list = userDao.queryBuilder().where(UserDao.Properties.Id.between(2, 15)).
limit(5).build().list();
for (int i = 0; i < list.size(); i++) {
Log.d("my_list", "search: "+ new Gson().toJson(list.get(i)));
}
return list;
5、使用dbservice
在要使用的地方先获取service,
private IUserDbService service = new UserDbServiceImpl();
接着就可以使用service进行增删改查操作了
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.button:
service.insertUser();
break;
case R.id.button2:
service.deleteUser("王五");
break;
case R.id.button3:
service.updateUser();
break;
case R.id.button4:
service.queryList();
break;
}
}
好了,关于greenDao的基本使用就这么多了,如果大家有什么疑问可以留言给我,我后续补充高级用法