GreenDao使用记录

普通的APP做持久化保存,最便捷的就是使用数据库。现在使用Android提供的数据库进行CURD的不多,我选择了GreenDao,这里我只说怎么用,原理我也不懂。

基本使用

1.查看GitHub完成基本的配置。

2.了解一些基本的注解的使用。

@Entity 实体注解,为greendao指明这是一个需要映射到数据库的实体类,也就是一个@Entity就是一张表。
@Id 主键,选择使用long或Long。我建议使用Long。
@Property 为该属性映射的列设置一个非默认的名称,默认是将单词大写,用下划线分割单词,如属性名customName对应列名CUSTOM_NAME
@NotNull 表明这个列非空
@Transient 表明此字段不存储到数据库中,也就是设置实体类中的这个字段不加入数据库

3.了解一些多表关联的注解使用。

@ToOne 一对一
@ToMany 一对多
我们要使用多表关联那么肯定就要设定某个字段关联多表的约束关系。这里我们需要使用greenDao提供的注解使用
使用@ToOne的joinProperty参数来指明外键。
使用@ToMany的属性代表目标实体的List,referencedJoinProperty指定目标实体的外键。好几张表的话需要定义@joinproperty注释列表,每个@joinproperty需要原始实体中的源属性和目标实体中的引用属性

具体的使用例子:

1.有这样一个数据xml,我们需要把数据都存在数据库里面所以就要建个表。仔细看一张表是不够的,所以要多张表去查询。

{
    "id": "message",
    "category": "system",
    "style": {
      "type": "1",
      "rank": "1",
      "duration": "300"
    },
    "content": {
      "icon": "http://thedeveloperworldisyours.com/wp-content/uploads/scareface.jpeg",
      "title": "推送通知标题",
      "text": "推送通知内容",
      "btnInfo": "go",
      "detailTxt": "内容详情",
      "detailImg": "内容图片",
      "detailUrl": "内容的H5URL"
    },
    "event": [
      {
        "id": 0,
        "package": "e.com.notificationcenter",
        "action": "e.com.notificationcenter.ACTION_NOTIFICATION",
        "uri": "",
        "params": [
          {
            "key": "key1",
            "value": "value1"
          },
          {
            "key": "key2",
            "value": "value2"
          }
        ]
      },
      {
        "id": 1,
        "package": "e.com.notificationcenter",
        "action": "e.com.notificationcenter.ACTION_NOTIFICATION",
        "uri": "",
        "params": [
          {
            "key": "type",
            "value": "activity"
          },
          {
            "key": "button",
            "value": "跳转NotificationActivity"
          }
        ]
      },
      {
        "id": 1,
        "package": "e.com.notificationcenter",
        "action": "e.com.notificationcenter.ACTION_TEST_RECEIVER",
        "uri": "",
        "params": [
          {
            "key": "type",
            "value": "receiver"
          },
          {
            "key": "button",
            "value": "发广播"
          }
        ]
      }
    ]
}

2.了解数据结构之后,我们开始建立JavaBean。

我们建立3张表分别是:
NotifyMessage,NotifyMessageEvent,NotifyMessageParams
注意代码中省略了get set方法

2.1 主表

@Entity
public class NotifyMessage {

    @Id(autoincrement = true)
    private Long id;
    @Unique
    private long timestamp;
    private String idString;
    private String tag;
    private String category;
    private int styleType;
    private int styleRank;
    private int styleDuration;
    private String icon;
    private String title;
    private String text;
    private String btnInfo;
    private String detailContent;
    private String detailImage;
    private String detailURL;
    private String time;
    @Transient
    private int headerID = 2;
    @Transient
    private PendingIntent pendingIntent;
    @Transient
    private String iconTag;


    @ToMany(joinProperties = {@JoinProperty(name = "timestamp", referencedName = "eventTimeStamp")})
    private List<NotifyMessageEvent> notifyMessageEvent;
    /**
     * Used to resolve relations
     */
    @Generated(hash = 2040040024)
    private transient DaoSession daoSession;
    /**
     * Used for active entity operations.
     */
    @Generated(hash = 1960478595)
    private transient NotifyMessageDao myDao;

    @Generated(hash = 1719562967)
    public NotifyMessage(Long id, long timestamp, String idString, String tag, String category,
                         int styleType, int styleRank, int styleDuration, String icon, String title, String text,
                         String btnInfo, String detailContent, String detailImage, String detailURL, String time) {
        this.id = id;
        this.timestamp = timestamp;
        this.idString = idString;
        this.tag = tag;
        this.category = category;
        this.styleType = styleType;
        this.styleRank = styleRank;
        this.styleDuration = styleDuration;
        this.icon = icon;
        this.title = title;
        this.text = text;
        this.btnInfo = btnInfo;
        this.detailContent = detailContent;
        this.detailImage = detailImage;
        this.detailURL = detailURL;
        this.time = time;
    }

