GreenDao并不支持全文检索,导致在大量数据中的查询效率低下。本文介绍了如何在GreenDao中添加支持全文检索的功能,希望对GreenDao粉有所帮助。
本文基于GreenDao V3.2.3 + rk3288 android7.1.2实测有效,读者有任何问题可留言沟通。

1.修改DaoGeneratorV3

1)Entity.java增加一个属性useFts,用来标识是否使用全文检索。

private boolean useFts;//lihuili add 20210310 for FTS public boolean isUseFts() {return useFts;}public void setUseFts(boolean useFts) {this.useFts = useFts;}Entity(Schema schema, String className) {this.schema = schema;this.className = className;properties = new ArrayList<Property>();propertiesPk = new ArrayList<Property>();propertiesNonPk = new ArrayList<Property>();propertyNames = new HashSet<String>();indexes = new ArrayList<Index>();multiIndexes = new ArrayList<Index>();toOneRelations = new ArrayList<ToOne>();toManyRelations = new ArrayList<ToManyBase>();incomingToManyRelations = new ArrayList<ToManyBase>();additionalImportsEntity = new TreeSet<String>();additionalImportsDao = new TreeSet<String>();interfacesToImplement = new ArrayList<String>();contentProviders = new ArrayList<ContentProvider>();constructors = true;useFts = false;}

2)模板dao.ftl增加:如果entity.useFts为true,就创建使用FTS4的虚表

<!-- lihuili add 20210310 for FTS --><#if entity.useFts>/** Creates the underlying database table. */public static void createTable(Database db, boolean ifNotExists) {String constraint = ifNotExists? "IF NOT EXISTS ": "";db.execSQL("CREATE VIRTUAL TABLE " + constraint + "\"${entity.dbName}\" USING FTS4 (" + //<#list entity.propertiesColumns as property>"\"${property.dbName}\" ${property.dbType}<#if property.constraints??> ${property.constraints} </#if><#if property_has_next>," +<#else>);");</#if> // ${property_index}: ${property.propertyName}</#list><#if entity.indexes?has_content >// Add Indexes<#list entity.indexes as index>db.execSQL("CREATE <#if index.unique>UNIQUE </#if>INDEX " + constraint + "${index.name} ON \"${entity.dbName}\"" +" (<#list index.properties as property>\"${property.dbName}\"<#if (index.propertiesOrder[property_index])??> ${index.propertiesOrder[property_index]}</#if><#sep>,</#list>);");</#list></#if>}<#else>/** Creates the underlying database table. */public static void createTable(Database db, boolean ifNotExists) {String constraint = ifNotExists? "IF NOT EXISTS ": "";db.execSQL("CREATE TABLE " + constraint + "\"${entity.dbName}\" (" + //<#list entity.propertiesColumns as property>"\"${property.dbName}\" ${property.dbType}<#if property.constraints??> ${property.constraints} </#if><#if property_has_next>," +<#else>);");</#if> // ${property_index}: ${property.propertyName}</#list><#if entity.indexes?has_content >// Add Indexes<#list entity.indexes as index>db.execSQL("CREATE <#if index.unique>UNIQUE </#if>INDEX " + constraint + "${index.name} ON \"${entity.dbName}\"" +" (<#list index.properties as property>\"${property.dbName}\"<#if (index.propertiesOrder[property_index])??> ${index.propertiesOrder[property_index]}</#if><#sep>,</#list>);");</#list></#if>         }</#if>

2.修改自动生成代码的java文件

以DaoGeneratorFaceCollectSTD.java为例:
1)创建一个15列的普通表check_list


