Spring Data JPA查询使用小结
JPA常用的查询方式
通过方法名构造查询
适合简单的单表查询(一般不适合or查询,因为and优先级比较高, 只能findBy1And2Or1And3,这种比较蹩脚的方式)
User findByUserId(long userId);
@Query注解,
适合稍复杂的查询。
注意这种情况下不是纯粹的SQL,这里的表达式里的表名要和当前的Entity一致,查询参数也要和实体进行对应起来,是userName而不是user_name。
注意,这种情况下不能select * , 同时limit也不能使用。
如果需要select *,可以这样 select a from User a;
@Query("select c from User c where c.userName = ?1")
User findByUserName(String userName);
如果需要使用纯粹的SQL,需要标记上nativeQuery
这样就能够使用纯SQL
@Query(value = "select * from user where userName = ?1 limit 1", nativeQuery = true)
User findByUserName(String userName);
通过Predicate构造查询
适用单表查询。
可以使用Specification工具类
Specification.where(eq(MarketingJob_.userId, userId))
.and(eq(MarketingJob_.status, search.getStatus()));
如果有复杂的不定条件的连表查询咋整?
default void updateModifiedOperatorAndUserModified(long id, String modifiedOperator, LocalDateTime userModified) {
String sql = "update flow_marketing_job set modified = NOW(), modified_operator = (:modifiedOperator)," +
" user_modified = (:userModified) where id = (:id)";
ImmutableMap<String, Object> params = ImmutableMap.of(
"modifiedOperator", modifiedOperator,
"userModified", userModified,
"id", id
);
getNamedParameterJdbcTemplate().update(sql, params);
}
有点让人窒息
多讲一下多个or和and同时使用的场景
通过方法名构造查询方法的情况下不建议适用Or查询,除非你是AOrB,不然方法名长的没法看。
这里还是示例一下
假设SQL是
select * from user where id = :id and (name = :name or phone = :phone)
可以看到,这是一个很合理的查询
用方法名的方式构造查询
selectAllByIdAndNameOrIdAndPhone(int id, String name, int id, String phone);
这还是一个简单的Or查询感觉爆炸了有木有
推荐用@Query的方式
@Query(value = "select * from user where id = :id and (name = :name or phone = :phone) ", nativeQuery = true)
爽了一些有木有
使用Specification
Specification.where(BaseJpaRepository.eq(User_.id, id))
.and(Specification
.where(BaseJpaRepository.eq(User_.name,name))
.or(BaseJpaRepository.eq(User_.phone, phone))
)
感觉有点不太爽,但也还好。
注意User_这个类是使用hibernate-jpamodelgen
生成的,
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.2.17.Final</version>
</dependency>
一些特殊情况讨论
存在复合属性的情况
todo
Mybatis和JPA使用对比
todo