问题
Consider the following method on a Spring Data JPA interface:
@Query("select distinct :columnName from Item i")
List<Item> findByName(@Param("columnName") String columnName);
I would like to use such a method for performing queries dynamically using different column names on the same entity. How can this be done?
回答1:
You can't. You'll have to implement such a method by yourself. And you won't be able to use parameters: you'll have to use String concatenation or the criteria API. What you'll pass won't be a column name but a field/property name. And it won't return a List<Item>
, since you only select one field.
回答2:
You can use QueryDSL support built into Spring Data. See this tutorial to get started.
回答3:
First of all you must implement custom Spring Data repository by adding interface:
public interface ItemCustomRepository {
List<Item> findBy(String columnName, String columnValue);
}
then you must extend your current Spring Data repository interface with newly created i.e.:
public interface ItemRepository extends JpaRepository<Item, Long>, ItemCustomRepository, QueryDslPredicateExecutor {
}
and then you must implement your interface using Query DSL dynamic expression feature (the name ItemRepositoryImpl is crucial - it will let you use original Spring Data repository implementation):
public class ItemRepositoryImpl implements ItemCustomRepository {
@Autowired
private ItemRepository itemRepository;
public List<Item> findBy(final String columnName, final String columnValue) {
Path<Item> item = Expressions.path(Item.class, "item");
Path<String> itemColumnName = Expressions.path(String.class, item, columnName);
Expression<String> itemValueExpression = Expressions.constant(columnValue);
BooleanExpression fieldEqualsExpression = Expressions.predicate(Ops.EQ, itemColumnName, itemValueExpression);
return itemRepository.findAll(fieldEqualsExpression);
}
}
来源:https://stackoverflow.com/questions/31554479/how-can-i-add-columns-dynamically-to-a-spring-data-jpa-query