Spring JPA find单表查询方法示例详解

目录
  • 一、findById(ID id)
  • 二、findAll()
  • 三、findAllById(Iterable<ID> ids)
  • 四、findAll(Sort sort) 单调排序
    • sort.by 源码
    • control层
  • 五、findAll(Sort sort) 多参数排序
    • Sort by 源码
    • control 层
  • 总结

一、findById(ID id)

通过id进行单条查询,先看看 findById(ID id) 的源码

@Override
public Optional<T> findById(ID id) {
   Assert.notNull(id, ID_MUST_NOT_BE_NULL);
   Class<T> domainType = getDomainClass();
   if (metadata == null) {
      return Optional.ofNullable(em.find(domainType, id));
   }
   LockModeType type = metadata.getLockModeType();
   Map<String, Object> hints = new HashMap<>();
   getQueryHints().withFetchGraphs(em).forEach(hints::put);
   return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
}

从源码可以看出,最终调用的是EntityManager的find方法,EntityManager是jpa用来做持久化的,有空可以跟大家探讨一下!
下面是控制台的输出:

Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from user user0_ where user0_.id=?

二、findAll()

查找所有的数据,源码如下:

@Override
public List<T> findAll() {
   return getQuery(null, Sort.unsorted()).getResultList();
}

从源码可以看出,最终调用了org.hibernate.Query的getResultList方法。

控制台输出如下:

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_

三、findAllById(Iterable<ID> ids)

通过ids进行多条查询,源码如下:

@Override
public List<T> findAllById(Iterable<ID> ids) {
   Assert.notNull(ids, "Ids must not be null!");
   if (!ids.iterator().hasNext()) {
      return Collections.emptyList();
   }
   if (entityInformation.hasCompositeId()) {
      List<T> results = new ArrayList<>();
      for (ID id : ids) {
         findById(id).ifPresent(results::add);
      }
      return results;
   }
   Collection<ID> idCollection = Streamable.of(ids).toList();
   ByIdsSpecification<T> specification = new ByIdsSpecification<>(entityInformation);
   TypedQuery<T> query = getQuery(specification, Sort.unsorted());
   return query.setParameter(specification.parameter, idCollection).getResultList();
}

从源码可以看出,跟findAll方法一样,最终调用的是org.hibernate.Query的getResultList方法,只不过加了id的集合。
控制台打印如下:

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ where user0_.id in (? , ?)

control层

@GetMapping("findAllById")
public List<User> findAllById(Integer[] ids) {
    return userService.findAllById(Arrays.asList(ids));
}

四、findAll(Sort sort) 单调排序

根据sort对象对所有数据进行相应的排序

@Override
public List<T> findAll(Sort sort) {
   return getQuery(null, sort).getResultList();
}

这个源码也是没啥可看的!需要注意的就是这个sort对象。

这个sort对象是需要我们自己去创建,然后根据自己的诉求传入相应的参数。这里我们就是使用sort.by来实现吧(也可以通过其他方法)

sort.by 源码

/**
 * Creates a new {@link Sort} for the given {@link Order}s.
 *
 * @param direction must not be {@literal null}.
 * @param properties must not be {@literal null}.
 * @return
 */
public static Sort by(Direction direction, String... properties) {
   Assert.notNull(direction, "Direction must not be null");
   Assert.notNull(properties, "Properties must not be null");
   Assert.isTrue(properties.length > 0, "At least one property must be given");
   return Sort.by(Arrays.stream(properties)//
         .map(it -> new Order(direction, it))//
         .collect(Collectors.toList()));
}

可以看到我们需要传入两个参数,分别是 directionproperties

direction 是排序方向(升序或降序)

properties 是排序的对象,是个数组(可以是单个也可以是多个)

control层

@GetMapping("findAllSort")
public List<User> findAllSort(String ascOrDesc, String[] para) {
    Sort sort;
    if(ascOrDesc.toLowerCase().equals("desc")){
        sort = Sort.by( Sort.Direction.DESC, para);
    }else {
        sort = Sort.by( Sort.Direction.ASC, para);
    }
    return userService.findAllSort(sort);
}

请求 findAllSort?ascOrDesc=desc&para=age,name,对 agename 进行降序排序,结果如下:

[{
	"id": 21,
	"name": "bb",
	"age": 12
}, {
	"id": 22,
	"name": "cc",
	"age": 11
}, {
	"id": 20,
	"name": "aa",
	"age": 11
}]

控制台输出如下:

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ order by user0_.age desc, user0_.name desc

五、findAll(Sort sort) 多参数排序

上面的只能进行单调的排序,就是说多个对象只能一同升序或者降序;而在实际需求中,有时候还需要对多个对象,进行不同的排序,有的升序,有的降序。想要完成这样的查询,我们还是需要依靠sort对象去实现。sort.by 的入参中还有可以传 order 数组和列表,我们就利用数组和列表对数据进行多参数的多样排序,话不多说,直接上码。

Sort by 源码

