spring data jpa入门教程

桃扇骨 2022-01-29 02:41 428阅读 0赞

文章目录

  • 配置文件
  • 编写实体类并创建好对应数据库
  • 编写对应Dao类
  • Repository常用方法使用规范
  • @query注解的使用
  • 使用Spring Data进行删除更新操作
  • CrudRepository
  • PagingAndSortingRepository
  • JpaRepository
  • 接口继承JpaSpecificationExcutor接口

配置文件

  • 首先要在pom中引入相关依赖


    org.springframework.data
    spring-data-jpa
    1.8.0.RELEASE



    org.hibernate
    hibernate-entitymanager
    4.3.6.Final
  • 在application.properties中配置好数据库和jpa的配置

    通用数据源配置

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.01:3306/springdata?charset=utf8mb4&useSSL=false
    spring.datasource.username=root
    spring.datasource.password=1234

    Hikari 数据源专用配置

    spring.datasource.hikari.maximum-pool-size=20
    spring.datasource.hikari.minimum-idle=5

    JPA 相关配置

    spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
    spring.jpa.show-sql=true
    spring.jpa.hibernate.ddl-auto=update # !注意不要用create

ddl-auto区别

  • ddl-auto:create:每次运行该程序,没有表格会新建表格,表内有数据会清空。
  • ddl-auto:create-drop:每次程序结束的时候会清空表。
  • ddl-auto:update:每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新。
  • ddl-auto:validate:运行程序会校验数据与数据库的字段类型是否相同,不同会报错。

编写实体类并创建好对应数据库

  1. import javax.persistence.Column;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.Id;
  5. import lombok.Data;
  6. /** * @ Author zhangbin * @ Date 2019/05/20 */
  7. @Data
  8. @Entity
  9. public class Teacher {
  10. //配置表的id,并且是使用自增
  11. @Id
  12. @GeneratedValue
  13. private Integer id;
  14. private String name ;
  15. private String classNumber ;
  16. }

编写对应Dao类

  1. import org.springframework.data.jpa.repository.Modifying;
  2. import org.springframework.data.jpa.repository.Query;
  3. import org.springframework.data.repository.Repository;
  4. import org.springframework.data.repository.RepositoryDefinition;
  5. import org.springframework.data.repository.query.Param;
  6. import java.util.List;
  7. /** * @ Author :zhangbin * @ Date :2019/05/20 */
  8. //有两种方式,要么用注解要么用继承
  9. //@RepositoryDefinition(domainClass = Teacher.class ,idClass = Integer.class)
  10. public interface TeacherRepository extends Repository<Teacher , Integer> {
  11. //===============使用springdata默认方式=============================
  12. /** * 根据名字查询老师 * @param name * @return */
  13. Teacher findByName(String name);
  14. /** * 根据班级名称进行查询老师(这里用到模糊匹配like) * @param classNumber * @return */
  15. List<Teacher> findByclassNumberLike(String classNumber);
  16. }

分析

  • (1)首先,我们这个接口是需要继承Repository这个接口
  • (2)泛型参数:第一个是我们制定这个接口所需要进行操作的实体JavaBean,第二个是我们实体JavaBean中主键的类型。(因为我这主键是id,用的Integer类型)
  • (3)继承的Repository这个接口有什么用?让我们看看源码分析一下
    在这里插入图片描述
    可以看到这是一个空接口,它的作用是什么呢?
  • 第一点:Repository是一个空接口,即是一个标记接口。
  • 第二点:若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean,纳入到IOC容器中,进而可以在该接口中定义满足一定规范的方法。IOC容器中实际存放了继承了Repository的接口的实现类,而这个实现类由spring帮助完成 。在applicationContext.xml中我们配置了springdata:这里的base-package指定了Repository Bean所在的位置,在这个包下的所有的继承了Repository的接口都会被IOC容器识别并纳入到容器中,如果没有继承Repository则IOC容器无法识别。
  • 第三点:我们也可以通过注解的方式替代继承Repository接口@RepositoryDefinition(domainClass=需要处理的实体类的类型,IdClass=主键的类型)。
  • 第四点:看看它有哪些子类:在这里插入图片描述
    比较常用的是标出来的三个,CrudRepositoryJpaRepositoryPagingAndSortingRepository

这样在我们通过controller和service层层调用(此处逻辑代码过于简单不予列出)之后就会发现数据被查出来了,可是我们也没有写这个dao接口的实现类啊,这就是Repository的强大之处,它内部集成了我们常用的方法,我们可以在继承他后可以直接调用相关方法了。这里我们使用到的是findby方法和模糊匹配findby..like方法,那它都给我们提供了哪些方法呢?

Repository常用方法使用规范



































































































































关键字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
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(?)

@query注解的使用

