您当前的位置:首页 > 互联网教程

greendao 框架数据库升级策略

发布时间:2025-05-25 02:28:02    发布人:远客网络

greendao 框架数据库升级策略

一、greendao 框架数据库升级策略

在进行Android项目开发时,合理使用数据库是提升项目功能与性能的关键。GreenDao作为轻量级、高性能的对象关系映射框架,受到开发者青睐。然而,在数据库升级过程中,GreenDao会自动删除并重建表,导致原有数据丢失,这无疑给开发者带来了挑战。如何在不丢失数据的情况下,实现GreenDao数据库升级策略?本文将详细解析。

GreenDao提供了一套自动升级机制,主要通过`onUpgrade()`方法实现。每当数据库版本发生变化时,系统会自动调用此方法执行升级逻辑。但在这一过程中,原有的表结构将被删除,并重新创建,数据也随之丢失。

为了在升级数据库时保留原有数据,开发者需要自定义升级策略。这通常涉及备份现有数据、删除旧表、创建新表,以及恢复数据等步骤。

-**备份数据**:首先,备份旧表数据,以备后续使用。

-**删除旧表**:在`onUpgrade()`方法内,明确删除需要升级的表。

-**创建新表**:根据新版本的表结构,创建或更新表。

-**数据恢复**:将备份数据恢复到新表中,确保数据的连续性和完整性。

通过上述步骤,开发者可以在不破坏原有数据的情况下,顺利完成数据库升级,为项目带来稳定、高效的运行环境。这一策略不仅体现了开发者对数据库管理的深度理解,也展示了对项目需求的细致考虑。

二、Android Greendao插入10万条数据OOM

1、private Runnable runnable= new Runnable(){@Override

2、List<Book> bookList= new ArrayList<>(); for(int i= 0; i< 5000; i++){

3、book.setUuid(UUID.randomUUID().toString());

4、book.setName("name");//其他set方法略

5、} catch(InterruptedException e){

6、mBookDao.insertOrReplaceInTx(bookList);

7、Log.d(TAG,"插入book数据:"+ bookList.size());

8、mBookDao.deleteAll(); long time= System.currentTimeMillis();

9、ExecutorService executorService= Executors.newFixedThreadPool(3); for(int i= 0; i< 200; i++){

10、executorService.submit(runnable);

11、executorService.shutdown(); for(;;){ if(executorService.isTerminated()){ break;

12、executorService.awaitTermination(1, TimeUnit.SECONDS);

13、} catch(InterruptedException e){

14、Log.d(TAG,"线程池完成:"+(System.currentTimeMillis()- time)+"ms");

15、runnable任务模拟1秒从网络拉取5000条数据并插入DB,insert方法使用线程池执行runnable任务。

16、执行时间超过1000秒,查看内存占用超过180M。如果数据量更多,肯定会发生OOM,基本上可以定位是greenDAO的问题。现在需要在两个方面优化,一是寻找内存占用的原因,二是提高数据的插入速度。

17、内存的占用随着insert的数据量越多而递增,从中间dump出java堆,得到hprof文件。注意这个文件不是标准格式,只能用AndroidStudio打开。

18、右击文件导出标准的hprof文件,用更加强大的MAT分析。

19、看到IdentityScope占了一半内存,可以确定是greenDAO缓存了插入数据。

20、mBookDao.insertOrReplaceInTx(bookList);mBookDao.detachAll();

21、greenDAO的缓存功能是有用的,没必要关闭,改成在插入数据后,调用一次detachAll,将identityScope清空。

22、public void detachAll(){ if(identityScope!= null){

23、对表插入大量数据,如果中间没有涉及到业务,可以先失效索引,待插入完成后重建索引。

24、String sql="drop index index_isbn";

25、sql="drop index index_publisherid";

26、sql="drop index index_author";

27、插入数据前,drop掉表中的索引。没有见到greenDAO有操作索引的方法,直接执行sql命令。

28、sql="create index index_isbn on book(isbn)";

29、sql="create index index_publisherid on book(publisherid)";

30、sql="create index index_author on book(author)";

31、插入数据完成后,重建索引。最后执行100w数据插入大约耗时450秒,比什么都不做快了两三倍。

32、上一个步骤的耗时包含了模拟网络和数据库操作的时间,使用多线程将两个环节分离,可以减少总时间。

33、greenDAO提供了AsyncSession这个异步操作类,使用daoSession.startAsyncSession()获取实例,内部实现使用了线程池和阻塞队列,原理很简单不用多讲。

34、mAsyncSession.runInTx(new Runnable(){@Override

35、mBookDao.insertOrReplaceInTx(bookList);

36、获取数据后,提交给AsyncSession异步插入数据库。要注意在合适地方使用waitForCompletion,等待AsyncSession完成已有任务。如果获取数据速度很快,而操作数据库很慢,会导致过多数据缓存在AsyncSession的内部阻塞队列。

37、最后测试一下100w数据插入数据库,耗时不到150秒,又快了几倍。

38、链接:

39、著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

三、greendao的tomany没效果

缓存机制程序会优先使用缓存内的数据。greenDAO是一个将对象映射到SQLite数据库中的轻量且快速的ORM解决方案,greendao的tomany没效果是由于缓存机制程序会优先使用缓存内的数据。greenDAO是一种Android数据库ORM(object/relationalmapping)框架,与OrmLite、ActiveOrm、LitePal等数据库相比,单位时间内可以插入、更新和查询更多的数据,而且提供了大量的灵活通用接口。