【系统学习SpringBoot】再遇Spring Data JPA之JPA应用详解(自定义查询及复杂查询)

《SpringBoot初遇Spring-Data-JPA》

在此,对Spring Data Jpa做详细的笔记(使用层面的,原理层日后再说哈哈。)



一、Spring Data JPA设置创建方式:
创建方式一共分为四种:


#配置数据库,使用SpringJPA
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 1486145487
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: updata  #分为四种。createcreate-dropupdate,validate
      #方便调试,展示sql
    show-sql: true

Here, spring.jpa.hibernate.ddl-auto can be none, update, create, create-drop, refer to the Hibernate documentation for details.

none This is the default for MySQL, no change to the database structure.
update Hibernate changes the database according to the given Entity structures.
create Creates the database every time, but don’t drop it when close.
create-drop Creates the database then drops it when the SessionFactory closes.

在这里,spring.jpa.hibernate.ddl- auto可以是none,update,create,creto - drop,有关详细信息,请参阅Hibernate文档:
【none】
这是MySQL的默认值,没有对数据库结构的更改。
【update】
Hibernate根据给定的实体结构改变数据库。
【create】
每次都创建数据库,但关闭时不要删除它
【create-drop】
创建数据库,然后在SessionFactory关闭时删除它。



二、Spring Data JPA自定义查找:

SpringDataJPA规矩如下(用的时候再查吧,,这东西不能强记):

Keyword Sample JPQL snippet
IsNotNull findByAgeNotNull …  where x.age not null【年龄不为空】
Like findByNameLike …  where x.name like ?【模糊查找是…】
NotLike findByNameNotLike …  where x.name not like ?【模糊查找不是…】
StartingWith findByNameStartingWith …  where x.name like ?(parameter bound with appended %)【模糊匹配,类似使用%结尾】
EndingWith findByNameEndingWith …  where x.name like ?(parameter bound with prepended %)【模糊匹配,类似使用%开始】
Containing findByNameContaining …  where x.name like ?(parameter bound wrapped in %)【模糊匹配,类似使用%开头和结尾】
OrderBy findByAgeOrderByName …  where x.age = ? order by x.name desc【查找后排序】
Not findByNameNot …  where x.name <> ?【查找列不是…的】
In findByAgeIn …  where x.age in ?
NotIn findByAgeNotIn …  where x.age not in ?
True findByActiveTrue …  where x.avtive = true
Flase findByActiveFalse …  where x.active = false
And  findByNameAndAge …  where x.name = ? and x.age = ?2
Or findByNameOrAge …  where x.name = ? or x.age = ?2
Between findBtAgeBetween …  where x.age between ? and ?2
LessThan findByAgeLessThan …  where x.age  <  ?
GreaterThan findByAgeGreaterThan …  where x.age > ?
After/Before
IsNull findByAgeIsNull …  where x.age is null



自定义查找实例:

    /**
     * 根据id查用户
     **/
    List findByIdOrName(Long id,String name);

    /**
     * 根据id查用户
     **/
    User queryXXXXByName(String name);

    /**
     * 根据id查name
     **/
    User readNameById(Long id);

    /**
     * 查年龄为10岁的学生
     **/
    List getByAge(int age);



三、Spring Data JPA分页查询:

    /**
     * 分页查询左右用户
     * @param pageable
     * @return
     */
    Page findAll(Pageable pageable);

    /**
     * 分页查询id不是传入id的用户
     * @param id
     * @param pageable
     * @return
     */
    Page findByIdNot(Long id,Pageable pageable);



测试代码如下:

 @Test
    public void findByIdNot() throws Exception {
        Pageable pageable =  new PageRequest(0,6,new Sort(Sort.Direction.DESC,"id"));
        List users = myUserRepository.findByIdNot((long)10,pageable).getContent();
        Assert.assertEquals(6,users.size());
    }

    @Test
    public void findAll() throws Exception {
        Pageable pageable =  new PageRequest(0,5,new Sort(Sort.Direction.ASC,"id"));
        List users = myUserRepository.findAll(pageable).getContent();
        for(int i = 0;i<5;i++){
            Assert.assertEquals(i+1,users.get(i).getId());
        }
        Assert.assertEquals(5,myUserRepository.findAll(pageable).getSize());
    }

【注意】分页查询,的结果Page,,Page接口继承自Slice,这个接口有以下方法

public interface Slice<T> extends Iterable<T> {
    int getNumber();//返回当前页码

    int getSize();//返回当前页大小(可能不是一整页)

    int getNumberOfElements();//返回当前的元素数量

    List getContent();//返回当前页的内容(查询结果)

    boolean hasContent();//判断是否有内容存在

    Sort getSort();//返回排序方式

    boolean isFirst();//判断是不是第一页

    boolean isLast();//判断是不是最后一页

    boolean hasNext();//判断是否还有下一页

    boolean hasPrevious();//判断是否上一页

    Pageable nextPageable();//返回下一页

    Pageable previousPageable();//返回上一页,如果当前已经是第一个,则返回,请求前一个可以是【null】。在调用此方法之前,客户端应该检查是否收到一个非值。

     Slice map(Convertersuper T, ? extends S> var1);//用给定的映射,映射当前的内容,为Slice
}

和List集合差不多很类似,,具体方法用的时候再查呗。,,上面注释有不对的地方欢迎评论。。。……^.^



四、Spring Data JPA限制查询:

有时候需求是,我需要查前几个,,我需要查第一个,(由于涉及到查第几个,需要排序,否则按默认排序,即数据库表顺序)

测试案例如下:

  //通过名字升序查询第一个
    User findFirstByOrderByNameAsc();
    //通过年龄降序,查第一个
    User findTopByOrderByAgeDesc();
    //排序,查年龄等于age的前五个
    List findFirst5ByAge(int age, Sort sort);



五、Spring Data JPA自定义SQL查询:

【注意】jpa在处理更新和删除操作是需要加事务注解,,否则会报错详情请见下篇,【错误解决】

    @Transactional
    @Modifying
    @Query("update user_test set name = ?1 where id = ?2")
    int updataById(String name, Long id);//更新id为传入id的用户的名称为name

    @Transactional
    @Modifying
    @Query("delete from user_test where id = ?1")
    void deleteById(Long id);//删除id为,,传入id的用户(不存在不删除)

测试代码如下:

  @Test
    public void deleteByUserId() throws Exception {
//        myUserRepository.deleteByUserId((long) 10);
        myUserRepository.updataById("小白", (long) 9);
    }

模糊查询关键字,like不很给力,用Containing

你可能感兴趣的:(SpringBoot,SpringBoot)