方法这么多,想要全部记住还是很困难的,所以我们也可以选择使用@query注解来进行开发。

  1. //==============使用query注解开发==============================================
  2. /** * 通过query注解进行开发模糊匹配(利用索引参数的方法) * @param classNumber * @return */
  3. @Query("select t from Teacher t where t.classNumber like %?1%")
  4. List<Teacher> queryTeacher(String classNumber);
  5. /** * 通过老师的名字来进行查询数据 * @param name * @return */
  6. @Query("select t from Teacher t where t.name = ?1")
  7. Teacher queryTeacherByName(String name );
  8. /** * 通过老师的名字来进行查询数据(利用命名参数的方法,注意query注解的写法不一样的) * @param name * @return */
  9. @Query("select t from Teacher t where t.name = :name")
  10. Teacher queryTeacherByName2(@Param("name") String name );
  11. /** * 使用原生的SQL语句进行操作(注意from这时候用的就是数据库的表名,而不是实体类名) * 必须添加nativeQuery = true,因为默认是false的 * @return */
  12. @Query(nativeQuery = true , value = "select count(1) from teacher")
  13. long countTeacherNumber();

使用Spring Data进行删除更新操作

我们之前都是写的查询操作,那么如果进行更新和删除操作,是不是也是一样的?

然而,请注意,并不是的,而且特别要注意下面两点:

(1)对于更新和删除操作,必须在接口的方法上面添加@Modifying注解,这样就用于标识这是一个修改的操作

(2)必须在调用这个接口方法的地方(一般就是service层)使用事务,即用@Transactional注解进行标识。

  • dao接口

    //================进行springdata的更新删除的处理======================

    1. /** * 根据老师表的id进行修改对应数据的老师名字 * 必须要添加@Modifying注解,并且要在调用的方法上添加事务注解@Transactional * @param name * @param id */
    2. @Modifying
    3. @Query("update Teacher t set t.name = ?1 where t.id = ?2")
    4. void updateTeacherById(String name , Integer id);:
  • service层代码

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import javax.transaction.Transactional;
    import java.util.List;

    /* @ Author :zhangbin @ Date :2019/05/20 /
    @Service
    public class SpringDataService {

    1. @Autowired
    2. private TeacherRepository teacherRepository;
    3. @Autowired
    4. private TeacherCrudRespository teacherCrudRespository;
    5. /** * 根据id进行修改老师的名字 * @param name * @param id */
    6. @Transactional
    7. public void updateTeacher(String name , Integer id){
    8. teacherRepository.updateTeacherById(name , id);
    9. }

    }

CrudRepository

CrudRepository继承了Repository接口,并添加了些基本的增伤改查方法。

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. package org.springframework.data.repository;
  6. import java.util.Optional;
  7. @NoRepositoryBean
  8. public interface CrudRepository<T, ID> extends Repository<T, ID> {
  9. <S extends T> S save(S var1);
  10. <S extends T> Iterable<S> saveAll(Iterable<S> var1);
  11. Optional<T> findById(ID var1);
  12. boolean existsById(ID var1);
  13. Iterable<T> findAll();
  14. Iterable<T> findAllById(Iterable<ID> var1);
  15. long count();
  16. void deleteById(ID var1);
  17. void delete(T var1);
  18. void deleteAll(Iterable<? extends T> var1);
  19. void deleteAll();
  20. }

PagingAndSortingRepository

PagingAndSortingRepository继承了CrudRepository,并添加了分页方法。

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. package org.springframework.data.repository;
  6. import org.springframework.data.domain.Page;
  7. import org.springframework.data.domain.Pageable;
  8. import org.springframework.data.domain.Sort;
  9. @NoRepositoryBean
  10. public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
  11. Iterable<T> findAll(Sort var1);
  12. Page<T> findAll(Pageable var1);
  13. }

要访问User页面大小为20 的第二页,您可以执行以下操作:

  1. PagingAndSortingRepository<User, Long> repository = // … get access to a bean
  2. Page<User> users = repository.findAll(PageRequest.of(1, 20));
  3. // or
  4. PageRequest pageRequest = new PageRequest(0, 5);
  5. Page<Teacher> page = teacherPagingAndSortRespository.findAll(pageRequest);
  6. // or
  7. //按照id的降序进行排序
  8. Sort.Order sortOrder = new Sort.Order(Sort.Direction.DESC, "id");
  9. //构建排序对象
  10. Sort sort = new Sort(sortOrder);
  11. //把分页和排序对象放入参数
  12. PageRequest pageRequest = new PageRequest(0, 5 , sort);
  13. Page<Teacher> page = teacherPagingAndSortRespository.findAll(pageRequest);

JpaRepository

