Spring Data JPA参考文档

文章摘抄spring 官网(https://docs.spring.io/spring-data/jpa/docs/2.2.2.RELEASE/reference/html/#jpa.query-methods.at-query)

JPA 介绍

JPA 全称为 JAVA Persistence API ,JPA 吸取了目前Java 持久化技术的有点,旨在规范、简化Java对象的持久化技术工作。使用JPA持久化对象,并不是依赖于某一个ORM框架

JPA 使用

Working with Spring Data Repositories

CrudRepository

public interface CrudRepository<T, ID> extends Repository<T, ID> {

  <S extends T> S save(S entity);      

  Optional<T> findById(ID primaryKey); 

  Iterable<T> findAll();               

  long count();                        

  void delete(T entity);               

  boolean existsById(ID primaryKey);   

  // … more functionality omitted.
}
  • Saves the given entity.
  • Returns the entity identified by the given ID.
  • Returns all entities.
  • Returns the number of entities.
  • Deletes the given entity.
  • Indicates whether an entity with the given ID exists.

PagingAndSortingRepository

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

官方文档上的示例

PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(PageRequest.of(1, 20));

//实际开发中,稍微进行了一些优化,可参考如下
/**
     * 排序 数组第一个元素: 排序项目名 数组第二个元素: 排序方向
     */
    private List<String> sort;

    /**
     * 转换为PageRequest
     * 
     * @return PageRequest
     */
    public PageRequest toPageRequest() {
        PageRequest pageRequest;

        int page = getPage() - 1;
        int count = getCount();

        if (CollectionUtils.isEmpty(sort)) {
            pageRequest = new PageRequest(page, count);
        } else {
            pageRequest = new PageRequest(page, count, buildSort());
        }

        return pageRequest;
    }
    
    private Sort buildSort() {
        List<Order> orders = new ArrayList<>();
        for (int i = 0; i < sort.size(); i += 2) {
            orders.add(new Order(Direction.fromString(sort.get(i + 1)),
                    sort.get(i)));            
        }
        return new Sort(orders);
    }
}

Fragments overriding (方法覆盖)

// 实际开发中,Bean对象都有一个共同类
interface CustomizedSave<T> {
  <S extends T> S save(S entity);
}

class CustomizedSaveImpl<T> implements CustomizedSave<T> {

  public <S extends T> S save(S entity) {
    // Your custom implementation
  }
}

Querydsl

public interface QuerydslPredicateExecutor<T> {

  Optional<T> findById(Predicate predicate);  

  Iterable<T> findAll(Predicate predicate);   

  long count(Predicate predicate);            

  boolean exists(Predicate predicate);        

  // … more functionality omitted.
}
  • Finds and returns a single entity matching the Predicate.
  • Finds and returns all entities matching the Predicate.
  • Returns the number of entities matching the Predicate.
  • Returns whether an entity that matches the Predicate exists.

开发中都会在 DAO 层实现该方法

interface UserRepository extends CrudRepository<User, Long>, QuerydslPredicateExecutor<User> {
}

Impl 中使用 (文档: http://www.querydsl.com/)

Predicate predicate = QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))

// 实际开发会用booleanBuilder 做连接,参考如下
 BooleanBuilder where = new BooleanBuilder();
 if (!StringUtils.isEmpty(id)) {
     where.and(QInspectionPlan.inspectionPlan.id.eq(Long.parseLong(id)));
 }
 return where.getValue();

userRepository.findAll(predicate);

Using @Query

// 使用Bean对象
public interface UserRepository extends JpaRepository<User, Long> {

  @Query("select u from User u where u.emailAddress = ?1")
  User findByEmailAddress(String emailAddress);
}
// 使用原生sql
public interface UserRepository extends JpaRepository<User, Long> {
  // 原生sql中还可以使用,countQuery 进行计数查询
  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
  User findByEmailAddress(String emailAddress);
}


在JPA 1.4以后,支持SpEL 表达式,但是不推荐使用

@Entity
public class User {

  @Id
  @GeneratedValue
  Long id;

  String lastname;
}

public interface UserRepository extends JpaRepository<User,Long> {

  @Query("select u from #{#entityName} u where u.lastname = ?1")
  List<User> findByLastname(String lastname);
}

Modifying Queries

方法上必须添加@Modifying 注解,该注解有一个属性 clearAutomatically ,默认false,如果设置为true,则方法查询后进行修改,再查询的话不会拿到旧数据(实际上清除缓存),根据实际情况,添加该注解

@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);

Delete Queries

interface UserRepository extends Repository<User, Long> {

  void deleteByRoleId(long roleId);

  @Modifying
  @Query("delete from User u where user.role.id = ?1")
  void deleteInBulkByRoleId(long roleId);
}

对于以上两个删除方法,官方文档是这样介绍的
尽管该deleteByRoleId(…)方法看起来基本上与产生相同的结果deleteInBulkByRoleId(…),但是在执行方法方面,这两个方法声明之间存在重要区别。顾名思义,后一种方法针对数据库发出单个JPQL查询(在批注中定义的查询)。这意味着即使当前加载的实例User也看不到生命周期回调。

为了确保生命周期查询被实际调用,调用会deleteByRoleId(…)执行一个查询,然后一个接一个地删除返回的实例,以便持久性提供程序实际上可以@PreRemove在这些实体上调用回调。

实际上,前者查询是执行查询,然后调用CrudRepository.delete(Iterable users)结果并使其行为与中其他delete(…)方法的实现保持同步的快捷方式CrudRepository。

发布了46 篇原创文章 · 获赞 6 · 访问量 2661

猜你喜欢

转载自blog.csdn.net/renguiriyue/article/details/103207536