【问题标题】:Return substring starting from the N occurrence返回从 N 次出现的子字符串
【发布时间】:2016-10-23 03:06:16
【问题描述】:

如何在查询JPA中QueryDsl中使用该功能

SUBSTRING_INDEX(str,delim,count)

返回字符串 str 在出现 count 分隔符 delim 之前的子字符串。

更新 1: 在尝试了这样的@MaciejDobrowolski 解决方案后:

QAcheteur ach = new QAcheteur("ach");
new JPAQuery(entityManager).from(ach)
 .list( Expressions.stringTemplate("SUBSTRING_INDEX({0},',',1)", ach.ancestors)  );

我收到了这个错误:

java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'SUBSTRING_INDEX' {originalText=SUBSTRING_INDEX}
    \-[EXPR_LIST] SqlNode: 'exprList'
       +-[DOT] DotNode: 'acheteur1_.ancestors' {propertyName=ancestors,dereferenceType=PRIMITIVE,getPropertyPath=ancestors,path=ach.ancestors,tableAlias=acheteur1_,className=persistence.Acheteur,classAlias=ach}
       |  +-[ALIAS_REF] IdentNode: 'acheteur1_.ID_ACHETEUR' {alias=ach, className=persistence.Acheteur, tableAlias=acheteur1_}
       |  \-[IDENT] IdentNode: 'ancestors' {originalText=ancestors}
       +-[QUOTED_STRING] LiteralNode: '',''
       \-[NUM_INT] LiteralNode: '3'

更新 2:(解决方案) 按照@DraganBozanovic 的回答,我创建了我的自定义方言来使用No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode,因为SUBSTRING_INDEXJPA 中是未知的,所以我们使用我们自己的方言来使其工作。

package dialect;

import org.hibernate.dialect.MySQL5Dialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;

public class CustomMySQLDialect extends MySQL5Dialect {

    public CustomMySQLDialect() {
        super();
        registerFunction("substring_index", new StandardSQLFunction("substring_index", StandardBasicTypes.STRING));
        registerFunction("replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING));
        ....
    }
}

在 JPA 配置中

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      ...
      ...
     <property name="jpaProperties">
         <props>
            <prop key="hibernate.dialect">dialect.CustomMySQLDialect</prop>
         </props>
      </property>
</bean>

P.S :我决定编写解决方案,因为它是两个答案的组合。

【问题讨论】:

  • 你已经尝试了什么?
  • @Shachaf.Gortler 我尝试path.substring(path.locate(",", count)),但定位函数不是从 N 次出现而是从索引开始
  • @Youssef 请尽可能分享您的代码。
  • okey @SkyWalker 我在执行测试查询时分享这部分内容,如果您想要其他内容,请告诉我。

标签: java hibernate jpa querydsl


【解决方案1】:

最简单的方法是使用Expressions.stringTemplate

Expressions.stringTemplate("SUBSTRING_INDEX({0},',',3)", columnPath)

更新

好的,我已经设法让它工作了。 我使用的是H2 Database,所以我使用了函数SUBSTR

QAcheteur ach = new QAcheteur("ach");
new JPASQLQuery(entityManager, new H2Templates())
        .from(ach)
        .list(Expressions.stringTemplate("SUBSTR({0}, 1, 3)", ach.ancestors));

关键是不要使用JPAQuery,而是使用JPASQLQuery,因为此查询使用本机函数。您只需关注this 教程即可。

【讨论】:

  • 感谢@MaciejDobrowolski,但为什么是Integer.class?该函数必须返回一个字符串
  • @Youssef 抱歉,我读错了函数定义 :) 已更正,感谢您指出这一点
  • 感谢@MaciejDobrowolski 但现在我遇到了一个异常No data type for node 我在我的问题中进行了更新,以便您可以查看异常日志。
  • 感谢 MaciejDobrowolski,但解决方案是您的答案和@DraganBozanovic 的答案的结合。所以我很困惑奖励的答案是什么
【解决方案2】:

由此发生异常:

Expressions.stringTemplate("SUBSTRING_INDEX({0},',',3)", ach.ancestors)

异常:节点没有数据类型

SQL 查询使用列名,而 HQL 查询使用类属性。您正在从分类中选择 artifact_id,但分类类没有名为“artifact_id”的属性。要修复它,请使用 HQL 中的类属性。

SELECT artifactId FROM Classification

资源链接:

  1. No data type for node: org.hibernate.hql.internal.ast.tree.IdentNode HQL

【讨论】:

  • @Youssef 如果可能的话,你可以通过github分享你的代码,这样我就可以在本地生成并且可以提供帮助。
  • 这是一个大项目,我如何分享它?我也使用 svn 而不是 github
  • 我不能这是我工作的公司的私人项目,你必须生成一个大数据库才能使用我的代码
【解决方案3】:

Hibernate 方言中的Register the custom function

registerFunction("substring_index", new StandardSQLFunction("SUBSTRING_INDEX", StandardBasicTypes.STRING));

然后您将能够从 JPQL/HQL(以及在 JPA 之上使用 Querydsl)调用它。

【讨论】:

  • 但我使用文字 1 只是为了测试它可以动态更改或具有其他整数列的值。
  • @Youssef 好的,我不知道。
  • @Youssef 您可以注册自定义函数以便能够从 JPA 查询中调用它。编辑了答案。
  • 感谢 DraganBozanovic,解决方案是您的答案和 @MaciejDobrowolski 的答案的结合。所以我很困惑奖励的答案是什么
  • @Youssef 你不应该担心这个,等到赏金期结束,让社区投票决定。 :) 此外,也许在接下来的几天里还会出现其他一些好的答案......
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2021-04-07
  • 2017-04-03
  • 2010-12-25
  • 2016-05-07
  • 2021-02-10
相关资源
最近更新 更多