Per JB Nizet i spring-data documentation, należy użyć niestandardowego interfejsu + repozytorium realizację.
Załóż interfejs z metodą:
public interface MyEntityRepositoryCustom {
List<User> findByFilterText(Set<String> words);
}
Utwórz realizacji:
@Repository
public class MyEntityRepositoryImpl implements MyEntityRepositoryCustom {
@PersistenceContext
private EntityManager entityManager;
public List<User> findByFilterText(Set<String> words) {
// implementation below
}
}
rozszerzyć nowy interfejs w istniejącym interfejsu repozytorium
public interface MyEntityRepository extends JpaRepository<MyEntity, Long>, MyEntityRepositoryCustom {
// other query methods
}
Wreszcie nazywamy metoda gdzie indziej:
dao.findByFilterText(new HashSet<String>(Arrays.asList(filterText.split(","))));
realizacja zapytań
Twój sposób wytwarzania zmiennej sql
, mianowicie poprzez złączenie sznurki do zapytania jest zła. Nie rób tego.
The word
którym jest łączenie musi być valid JPQL identifier, mianowicie :
następnie java identifier start, po czym ewentualnie jakiegoś java identifier part. Oznacza to, że jeśli Twój plik CSV zawiera foo bar,baz
, spróbujesz użyć foo bar
jako identyfikatora, a otrzymasz wyjątek.
Można zamiast tego użyć CriteriaBuilder
skonstruować kwerendę w sposób bezpieczny:
public List<User> findByFilterText(Set<String> words) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> q = cb.createQuery(User.class);
Root<User> user = q.from(User.class);
Path<String> namePath = user.get("name");
Path<String> userTypeClassTypeDisplayName =
user.get("userType").get("classType").get("displayName");
Path<String> userTypeModel = user.get("userType").get("model");
List<Predicate> predicates = new ArrayList<>();
for(String word : words) {
Expression<String> wordLiteral = cb.literal(word);
predicates.add(
cb.or(
cb.like(cb.lower(namePath), cb.lower(wordLiteral)),
cb.like(cb.lower(userTypeClassTypeDisplayName),
cb.lower(wordLiteral)),
cb.like(cb.lower(userTypeModel), cb.lower(wordLiteral))
)
);
}
q.select(doc).where(
cb.and(predicates.toArray(new Predicate[predicates.size()]))
);
return entityManager.createQuery(q).getResultList();
}
spójrz na 'JpaSpecificationExecutor' –
Udostępnienie implementacji dla DAO i wykonanie tego kwerendy dynamicznej z implementacji. http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.single-repository-behavour. DAO nie powinien się dzielić. Powinien mieć jako argument List lub Set . Dzwoniący powinien poradzić sobie z dzieleniem. –