    @Generated(hash = 1236766346)
    public NotifyMessage() {
    }
    /**
     * To-many relationship, resolved on first access (and after reset).
     * Changes to to-many relations are not persisted, make changes to the target entity.
     */
    @Generated(hash = 722358099)
    public List<NotifyMessageEvent> getNotifyMessageEvent() {
        if (notifyMessageEvent == null) {
            final DaoSession daoSession = this.daoSession;
            if (daoSession == null) {
                throw new DaoException("Entity is detached from DAO context");
            }
            NotifyMessageEventDao targetDao = daoSession.getNotifyMessageEventDao();
            List<NotifyMessageEvent> notifyMessageEventNew = targetDao
                    ._queryNotifyMessage_NotifyMessageEvent(timestamp);
            synchronized (this) {
                if (notifyMessageEvent == null) {
                    notifyMessageEvent = notifyMessageEventNew;
                }
            }
        }
        return notifyMessageEvent;
    }

    /**
     * Resets a to-many relationship, making the next get call to query for a fresh result.
     */
    @Generated(hash = 400246657)
    public synchronized void resetNotifyMessageEvent() {
        notifyMessageEvent = null;
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 128553479)
    public void delete() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.delete(this);
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 1942392019)
    public void refresh() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.refresh(this);
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 713229351)
    public void update() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.update(this);
    }
 /** called by internal mechanisms, do not call yourself. */
    @Generated(hash = 528583178)
    public void __setDaoSession(DaoSession daoSession) {
        this.daoSession = daoSession;
        myDao = daoSession != null ? daoSession.getNotifyMessageDao() : null;
    }   

有英文注释的是GreenDao自动生成的代码我们不要改。我们在主表里面使用了@ToMany的注解,又定义了joinProperties,意思是与NotifyMessageEvent关联的外键是timestamp与eventTimeStamp,都是long类型,这里写外键关系的时候不要写其它的数据结构,不然会有问题。什么问题,自己写一个看看报错就知道了。

2.2 附表 关联主表NotifyMessage

@Entity
public class NotifyMessageEvent {
    @Id(autoincrement = true)
    private Long id;
    private int eventID;
    @NotNull
    private long eventTimeStamp;
    private String notifyPackage;
    private String notifyAction;
    private String eventURL;
    @ToMany(joinProperties = {@JoinProperty(name = "eventTimeStamp", referencedName = "paramTimeStamp")})
    private List<NotifyMessageParams> params;
    /**
     * Used to resolve relations
     */
    @Generated(hash = 2040040024)
    private transient DaoSession daoSession;
    /**
     * Used for active entity operations.
     */
    @Generated(hash = 884557405)
    private transient NotifyMessageEventDao myDao;

    @Generated(hash = 1282602662)
    public NotifyMessageEvent(Long id, int eventID, long eventTimeStamp, String notifyPackage,
                              String notifyAction, String eventURL) {
        this.id = id;
        this.eventID = eventID;
        this.eventTimeStamp = eventTimeStamp;
        this.notifyPackage = notifyPackage;
        this.notifyAction = notifyAction;
        this.eventURL = eventURL;
    }

    @Generated(hash = 2006772937)
    public NotifyMessageEvent() {
    }
    /**
     * To-many relationship, resolved on first access (and after reset).
     * Changes to to-many relations are not persisted, make changes to the target entity.
     */
    @Generated(hash = 454729913)
    public List<NotifyMessageParams> getParams() {
        if (params == null) {
            final DaoSession daoSession = this.daoSession;
            if (daoSession == null) {
                throw new DaoException("Entity is detached from DAO context");
            }
            NotifyMessageParamsDao targetDao = daoSession.getNotifyMessageParamsDao();
            List<NotifyMessageParams> paramsNew = targetDao._queryNotifyMessageEvent_Params(eventTimeStamp);
            synchronized (this) {
                if (params == null) {
                    params = paramsNew;
                }
            }
        }
        return params;
    }

    /**
     * Resets a to-many relationship, making the next get call to query for a fresh result.
     */
    @Generated(hash = 1798791244)
    public synchronized void resetParams() {
        params = null;
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 128553479)
    public void delete() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.delete(this);
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 1942392019)
    public void refresh() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.refresh(this);
    }

    /**
     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.
     * Entity must attached to an entity context.
     */
    @Generated(hash = 713229351)
    public void update() {
        if (myDao == null) {
            throw new DaoException("Entity is detached from DAO context");
        }
        myDao.update(this);
    }
    
    /** called by internal mechanisms, do not call yourself. */
    @Generated(hash = 905504949)
    public void __setDaoSession(DaoSession daoSession) {
        this.daoSession = daoSession;
        myDao = daoSession != null ? daoSession.getNotifyMessageEventDao() : null;
    }    