```java
private static Entity addCheck_list(Schema schema){Entity check_list = schema.addEntity("check_list");check_list.addLongProperty("item_id").primaryKey().autoincrement();check_list.addLongProperty("file_id");check_list.addStringProperty("name");check_list.addStringProperty("identy_no");check_list.addStringProperty("col3");check_list.addStringProperty("col4");check_list.addStringProperty("col5");check_list.addStringProperty("col6");check_list.addStringProperty("col7");check_list.addStringProperty("col8");check_list.addStringProperty("col9");check_list.addStringProperty("col10");check_list.addStringProperty("col11");check_list.addStringProperty("col12");check_list.addStringProperty("col13");check_list.addStringProperty("col14");check_list.addStringProperty("col15");      return check_list;}

2)创建一个3列的虚表,这3列与普通表完全一样
关键点:需要调用setUseFts(true),明确告诉程序创建虚表。```javaprivate static Entity addCheck_list_fts(Schema schema){Entity check_list_fts = schema.addEntity("check_list_fts");check_list_fts.setUseFts(true);//使用FTS4check_list_fts.addLongProperty("item_id").primaryKey().autoincrement();        check_list_fts.addStringProperty("name");check_list_fts.addStringProperty("identy_no");         return check_list_fts;
}

3)在main函数中调用上面封装的函数

public static void main(String[] args) throws Exception {Schema schema = new Schema(SCHEMA_VERSION_INFO_DB, "com.routon.idr.facecollect.std.dao.info");schema.enableActiveEntitiesByDefault();schema.enableKeepSectionsByDefault();addCommonParam(schema);addFaceInfo(schema);addCheckfile_info(schema);addCheck_list(schema);addCheck_list_fts(schema);new DaoGenerator().generateAll(schema, "../iDRFaceCollectSTD/src");}

4)Run As Java Application自动生成代码

3.修改DaoCoreV3

1)修改Property.java,增加支持match
注意:一定要带问号!

public class Property {...public WhereCondition match(Object value) {return new PropertyCondition(this, " match?", value);}
}

4.封装FTS查询函数

以FaceInfoCtrl.java为例:
1)函数QueryCheckListFtsByIdentyNo()调用match()构造where条件

public List<Check_list_fts> QueryCheckListFtsByIdentyNo(String identy_no){if(!TextUtils.isEmpty(identy_no)){Check_list_ftsEntityDao entityDao = new Check_list_ftsEntityDao(getDBManager());if(entityDao!=null){Check_list_ftsDao dao = entityDao.getEntityDao();QueryBuilder<Check_list_fts> builder = dao.queryBuilder();builder = builder.where(Check_list_ftsDao.Properties.Identy_no.match(identy_no));long beginTick = SystemClock.uptimeMillis();List<Check_list_fts> checkListFtss = builder.build().list();long endTick = SystemClock.uptimeMillis();Log.d(TAG, "match " + identy_no + " use " + (endTick-beginTick) + "ms");if(checkListFtss!=null && checkListFtss.size()>0){Log.d(TAG, checkListFtss.get(0).getName());}return checkListFtss;}}return null;}

5.验证测试FTS4全文检索

1)先单独运行一下添加了FTS支持的test.apk,生成一个数据库文件face_info.db, 该文件中已经自动创建了空表check_list_fts
2)创建一个插入65535条记录的sql脚本文件CHECK_LIST_FTS.sql,例:

INSERT INTO "CHECK_LIST_FTS" VALUES ('1', '夏紫寒', '642401194107180628');
INSERT INTO "CHECK_LIST_FTS" VALUES ('2', '范梦松', '220904201505271831');
INSERT INTO "CHECK_LIST_FTS" VALUES ('3', '魏孤岚', '612232196501110123');


3)从终端pull face_info.db到pc
4)在pc使用在navicat premium把CHECK_LIST_FTS.sql导入到CHECK_LIST_FTS表
5)从pc push face_info.db到终端
6)在test.apk中添加调用FTS查询的函数QueryCheckListFtsByIdentyNo()
7)对比测试普通查询和FTS4全文检索的效率
在65535条记录中,普通查询平均耗时190ms,FTS4全文检索平均耗时5ms!

