【问题标题】:How to make a dynamic query for MySQL如何对 MySQL 进行动态查询
【发布时间】:2015-07-14 11:05:31
【问题描述】:

我使用了Spring MVC,如何对Mysql进行动态查询? 我的控制器中有类似的东西:public String getNewsByDateAndAuthor(Model model, HttpServletRequest request) {}

如何使用我的 URL 中的所有参数和 request.getParameterMap(),而我的地图是 <String, List<String>> 来创建一个动态查询?

例如,如果我有 3 个参数,我想生成一个这样的查询:

SELECT * FROM news WHERE parameter = IN(val1, val2...) AND parameter2 = IN(val1, val2...) AND parameter3 = IN(val1, val2...)

或者类似的,我只有一个参数;

SELECT * FROM news WHERE parameter = IN(val1, val2...)

如果有人知道,请告诉我如何做到这一点。

我想要一些这样的代码:

public String getQuery(Map<String,List<String>> parameters){
        List<String> author = new ArrayList<>();
        List<String> startDate = new ArrayList<>();
        List<String> endDate = new ArrayList<>();
        List<String> categories = new ArrayList<>();
        List<String> about = new ArrayList<>();
        List<String> soureID = new ArrayList<>();

        if (!parameters.get("author").isEmpty())
            for (int i = 0; i < parameters.get("author").size(); i++) {
                author.add(parameters.get("author").get(i));
            }

        if (!parameters.get("startDate").isEmpty())
            for (int i = 0; i < parameters.get("startDate").size(); i++) {
                startDate.add(parameters.get("startDate").get(i));
            }

        if (!parameters.get("endDate").isEmpty())
            for (int i = 0; i < parameters.get("endDate").size(); i++) {
                endDate.add(parameters.get("endDate").get(i));
            }

        if (!parameters.get("categories").isEmpty())
            for (int i = 0; i < parameters.get("categories").size(); i++) {
                categories.add(parameters.get("categories").get(i));
            }

        if (!parameters.get("about").isEmpty())
            for (int i = 0; i < parameters.get("about").size(); i++) {
                about.add(parameters.get("about").get(i));
            }

        if (!parameters.get("soureID").isEmpty())
            for (int i = 0; i < parameters.get("soureID").size(); i++) {
                soureID.add(parameters.get("soureID").get(i));
            }

        StringBuilder queryBuilder = new StringBuilder();
        queryBuilder.append("SELECT * FROM news WHERE");

        if (!author.isEmpty()) {
            String authors = author.toString();
            authors.replace(" ", " , ");
            queryBuilder.append(" author = IN ( " + authors + " ) AND");
        }
        if (!startDate.isEmpty()) {
            String startDates = startDate.toString();
            startDates.replace(" ", " , ");
            queryBuilder.append(" author = IN ( " + startDates + " ) AND");
        }
        if (!endDate.isEmpty()) {
            String endDates = endDate.toString();
            endDates.replace(" ", " , ");
            queryBuilder.append(" author = IN ( " + endDates + " ) AND");
        }
        if (!categories.isEmpty()) {
            String categoriesR = categories.toString();
            categoriesR.replace(" ", " , ");
            queryBuilder.append(" author = IN ( " + categoriesR + " ) AND");
        }
        if (!about.isEmpty()) {
            String abouts = about.toString();
            abouts.replace(" ", " , ");
            queryBuilder.append(" author = IN ( " + abouts + " ) AND");
        }
        if (!soureID.isEmpty()) {
            String sourceIDs = soureID.toString();
            sourceIDs.replace(" ", " , ");
            queryBuilder.append(" author = IN ( " + sourceIDs + " ) AND");
        }

        queryBuilder.delete(queryBuilder.length() - 3, queryBuilder.length());

        String query = queryBuilder.toString();

        return query;
}

【问题讨论】:

  • 不,您不想要这样的方法,您不想使用 String concat 创建动态查询。请改用Criteria API。

标签: java mysql spring-mvc dynamicquery dynamic-queries


【解决方案1】:

您不想要这样的方法,也不想使用字符串连接来创建动态查询。您想为此使用Criteria API

类似下面的东西

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<News> cq = cb.createQuery(News.class);
Root<News> news = cq.from(News.class);

if (!parameters.get("author").isEmpty()) {
    cq.where(cb.in(news.get("author"), parameters.get("author"));
}

TypedQuery<News> query = em.createQuery(cq);
return query.getResultList();

由于您有多个结果,您可能首先要创建Predicates 的列表,然后使用cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()]); 应用它们。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<News> cq = cb.createQuery(News.class);
Root<News> news = cq.from(News.class);
List<Predicate> predicates = new ArrayList<Predicate>();

if (!parameters.get("author").isEmpty()) {
    predicates.add(cb.in(news.get("author"), parameters.get("author")));
}

// Other params here.

cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()]));
TypedQuery<News> query = em.createQuery(cq);
return query.getResultList();

【讨论】:

  • Ehrm 没有,因为它们都驻留在 java.persistence 包或其子包之一中。只需包含 JPA 依赖项并让您的 IDE 解决。
  • 那是EntityManager 我假设你在哪里使用JPA(如果不是这种方法是行不通的)。如果您使用纯 SQL 而不是 JPA (HQL),则此方法将不起作用。但你的问题并不清楚。
  • 我该如何定义呢?实体管理器 em; CriteriaBuilder cb = em.getCriteriaBuilder();?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 2021-03-07
  • 2020-04-02
相关资源
最近更新 更多