2.3 NotifyMessageEvent关联了NotifyMessageParams

@Entity
public class NotifyMessageParams {

    @Id(autoincrement = true)
    private Long id;
    @NotNull
    private long paramTimeStamp;
    private String key;
    private String value;

    @Generated(hash = 1754893391)
    public NotifyMessageParams(Long id, long paramTimeStamp, String key,
                               String value) {
        this.id = id;
        this.paramTimeStamp = paramTimeStamp;
        this.key = key;
        this.value = value;
    }

    @Generated(hash = 744686383)
    public NotifyMessageParams() {
    }

我们看到在设置了一对多之后GreenDao都会自动生成一些方法。比如像NotifyMessage里面的
getNotifyMessageEvent() 这里直接就返回了一个集合,获取到了另一张表 NotifyMessageEvent 里面的数据,很方便。我这里设置的一对多比较简单,就是更加时间来设置一对多。

使用表

1.初始化表,一般来说我们初始化数据库在Application里面,我们项目特殊所以就直接在调用的地方进行初始化。看代码。

private static final String TAG = DBManager.class.getSimpleName();

    private static DBManager manager;
    private static final String NOTIFICATION_CENTER_DB = "notification_center.db";
    private DaoSession mDaoSession;


    private DBManager(Context context) {
//        AppApplication context = AppApplication.getInstance();
        if (context != null) {
            Log.e(TAG, "context not null");
            DaoMaster.DevOpenHelper mDBHelper = new DaoMaster.DevOpenHelper(context, NOTIFICATION_CENTER_DB);
            Database sql = mDBHelper.getWritableDb();
            DaoMaster mDaoMaster = new DaoMaster(sql);
            mDaoSession = mDaoMaster.newSession(IdentityScopeType.None);
        } else {
            Log.e(TAG, "context null !!!!!!!!!!!!!!!!!!!!!!!!");
        }
    }

    public static DBManager getInstance(Context context) {
        if (manager == null) {
            synchronized (DBManager.class) {
                if (manager == null) {
                    manager = new DBManager(context);
                    Log.e(TAG, "hascode = " + manager.hashCode());
                }
            }
        }
        return manager;
    }

看到一个IdentityScopeType.None 意思是None时不启用缓存,不写这个参数就是启用缓存。

2.查询数据
上面我们获取了DaoSession,有了它就可以查数据什么的了。

    //主表
    public NotifyMessageDao getNotifyMessageDao() {

        return mDaoSession.getNotifyMessageDao();
    }

    //附表
    public NotifyMessageEventDao getNotifyMessageEventDao() {
        return mDaoSession.getNotifyMessageEventDao();
    }
    //附表

    public NotifyMessageParamsDao getNotifyParamsDao() {
        return mDaoSession.getNotifyMessageParamsDao();
    }

2.1 查数据,例如查所有表的数据:

    public List searchAllNotifyMessage() {
        Query query = getNotifyMessageDao().queryBuilder().orderDesc(NotifyMessageDao.Properties.Timestamp)
                .build();
        List notes = query.list();
        QueryBuilder.LOG_SQL = false;
        QueryBuilder.LOG_VALUES = false;
        return notes;
    }

这里是根据时间来倒序查询。最终会返回一个List集合给我们。那些个Log的字段就是是否打印SQL句子,看自己的需求了。

2.2 查数据,直接查询数量

public long queryNotifyMessageCount() {
        return getNotifyMessageDao().queryBuilder().count();
    }

2.3 设置自己的SQL语句来进行查询。比如:GreenDao提供的一个字段不够你用,那么就自己来写吧。比如查询7天的内容。我们的

    public List<NotifyMessage> searchSevenDayMessage() {
        String[] selectionArg = null;
        String sql = createSQL();
//        Cursor cursor = getDaoSession().getDatabase().rawQuery(sql, null);
        List<NotifyMessage> notifyMessages = getNotifyMessageDao().queryRaw(sql, selectionArg);
        Log.e(TAG, "searchSevenDayMessage Size = " + notifyMessages.size() + "  sql =" + sql);
        return notifyMessages;
    }
    private String createSQL() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        long time = System.currentTimeMillis();
        // 现在的时间
        String currentTime = simpleDateFormat.format(time);
        //7天前的时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -7);
        String beforeDays = simpleDateFormat.format(calendar.getTime());
        StringBuffer stringBuffer = new StringBuffer();
//        stringBuffer.append("select * from ");
//        stringBuffer.append(tableName);
        stringBuffer.append(" where ");
        stringBuffer.append(" datetime( ");
        stringBuffer.append(" TIME ");
        stringBuffer.append(" ) ");
        stringBuffer.append(" between datetime( '");
        stringBuffer.append(beforeDays);
        stringBuffer.append("') and datetime( '");
        stringBuffer.append(currentTime);
        stringBuffer.append("')");
        stringBuffer.append(" order by ");
        stringBuffer.append(" TIMESTAMP ");
        stringBuffer.append(" desc ");
        return stringBuffer.toString();
    }

