Reputation: 4474
I want to perform a query like this:
SELECT * FROM table WHERE
col1 = 'value1' OR
col2 = 'value2' OR
col3 = 'value3' OR
col4 = 'value4';
Using Spring's JpaRepository
I should use something like this:
List<MyEntity> findByCol1OrCol2OrCol3OrCol4(
String col1, String col2, String col3, String col4
);
Now imagine I don't want to check 4 columns but 10 or 20, the method name would be really long!
I have seen in this answer that I could use Specification
to search the same text in many columns, but I want different text values for every one.
Is there any way to shorten the find method and add the columns (and the corresponding values) dynamically?
Thanks
Upvotes: 1
Views: 211
Reputation: 191
This can be achieved via Specifications and Map(attribute name, value). Code sample (works for any data):
Map<String, Object> whereClause = new HashMap<>();
whereClause.put("lastname", "Super-Lastname");
whereClause.put("firstname", "Firstńame");
userRepository.findOne(Specifications.where(
CommonSpecifications.attributesEquals(whereClause))
)
public static <T> Specification<T> attributesEquals(Map<String, Object> whereClause) {
return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream()
.filter(a -> whereClause.keySet().contains(a.getName()))
.map(a -> builder.equal(root.get(a.getName()), whereClause.get(a.getName())))
.toArray(Predicate[]::new));
}
Upvotes: 1