# springJpa **Repository Path**: shao_win/springJpa ## Basic Information - **Project Name**: springJpa - **Description**: 记录一下spring jpa的一些用法 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2016-12-19 - **Last Updated**: 2021-11-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README #springJpa Spring Data JPA作为Spring Data的其中一个模块,主要是为了统一和简化各种类型的持久化存储,定义了一系列操作关系型数据库和O/R映射的API,只需要定义和编写一些查询方法的接口即可使用。 ## 目录 ## 简单CRUD JPA内置了一些简单操作的方法,下面是一个基础的API接口,很多API接口都继承了这个接口,如JpaRepository,MongoRepository: ![](media/14819865837853/14821155679196.jpg) 具体用法: 1. 定义一个User类的Repository ![](media/14819865837853/14821158522072.jpg) 2. 使用UserRepository进行对user的CRUD - 新增/修改:userRepository.save(user); - 查找:userRepository.findAll() - 分页查找:userRepository.findAll(pageable) - id删除:userRepository.delete(id); - 实体删除:userRepository.delete(id); ## 复杂查询 对应一些较为复杂的查询,可能JPA内置的API,动态查询API仍无法满足需求,这时需要重写JpaSpecificationExecutor的方法了。下面的场景是我需要重写改接口方法的例子: 场景:有一个User的实体类,如下: ``` @Entity(name = "user") @Table(name = "appbricks_user") @JsonIgnoreProperties(ignoreUnknown = true) @JsonFilter("JsonFilter") @JsonPropertiesFilter(filterFields = {"password"}) public class User implements Serializable { private static final long serialVersionUID = 1880648130504622442L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(nullable = false) private String username; @Column(nullable = false) private String password; private String fullname; @JsonProperty("departmentId") @Transient private Integer departId; } ``` 需要根据departId查询,并且在此基础上能够对username或fullname字段进行模糊查询,同时需要分页,最终需要的sql(未加上分页)如下: ``` select * from user where departId=? and (username like '%?%' or fullname like '%?%') ``` 刚开始时定义下面的一个方法: ``` @Repository public interface UserRepository extends JpaRepository{ Page findDepartIdAndUsernameLikeOrFullnameLike(Integer departId,String username,String fullname,Pageable pageable); } ``` 最后打印出来的sql: ``` select * from user where departId=? and username like '%?%' or fullname like '%?%' ``` 少了一个括号,使用@Query注解直接写sql,好像又需要自己写分页的sql,这样一来,就很难做到跨数据库了,因此,最后采用重写JpaSpecificationExecutor的方法的方式实现: ``` @Repository public interface UserRepository extends JpaRepository, JpaSpecificationExecutor{ } ``` ``` this.userRepository.findAll(new Specification() {//复杂条件查询,where template=? and (name like ? or description like ?) @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { Path templateExp = root.get("departId"); Path nameExp = root.get("username"); Path descriptionExp = root.get("fullname"); // List list = new ArrayList<>(); // list.add(cb.or(cb.like(nameExp, "%" + search + "%"), cb.like(descriptionExp, "%" + search + "%"))); Predicate predicate = cb.or(cb.like(nameExp, "%" + search + "%"), cb.like(descriptionExp, "%" + search + "%")); return cb.and(predicate, cb.equal(templateExp, String.valueOf(departId))); } }, (Pageable)pageable); ```