上一篇文章简单记录了greenDao的导入和使用,这篇文章则主要是记录在开发中使用greenDao,一些管理类的封装,
主要类的结构如下
其中DaoMaster、DaoSession、TopicHistoryBeanDao(与上文中UserDao是类似的)是用Make project 自动生成的。
主要思路是,数据库和表分开管理,因为我们可能随着开发进行,添加很多表,
DaoManager(数据库管理类)
public class DaoManager {
private static DaoManager mInstance;
private DaoMaster mDaoMaster;
private DaoSession mDaoSession;
private static final String DBNAME = "look_history_db";
private DaoManager() {
//数据库初始化
DBHelper devOpenHelper = new DBHelper(MyApplication.getContext(),DBNAME,null);
mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());//是使用的哪个devOpenHelper.getWritableDb()/getWritableDatebase
mDaoSession = mDaoMaster.newSession();
}
public DaoMaster getDaoMaster() {
return mDaoMaster;
}
public DaoSession getSession() {
return mDaoSession;
}
public static DaoManager getInstance() {
if (mInstance == null) {
mInstance = new DaoManager();
}
return mInstance;
}
}
EntityManager(数据库表的管理类)
表管理类
/*
* 数据库中表的管理
* TopicHistoryBeanDao 是数据库中的一个表,这里可以添加很多表的获取,便于管理
*/
public class EntityManager {
private static EntityManager entityManager;
private TopicHistoryBeanDao historyBeanDao;
public EntityManager() {
historyBeanDao = DaoManager.getInstance().getSession().getTopicHistoryBeanDao();
}
/**
* 创建单例
*
* @return
*/
public static EntityManager getInstance() {
if (entityManager == null) {
entityManager = new EntityManager();
}
return entityManager;
}
public TopicHistoryBeanDao getHistoryBeanDao() {
return historyBeanDao;
}
}
HistroyTableManager(表的数据操作管理类)
对应的表的增删改查管理类,这里可以按照你需要的功能进行编写。不是必须这样些,只做提示。
我觉得还是把HistoryTopicBean的字段贴一下,不然可能会看的难受
TopicHistoryBean
@Entity
public class TopicHistoryBean {
@Id(autoincrement = true)
private Long id;
private String tid;
private String fid;
private String forumname;
private String icon;
private String author;
private String authorid;
private String subject;
private String postdate;
private String like_count;
private String replies;
private String hits;
private String attach;
private long savetime;//保存时间
}
HistroyTableManager
public class HistroyTableManager {
private static HistroyTableManager mInstance;
public TopicHistoryBeanDao historyBeanDao;
private HistroyTableManager(){
historyBeanDao=EntityManager.getInstance().getHistoryBeanDao();
}
/**
* @return
*/
public static HistroyTableManager getInstance() {
if (mInstance == null) {
mInstance = new HistroyTableManager();
}
return mInstance;
}
/**
* 插入数据不能插入相同的帖子数据
*
* @param bean
*/
public void insert(TopicListBean bean) {
//当数据库中有该数据的时候,
TopicHistoryBean historyBean = TopicHistoryBean.toTopicHistoryBean(bean);
LogUtils.e("要插入的数据为:historyBean==" + historyBean.toString());
//查询指定的作者和主题的历史记录
List<TopicHistoryBean> list = getTheTopics(bean.getAuthor(), bean.getSubject());
boolean isHas = false;
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(historyBean)) {
isHas = true;
}
}
//如果有的话,就进行修改数据
if (isHas) {
LogUtils.e("当前帖子已经存在,进行修改参数操作");
} else {
historyBeanDao.insert(historyBean);
LogUtils.e("插入数据");
}
}
public void insert(TopicHistoryBean bean) {
historyBeanDao.insert(bean);
}
/**
* 删除某一条数据
*
* @param bean
*/
public void delete(TopicHistoryBean bean) {
historyBeanDao.delete(bean);
}
/**
* 删除全部数据
*/
public void deleteAll() {
historyBeanDao.deleteAll();
}
/**
* 查询全部数据
*
* @return
*/
public List<TopicHistoryBean> getAllHistory() {
return historyBeanDao.queryBuilder().list();
}
/**
* 查询指定的浏览历史是否已经在数据库中
*
* @return
*/
public List<TopicHistoryBean> getTheTopics(String name, String subject) {
return historyBeanDao.queryBuilder()
.where(TopicHistoryBeanDao.Properties.Author.eq(name), TopicHistoryBeanDao.Properties.Subject.eq(subject))
.build()
.list();
}
}
版本升级
- greenDao3.0的版本升级,基本思路是:
创建临时表-->删除原表-->创建新表-->复制临时表数据到新表并删除临时表
并且我们新增加的和修改的字段做好为String类型,避免字段不能为null的情况发生
- MigrationHelper(数据迁移类)
public class MigrationHelper {
private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION =
"MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
private static MigrationHelper instance;
public static MigrationHelper getInstance(){
if (instance==null){
instance = new MigrationHelper();
}
return instance;
}
/**
* 数据迁移
* @param db
* @param daoClasses
*/
public void migrate(Database db, Class<? extends AbstractDao<?,?>>... daoClasses ){
generateTempTables(db, daoClasses);
DaoMaster.dropAllTables(db, true);
DaoMaster.createAllTables(db, false);
restoreData(db, daoClasses);
LogUtils.i("greenDAO", "MigrationHelper---migrate");
}
/**
* 生成临时列表
* @param db
* @param daoClasses
*/
private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String divider = "";
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList<>();
StringBuilder createTableStringBuilder = new StringBuilder();
createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");
for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;
if (getColumns(db, tableName).contains(columnName)) {
properties.add(columnName);
String type = null;
try {
type = getTypeByClass(daoConfig.properties[j].type);
} catch (Exception exception) {
}
createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);
if (daoConfig.properties[j].primaryKey) {
createTableStringBuilder.append(" PRIMARY KEY");
}
divider = ",";
}
}
createTableStringBuilder.append(");");
db.execSQL(createTableStringBuilder.toString());
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
}
}
private void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList();
for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;
if (getColumns(db, tempTableName).contains(columnName)) {
properties.add(columnName);
}
}
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(insertTableStringBuilder.toString());
db.execSQL(dropTableStringBuilder.toString());
}
}
private String getTypeByClass(Class<?> type) throws Exception {
if (type.equals(String.class)) {
return "TEXT";
}
if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
return "INTEGER";
}
if (type.equals(Boolean.class)) {
return "BOOLEAN";
}
Exception exception =
new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
throw exception;
}
private static List<String> getColumns(Database db, String tableName) {
List<String> columns = new ArrayList<>();
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
if (cursor != null) {
columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
}
} catch (Exception e) {
Log.v(tableName, e.getMessage(), e);
e.printStackTrace();
} finally {
if (cursor != null) cursor.close();
}
return columns;
}
}
- DBHelper(自定义Helper类)
这里进行版本升级时的数据迁移,等操作
public class DBHelper extends DaoMaster.OpenHelper {
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
//需要对版本升级进行处理
super.onUpgrade(db, oldVersion, newVersion);
LogUtils.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
if (oldVersion < newVersion) {
LogUtils.e("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
MigrationHelper.getInstance().migrate(db, TopicHistoryBeanDao.class);
//更改过的实体类(新增的不用加) 更新UserDao文件 可以添加多个 XXDao.class 文件
// MigrationHelper.getInstance().migrate(db, UserDao.class,XXDao.class);
}
}
}
添加字段进行编译
1.在TopicHistoryBean 中添加一个字段String newColum–>Build–>Make Project 编译后自动将该字段添加到构造函数中,并实现set,get方法。
@Entity
public class TopicHistoryBean {
@Id(autoincrement = true)
private Long id;
private String tid;
private String fid;
private String forumname;
private String icon;
private String author;
private String authorid;
private String subject;
private String postdate;
private String like_count;
private String replies;
private String hits;
private String attach;
private long savetime;//保存时间
private String newColum;//新增字段
@Generated(hash = 461609634)
public TopicHistoryBean(Long id, String tid, String fid, String forumname, String icon, String author, String authorid, String subject, String postdate,
String like_count, String replies, String hits, String attach, long savetime, String newColum) {
this.id = id;
this.tid = tid;
this.fid = fid;
this.forumname = forumname;
this.icon = icon;
this.author = author;
this.authorid = authorid;
this.subject = subject;
this.postdate = postdate;
this.like_count = like_count;
this.replies = replies;
this.hits = hits;
this.attach = attach;
this.savetime = savetime;
this.newColum = newColum;
}
...
public String getNewColum() {
return this.newColum;
}
public void setNewColum(String newColum) {
this.newColum = newColum;
}
}
2.将module中build.gradle中的版本号修改为比当前大–>Sync Now–>as 中的绿箭头安装到模拟器或真机中。
greendao {
schemaVersion 2 //新版本
daoPackage 'com.*****.db'//这个是生成代码保存的包名
targetGenDir 'src/main/java'//保存到java代码路径
}
3.查看日志
如果出现这条日志,说明你的数据表已经升级ok了
10-19 12:11:48.782 7925-7925/? E/version: [ className=com.alpha.alphaapp.db.DBHelper,methodName=onUpgrade,lineNumber=34 ] 1---先前和更新之后的版本---2
打印保存的HistoryTopicBean,很显然,我们新添的字段newColum,已经存在,但是因为前面的数据没有该字段,所以为null
TopicHistoryBean{id=1, tid='3468', fid='9', forumname='夺晶战神界', icon='http://cdn.gdalpha.com/icon/100/100.jpg', author='大表姐', authorid='26', subject='【官网嘉年华】爆裂王者大作战震撼上线,快来开启你的探索之旅!', postdate='1502251719', like_count='17', replies='27', hits='1419', attach='[]', savetime=1508384399, newColum='null'}
以上就是我的greenDao的使用过程,如果大家在使用过程中存在发现,欢迎及时反馈。共同进步。