Как сделать динамический запрос для MySQL

Я использовал 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;
}

person Dumitru Vlad    schedule 14.07.2015    source источник
comment
Нет, вам не нужен такой метод, вы не хотите использовать String concat для создания динамического запроса. Вместо этого используйте Criteria API.   -  person M. Deinum    schedule 14.07.2015


Ответы (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();
person M. Deinum    schedule 14.07.2015
comment
Эм, нет, так как все они находятся в пакете java.persistence или в одном из его подпакетов. Просто включите зависимости JPA и позвольте вашей IDE разобраться с этим. - person M. Deinum; 14.07.2015
comment
Это EntityManager я предположил, что вы используете JPA (в противном случае этот подход не сработает). Если вы используете простой SQL вместо JPA (HQL), этот подход не будет работать. Но это не было ясно из вашего вопроса. - person M. Deinum; 14.07.2015
comment
и как я могу это определить? EntityManager em; CriteriaBuilder cb = em.getCriteriaBuilder();? - person Dumitru Vlad; 14.07.2015