这里要要注意,SQL语句里面时间查询,你需要存入正常的年月日的。不能存一个时间戳,来查询几天之内的数据。然后使用GreenDao的时候,为了方便我们使用它的内键方法getNotifyMessageDao().queryRaw(),这里面已经写好了select * from这种东西,自己就不要写了,写了会报错。

2.4 删除数据,可以直接传入JavaBean来删除,ID等方式

    public void deleteData(long key) {
        if (mDaoSession != null) {
            getNotifyMessageDao().deleteByKey(key);
            List<NotifyMessage> notifyMessages = getNotifyMessageDao().loadAll();
            Log.e(TAG, "DEL = " + notifyMessages.size());

        }
    }

    public void deleteAllData() {
        if (mDaoSession != null) {
            getNotifyMessageDao().deleteAll();
            getNotifyMessageEventDao().deleteAll();
            getNotifyParamsDao().deleteAll();
        }
    }

看到一个DeleteAllData方法,就是把表里面的内容都删除。在我们删除了主表里面的内容之后,关联的表的数据还在的。不要以为自己做了一对多,关联了几个字段,删除主表的一条数据或者多条数据,附表里面的内容也就跟着删了,那是不可能的。

3 GreenDao里面有线程池。我们可以生成ASYNC然后CURD。例如:

    public AsyncSession getAsyncSession() {
        if (mDaoSession != null) {
            AsyncSession asyncSession = mDaoSession.startAsyncSession();
            return asyncSession;
        }
        return null;
    }

3.1 2种增加的方式一种线程池的一种普通的。

//同步
    private void asyncAdd() {
        DBManager.getInstance(mContext).getAsyncSession().runInTx(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3000; i++) {
                    final NotifyMessage notifyMessage = new NotifyMessage();
                    final NotifyMessageEvent notifyMessageEvent = new NotifyMessageEvent();
                    final NotifyMessageParams msgParams = new NotifyMessageParams();

                    //message
//                    notifyMessage.setRequestID("5710970123456789H3RA002" + i);
                    notifyMessage.setTimestamp(1333333333L + i);
                    notifyMessage.setCategory("system");
                    notifyMessage.setStyleType(1);
                    notifyMessage.setStyleRank(2);
                    notifyMessage.setStyleDuration(500);
                    notifyMessage.setIcon("icon");
                    notifyMessage.setTitle("title");
                    notifyMessage.setText("嘿嘿");
                    notifyMessage.setDetailContent("周杰伦全新单曲上线了!《不爱我就拉倒》");
//            event
                    notifyMessageEvent.setEventTimeStamp(1333333333L + i);
                    notifyMessageEvent.setEventID(1 + i);
                    notifyMessageEvent.setEventURL("http://www.baidu.com");
//            param
                    msgParams.setParamTimeStamp(1333333333L + i);
                    msgParams.setValue("value++" + i);
                    msgParams.setKey("key--" + i);
			DBManager.getInstance(mContext).getNotifyMessageDao().insertOrReplaceInTx(notifyMessage);
			DBManager.getInstance(mContext).getNotifyMessageEventDao().insertOrReplaceInTx(notifyMessageEvent);                  
			DBManager.getInstance(mContext).getNotifyParamsDao().insertOrReplaceInTx(msgParams);
                }
            }
        });
    }

//异步
     DBManager.getInstance(mContext).getAsyncSession().runInTx(new Runnable() {
                @Override
                public void run() {
              DBManager.getInstance(mContext).getNotifyMessageDao().insertOrReplaceInTx(notifyMessage);  
              DBManager.getInstance(mContext).getNotifyMessageEventDao().insertOrReplaceInTx(notifyMessageEvent);  
              DBManager.getInstance(mContext).getNotifyParamsDao().insertOrReplaceInTx(msgParams);             
                }
            });

4.看一下多表怎么取数据。例如:我们获取每条消息里面的第一个package的名称

String packageString = mListData.get(adapterPosition).getNotifyMessageEvent().get(0).getNotifyPackage();

最后

简单的使用了GreenDao,当然还有更多的东西我没有用到,例如升级数据库,更新数据等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值