/**
 * Creates a new {@link Sort} for the given {@link Order}s.
 *
 * @param orders must not be {@literal null}.
 * @return
 */
public static Sort by(List<Order> orders) {
   Assert.notNull(orders, "Orders must not be null");
   return orders.isEmpty() ? Sort.unsorted() : new Sort(orders);
}
/**
 * Creates a new {@link Sort} for the given {@link Order}s.
 *
 * @param orders must not be {@literal null}.
 * @return
 */
public static Sort by(Order... orders) {
   Assert.notNull(orders, "Orders must not be null");
   return new Sort(Arrays.asList(orders));
}

control 层

@GetMapping("findAllMoreSort")
public List<User> findAllMoreSort(String[] sorts,String[] paras) {
    int length = sorts.length;
    //Sort.Order[] orders = new Sort.Order[length];
    List<Sort.Order> listOrder = new ArrayList<>();
    for(int i=0; i<length; i++){
//      orders[i] = new Sort.Order(sorts[i].toLowerCase().equals("asc") ?
//                        Sort.Direction.ASC : Sort.Direction.DESC, paras[i]);
        listOrder.add(new Sort.Order(sorts[i].toLowerCase().equals("asc") ?
                            Sort.Direction.ASC : Sort.Direction.DESC, paras[i]));
    }
    //Sort sort = Sort.by(orders);
    Sort sort = Sort.by(listOrder);
    return userService.findAllSort(sort);
}

请求findAllMoreSort?sorts=asc,desc&paras=age,name,对age升序,对name降序,结果如下:

[{
	"id": 22,
	"name": "cc",
	"age": 11
}, {
	"id": 20,
	"name": "aa",
	"age": 11
}, {
	"id": 21,
	"name": "bb",
	"age": 12
}]

控制台输出如下:

Hibernate: select user0_.id as id1_0_, user0_.age as age2_0_, user0_.name as name3_0_ from user user0_ order by user0_.age asc, user0_.name desc

总结

find 相当于增删改查中的查,也是其中最复杂的一个操作,因为涉及的东西比较多。这篇主要是整理了单表的单条查询和多条查询,下一篇准备看看单表的分页查询。

