原文地址:https://liujiao111.github.io/2019/07/01/java-data-jpa/
JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR 338,这些接口所在包为javax.persistence。PA的出现主要是为了简化持久层开发以及整合ORM技术,结束Hibernate、TopLink、JDO等ORM框架各自为营的局面。JPA是在吸收现有ORM框架的基础上发展而来,易于使用,伸缩性强。
Spring Data JPA是Spring Data家族的一部分,可以轻松实现基于JPA的存储库。 此模块处理对基于JPA的数据访问层的增强支持。 它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
Spring Data JPA旨在通过减少实际需要的工作量来显著改善数据访问层的实现。 作为开发人员,您编写repository接口,包括自定义查找器方法,Spring将自动提供实现。
总的来说JPA是ORM规范,Hibernate、TopLink等是JPA规范的具体实现,这样的好处是开发者可以面向JPA规范进行持久层的开发,而底层的实现则是可以切换的。Spring Data Jpa则是在JPA之上添加另一层抽象(Repository层的实现),极大地简化持久层开发及ORM框架切换的成本。
具体使用Spring Data Jpa来完成增删改查功能的步骤如下:
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
6.0.6
@Data
@Entity
@DynamicUpdate
public class UserInfo extends BaseDomain{
@Id
private String id;
@Column(name = "wechat_name")
private String wechatName;
@Column(name = "real_name")
private String realName;
private Integer gender;
@Column(name = "wechat_id")
private String wechatId;
private Integer age;
private String birthday;
private String phone;
字段有点多,并且使用了lombak,不用写getter/setter方法
public interface UserRepository extends JpaRepository {
}
这样就可以实现简单的增删改查了。这个接口拥有如下方法:
如果我们需要自定义查询,可以在接口里面定义,只需要写名字,它会自动映射,这点是比较强大的,比如我们需要根据userName查询,并且按照createTime进行升序排序,则方法名可以定义为findAllByUserNameOrderByCreateTime
规则:find+全局修饰+By+实体的属性名称+限定词+连接词+ …(其它实体属性)+OrderBy+排序属性+排序方向
比如:
List findBySourceUserIdAndTargetUserIdAndType(String sourceUserId, String targetUserId, Integer type);
根据多条件查询,在参数中按照顺序传入即可,对应的规则具体参考官方文档。
那么, 简单的查询是可以轻松搞定,但是分页以及多条件这种复杂查询怎么办呢?这种的话也能解决,类似hibernate那种操作的,具体可以参考下列代码:
Page talkingPage = talkingRepository.findAll((Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) -> {
List predicates = new ArrayList<>();
if (talkingReq.getContent() != null) {
predicates.add(criteriaBuilder.like(root.get("content"), "%" + talkingReq.getContent() + "%"));
}
if (talkingReq.getStartCity() != null) {
predicates.add(criteriaBuilder.equal(root.get("startCity"), talkingReq.getStartCity()));
}
if (talkingReq.getTargetCity() != null) {
predicates.add(criteriaBuilder.equal(root.get("targetCity"), talkingReq.getTargetCity()));
}
if (talkingReq.getStartTimeStart() != null && talkingReq.getStartTimeEnd() != null) {
predicates.add(criteriaBuilder.between(root.get("startTime"), talkingReq.getStartTimeStart(), talkingReq.getStartTimeEnd()));
}
//查询发送成功并且未删除的
predicates.add(criteriaBuilder.equal(root.get("status"), 1));
return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}, pageable);
上述操作可以实现多条件查询,模糊查询并且分页。