GreenDAO整个运行的逻辑是通过配置其提供的JavaSE代码,自动在一个文件夹下生成需要Bean、DAO、DaoMaster、DaoSession;然后在Android代码中通过创建DaoSession来操作数据库,具体方法如下:
在./src/main目录下创建一个与java同层级的java-gen文件夹.
打开build.gradle,引入sourceSets
sourceSets {
main {
java.srcDirs = [‘src/main/java‘, ‘src/main/java-gen‘]
}
}
这句话的意思是把java-gen文件夹下的java文件也归入srcDir中,主要是因为GreenDAO的逻辑是通过其提供的一套Java SE代码配置后自动在java-gen文件夹下生成对应的*DAO.java、DaoMaster.java、DaoSession.java文件。在Android代码中通过调用这几个类来操作数据库。
引入dependencies
dependencies {
compile ‘de.greenrobot:greendao:1.3.7‘
}
下载地址:GitHub link
下载这个Demo的原因是要引入这个示例工程来实现自动创建需要的DaoMaster、DaoSession等等,GreenDao上手麻烦的原因就在于一开始以为只要gradle随便引入一个库之后就可以使用了,没想到最关键的是需要引入这个JavaSE工程来实现关键代码的自动创建。
这个Demo工程也不用怎么仔细的去看,下载解压之后Copy里面的MyDaoGenerator文件夹Code link
把这个文件夹拷贝到你的工程跟目录中,就是与app文件夹同层级的目录里。
将MyDaoGenerator include到工程中:
打开settings.gradle,修改内容
include ‘:app‘, ‘:MyDaoGenerator‘
打开MyDaoGenerator的build.gradle文件,配置outputDir,路径就是存放自动生成DaoMaster和其他代码的地方。这里给个示例:
def outputDir = "../app/src/main/java-gen"
注意’def
‘,GitHub上的这个Demo掉了’def
‘导致我一直编译错误。
接下来需要创建DaoMaster.java等
打开MyDaoGenerator工程中的MyDaoGenerator.java
配置里面的代码,如示例:
public static void main(String args[]) throws Exception {
Schema schema = new Schema( 1, "com.xxx.bean");
// 1: 数据库版本号
// com.xxx.bean:自动生成的Bean对象会放到/java-gen/com/xxx/bean中
schema.setDefaultJavaPackageDao("com.xxx.dao");
// DaoMaster.java、DaoSession.java、BeanDao.java会放到/java-gen/com/xxx/dao中
// 上面这两个文件夹路径都可以自定义,也可以不设置
initUserBean(schema); // 初始化Bean了
new DaoGenerator().generateAll(schema, args[0]);// 自动创建
}
private static void initUserBean(Schema schema) {
Entity userBean = schema.addEntity("UserBean");// 表名
userBean.setTableName("user"); // 可以对表重命名
userBean.addStringProperty("id").primaryKey().index();// 主键,索引
userBean.addStringProperty("phone");
userBean.addStringProperty("profile_picture");
userBean.addStringProperty("client_id");
userBean.addStringProperty("name");
userBean.addStringProperty("location");
userBean.addStringProperty("gender");
}
这里只需要关注一个问题,就是如果数据库要升级,这里是修改代码后全量重新创建。
假设要给user表增加一个”age”属性,并且增加school表的做法是:
把数据库版本号修改为2
在initUserBean方法中加入userBean.addStringProperty("age");
新建initSchoolBean方法
当明白这个文件的写法之后就要运行这个文件了,进到AndroidStudio的Gradel面板中执行run任务。
执行完成之后就会在java-gen文件夹下生成需要的代码了。
初始化代码示例:
THDevOpenHelper helper = new THDevOpenHelper(context, "my-db", null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
这句话执行之后就会在app的文件夹下生成my-db.db了
如果看到这里你还没有产生疑问,那说明你没有认真看这篇文章,THDevOpenHelper
是什么玩意?
这是我封装的DaoMaster.OpenHelper,之所以要做一层封装是因为默认的DaoMaster.OpenHelper在碰到数据库升级的时候会删除旧的表来创建新的表,这样就会导致旧表的数据全部丢失了,所以一定要封装DaoMaster.OpenHelper来实现数据库升级
示例如下:
public class THDevOpenHelper extends DaoMaster.OpenHelper {
public THDevOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
//创建新表,注意createTable()是静态方法
// SchoolDao.createTable(db, true);
// 加入新字段
// db.execSQL("ALTER TABLE ‘moments‘ ADD ‘audio_path‘ TEXT;");
// TODO
break;
}
}
}
为了更好的使用Dao,你应该创建一个DaoHelper。
示例如下:
public class UserBeanDaoHelper implements THDaoHelperInterface {
private static UserBeanDaoHelper instance;
private UserBeanDao userBeanDao;
private UserBeanDaoHelper() {
try {
userBeanDao = THDatabaseLoader.getDaoSession().getUserBeanDao();
} catch (Exception e) {
e.printStackTrace();
}
}
public static UserBeanDaoHelper getInstance() {
if(instance == null) {
instance = new UserBeanDaoHelper();
}
return instance;
}
@Override
public <T> void addData(T bean) {
if(userBeanDao != null && bean != null) {
userBeanDao.insertOrReplace((UserBean) bean);
}
}
@Override
public void deleteData(String id) {
if(userBeanDao != null && !TextUtils.isEmpty(id)) {
userBeanDao.deleteByKey(id);
}
}
@Override
public UserBean getDataById(String id) {
if(userBeanDao != null && !TextUtils.isEmpty(id)) {
return userBeanDao.load(id);
}
return null;
}
@Override
public List getAllData() {
if(userBeanDao != null) {
return userBeanDao.loadAll();
}
return null;
}
@Override
public boolean hasKey(String id) {
if(userBeanDao == null || TextUtils.isEmpty(id)) {
return false;
}
QueryBuilder<UserBean> qb = userBeanDao.queryBuilder();
qb.where(UserBeanDao.Properties.Id.eq(id));
long count = qb.buildCount().count();
return count > 0 ? true : false;
}
@Override
public long getTotalCount() {
if(userBeanDao == null) {
return 0;
}
QueryBuilder<UserBean> qb = userBeanDao.queryBuilder();
return qb.buildCount().count();
}
@Override
public void deleteAll() {
if(userBeanDao != null) {
userBeanDao.deleteAll();
}
}
public void testQueryBy() {
List joes = userBeanDao.queryBuilder()
.where(UserBeanDao.Properties.Phone.eq("Joe"))
.orderAsc(UserBeanDao.Properties.Phone)
.list();
QueryBuilder<UserBean> qb = userBeanDao.queryBuilder();
qb.where(qb.or(UserBeanDao.Properties.Phone.gt(10698.85),
qb.and(UserBeanDao.Properties.Phone.eq("id"),
UserBeanDao.Properties.Phone.eq("xx"))));
qb.orderAsc(UserBeanDao.Properties.Id);// 排序依据
qb.list();
}
}
最后友情附上THDaoHelperInterface.java
public interface THDaoHelperInterface {
public <T> void addData(T t);
public void deleteData(String id);
public <T> T getDataById(String id);
public List getAllData();
public boolean hasKey(String id);
public long getTotalCount();
public void deleteAll();
}
本文是用Markdown写的,所以很多该附图的地方并没有附图。如果遇到看不懂的地方。
原文:http://blog.csdn.net/h3c4lenovo/article/details/43566169