Java JPA标准查询。如何摆脱字符串参数。在条件api中生成不带字符串的查询。类型安全查询

Java JPA标准查询。如何摆脱字符串参数。在条件api中生成不带字符串的查询。类型安全查询,java,eclipse,jpa,types,criteria-api,Java,Eclipse,Jpa,Types,Criteria Api,我正在尝试从JPA JPQL查询转移到我的应用程序中的条件查询 主要原因是我已经厌倦了重构字符串和修复大量运行时jpa异常,这些异常是由非类型安全JPQL的引起的 我在网上搜索了其他支持类型安全和ide重构机制的JPA解决方案。条件查询似乎很有希望 有一个问题困扰着我: 在方法参数中使用字符串。 是否可以用类型安全的java对象/变量(可能是java反射)来替换它 下面是示例代码: public List<BankAccount> findWithBalance(int amount

我正在尝试从JPA JPQL查询转移到我的应用程序中的条件查询

主要原因是我已经厌倦了重构字符串和修复大量运行时jpa异常,这些异常是由非类型安全JPQL的引起的

我在网上搜索了其他支持类型安全和ide重构机制的JPA解决方案。条件查询似乎很有希望

有一个问题困扰着我:

在方法参数中使用字符串。 是否可以用类型安全的java对象/变量(可能是java反射)来替换它

下面是示例代码:

public List<BankAccount> findWithBalance(int amount) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<BankAccount> cq = cb.createQuery(BankAccount.class);
    Root<BankAccount> from = cq.from(BankAccount.class);

    ParameterExpression<Integer> balance = cb.parameter(Integer.class);
    cq.select(from);

    Predicate predicate = cb.gt(from.<Integer> get("balance"), balance);

    cq.where(predicate);
    cq.orderBy(cb.asc(from.get("ownerName")));

    TypedQuery<BankAccount> query = em.createQuery(cq);

    query.setParameter(balance, amount);

    return query.getResultList();
}
public List findWithBalance(整数金额){
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(BankAccount.class);
Root-from=cq.from(BankAccount.class);
ParameterExpression balance=cb.parameter(Integer.class);
cq.选择(从中);
谓词=cb.gt(from.get(“balance”)、balance;
cq.where(谓词);
cq.orderBy(cb.asc(from.get(“ownerName”));
TypedQuery=em.createQuery(cq);
query.setParameter(余额、金额);
返回query.getResultList();
}
如您所见,字符串有以下几种:

  • “余额”
  • “所有者名称”
若我要更改这个参数的名称,我就不会在IDE或编译时出错。我将不得不在运行时测试它,这在像我这样的大型项目上是不好的

我使用:

  • 带hibernate的JPA
  • jdbc
  • 游戏框架

请提供帮助。

元模型生成器似乎也是一个很好的解决方案:

示例实体:

@Entity
public class Order {
    @Id
    @GeneratedValue
    Integer id;
    @ManyToOne
    Customer customer;
    @OneToMany
    Set<Item> items;
    BigDecimal totalCost;
    // standard setter/getter methods
}
因此,我们可以按如下方式构建类型安全的sql查询:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);
CriteriaBuilder cb=entityManager.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(Order.class);
SetJoin itemNode=cq.from(Order.class).join(Order.items);
cq.where(cb.equal(itemNode.get(Item.id),5)).distinct(true);


创建一个元模型,并使用该元模型而不是硬编码的值。请参阅。或者使用一些框架(例如)。作为标准查询的替代方案,我将尝试查询DSL()。QueryDSL查询更易于读写。typesafty还基于生成的类。谢谢你的评论。你能告诉我们关于元模型的想法吗?是否有可能自动生成元模型类?或者我必须始终手动定义该元模型类,创建具有相同名称且结尾带有下划线的java类吗?“仅链接”回复不受鼓励,因为每当URL被破坏时(服务器停机、内容移动等),它们都会被破坏。问题应该在文本中回答;之后,您可以添加您认为有助于提供深入解释的链接。
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
SetJoin<Order, Item> itemNode = cq.from(Order.class).join(Order_.items);
cq.where( cb.equal(itemNode.get(Item_.id), 5 ) ).distinct(true);