GreenDao3.2.2集成使用以及数据库的升级
来源:互联网 发布:ssh安装 centos 编辑:程序博客网 时间:2024/06/06 01:50
GreenDao3.2.2集成使用以及数据库的升级
一概念
是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案。
二优点:
一个精简的库;性能最大化;内存开销最小化;易于使用的 APIs;对 Android 进行高度优化。
三集成
1在app的build.gradle 红色的是要添加的
apply plugin: 'com.android.application'apply plugin: 'org.greenrobot.greendao' // apply pluginandroid { //初始化greendao基本信息 greendao{ schemaVersion 1 daoPackage 'com.admom.mygreendaotest.gen' targetGenDir 'src/main/java' }//schemaVersion: 数据库schema版本,也可以理解为数据库版本号//daoPackage:设置DaoMaster、DaoSession、Dao包名//targetGenDir:设置DaoMaster、DaoSession、Dao目录//targetGenDirTest:设置生成单元测试目录//generateTests:设置自动生成单元测试用例}dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' compile 'org.greenrobot:greendao:3.2.2'}
2在工程的build.gradle里添加如下代码
buildscript { repositories { jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:2.3.2' 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 }}
3根据
greendao{ schemaVersion 1 daoPackage 'com.example.wbxu.gen' targetGenDir 'src/main/java' }
的配置 在src/java/ com.example.wbxu 这个包的下边创建gen用于存放DaoMaster DaoSession Dao【操作表的根据bean生成的】,
4创建实体类bean
4创建实体类bean
@Entitypublic class Fruit { @Id(autoincrement = true) //设置主键自增长 private Long id; //自增id必须为long类型的 private String Name; //名字 @NotNull private int Count; //个数}
然后点击Build Make Project 就会在gen文件夹里生成DaoMaster DaoSession 对应实体【对应表的Dao】
5编写DaoManager创建数据库、创建数据库表、包含增删改查的操作
public class DaoManager { private static final String TAG = DaoManager.class.getSimpleName(); //创建数据库的名字 private static final String DB_NAME = "MyGreenDb.db"; //初始化上下文 private Context context; //多线程中要被共享的使用volatile关键字修饰 GreenDao管理类 private volatile static DaoManager mInstance; //它里边实际上是保存数据库的对象 private static DaoMaster mDaoMaster; //创建数据库的工具 private static DaoMaster.DevOpenHelper mHelper; //管理gen里生成的所有的Dao对象里边带有基本的增删改查的方法 private static DaoSession mDaoSession; /** * 单例模式获得操作数据库对象 * @return */ public static DaoManager getInstance(){ if(mInstance==null){ synchronized (DaoManager.class){ if(mInstance==null){ mInstance=new DaoManager(); } } } return mInstance; } /** * 初始化上下文创建数据库的时候使用 */ public void init(Context context){ this.context = context; } /** * 判断是否有存在数据库,如果没有则创建 * @return */ public DaoMaster getDaoMaster(){ if(mDaoMaster == null) { mHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null); mDaoMaster = new DaoMaster(mHelper.getWritableDatabase()); } return mDaoMaster; } /** * 完成对数据库的添加、删除、修改、查询操作, * @return */ public DaoSession getDaoSession(){ if(mDaoSession == null){ if(mDaoMaster == null){ mDaoMaster = getDaoMaster(); } mDaoSession = mDaoMaster.newSession(); } return mDaoSession; } /** * 关闭所有的操作,数据库开启后,使用完毕要关闭 */ public void closeConnection(){ closeHelper(); closeDaoSession(); } public void closeHelper(){ if(mHelper != null){ mHelper.close(); mHelper = null; } } public void closeDaoSession(){ if(mDaoSession != null){ mDaoSession.clear(); mDaoSession = null; } }}
6编写对应表的工具类 实现操作该表的方法
public class FruitDaoUtil { private DaoManager mManager; private String TAG="flag"; //操作Fruit的构造函数 public FruitDaoUtil(Context context) { mManager = DaoManager.getInstance(); mManager.init(context); } /** * 完成fruit记录的插入,如果表未创建,先创建fruit表 * * @param fruit * @return 返回long值 -1为失败 */ public boolean insertFruit(Fruit fruit) { boolean flag = false; flag = mManager.getDaoSession().getFruitDao().insertOrReplace(fruit) == -1 ? false : true; Log.i(TAG, "-------插入一条的结果为"+flag); return flag; } /** * 插入多条数据,在子线程操作 * @return */ public boolean insertListFruit(final List<Fruit> mList) { boolean flag = false; try { mManager.getDaoSession().runInTx(new Runnable() { @Override public void run() { for (Fruit fruit : mList) { mManager.getDaoSession().insertOrReplace(fruit); } } }); flag = true; } catch (Exception e) { e.printStackTrace(); } return flag; } /** * 刷新指定数据 */ public boolean reFreshFruit(Fruit fruit){ boolean flag = false; mManager.getDaoSession().refresh(fruit); return flag; } /** * 修改一条数据 * @return */ public boolean updateFruit(Fruit fruit){ boolean flag = false; try { mManager.getDaoSession().update(fruit); flag = true; }catch (Exception e){ e.printStackTrace(); } return flag; } /** * 删除单条记录 * @return */ public boolean deleteFruit(Fruit fruit){ boolean flag = false; try { mManager.getDaoSession().delete(fruit); flag = true; }catch (Exception e){ e.printStackTrace(); } return flag; } /** * 删除所有记录 * @return */ public boolean deleteAll(){ boolean flag = false; try { mManager.getDaoSession().deleteAll(Fruit.class); flag = true; }catch (Exception e){ e.printStackTrace(); } return flag; } /** * 查询所有记录 * @return */ public List<Fruit> queryAllFruit(){ return mManager.getDaoSession().loadAll(Fruit.class); } /** * 根据主键id查询记录 * @param key * @return */ public Fruit queryFruitById(long key){ return mManager.getDaoSession().load(Fruit.class, key); } /** * 使用 sql语句进行查询操作 * 参数一sql语句 参数二查询条件限定 */ public List<Fruit> queryFruitBySql(String sql, String[] conditions){ return mManager.getDaoSession().queryRaw(Fruit.class, sql, conditions); } /** * 使用queryBuilder进行查询 * @return */ public List<Fruit> queryFruitByQueryBuilder(long id){ QueryBuilder<Fruit> queryBuilder = mManager.getDaoSession().queryBuilder(Fruit.class); return queryBuilder.where(FruitDao.Properties.Id.eq(id)).list(); }}
7测试MainActivity的测试按钮点击事件如下
public void onClick(View view) { switch (view.getId()) { case R.id.insertsingle: //插入单个的 mFruitDaoUtil.insertFruit(new Fruit(1L,"苹果1",1)); break; case R.id.multinsert: //插入多个的 List<Fruit> list=new ArrayList<Fruit>(); for (int i = 0; i < 10; i++) { list.add(new Fruit(Long.parseLong(i+""),"桃子"+i,i)); } mFruitDaoUtil.insertListFruit(list); break; case R.id.refresh: //刷新单个的 mFruitDaoUtil.reFreshFruit(new Fruit(1L,"苹果1",10)); break; case R.id.update: //更新单个的 mFruitDaoUtil.reFreshFruit(new Fruit(1L,"苹果1",20)); break; case R.id.deletesingle: //删除单个的 mFruitDaoUtil.deleteFruit(new Fruit(4L,"苹果1",20)); break; case R.id.deleteMult: //删除全部 mFruitDaoUtil.deleteAll(); break; case R.id.checksingle: //按主键查询一个 Fruit f= mFruitDaoUtil.queryFruitById(1L); Log.d("flag","---------按条件查询的结果为"+f.getName()+"-----"+f.getId()); break; case R.id.checkmult: //按条件查询 List<Fruit> l= mFruitDaoUtil.queryFruitBySql("Name,Count",new String[]{"苹果1","1"}); for (int i = 0; i <l.size(); i++) { Log.d("flag","---------按条件查询的结果为"+l.get(i).getName()+"-----"+l.get(i).getId()); } break; case R.id.querybuilder: //querybuilder查询 List<Fruit> List =mFruitDaoUtil.queryFruitByQueryBuilder(1L); for (int i = 0; i <List.size(); i++) { Log.d("flag","---------按条件查询的结果为"+List.get(i).getName()+"-----"+List.get(i).getId()); } break; case R.id.upDataDB: MySQLiteOpenHelper o=new MySQLiteOpenHelper(this,"MyGreenDb.db",null); DaoMaster daoMaster = new DaoMaster(o.getWritableDatabase()); break; }}
四常用的注解解释:
@Entity 实体注解
@NotNull 设置表中的当前列的值不为空
@Convert 制定自定义类型
@Generated GreenDao运行所产生的构造函数或者方法,被此标注的代码可以更新或者下次运行时清除
@Id 主键Long型,可以通过@Id(autoincrement = true)设置自增长,通过这个注解标记的字段必 须是long,数据库中表示它就是主键,并且默认为自增长
@Index 使用@Index作为一个属性累创建一个索引,定义多列索引(@Iink Entity#indexes())
@JoinEntity 定义表连接关系
@JoinProperty 定义名称和引用名称属性关系
@Keep 注解的代码在GreenDao下运行时保持不变
1.注解实体类:默认禁止修改此类
2.注解其他代码,默认禁止修改注解的代码段
@Order 制定排序
@Property 设置一个非默认关系映射所对应的列名,默认使用的字段名。
例:@Property(nameInDb="name")
@ToMany 定义多个实体对应的关系
@ToOne 定义与另一个实体(一个实体对象)的关系
@Transient 添加该标记之后不会生成数据库表的列
@Unique 向数据库列添加一个唯一的约束
@NotNull 设置表中的当前列的值不为空
@Convert 制定自定义类型
@Generated GreenDao运行所产生的构造函数或者方法,被此标注的代码可以更新或者下次运行时清除
@Id 主键Long型,可以通过@Id(autoincrement = true)设置自增长,通过这个注解标记的字段必 须是long,数据库中表示它就是主键,并且默认为自增长
@Index 使用@Index作为一个属性累创建一个索引,定义多列索引(@Iink Entity#indexes())
@JoinEntity 定义表连接关系
@JoinProperty 定义名称和引用名称属性关系
@Keep 注解的代码在GreenDao下运行时保持不变
1.注解实体类:默认禁止修改此类
2.注解其他代码,默认禁止修改注解的代码段
@Order 制定排序
@Property 设置一个非默认关系映射所对应的列名,默认使用的字段名。
例:@Property(nameInDb="name")
@ToMany 定义多个实体对应的关系
@ToOne 定义与另一个实体(一个实体对象)的关系
@Transient 添加该标记之后不会生成数据库表的列
@Unique 向数据库列添加一个唯一的约束
五关于数据库的更新
原理:首先创建临时表(数据格式和原表一模一样)。
把当前表的数据插入到临时表中去。
删除掉原表,创建新表。
把临时表数据插入到新表中去,然后删除临时表。
下边贴上国外大神的写的更新数据库的操作类
把当前表的数据插入到临时表中去。
删除掉原表,创建新表。
把临时表数据插入到新表中去,然后删除临时表。
下边贴上国外大神的写的更新数据库的操作类
public class MigrationHelper2 { public static boolean DEBUG = false; private static String TAG = "MigrationHelper2"; private static final String SQLITE_MASTER = "sqlite_master"; private static final String SQLITE_TEMP_MASTER = "sqlite_temp_master"; public static void migrate(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) { printLog("【The Old Database Version】" + db.getVersion()); Database database = new StandardDatabase(db); migrate(database, daoClasses); } public static void migrate(Database database, Class<? extends AbstractDao<?, ?>>... daoClasses) { printLog("【Generate temp table】start"); generateTempTables(database, daoClasses); printLog("【Generate temp table】complete"); dropAllTables(database, true, daoClasses); createAllTables(database, false, daoClasses); printLog("【Restore data】start"); restoreData(database, daoClasses); printLog("【Restore data】complete"); } private static void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) { for (int i = 0; i < daoClasses.length; i++) { String tempTableName = null; DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]); String tableName = daoConfig.tablename; if (!isTableExists(db, false, tableName)) { printLog("【New Table】" + tableName); continue; } try { tempTableName = daoConfig.tablename.concat("_TEMP"); StringBuilder dropTableStringBuilder = new StringBuilder(); dropTableStringBuilder.append("DROP TABLE IF EXISTS ").append(tempTableName).append(";"); db.execSQL(dropTableStringBuilder.toString()); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("CREATE TEMPORARY TABLE ").append(tempTableName); insertTableStringBuilder.append(" AS SELECT * FROM ").append(tableName).append(";"); db.execSQL(insertTableStringBuilder.toString()); printLog("【Table】" + tableName +"\n ---Columns-->"+getColumnsStr(daoConfig)); printLog("【Generate temp table】" + tempTableName); } catch (SQLException e) { Log.e(TAG, "【Failed to generate temp table】" + tempTableName, e); } } } private static boolean isTableExists(Database db, boolean isTemp, String tableName) { if (db == null || TextUtils.isEmpty(tableName)) { return false; } String dbName = isTemp ? SQLITE_TEMP_MASTER : SQLITE_MASTER; String sql = "SELECT COUNT(*) FROM " + dbName + " WHERE type = ? AND name = ?"; Cursor cursor=null; int count = 0; try { cursor = db.rawQuery(sql, new String[]{"table", tableName}); if (cursor == null || !cursor.moveToFirst()) { return false; } count = cursor.getInt(0); } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); } return count > 0; } private static String getColumnsStr(DaoConfig daoConfig) { if (daoConfig == null) { return "no columns"; } StringBuilder builder = new StringBuilder(); for (int i = 0; i < daoConfig.allColumns.length; i++) { builder.append(daoConfig.allColumns[i]); builder.append(","); } if (builder.length() > 0) { builder.deleteCharAt(builder.length() - 1); } return builder.toString(); } private static void dropAllTables(Database db, boolean ifExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "dropTable", ifExists, daoClasses); printLog("【Drop all table】"); } private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { reflectMethod(db, "createTable", ifNotExists, daoClasses); printLog("【Create all table】"); } /** * dao class already define the sql exec method, so just invoke it */ private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) { if (daoClasses.length < 1) { return; } try { for (Class cls : daoClasses) { Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class); method.invoke(null, db, isExists); } } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } private static 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"); if (!isTableExists(db, true, tempTableName)) { continue; } try { // get all columns from tempTable, take careful to use the columns list List<String> columns = getColumns(db, tempTableName); ArrayList<String> properties = new ArrayList<>(columns.size()); for (int j = 0; j < daoConfig.properties.length; j++) { String columnName = daoConfig.properties[j].columnName; if (columns.contains(columnName)) { properties.add(columnName); } } if (properties.size() > 0) { final String columnSQL = TextUtils.join(",", properties); StringBuilder insertTableStringBuilder = new StringBuilder(); insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" ("); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(") SELECT "); insertTableStringBuilder.append(columnSQL); insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";"); db.execSQL(insertTableStringBuilder.toString()); printLog("【Restore data】 to " + tableName); } StringBuilder dropTableStringBuilder = new StringBuilder(); dropTableStringBuilder.append("DROP TABLE ").append(tempTableName); db.execSQL(dropTableStringBuilder.toString()); printLog("【Drop temp table】" + tempTableName); } catch (SQLException e) { Log.e(TAG, "【Failed to restore data from temp table 】" + tempTableName, e); } } } private static List<String> getColumns(Database db, String tableName) { List<String> columns = null; Cursor cursor = null; try { cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null); if (null != cursor && cursor.getColumnCount() > 0) { columns = Arrays.asList(cursor.getColumnNames()); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) cursor.close(); if (null == columns) columns = new ArrayList<>(); } return columns; } private static void printLog(String info){ if(DEBUG){ Log.d(TAG, info); } }}
然后创建自定义的更新数据库类继承DaoMaster.OpenHelper
** * Created by wbxu on 2017/6/19. * 自定义 MySQLiteOpenHelper集成 DaoMaster.OpenHelper 重写更新数据库的方法 * 当app下的build.gradle 的schemaVersion数据库的版本号改变时,,创建数据库会调用onUpgrade更细数据库的方法 */public class MySQLiteOpenHelper extends DaoMaster.OpenHelper{ /** * * @param context 上下文 * @param name 原来定义的数据库的名字 新旧数据库一致 * @param factory 可以null */ public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) { super(context, name, factory); } /** * * @param db * @param oldVersion * @param newVersion * 更新数据库的时候自己调用 */ @Override public void onUpgrade(Database db, int oldVersion, int newVersion) { Log.d("flag","-----调用了"); //具体的数据转移在MigrationHelper2类中 /** * 将db传入 将gen目录下的所有的Dao.类传入 */ MigrationHelper2.migrate(db,FruitDao.class, AnimalsDao.class, PeoreDao.class); }}
使用方法:
1当新建一个表就是新建一个bean 然后build makeProject 会在gen生成对应的dao文件 将类名传入MigrationHelper2.migrate(db,FruitDao.class, AnimalsDao.class, PeoreDao.class);这个更新的方法里
2更改app下build.gradle的数据库的版本号
//初始化greendao基本信息
greendao{
schemaVersion 4
daoPackage 'com.example.wbxu.mygreendaodemo.gen'
targetGenDir 'src/main/java'
}
3调用让其更新
在想要更新的地方如mainActivity 或 Application 更新数据库
//传入参数二是新旧的数据库名字需要一致
MySQLiteOpenHelper o=new MySQLiteOpenHelper(this,"MyGreenDb.db",null);
DaoMaster daoMaster = new DaoMaster(o.getWritableDatabase());
源码下载:http://download.csdn.net/detail/bskfnvjtlyzmv867/9835023
2更改app下build.gradle的数据库的版本号
//初始化greendao基本信息
greendao{
schemaVersion 4
daoPackage 'com.example.wbxu.mygreendaodemo.gen'
targetGenDir 'src/main/java'
}
3调用让其更新
在想要更新的地方如mainActivity 或 Application 更新数据库
//传入参数二是新旧的数据库名字需要一致
MySQLiteOpenHelper o=new MySQLiteOpenHelper(this,"MyGreenDb.db",null);
DaoMaster daoMaster = new DaoMaster(o.getWritableDatabase());
源码下载:http://download.csdn.net/detail/bskfnvjtlyzmv867/9835023
阅读全文
0 0
- GreenDao3.2.2集成使用以及数据库的升级
- GreenDao3.0+的配置使用以及数据库升级
- Android数据库GreenDAO3.2.2的使用(四、数据库升级)
- Android数据库GreenDAO3.2.2的使用(一,集成数据库)
- greenDAO的使用详解---(2)greenDAO3.2.2数据库的升级
- greenDAO的使用详解---(3)greenDAO3.2.2数据库的升级bug解决
- (二)GreenDao3.0的数据库升级
- GreenDao3.2.2 App数据库升级遇到问题
- GreenDao3 数据库升级问题
- GreenDao3.0升级数据库
- GreenDao3.0数据库升级
- Android数据库GreenDAO3.2.2的使用(二,数据库使用)
- greendao3.2.0的使用及升级
- GreenDao3.2的使用,以及实体类添加字段时进行升级。
- Android数据库框架-----GreenDao3的相关使用和版本升级更新
- GreenDao3的集成
- Android数据库——GreenDAO3.2.2的使用
- Android数据库框架——GreenDao3.2的配置 升级
- PHP date strtotime
- Muduo网络库源码分析(四)EventLoopThread和EventLoopThreadPool的封装
- ubuntu wifi问题(没有driver/wifi hard blocked)
- java
- 花开两朵 天各一方
- GreenDao3.2.2集成使用以及数据库的升级
- 实例化需求SBE
- 常用SVN命令,超详细
- 重载、覆盖(重写)、多重继承的区别
- 6/20学习笔记
- web.config详解
- 121. Best Time to Buy and Sell Stock
- 递归
- Could not find com.android.tools.build:gradle:3.0.0-alpha3