【问题标题】:Ormlite like query on map of fieldsOrmlite 类似字段地图上的查询
【发布时间】:2013-05-27 07:34:52
【问题描述】:

我已经使用 ORMLite 将近一年了,我发现它非常棒,它很简单而且很有效。

我有一个实现广泛搜索功能的项目要求 - 用户输入一个值,并且应该返回表中的任何匹配字段 (POJO)。表与 Java 对象具有简单的 1:1 关系。

我可以使用 queryBuilder().where().like(...) 为 KNOWN 类实现这一点,但是,我想为所有子类构建一个通用的动态函数。

我所有的持久类都派生自一个“持久”基类,该基类具有一些基本的内务管理、处理单个对象的存储和删除。这是我放置“查找”函数的地方,理想情况下它返回一个迭代器或一个 List,最好是一个迭代器。

我已经为所有 DatabaseField 带注释的字段提供了一个 Map现在,我只想要一个“蛮力”是字符串“X”出现在字段 Y 的任何位置。我会弄清楚数据类型转换并稍后检查。如果我可以动态构建查询,那么我可以在下一个版本中解决数据输入问题。

我查看了将地图作为参数的方法,它们是窄匹配的,即所有都必须匹配。我正在寻找相反的结果:任何匹配都可以。

我能想到的唯一方法是构建单独的“like”组件并将它们串在一起形成一个更大的语句,从文档中,我无法弄清楚如何动态地做到这一点。

欢迎提出任何建议。

【问题讨论】:

    标签: mapping ormlite


    【解决方案1】:

    好的,我弄乱了一些代码,这实现了我想要的——但我非常欢迎 cmets 改进或提出更好的方法来实现预期的结果。

     protected QueryBuilder<T, Long> getQuery(String text, boolean wide, boolean count) {
          if (null == fields)
             reflectKeyInfo();
    
          QueryBuilder<T, Long> qb = null;
    
          if (count)
             qb = getDao().queryBuilder().setCountOf(true);
          else
             qb = getDao().queryBuilder();
    
          if (null == qb)
             return null;
    
          Where<T, Long> where = qb.where();
    
          boolean equals = text.contains("=") ;
          boolean like   = text.contains("~") ;
    
          if (equals || like)  {
             String field = null ;
             String value = null ;
    
             try {
                if (equals) {
                   field = Strings.left(text, text.indexOf("=")) ;
                   value = Strings.right(text, text.indexOf("=")) ;
    
                   if (Strings.isValid(field) && Strings.isValid(value))
                      where.eq(field, value) ;
                }
                else
                   if (like) {
                      field = Strings.left(text, text.indexOf("~")) ;
                      value = Strings.right(text, text.indexOf("~")) ;
    
                      if (Strings.isValid(field) && Strings.isValid(value))
                         where.like(field, "%" + value + "%") ;
                   }
                }
             catch (SQLException e) {
                lastError = GlobalConfig.log(e, true) ;
                Dialogs.alert("Query Failed",
                                   "<br />Unable to extract field and value from " +
                                   field + "=" + value + "<br />" + lastError) ;
             }
          }
          else
             for (String field : fields.keySet()) {
                try {
                   if (fields.get(field).isAssignableFrom(String.class)) {
                      if (wide)
                         where.like(field, "%" + text + "%");
                      else
                         where.eq(field, text);
    
                      where.or();
                   }
                }
                catch (SQLException e) {
                   lastError = GlobalConfig.log(e, true);
                }
             } // for
          return qb;
      }
    

    【讨论】:

    • 这看起来可行。需要考虑的一件事是,您可以将多个eq(...)like(...) 子句与Where.or(int) 命令一起提交。因此,您可以计算 eqlike 子句的数量,然后只需执行 where.or(clauseCount) ,这会将它们与 SQL OR 串在一起。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 2018-07-10
    相关资源
    最近更新 更多