SpringDataJpa

SpringData Jpa笔记

一、简介

Spring data JPA是Spring在ORM框架,以及JPA规范的基础上,封装的一套JPA应用框架,并提供了一整套的数据访问层解决方案。

Spring data JPA提供给用户的主要有以下几个接口:

  1. Repository:

    仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别

  2. CrudRepository:

    继承Repository,实现了一组CRUD相关的方法

  3. PagingAndSortingRepository:

    继承CrudRepository,实现了一组分页排序相关的方法

  4. JpaRepository:

    继承PagingAndSortingRepository,实现一组JPA规范相关的方法

  5. JpaSpecificationExecutor:

    比较特殊,不属于Repository体系,实现一组JPA Criteria查询相关的方法

这么说直接继承JpaRepository接口,不就拥有所有功能了吗?

规则

Jpa通过对方法名称命名,将其转化成sql语句,具体规则如下:

And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equal findById, findByIdEquals
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEqual findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEqual findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,Not Null findByNameNotNull where name is not
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)

示例

实体类

@Component
@Entity //实体类注解
public class Student {

    @Id   //主键
    @GeneratedValue//主键生成策略
    private int s_id;
    private String s_name;
    private String S_sex;


 ..........其他略去
}

jpa接口

使用接口继承jpa提供的接口,以此拥有jpa提供的功能

public interface StuJpa extends JpaRepository<Student,Integer{
//继承接口,泛型中是实体类类型和主键类型

}

服务类

在服务类中调用jpa方法:

@Service
public class StuService {
    @Autowired
    StuJpa stuJpa;

    public List<Student> getStus(){
        System.out.println("----------调用jpa");
        List<Student> all = stuJpa.findAll();
        return all;
    }

}

二、详细方法

查看一下主要的三个 Repository中的方法:

@NoRepositoryBean
public interface JpaRepository<TIDextends PagingAndSortingRepository<TID>, 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> saveAndFlush(S var1);

    void deleteInBatch(Iterable<T> var1);

    void deleteAllInBatch();

    getOne(ID var1);

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

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



@NoRepositoryBean
public interface PagingAndSortingRepository<TIDextends CrudRepository<TID{
    Iterable<T> findAll(Sort var1);

    Page<T> findAll(Pageable var1);
}



@NoRepositoryBean
public interface CrudRepository<TIDextends Repository<TID{
    <S extends T> save(S var1);

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

    Optional<T> findById(ID var1);

    boolean existsById(ID var1);

    Iterable<T> findAll();

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

    long count();

    void deleteById(ID var1);

    void delete(T var1);

    void deleteAll(Iterable<? extends T> var1);

    void deleteAll();
}

分页查询、插入示例

提供的接口也有分页、排序的功能。

@Transactional注解在某些操作中需要添加,如删除、更新等。

@Service
@Transactional
public class StuService {
    @Autowired
    StuJpa stuJpa;


    //分页
    public void page(Integer o,Integer l) throws Exception{

        //Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        Pageable page = PageRequest.of(o, l);
        Page<Student> all = stuJpa.findAll(page);

        System.out.println("TotalElement: "+all.getTotalElements());
        System.out.println("TotalPages: "+all.getTotalPages());
        System.out.println("NumberOfElements: "+all.getNumberOfElements());
        System.out.println("Size: "+all.getSize());
        System.out.println("Content: "+all.getContent());

        all.forEach(System.out::println);
    }


    //保存
    public void saveStu(Student student){
        stuJpa.save(student);
    }


}

对应的sql语句如下:

select * from ( select row_.*, rownum rownum_ from ( select student0_.s_id as s_id1_2_, student0_.s_sex as s_sex2_2_, student0_.s_name as s_name3_2_ from student student0_ ) row_ where rownum <= ?) where rownum_ > ?

三、注解

@GeneratedValue注解

主键生成策略:

TABLE: 使用一个特定的数据库表格来保存主键
SEQUENCE: 根据底层数据库的序列来生成主键,条件是数据库支持序列。这个值要与generator一起使用,generator 指定生成主键使用的生成器(可能是orcale中自己编写的序列)
IDENTITY: 主键由数据库自动生成(主要是支持自动增长的数据库,如mysql)
AUTO: 主键由程序控制,也是GenerationType的默认值

@Query注解

sql查询:在某些复杂查询中,方法命名无能为力时,使用注解进行sql语句的编写。

Query注解使用jpql语句,jpql语句是sql的变种,查询关键字都是一样的。

唯一的区别是:JPQL是面向对象的

JPA的查询语言,类似于sql

 1.里面不能出现表名,列名,只能出现java的类名,属性名,区分大小写

 2.出现的sql关键字是一样的意思,不区分大小写

 3.不能写select * 要写select 别名

Query具体使用示例:

public interface StuJpa extends JpaRepository<StudentInteger
  /** 
   * 命名参数 
   * 描述:推荐使用这种方法,可以不用管参数的位置 
   */

  @Query("select u from Student u where u.s_name = :name"
  User findStudentByName(@Param("name") String name)
    
  /** 
   * 索引参数 
   * 描述:使用?占位符 
   */

  @Query("select u from Student u where u.s_name = ?1")// 1表示第一个参数 
  User findStudentByName(String name)
    
  /** 
   * 描述:可以通过@Modifying@Query来实现更新 
   * 注意:Modifying queries的返回值只能为void或者是int/Integer 
   */

  @Modifying
  @Query("update Student u set u.s_name = :name where u.s_id = :id"
  int updateStudentById(@Param("name") String name, @Param("id") int id)

原文地址:https://www.cnblogs.com/cgl-dong/p/13391203.html