如何使用EclipseLink解析Java Persistence Query Languare(JPQL)?

时间:2018-01-17 15:13:17

标签: jpa eclipselink jpql

我正在开发一个NamedQueryManager EJB,它从客户端接收一个JPQL字符串,并返回一个只选择用户有权读取的数据的查询。例如,如果客户端程序需要Companies,它将创建以下查询并发送到NamedQueryManager。

  • SELECT c FROM Company c

NamedQueryManager会考虑查询和当前用户,如果用户没有读取公司实体的完全权限,则会返回类似于以下内容的查询:

  • SELECT c FROM Company c where c.reader =:user

我没有创建自己的解析器,而是研究了EclipseLink 2.6.1并发现我可以执行以下操作来解析查询:

JPQLExpression jpql = new JPQLExpression(jpqlString, new JPQLGrammar2_1());

if (jpql.getQueryStatement() instanceof SelectStatement) {

    logger.debug("JPQL Expression is a Select statement.");

} else if (jpql.getQueryStatement() instanceof UpdateStatement) {

    logger.debug("JPQL Expression is a Update statement.");

} else if (jpql.getQueryStatement() instanceof DeleteStatement) {

    logger.debug("JPQL Expression is a Delete statement.");

} else {

    logger.debug("JPQL Expression is an unknown statement.");

}

然后我可以遍历QueryStatement的子节点并确定语句的各个部分。例如,以下循环遍历Select子句。

SelectStatement st = (SelectStatement) jpql.getQueryStatement();

logger.debug("JPQL Select Statement: {}", st);

logger.debug("********************");

SelectClause sc = (SelectClause) st.getSelectClause();

logger.debug("Select Clause: {}", sc);

for (Expression e : sc.children()) {

    logger.debug("Child: {}", e);

}

for (Expression e : sc.orderedChildren()) {

    logger.debug("Ordered Child: {}", e);

}

所以我的问题是我是否正确使用EclipseLink来解析和修改我的JPQL?

我对解析很满意但是如何修改?我应该使用解析的JPQL构建一个新的JPQL字符串,还是可以直接向解析的JPQL添加信息以创建新的查询?

我开始研究如何确定传递的jpql字符串是否有效,并在org.eclipse.persistence.internal.jpa.jpql包中找到对HermesParser类的引用。

我应该远离"内部"包?

我不认为以下用于解析jpql字符串的代码使用HermesParser,但是org.eclipse.persistence.jpa.jpql.parser package-info表示"这是爱马仕的核心,......"

JPQLExpression jpql = new JPQLExpression(jpqlString, new JPQLGrammar2_1()); 

所以这让我想问什么是爱马仕?

非常感谢任何大图片的帮助或参考。

注意:这是以下问题的延续。

Should I use @NamedQuery annotation or addNamedQuery method?

0 个答案:

没有答案