我一直在使用标准JPA实现,并且在创建动态查询时没有问题,因为算法会搜索数据库中的用户。但是,我们正在转向Spring Framework(不幸的是旧版本 - 3.2),我根本无法弄清楚如何在Spring中创建动态查询。
使用javax.persistance.EntityManager
,我可以调用createQuery
并为其提供一个字符串。但是,我发现在Spring中我只能使用类似下面的代码,我在注释中定义查询。
@Repository
@SuppressWarnings("unused")
public interface PersonRepository extends JpaRepository<Person, Long>, CrudRepository<Person, Long> {
@Override
List<Person> findAll(Sort sort);
@Override
List<Person> findAll();
@Query("SELECT p FROM Person p ORDER BY p.lname ASC, p.fname ASC, p.mname ASC")
List<Person> findAllSort();
@Query("SELECT p FROM Person p WHERE UPPER(p.userName) = UPPER(?1)")
Person findPersonByUsername(String username);
}
这是我能给你的最简单的动态查询示例,我想为Spring复制:
public List<Person> getPersons(List<Long> perIds) {
List<Person> persons;
String whereClause = "";
for (int i = 0; i < perIds.size(); i++) {
if (i != 0)
whereClause += " OR ";
whereClause += "p.perId = '" + perIds.get(i) + "'";
}
persons = em.createQuery("SELECT p FROM Person p WHERE " + whereClause).getResultList();
return persons;
}
也许是一个更好的问题这里是询问是否可能,或者我是否应该使用实体管理器保留我的实现。话虽如此,是否有人推荐我将我的代码从使用EntityManager更改为使用Spring Framework?
答案 0 :(得分:2)
我不知道我们能不能按你的要求做。 但我可以替代你的方法。
public List<Person> getPersons(List<Long> perIds) {
return em.createQuery(
"SELECT p FROM Person p WHERE p.perId = "
+ org.springframework.util.StringUtils.collectionToDelimitedString(perIds, " OR p.perId = ", "'", "'")
).getResultList();
}
答案 1 :(得分:1)
Spring 允许使用@Repository
,但强制你这样做。 Spring甚至提供了一个很好的JPA接口,它将低级别的关注点(数据源定义和事务管理)与高级别的关注点(DAO,声明性事务)区分开来。
Spring Framework Reference Manual中有一个关于JPA的chapter。您还应该阅读前几章中有关事务管理的部分。
答案 2 :(得分:1)
为什么不使用IN
查询条件?
Spring应该允许你这样做:
@Query( "SELECT p FROM Person p WHERE p.perId in :ids" )
findPersonsInIdList(@Param("ids") List<Long> perIds);
答案 3 :(得分:-1)
请考虑下面的示例。也许您正在寻找类似的东西。尽管您的问题不是很简单,但是想要使用标准或规范,您可以实现很多很棒的事情。
@Service
Optional<Person> findByEmail(String email);
@NoRepositoryBean
public interface PersonRepositoryCustom {
Optional<Person> findByEmail(String email);
}
@Repository
public class PersonRepositoryImpl extends QuerydslRepositorySupport implements PersonRepositoryCustom {
public PersonRepositoryImpl() {
super(Person.class);
}
@Override
public Optional<Person> findByEmail(String email) {
JPAQuery<Person> query = getQuerydsl()
.createQuery()
.from(QPerson.person)
.where(QPerson.person.email.equalsIgnoreCase(email))
.select(QPerson.person);
return query.fetch().stream().findFirst();
}
}