简体   繁体   English

从带有参数的JPQL查询中选择全部

[英]select all from a JPQL query, with paremeters

I have selection parameters on flat data, only don't know how to either omit a parameter entirely, or make it a complete wildcard. 我在平面数据上有选择参数,只知道如何完全省略参数,或者使其成为完整的通配符。 The search might use one or all parameters. 搜索可能使用一个或所有参数。 How is this done? 这是怎么做到的? With ANY or ALL ? 随着ANYALL Or, is there another way? 或者,还有另一种方式吗?

I would like to use one general query with all the paremeters, and pass in "all" or "any", something along those lines, for some of those parameters. 我想对所有参数使用一个通用查询,并传递“全部”或“任何”,这些行中的某些参数。

existing code: 现有代码:

package legacy.database;

import java.sql.Timestamp;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

public class MyQueries {

    private static final Logger log = Logger.getLogger(MyQueries.class.getName());
    private final EntityManagerFactory emf = Persistence.createEntityManagerFactory("LegacyDatabasePU");
    private final EntityManager em = emf.createEntityManager();

    public MyQueries() {
    }

    public List<Clients> findAll() {
        Query q = em.createQuery("select c from Clients c");
       List<Clients> clients = q.getResultList();
        return clients;
    }

    public List<Clients> selectWithParameters(Criteria c) {
        log.info(c.toString());
        String opener = c.getOpener();
        String closer1 = c.getCloser1();
        String status = c.getStatus();
        Query q = em.createQuery(
                "SELECT c FROM Clients c "
                + "WHERE c.status like :status "
                + "and c.closer1 like :closer1 "
                + "and c.opener like :opener");
        q.setParameter("opener", opener);
        q.setParameter("closer1", closer1);
        q.setParameter("status", status);
        log.info(q.toString());
        List<Clients> clients = q.getResultList();
        log.fine(clients.toString());
        return clients;
    }

    public Clients findById(int id) {
        Clients client = em.find(Clients.class, id);
        return client;
    }

    public void send(int id) {
        Clients c = em.find(Clients.class, id);
        java.util.Date date = new java.util.Date();
        Timestamp t = new Timestamp(date.getTime());
        em.getTransaction().begin();
        c.setDateUpdated(t.toString());
        em.getTransaction().commit();
    }
}

In case the parameters are optional, the criteria API provides some more flexibility. 如果参数是可选的,则标准API提供了一些更大的灵活性。 If the selectWithParameters is called often, consider using parameters, since the DB can cache the parametrized query then. 如果经常调用selectWithParameters ,请考虑使用参数,因为DB可以缓存参数化查询。

selectWithParameters with optional parameters reads like this: 带有可选参数的selectWithParameters读取如下:

public List<Clients> selectWithParameters(Criteria criteria) {
    log.info(criteria.toString());
    String opener = criteria.getOpener();
    String closer1 = criteria.getCloser1();
    String status = criteria.getStatus();

    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Clients> query = criteriaBuilder.createQuery(Clients.class);
    Root<Clients> c = query.from(Clients.class);
    List<Predicate> wherePredicates = new LinkedList<Predicate>();
    if (null != status) {
        wherePredicates.add(criteriaBuilder.like(c.get("status"), status));
    }
    if (null != closer1) {
        wherePredicates.add(criteriaBuilder.like(c.get("closer1"), closer1));
    }
    if (null != opener) {
        wherePredicates.add(criteriaBuilder.like(c.get("opener"), opener));
    }
    query.where(wherePredicates.toArray(new Predicate[0]));

    List<Clients> clients = em.createQuery(query).getResultList();
    log.fine(clients.toString());
    return clients;
}

Thank you, Heiner. 海纳,谢谢你。 This worked, not sure why I had trouble with Heiner's code, but his sample put me in the right direction: 这工作,不知道为什么我遇到海纳的代码有问题,但他的样本让我朝着正确的方向:

public List<Clients> selectByCriteria(Criteria criteria) {
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Clients> clientCriteriaQuery = criteriaBuilder.createQuery(Clients.class);
    Root<Clients> clientRoot = clientCriteriaQuery.from(Clients.class);
    clientCriteriaQuery.select(clientRoot);
    List<Predicate> predicates = new ArrayList<>();
    predicates.add(criteriaBuilder.like(clientRoot.get(Clients_.phone1), "%" + criteria.getPhone1() + "%"));
    if (!criteria.getOpener().equalsIgnoreCase("all")) {
        predicates.add(criteriaBuilder.like(clientRoot.get(Clients_.opener), "%" + criteria.getOpener() + "%"));
    }
    if (!criteria.getCloser1().equalsIgnoreCase("all")) {
        predicates.add(criteriaBuilder.like(clientRoot.get(Clients_.closer1), "%" + criteria.getCloser1() + "%"));
    }
    if (!criteria.getStatus().equalsIgnoreCase("all")) {
        predicates.add(criteriaBuilder.like(clientRoot.get(Clients_.status), "%" + criteria.getStatus() + "%"));
    }
    clientCriteriaQuery.where(predicates.toArray(new Predicate[0]));
    List<Clients> clients = em.createQuery(clientCriteriaQuery).getResultList();
    return clients;
}

There's probably no substantive difference (?) from what Heiner answered. 海纳的回答可能没有实质性的差异(?)。 JPA and JPQL are a bit murky. JPA和JPQL有点模糊。 I can't believe it, but I almost prefer SQL! 我简直不敢相信,但我几乎更喜欢SQL! I'll have to adjust. 我得调整一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM