Spring JPA Repository如何实现带括号的WHERE子句查询?
解决Spring JPA Repository查询逻辑匹配问题
你的问题出在JPA派生查询的运算符优先级上:And的优先级高于Or,所以findByUserOrEmailAndMdp会被解析成user=? OR (email=? AND mdp=?),和你想要的(user=? OR email=?) AND mdp=?逻辑不符。下面是两种正确的实现方式:
方式一:使用@Query注解(推荐)
直接通过JPQL或原生SQL精确控制条件的括号逻辑,避免派生查询的歧义:
JPQL版本(面向实体)
@Repository("UtilisateurRepo") public interface UtilisateurRepo extends JpaRepository<Utilisateur,String> { @Query("SELECT u FROM Utilisateur u WHERE (u.user = :user OR u.email = :email) AND u.motDePasse = :mdp") Utilisateur findByCredentials(@Param("user") String user, @Param("email") String email, @Param("mdp") String mdp); }
注意实体类的属性名要和JPQL中的字段对应(比如实体里密码字段是motDePasse,对应数据库的mot_de_passe)。
原生SQL版本(直接操作数据库表)
如果更习惯写原生SQL,可以开启nativeQuery=true:
@Repository("UtilisateurRepo") public interface UtilisateurRepo extends JpaRepository<Utilisateur,String> { @Query(value = "select user, email, mot_de_passe from utilisater where (user=:user or email=:email) and mot_de_passe= :mdp", nativeQuery = true) Utilisateur findByCredentials(@Param("user") String user, @Param("email") String email, @Param("mdp") String mdp); }
方式二:修正派生查询方法命名
JPA支持通过方法名中的括号来分组条件,实现你需要的逻辑:
@Repository("UtilisateurRepo") public interface UtilisateurRepo extends JpaRepository<Utilisateur,String> { Utilisateur findBy(UserOrEmail)AndMotDePasse(String user, String email, String motDePasse); }
不过这种方式可读性稍差,对于复杂条件容易出错,不如@Query直观。
内容的提问来源于stack exchange,提问作者OmB
相关产品推荐
相关产品推荐

