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

本文详细介绍 SpringData JPA 的基本使用方法,包括数据库创建方式的配置、自定义查询、分页查询、限制查询及自定义 SQL 查询等内容,并提供丰富的示例代码。

《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
IsNotNullfindByAgeNotNull…  where x.age not null【年龄不为空】
LikefindByNameLike…  where x.name like ?【模糊查找是…】
NotLikefindByNameNotLike…  where x.name not like ?【模糊查找不是…】
StartingWithfindByNameStartingWith…  where x.name like ?(parameter bound with appended %)【模糊匹配,类似使用%结尾】
EndingWithfindByNameEndingWith…  where x.name like ?(parameter bound with prepended %)【模糊匹配,类似使用%开始】
ContainingfindByNameContaining…  where x.name like ?(parameter bound wrapped in %)【模糊匹配,类似使用%开头和结尾】
OrderByfindByAgeOrderByName…  where x.age = ? order by x.name desc【查找后排序】
NotfindByNameNot…  where x.name <> ?【查找列不是…的】
InfindByAgeIn…  where x.age in ?
NotInfindByAgeNotIn…  where x.age not in ?
TruefindByActiveTrue…  where x.avtive = true
FlasefindByActiveFalse…  where x.active = false
And findByNameAndAge…  where x.name = ? and x.age = ?2
OrfindByNameOrAge…  where x.name = ? or x.age = ?2
BetweenfindBtAgeBetween…  where x.age between ? and ?2
LessThanfindByAgeLessThan…  where x.age  <  ?
GreaterThanfindByAgeGreaterThan…  where x.age > ?
After/Before
IsNullfindByAgeIsNull…  where x.age is null



自定义查找实例:

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

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

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

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



三、Spring Data JPA分页查询:

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

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



测试代码如下:

 @Test
    public void findByIdNot() throws Exception {
        Pageable pageable =  new PageRequest(0,6,new Sort(Sort.Direction.DESC,"id"));
        List<User> 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<User> 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<T> getContent();//返回当前页的内容(查询结果)

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

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

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

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

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

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

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

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

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

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



四、Spring Data JPA限制查询:

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

测试案例如下:

  //通过名字升序查询第一个
    User findFirstByOrderByNameAsc();
    //通过年龄降序,查第一个
    User findTopByOrderByAgeDesc();
    //排序,查年龄等于age的前五个
    List<User> 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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鼠晓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值