JPQL中如何正确使用LIKE与CASE子句?@Query注解查询报错排查
问题原因
默认@Query注解使用HQL(Hibernate查询语言)进行语法解析,你写入的是原生SQL语句,语法规则不匹配导致启动校验失败。同时你提供的Repository代码末尾存在重复的方法定义,属于Java语法错误,也会导致编译问题。
解决方案
方案1:直接使用原生SQL执行(推荐)
你已经确认原生SQL可以正常运行,只需要在@Query注解中添加nativeQuery = true属性,指定该语句按原生SQL解析即可,同时删除末尾重复的冗余方法定义。
修正后的代码如下:
package stpt.Repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import stpt.entities.StopTimes; import java.util.List; public interface StopTimesRepository extends JpaRepository<StopTimes,String> { @Query("SELECT arrivalTime FROM StopTimes st WHERE tripId IN (:id)") List<String> findBySpecificTime(@Param("id") String id); // 新增nativeQuery = true属性指定使用原生SQL @Query(value = "SELECT distinct st.arrivalTime " + "FROM StopTimes st, Trips t, Routes r, Stops s " + "WHERE r.routeShortName IN (:short_name) " + "AND t.tripHeadsign IN (:heading) " + "AND st.tripId=t.tripId " + "AND t.routeId=r.routeId " + "AND s.stopId=st.stopId " + "AND CASE WHEN dayname(current_date())='saturday' OR dayname(current_date())='sunday' THEN t.serviceId like '%-sd' else t.serviceId like '%-lv' END " + "AND CASE HOUR(current_time())=11 THEN st.arrivalTime LIKE '23%' else st.arrivalTime LIKE '23%' END " + "AND s.stopName IN (:stop)", nativeQuery = true) List<String> findByArrivalTime(@Param("short_name") String short_name, @Param("heading") String heading, @Param("stop") String stop); }
方案2:改写为HQL语法
如果要使用HQL,需要做如下调整:
- 逗号分隔的隐式表关联改为显式JOIN关联
- CASE表达式调整为HQL支持的格式,数据库原生函数如果HQL不支持需要自行注册自定义函数
- 所有字段名要和实体类的属性名保持一致,不能直接使用数据库表字段名
额外注意事项
你当前IN关键字对应的参数都是String单值类型,如果后续需要支持多值匹配,请将参数类型改为List<String>。
内容的提问来源于stack exchange,提问作者Cristi
相关产品推荐
相关产品推荐

