美文网首页
Spring data JPA的简单用法

Spring data JPA的简单用法

作者: 彩虹之梦 | 来源:发表于2017-05-21 08:58 被阅读0次

    1、导入jar包。

    org.springframework.boot

    spring-boot-starter-data-jpa

    2、配置文件

    #spring data jpa

    spring.jpa.generate-ddl=true

    spring.jpa.show-sql=true

    spring.jpa.hibernate.ddl-auto=update

    3、实体的定义

    4、定义Repository接口,继承Repository接口。

    /**

    * 1、Repository是一个空接口,即是一个标记接口

    * 2、若我们定义的接口继承了Repository,则该接口会被IOC容器识别为一个Repository Bean,纳入到IOC容器中,

    * 进而可以在该接口中定义满足一些规范的方法。

    *3、实际上,也可以通过@RepositoryDefinition()注解的方式来替代继承Repository接口

    *@RepositoryDefinition(domainClass= Person.class,idClass = Integer.class)

    */

    public interfacePersonRepositoryextendsRepository {

    Person findByLastName(String lastName);

    }

    说明:Repository接口中,泛型是对应的实体,类型是对应实体的主键。

    5、Repository的子接口。

    CrudRepository接口:继承Repository接口,实现了增删改查方法。

    JpaRepository接口:继承PagingAndStoringRepository,实现了一组JPA规范的相关方法。

    PagingAndStoringRepository接口:继承CrudRepository接口,实现了分页排序相关的方法。

    SimpleJpaRepository接口:

    JpaSpecificationExcutor接口:不属于Repository体系,实现一组Criteria查询相关方法。

    6、Repository接口中声明方法的规范

    1、查询方法以 find | read | get 开头;

    2、涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性以首字母大写

    例如:定义一个 Entity 实体类 class User{

    private String firstName;

    private String lastName; }

    使用And条件连接时,应这样写: findByLastNameAndFirstName(String lastName,String firstName); 条件的属性名称与个数要与参数的位置与个数一一对应

    3、直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:

    4、支持级联查询

    若当前类有符合条件的属性,则优先使用,而不使用级联属性。若要使用级联属性,则属性之间使用下划线进行分割。

    使用关键字进行查询例子:

    //where lastName like ?%

    List findByLastNameStartingWith(String lastName);

    //where lastName like ?% and id< ?

    List getByLastNameStartingWithAndIdLessThan(String lastName,Integer id);

    //where lastName in (?,?) or birth

    List findByEmailIOrBirthLessThan(List email, Date birth);

    //where a.id>?

    List findByAddress_IdGreaterThan(Integer id);

    5、@Query注解(查询)

    //查询Id最大的那个Person(注意:from后面跟着的实体名Person)

    //使用@Query注解可以自定义JPQL,语句实现更灵活的查询

    @Query("select p from Person p where p.id=(select max(p2.id) from Person p2)")

    Person findMaxIdPerson();;

    //为Query注解传递参数方式1:使用占位符(参数有顺序)

    @Query("select p from Person p where p.lastName=?1 and p.email=?2")

    List testQueryAnnotationParams(String lastName,String email);

    //为Query注解传递参数方式2:命名参数的方式(参数无顺序)

    @Query("select p from Person p where p.lastName=:lastName and p.email=:email")

    List testQueryAnnotationParams2(@Param("email") String email,@Param("lastName") String lastName);

    //Like参数的传递(在占位符上使用%)

    @Query("select p from Person p where p.lastName like %?1% or p.email like %?2%")

    List testQueryAnnotationLikeParam(String lastName,String email);

    //Like参数的传递(在占位符上使用%)

    @Query("select p from Person p where p.lastName like %?% or p.email like %?%")

    List testQueryAnnotationLikeParam2(@Param("lastName") String lastName,@Param("email ") String email);

    //使用原生的SQL注解

    @Query(value ="select count(id) from person",nativeQuery =true)

    intgetPersonCount();

    6、Modifying注解

    //可以通过自定义的JPQL完成update和delete操作,注意:JPQL不支持插入语句(insert)

    //在Query注解中,编写JPQL语句,但必须使用@Modiying进行修饰,以通知spring data,这是一个update或者是delete

    //update或者是delete操作需要使用事物,此时需要定义Service层,在Service层上添加事物操作

    //默认情况下,springdata的每个方法上都是有事物的,但都是一个只读事物,他们不能完成修改操作

    @Modifying

    @Query("update Person p set p.email=?1 where id=?2")

    intupdatePersonLastName(String email,Integer id);

    Service层的事物:

    @Service

    public classPersonServiceImplimplementsPersonService {

    @Autowired

    privatePersonRepositorypersonRepository;

    @Override

    @Transactional

    public intupdateLastName(String email, Integer id) {

    intcount=personRepository.updatePersonLastName("dd",1);

    returncount;

    }

    }

    7、CrudRepository子接口

    public interfacePersonRepositoryextendsCrudRepository

    Service接口:

    public interfacePersonService {

    intupdateLastName(String email,Integer id);

    voidsavePersons(List list);

    }

    Service接口实现:

    @Service

    public classPersonServiceImplimplementsPersonService {

    @Autowired

    privatePersonRepositorypersonRepository;

    @Override

    @Transactional

    public intupdateLastName(String email, Integer id) {

    intcount=personRepository.updatePersonLastName("dd",1);

    returncount;

    }

    @Transactional

    @Override

    public voidsavePersons(List list) {

    personRepository.save(list);

    }

    }

    批量添加测试:

    @Test

    public voidtestSave() {

    List persons =newArrayList<>();

    for(inti ='a'; i >='z'; i++) {

    Person person =newPerson();

    person.setBirth(newDate());

    person.setLastName("彩虹"+(char)i);

    person.setEmail((char)i+"836908728@qq.com"+(char)i);

    person.setId(i +10);

    persons.add(person);

    }

    personService.savePersons(persons);

    }

    8、PageAndSortingRepository子接口

    (是一个只读操作,不需要事物)

    //pageNo的记录是从1开始

    intpageNo =6-1;

    intpageSize =5;

    //Pageable接口通常使用的其PageRequest实现类,其中封装了分页的相关信息(page,size,sort)

    //排序相关,Sort封装了排序的信息

    //Order是针对于某一个属性进行升序还是降序

    Order order1=newSort.Order(Direction.DESC,"id");

    Order order2=newSort.Order(Direction.ASC,"email");

    //sort可以包含多个

    Sort sort=newSort(order1,order2);

    PageRequest pageable =newPageRequest(pageNo, pageSize,sort);

    Page page =personRepository.findAll(pageable);

    System.out.println("总记录数:"+ page.getTotalElements());

    System.out.println("当前第几页:"+ (page.getNumber()+1));

    System.out.println("总页数:"+ page.getTotalPages());

    System.out.println("当前页面的list:"+ page.getContent());

    System.out.println("当前页面的记录数:"+ page.getNumberOfElements());

    9、JpaRepository接口:是PagingAndSortingRepository的子接口

    public interfacePersonRepositoryextendsJpaRepository

    @Test

    public voidtestJpaRepository() {

    Person person =newPerson();

    person.setBirth(newDate());

    person.setLastName("云南");

    person.setEmail("836908728@qq.com");

    person.setId(27);

    Person person1 =personRepository.saveAndFlush(person);

    System.out.println(person == person1);

    }

    9、JpaSpecificationExecutor接口,不属于Repository体系

    (实现带查询条件的分页)

    public interfacePersonRepositoryextendsJpaRepository,JpaSpecificationExecutor

    @Test

    /**

    * 实现带查询条件的分页:

    * 使用JpaSpecificationExecutor的PagefindAll(Specificationspec,Pageable pageable)

    * Specification:封装了JPA Criteria查询的查询条件

    * Pageable:封装了请求分页的信息,例如:pageNo,pageSize,Sort

    */

    public voidtestJpaSpecificationExecutor(){

    intpageNo=3-1;

    intpageSize=5;

    PageRequest pageRequest=newPageRequest(pageNo,pageSize);

    Specification specification=newSpecification() {

    /**

    *

    *@paramroot:代表查询的实体类

    *@paramcriteriaQuery:可以从中得到root对象,即告知JPA Criteria查询要查询哪一个实体类,还可以添加查询条件

    *                    还可以结合EntityManager对象得到最终查询的TypeQuery对象

    *@paramcriteriaBuilder:CriteriaBuilder 用于创建Criteria相关对象的工厂,当然可以从中获取到Predicate对象

    *@returnPredicate类型,代表一个查询条件

    */

    @Override

    //如:实现id>5

    publicPredicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {

    Path path=root.get("id");

    Predicate predicate=criteriaBuilder.gt(path,5);

    returnpredicate;

    }

    };

    Page page=personRepository.findAll(specification,pageRequest);

    System.out.println("总记录数:"+ page.getTotalElements());

    System.out.println("当前第几页:"+ (page.getNumber() +1));

    System.out.println("总页数:"+ page.getTotalPages());

    System.out.println("当前页面的list:"+ page.getContent());

    System.out.println("当前页面的记录数:"+ page.getNumberOfElements());

    }

    10、自定义Repository接口

    •步骤:

    –定义一个接口: 声明要添加的, 并自实现的方法

    –提供该接口的实现类: 类名需在要声明的 Repository 后添加 Impl, 并实现方法

    –声明 Repository 接口, 并继承 1) 声明的接口

    –使用.

    –注意: 默认情况下, Spring Data 会在 base-package 中查找 "接口名Impl" 作为实现类. 也可以通过 repository-impl-postfix 声明后缀.

    如:定义一个接口:

    2、实现接口

    3、继承自定义接口

    public interfacePersonRepositoryextendsJpaRepository,JpaSpecificationExecutor,TestRepository

    相关文章

      网友评论

          本文标题:Spring data JPA的简单用法

          本文链接:https://www.haomeiwen.com/subject/jbiyxxtx.html