以上就是Spring JPA find单表查询方法示例详解的详细内容,更多关于Spring JPA find单表查询的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring JPA find分页示例详解

    目录 前言 源码 一.单纯分页查询 查询结果 结论 二.排序分页查询 查询结果 三.方法整理 总结: 前言 在现实项目中,数据量一般都不小,如果一次性全部请求出来,肯定是影响性能,而且大量数据展示到页面上观感也不好.这时我们就需要用到分页,给定一个 pageSize,每次请求的数量就是 pageSize 的大小,这样既可以节约时间,又可以美化页面.Spring JPA 就为我们提供这样一个方法,准确来说是提供了一个对象用来约束数据按照分页的形式进行请求. 源码 findAll(Pageable

  • Spring JPA之save方法示例详解

    目录 一.save(单条添加) 源码 service 层 control层 二.saveAll(批量添加) 源码 service control层 一.save(单条添加) 源码 @Transactional @Override public <S extends T> S save(S entity) { Assert.notNull(entity, "Entity must not be null."); if (entityInformation.isNew(enti

  • Spring JPA学习之delete方法示例详解

    目录 一.deleteById 和 delete deleteById(Id id)(通过id进行删除) delete(T entity)(通过实体对象进行删除) 实例 service 层 control层 二.deleteAllById 和 deleteAll 1.deleteAllById(Iterable<? extends ID> ids)(通过id进行批量删除) 2.deleteAll(Iterable<? extends T> entities)(通过实体对象进行批量删

  • Spring JPA联表查询之OneToMany源码解析

    目录 前言 源码 单向联表 user 实体类 house 实体类 查询结果 双向联表 user 实体类 house 实体类 对象获取 前言 我们在实际项目中,除了会碰到一对一的情况,还有一对多的情况,比如一个用户可以有多辆车,而一辆车只能有一个用户等等,今天我们就来一起学习下 OneToMany(一对多). 源码 @OneToMany 注解实现一对多关系映射.比如用户跟房子的关系, 一个用户可以有好多房子,而一个房子只能一个用户.老规矩,实例之前先看看源码: public @interface

  • Spring JPA联表查询之OneToOne源码详解

    目录 前言 源码 注解属性 单向联表 user 实体类 car 实体类 查询结果 双向联表 user 实体 car 实体 查询结果 延迟加载(懒加载) user 实体 查询结果: 查询完会发现,控制台又打印了一个 JPQL: 最后结论 前言 前面几篇我们学习的都是单表查询,就是对一张表中的数据进行查询.而实际项目中,基本都会有多张表联合查询的情况,今天我们就来了解下JPA的联表查询是如做的. 源码 @OneToOne 注解实现一对一关系映射.比如用户跟车辆的关系(这里假设一个人只能有一辆车),一

  • Spring JPA之find拓展方法示例详解

    目录 前言 一.单条件查询 1.精确查询(确定值,例如:=.is) 2.范围查询(一定范围,例如<.<=.>.>=.in.between) a)运算符 b)between c)in 3.模糊查询 a)findByNameLike b)findByNameStartingWith 二.多条件查询 三.关键字 最后总结: 前言 前两篇我们详细了解了 findById 和 findAll 以及 findAll 的分页查询,如果说JPA只有上面的两种查询功能,那就太low了,今天让我们再深

  • Spring JPA联表查询之注解属性详解

    目录 前言 一.targetEntity 二.cascade 1.不定义 2.CascadeType.PERSIST 3.CascadeType.REMOVE 4.CascadeType.REFRESH 5.CascadeType.MERGE 6.CascadeType.ALL 三.fetch FetchType.LAZY FetchType.EAGER 四.mappedBy 五.orphanRemoval 前言 对于联表查询的四个注解 @OneToOne.@OneToMany.@ManyToO

  • MySQL单表查询操作实例详解【语法、约束、分组、聚合、过滤、排序等】

    本文实例讲述了MySQL单表查询操作.分享给大家供大家参考,具体如下: 语法 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名                   WHERE 条件                   GROUP BY field                   HAVING 筛选                   ORDER BY field                   LIMIT 限制条数 二.关键字的执行优先级(重点) 重点中的重点:关键

  • JPA @Basic单表查询如何实现大字段懒加载

    JPA @Basic单表查询实现大字段懒加载 近期看了JPA@Basic注解的使用,看到该注解可以设置字段的懒加载. 1.以前碰到的懒加载: 我们知道,多表关联的时候,我们是可以配置懒加载的,比如一个Company类,里面可以关联员工表,办公设备表,当我们查看公司信息的时候,我们并不需要直接加载员工表,办公设备表,只需要在用户查看员工,查看设备的时候再加载,这样可以提高加载效率. 长话短说,大概是这样子的 @Entity @Table(name = "Company") public

  • springboot jpa分库分表项目实现过程详解

    这篇文章主要介绍了springboot jpa分库分表项目实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 分库分表场景 关系型数据库本身比较容易成为系统瓶颈,单机存储容量.连接数.处理能力都有限.当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库.优化索引,做很多操作时性能仍下降严重.此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间. 分库分表用于应对当前互联网常见的两个场景--大数

  • 浅谈使用Java Web获取客户端真实IP的方法示例详解

    Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: 方式一.客户端未经过代理,直接访问服务器端(nginx,squid,haproxy): 方式二.客户端通过多级代理,最终到达服务器端(nginx,squid,haproxy): 客户端请求信息都包含在HttpServletRequest中,可以通过方法getRemoteAddr()获得该客户端IP.

  • Spring Cloud动态配置刷新RefreshScope使用示例详解

    目录 引言 一.了解@RefreshScope,先要了解@Scope 二.RefreshScope 的实现原理 三.使用——@RefreshScope 使用流程 引言 用过Spring Cloud的同学都知道在使用动态配置刷新的我们要配置一个 @RefreshScope,在类上才可以实现对象属性的的动态更新. @RefreshScope 能实现动态刷新全仰仗着 @Scope这个注解. 一.了解@RefreshScope,先要了解@Scope 1.RefreshScope继承于GenericSco

  • Go Java算法之Excel表列名称示例详解

    目录 Excel表列名称 方法一:数学(Java) 方法一:数学(Go) Excel表列名称 给你一个整数 columnNumber ,返回它在 Excel 表中相对应的列名称. 例如: A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 ... 示例 1: 输入:columnNumber = 1 输出:"A" 示例 2: 输入:columnNumber = 28 输出:"AB"

  • Spring boot进行参数校验的方法实例详解

    Spring boot开发web项目有时候我们需要对controller层传过来的参数进行一些基本的校验,比如非空.整数值的范围.字符串的长度.日期.邮箱等等.Spring支持JSR-303 Bean Validation API,可以方便的进行校验. 使用注解进行校验 先定义一个form的封装对象 class RequestForm { @Size(min = 1, max = 5) private String name; public String getName() { return n

  • Go语言中的字符串处理方法示例详解

    1 概述 字符串,string,一串固定长度的字符连接起来的字符集合.Go语言的字符串是使用UTF-8编码的.UTF-8是Unicode的实现方式之一. Go语言原生支持字符串.使用双引号("")或反引号(``)定义. 双引号:"", 用于单行字符串. 反引号:``,用于定义多行字符串,内部会原样解析. 示例: // 单行 "心有猛虎,细嗅蔷薇" // 多行 ` 大风歌 大风起兮云飞扬. 威加海内兮归故乡. 安得猛士兮守四方! ` 字符串支持转义

  • 编译安装redisd的方法示例详解

    安装方法: yum安装 查看yum仓库redis版本 [root@centos ~]# yum list redis Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile Available Packages redis.x86_64 3.2.12-2.el7 myepel yum安装 [root@centos ~]# yum install redis -y 启动服务并设为开机启动

随机推荐