Podczas korzystania z interfejsu API JPA Criteria, jaka jest zaleta bezpośredniego używania parametru ParameterExpression? Na przykład. kiedy chcą, aby szukać klienta wg nazwy w zmiennej String, mogę napisać coś podobnegoprzy użyciu wyrażenia ParameterExpression w porównaniu z JPA Criteria API
private List<Customer> findCustomer(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> criteriaQuery = cb.createQuery(Customer.class);
Root<Customer> customer = criteriaQuery.from(Customer.class);
criteriaQuery.select(customer).where(cb.equal(customer.get("name"), name));
return em.createQuery(criteriaQuery).getResultList();
}
z parametrami staje:
private List<Customer> findCustomerWithParam(String name) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> criteriaQuery = cb.createQuery(Customer.class);
Root<Customer> customer = criteriaQuery.from(Customer.class);
ParameterExpression<String> nameParameter = cb.parameter(String.class, "name");
criteriaQuery.select(customer).where(cb.equal(customer.get("name"), nameParameter));
return em.createQuery(criteriaQuery).setParameter("name", name).getResultList();
}
Dla zwięzłości wolałbym pierwszą drogę, zwłaszcza gdy zapytanie staje się dłuższe z opcjonalnymi parametrami. Czy są jakieś wady używania takich parametrów, jak SQL injection?
Nie mogę mówić w ogóle o JPA , ale dowiedziałem się, że OpenJPA wewnętrznie konwertuje zapytanie Kryterium do JPQL i można to wydrukować za pomocą funkcji specyficznej dla OpenJPA (zobacz htt p: //openjpa.apache.org/builds/2.1.1/apache-openjpa/docs/ch13s03.html). Pierwsze zapytanie oznacza "WYBIERZ c Z klienta c GDZIE c.nazwa =" test klienta "". Oznacza to, że NIE korzysta z parametru, więc jeśli zostanie on dalej przetłumaczony na SQL, odpowiednia przygotowana instrukcja NIE użyje parametru. Druga wersja przekłada się na JPQL "SELECT c FROM Customer c WHERE c.name =: name", więc użyję parametrów. –
Po kilku dalszych testach stwierdziłem, że pisanie tego samego zapytania z JPQL i używanie nazwy "OR" x '= "x" wstrzykuje JPQL. Podczas korzystania z kryterium API wygenerowany plik JPQL, który loguje OpenJPA wygląda dokładnie tak samo. Jednak rzeczywisty SQL, który jest rejestrowany przez OpenJPA, następnie używa przygotowanej instrukcji z parametrem o wartości "" LUB "x" = "x" zamiast "" w przypadku JPQL.Oznacza to, że SQL injection nie działa tutaj! Niestety nie mam pojęcia, jak wiarygodne jest to. Wydaje się, że to nieudokumentowana funkcja. –
Wskazówka: Właśnie wypróbowałem http://www.querydsl.com/, a jego składnia jest znacznie bardziej zwięzła i czytelna. Wydaje się chronić przed iniekcją sql przy użyciu parametrów domyślnie. –