首页 > 编程语言 > 详细

spring data jpa 看这一篇就够了

时间:2020-09-18 09:06:26      阅读:88      评论:0      收藏:0      [点我收藏+]
什么是Spring Data JPA?
Spring Data 是Spring提供的操作数据的框架在Spring data JPA是Spring data的一个模块,通过Spring data 基于jpa标准操作数据的模块。

Spring Data的核心能力,就是基于JPA操作数据,并且可以简化操作持久层的代码。
Spring Data JPA提供的核心接口

1.Repository:

@org.springframework.stereotype.Repository
public interface UserRepository  extends Repository<User, Integer> {
}
  • 提供了方法名成查询方式:
        方法的名称要遵循 findBy + 属性名(首字母大写) + 查询条件(首字母大写 Is Equals)

        findByNameLike(String name)

    findByName(String name)

    findByNameAndAge(String name, Integer age)

    findByNameOrAddress(String name) 等...

  • 基于@Query注解的查询和更新
/**
     * SQL nativeQuery的值是true 执行的时候不用再转化
     * @param name
     * @return
     */
    @Query(value = "SELECT * FROM table_user WHERE name = ?1", nativeQuery = true)
    List<User> findByUsernameSQL(String name);

//基于HQL

   /**
     * 基于HQL
     * @param name
     * @param id
     * @return
     */
    @Query("Update User set name = ?1 WHERE id = ?2")
    @Modifying
    int updateNameAndId(String name, Integer id);

2.CrudReposiroty : 继承了Repository

/*
 * Copyright 2008-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

import java.util.Optional;

/**
 * Interface for generic CRUD operations on a repository for a specific type.
 * 
 * @author Oliver Gierke
 * @author Eberhard Wolff
 */
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

    /**
     * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
     * entity instance completely.
     * 
     * @param entity must not be {@literal null}.
     * @return the saved entity will never be {@literal null}.
     */
    <S extends T> S save(S entity);

    /**
     * Saves all given entities.
     * 
     * @param entities must not be {@literal null}.
     * @return the saved entities will never be {@literal null}.
     * @throws IllegalArgumentException in case the given entity is {@literal null}.
     */
    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    /**
     * Retrieves an entity by its id.
     * 
     * @param id must not be {@literal null}.
     * @return the entity with the given id or {@literal Optional#empty()} if none found
     * @throws IllegalArgumentException if {@code id} is {@literal null}.
     */
    Optional<T> findById(ID id);

    /**
     * Returns whether an entity with the given id exists.
     * 
     * @param id must not be {@literal null}.
     * @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
     * @throws IllegalArgumentException if {@code id} is {@literal null}.
     */
    boolean existsById(ID id);

    /**
     * Returns all instances of the type.
     * 
     * @return all entities
     */
    Iterable<T> findAll();

    /**
     * Returns all instances of the type with the given IDs.
     * 
     * @param ids
     * @return
     */
    Iterable<T> findAllById(Iterable<ID> ids);

    /**
     * Returns the number of entities available.
     * 
     * @return the number of entities
     */
    long count();

    /**
     * Deletes the entity with the given id.
     * 
     * @param id must not be {@literal null}.
     * @throws IllegalArgumentException in case the given {@code id} is {@literal null}
     */
    void deleteById(ID id);

    /**
     * Deletes a given entity.
     * 
     * @param entity
     * @throws IllegalArgumentException in case the given entity is {@literal null}.
     */
    void delete(T entity);

    /**
     * Deletes the given entities.
     * 
     * @param entities
     * @throws IllegalArgumentException in case the given {@link Iterable} is {@literal null}.
     */
    void deleteAll(Iterable<? extends T> entities);

    /**
     * Deletes all entities managed by the repository.
     */
    void deleteAll();
}

技术分享图片

CrudReposiroty主要是添加了对数据的增删改查的方法

3.PagingAndSortingRepository: 继承了CrudRepository

/**
 * 继承了Repository,缺点只能对所有的数据进行排序或者分页
 */
@Repository
public interface UserPagingAndSortingReposiroty extends PagingAndSortingRepository<User, Integer> {
}

4.JPARepository: 继承了PagingAndSortingRepository接口

在开发中常用JPARepository

优点: 对继承父接口中方法的返回值进行了适配,因为在父类接口中通常都返回迭代器,需要我们自己进行强制类型转化。而在JpaRepository中,直接返回了List

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.data.jpa.repository;