在GreenDao开源代码中添加FTS4全文检索功能相关推荐

  1. 苹果开源代码中惊现“wechat”,老外注释的吐槽亮了!

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 每个科技大厂的开源项目,几乎都是各领域开发者最重要的研究学习 ...

  2. c# mysql代码中写事务_代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性...

    [c#]代码库代码中使用事务前提:务必保证一个功能(或用例)在同一个打开的数据连接上,放到同一个事务里面操作. 首先是在D层添加一个类为了保存当前操作的这一个连接放到一个事务中执行,并事务执行打开同一 ...

  3. C语言系列(二):最近重拾C语言的想法,谈到C中易错点,难点;以及开源代码中C语言的一些常用技巧,以及如何利用define、typedef、const等写健壮的C程序...

    写在前面的话:本系列主要是自己在c语言运用时,对一些不了解,但开源代码中常用的技巧,和一些c语言中偏门和易错点进行解析. 加入了自己的分析,如果不到位请多海涵,另外,引用一些非常好的文章(都有引用li ...

  4. 命令模式在开源代码中的应用

    命令模式的作用:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开. 案例 JDK 中的线程 java.lang.Thread,使用了命令模式. Thread 类的构造方法可以接收实现 ...

  5. java注释里加_如何在代码中添加注释

    什么是代码注释,如何在代码中添加注释,相信每一位了解编程的人并不陌生.注释里往往有很多有趣的脑洞和「真心话」.今天我们一起去看看那些6到飞起,被玩坏了的幽默注释吧. 信息量太大的注释系列-- 1.你造 ...

  6. xxljob在业务代码中添加任务(登录后token验证)

    之前做过一次在业务代码中调用xxljob的接口添加任务启动任务,xxljob的接口添加免登录验证注解后直接调用,博文地址:xxl-job 在业务代码中添加任务,后面用到的groupId获取方法也在这里 ...

  7. [译] 代码中添加注释之好坏丑

    原文地址:Putting comments in code: the good, the bad, and the ugly. 原文作者:Bill Sourour 译文出自:掘金翻译计划 译者: ba ...

  8. 富文本中添加字体选项功能_扑中的字体功能

    富文本中添加字体选项功能 A little extra help for styling your text 样式设置方面的一些额外帮助 I recently learned about a litt ...

  9. python右键弹出菜单编写_python实现应用程序在右键菜单中添加打开方式功能

    最近项目组开发的一个小工具想要在右键菜单中添加打开方式,以有道云笔记为例进行了需求拆解和代码编写 1.需求拆解: 如何实现手动添加右键菜单的打开方式: Step1:打开注册表编辑器,Win+R-> ...

最新文章

  1. 【 FPGA/IC 】谈谈复位
  2. 这六段代码隐藏着深度学习的前世今生!
  3. python中enumerate()函数_Python enumerate() 函数
  4. mongoDB 使用手册
  5. PyQt5 打包问题解决 Unable to find “D:\anaconda3\lib\site-packages\PyQt5\Qt\translations\qtwebengine_locale
  6. Power BI Desktop中的分解树
  7. 发布Oracle存储过程包c#代码生成工具(CodeRobot)
  8. linux下tab作用的描述?
  9. account.php,account.php
  10. 数据挖掘算法之Apriori算法应用实例
  11. cache abstraction
  12. SpringBoot 实现AOP的简单测试demo
  13. 信息系统项目管理师核心考点(八)软件集成技术
  14. 空气净化器什么牌子好,家用空气净化器哪个牌子好推荐
  15. DevExpress中动态设置主题、皮肤
  16. 基于EasyNVR摄像机网页无插件直播服务二次开发实现H5播放页面的简单集成方案
  17. oracle 删除po查询,Oracle EBS:PO 常用的查询及Tips
  18. (转)Java RMI远程方法调用详解
  19. Opencv学习笔记 - ArUco,一个开源的微型的现实增强库
  20. 力扣打卡(16):回溯算法:心静下来刷题。静心方可成事

热门文章

  1. 1. 深度生成模型-扩散模型(非均衡热力学的深度无监督学习)
  2. cropping IplImage most effectively
  3. 抖音淘宝电商直播运营SOP计划表格脚本
  4. 计量经济学常见模型经济含义解释
  5. 数据库|如何解决数据库插入中文字体时显示问号
  6. SDK视频渲染测试流程
  7. Fiddler新版全平台适配抓包,关键还免费,再也不用费劲找破解版了
  8. 在线PS,MATLAB,AutoCAD等软件
  9. 聚合固码,聚合支付接口,三方支付接口
  10. 从配置Druid,学习@ConfigurationProperties注解方法