【问题标题】:select all from a JPQL query, with paremeters从 JPQL 查询中全选,带参数
【发布时间】:2014-10-18 00:42:36
【问题描述】:

我有平面数据的选择参数,只是不知道如何完全省略参数,或使其成为完整的通配符。搜索可能使用一个或所有参数。这是怎么做到的?使用ANYALL?或者,还有其他方法吗?

我想对所有参数使用一个通用查询,并为这些参数中的一些传入“all”或“any”,类似这些内容。

现有代码:

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();
    }
}

【问题讨论】:

    标签: java sql database jpa jpql


    【解决方案1】:

    如果参数是可选的,标准 API 会提供更多的灵活性。 如果经常调用selectWithParameters,考虑使用参数,因为DB可以缓存参数化查询。

    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;
    }
    

    【讨论】:

      【解决方案2】:

      谢谢你,海纳。这行得通,不知道为什么我对 Heiner 的代码有问题,但他的示例让我朝着正确的方向前进:

      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;
      }
      

      与海纳的回答可能没有实质性区别(?)。 JPA 和 JPQL 有点模糊。我不敢相信,但我几乎更喜欢 SQL!我得调整一下。

      【讨论】:

        猜你喜欢
        • 2016-03-29
        • 2018-11-07
        • 2021-08-22
        • 2019-10-15
        • 2018-08-15
        • 2017-08-14
        • 2013-04-04
        • 2014-07-23
        • 1970-01-01
        相关资源
        最近更新 更多