import java.util.List;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.QueryByExampleExecutor;

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    List<T> findAll();

    List<T> findAll(Sort var1);

    List<T> findAllById(Iterable<ID> var1);

    <S extends T> List<S> saveAll(Iterable<S> var1);

    void flush();

    <S extends T> S saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    T getOne(ID var1);

    <S extends T> List<S> findAll(Example<S> var1);

    <S extends T> List<S> findAll(Example<S> var1, Sort var2);
}

5.JpaSpecificationExecutor: 这个接口单独存在,没有继承以上说的接口

主要提供了多条件查询的支持,并且可以在查询中添加分页和排序。

因为这个接口单独存在,因此需要配合以上说的接口使用,如:


/**
 * JpaSpecificationExecutor是单独存在的,需要配合这JpaRepository一起使用
 */
@Repository
public interface UserJpaSpecificationExecutor extends JpaSpecificationExecutor<User>, JpaRepository<User, Integer> {
}

技术分享图片


package com.amber;

import com.amber.pojo.User;
import com.amber.repository.UserJpaSpecificationExecutor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.junit4.SpringJUnit4Cla***unner;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@RunWith(SpringJUnit4Cla***unner.class)
@SpringBootTest(classes = JPAApplication.class)
public class UserJpaSecificationExecutorTest {

    @Autowired
    UserJpaSpecificationExecutor userJpaSpecificationExecutor;

    /**
     * 多条件查询的另外一种写法
     */
    @Test
    public void testUser2(){
        //Specification是个接口,封装了查询信息
        Specification<User> specification = new Specification<User>() {
            /**
             * Predicate封装了单个查询条件
             * @param root 对查询对象属性的封装,比如我们这里是查询User,因此root可以看成是User
             * @param query CriteriaQuery封装了查询中的各部分信息, Select from order
             * @param cb CB查询条件的构造器
             * @return
             */
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate p1 = cb.equal(root.get("name"), "amber");
                Predicate p2 = cb.equal(root.get("age"), "18");
                return cb.and(p1,p2);
            }
        };
        List<User> users = userJpaSpecificationExecutor.findAll(specification);
        System.out.println(users);
    }

    /**
     * 多条件查询
     */
    @Test
    public void testUser1(){
        //Specification是个接口,封装了查询信息
        Specification<User> specification = new Specification<User>() {
            /**
             * Predicate封装了单个查询条件
             * @param root 对查询对象属性的封装,比如我们这里是查询User,因此root可以看成是User
             * @param query CriteriaQuery封装了查询中的各部分信息, Select from order
             * @param cb CB查询条件的构造器
             * @return
             */
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                Predicate p1 = cb.equal(root.get("name"), "amber");
                Predicate p2 = cb.equal(root.get("age"), "18");
                predicates.add(p1);
                predicates.add(p2);
                Predicate[] predicateArr = new Predicate[predicates.size()];
                return cb.and(predicates.toArray(predicateArr));
            }
        };
        List<User> users = userJpaSpecificationExecutor.findAll(specification);
        System.out.println(users);
    }

    /**
     * 单条件查询
     */
    @Test
    public void testUser(){
        //Specification是个接口,封装了查询信息
        Specification<User> specification = new Specification<User>() {
            /**
             * Predicate封装了单个查询条件
             * @param root 对查询对象属性的封装,比如我们这里是查询User,因此root可以看成是User
             * @param query CriteriaQuery封装了查询中的各部分信息, Select from order
             * @param cb CB查询条件的构造器
             * @return
             */
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

                Predicate p1 = cb.equal(root.get("name"), "amber");
                return p1;
            }
        };
        List<User> users = userJpaSpecificationExecutor.findAll(specification);
        System.out.println(users);
    }
}

总结:
  Spring Data Jpa中一共提供了

* 1.Repository:*
  提供了findBy + 属性方法
  @Query
  HQL: nativeQuery 默认false
  SQL: nativeQuery 默认truebr/>更新的时候,需要配合@Modifying使用
2. CurdRepository:
继承了Repository 主要提供了对数据的增删改查
3.PagingAndSortRepository:
继承了CrudRepository 提供了对数据的分页和排序,缺点是只能对所有的数据进行分页或者排序,不能做条件判断
4.JpaRepository:** 继承了PagingAndSortRepository
开发中经常使用的接口,主要继承了PagingAndSortRepository,对返回值类型做了适配
* 5.JpaSpecificationExecutor
提供多条件查询

spring data jpa 看这一篇就够了

原文:https://blog.51cto.com/5148737/2534639

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!