JpaRepository继承了PagingAndSortingRepository接口完善了分页排序的功能。

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. package org.springframework.data.jpa.repository;
  6. import java.util.List;
  7. import org.springframework.data.domain.Example;
  8. import org.springframework.data.domain.Sort;
  9. import org.springframework.data.repository.NoRepositoryBean;
  10. import org.springframework.data.repository.PagingAndSortingRepository;
  11. import org.springframework.data.repository.query.QueryByExampleExecutor;
  12. @NoRepositoryBean
  13. public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
  14. List<T> findAll();
  15. List<T> findAll(Sort var1);
  16. List<T> findAllById(Iterable<ID> var1);
  17. <S extends T> List<S> saveAll(Iterable<S> var1);
  18. void flush();
  19. <S extends T> S saveAndFlush(S var1);
  20. void deleteInBatch(Iterable<T> var1);
  21. void deleteAllInBatch();
  22. T getOne(ID var1);
  23. <S extends T> List<S> findAll(Example<S> var1);
  24. <S extends T> List<S> findAll(Example<S> var1, Sort var2);
  25. }

接口继承JpaSpecificationExcutor接口

说明:不属于Repository体系,实现一组 JPA Criteria 查询相关的方法。Specification:封装 JPA Criteria 查询条件。通常使用匿名内部类的方式来创建该接口的对象。

主要接口方法如下:主要就是条件过滤,比如我们在分页的时候需要一些条件,这样就可以更好的进行分页处理。

  1. //
  2. // Source code recreated from a .class file by IntelliJ IDEA
  3. // (powered by Fernflower decompiler)
  4. //
  5. package org.springframework.data.jpa.repository;
  6. import java.util.List;
  7. import java.util.Optional;
  8. import org.springframework.data.domain.Page;
  9. import org.springframework.data.domain.Pageable;
  10. import org.springframework.data.domain.Sort;
  11. import org.springframework.data.jpa.domain.Specification;
  12. import org.springframework.lang.Nullable;
  13. public interface JpaSpecificationExecutor<T> {
  14. Optional<T> findOne(@Nullable Specification<T> var1);
  15. List<T> findAll(@Nullable Specification<T> var1);
  16. Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
  17. List<T> findAll(@Nullable Specification<T> var1, Sort var2);
  18. long count(@Nullable Specification<T> var1);
  19. }

示例代码如下:(用于实现分页和过滤的作用)

  1. package com.hnu.scw.repository;
  2. import com.hnu.scw.model.Teacher;
  3. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  4. import org.springframework.data.repository.PagingAndSortingRepository;
  5. /** * @ Author :zhangbin * @ Date :2019/05/20 */
  6. public interface TeacherJpaSpecificationExecutorRepository extends PagingAndSortingRepository<Teacher , Integer> ,JpaSpecificationExecutor<Teacher >{
  7. }
  8. import jdk.nashorn.internal.runtime.Specialization;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.context.ApplicationContext;
  11. import org.springframework.context.support.ClassPathXmlApplicationContext;
  12. import org.springframework.data.domain.Page;
  13. import org.springframework.data.domain.PageRequest;
  14. import org.springframework.data.domain.Sort;
  15. import org.springframework.data.jpa.domain.Specification;
  16. import javax.persistence.criteria.*;
  17. /** * @ Author :zhangbin * @ Date :2019/05/20 */
  18. public class JpaSpecificationExecutorService {
  19. //用于操作老师实体的接口
  20. @Autowired
  21. private TeacherJpaSpecificationExecutorRepository teacherJpaSpecificationExecutorRepository;
  22. /** * 进行测试JpaSpecificationExecutor这个接口的相关方法 * 实现查询第一页的前五条数据根据id升序排序,并且id要大于20 */
  23. public List<Teacher> testJpaSpecificationExecutor(){
  24. //设置分页要进行过滤的条件
  25. Specification specification = new Specification<Teacher>(){
  26. @Override
  27. public Predicate toPredicate(Root<Teacher> root,
  28. CriteriaQuery<?> criteriaQuery,
  29. CriteriaBuilder criteriaBuilder) {
  30. Path path = root.get("id");
  31. //设置过滤条件为id大于20 ,其中的gt就是表示大于
  32. Predicate predicate = criteriaBuilder.gt(path , 20);
  33. return predicate;
  34. }
  35. };
  36. //按照id的降序进行排序
  37. Sort.Order sortOrder = new Sort.Order(Sort.Direction.ASC, "id");
  38. //构建排序对象
  39. Sort sort = new Sort(sortOrder);
  40. PageRequest pageRequest = new PageRequest(0, 5 , sort);
  41. //把分页和排序对象以及过滤对象放入参数
  42. Page<Teacher> page = teacherJpaSpecificationExecutorRepository.findAll(specification ,pageRequest);
  43. return page.getContent();
  44. }
  45. }

参考博客:https://blog.csdn.net/Cs_hnu_scw/article/details/80786161
参考资料:https://docs.spring.io/spring-data/jpa/docs/2.1.8.RELEASE/reference/html/

发表评论

表情:
评论列表 (有 0 条评论,428人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring Data JPA入门

    转载的博客: Spring Data是什么 Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷,并支持map-