Spring JPA find单表查询方法示例详解
作者:烟雨戏江南 发布时间:2022-11-03 19:43:38
一、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()));
}
可以看到我们需要传入两个参数,分别是 direction 和 properties:
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¶=age,name
,对 age 和 name 进行降序排序,结果如下:
[{
"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¶s=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
来源:https://juejin.cn/post/7223325947339882555
猜你喜欢
- 前情提要我们上节内容学习了如何创建\注册\读取bean我们发现bean对象操作十分的繁琐!所以我们这个章节,就带大家来了解更加简单的bean
- 一、达梦数据库简介说明:有关国产数据库完整的博客太少了,所以就想弄一个完整的专栏给大家提供一些帮助。在现在这种国际形势下,网络安全是每个企业
- SpringBoot集成Mybatis时mybatis.mapper-locations和@MapperScan的作用1、mybatis.m
- 本文实例为大家分享了Java实现简单ATM机功能的具体代码,供大家参考,具体内容如下项目介绍基于大家使用银行卡在ATM机取款操作,进行相对应
- @Autowired使用构造函数注入public Class Outer { private Inner inner; @Autowired
- 本文实例讲述了spring mvc 实现获取后端传递的值。分享给大家供大家参考,具体如下:jsp页面怎么获取从后端传递过来的值?JSTL 方
- 今天来说一个Java多机部署下定时任务的处理方案。需求: 有两台服务器同时部署了同一套代码, 代码中写有spring自带的定时任务,但是每次
- 本文实例为大家分享了Java实现寻找迷宫出路的具体代码,供大家参考,具体内容如下项目名称寻找迷宫出路项目描述给定一个自定义迷宫,0表示能通过
- MyBatis是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。spri
- 一、何为栈?栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称
- 一、概要我们可以用java实现简单的登录界面。如上效果,直观但也需要一步一步来完成,从界面弹窗的设置,图片的插入,文本框的设置,到登录的按钮
- 概要设计模式是一门艺术,如果真正了解这门艺术,你会发现,世界都将变得更加优美。定义定义一个用于创建对象的接口,让其子类去决定实例化那个类使用
- @Cacheable在同一类中方法调用无效上述图片中,同一个类中genLiveBullets()方法调用同类中的queryLiveByRoo
- 在Java的线程执行中,不管是直接继承Thread的方式,还是实现Runnable接口的方式,都不会获取到线程执行的返回结果。这样如果线程在
- JAVA常用关键字及其用法简要说明Abstract: 抽象的 一个Java语言中的关键字,用在类的声明中来指明一个类是不能被实例化的,但是可
- 在我们使用mybatis plus 时, mybatis plus 可以帮我们自动封装我们的实体类用来查询添加,当我们遇见我们的尸体类名与我
- 使用spring redis的increment方法时,报错:nested exception is redis.clients.jedis
- springBoot是java开发中会经常用到的框架,那么在实际项目中项目配置了springBoot框架,应该如何在项目中读取配置文件中的参
- 1. 公共字段自动填充1.1 问题分析在新增员工时需要设置创建时间、创建人、修改时间、修改人等字段,在编辑员工时需要设置修改时间、修改人等字
- 本文实例讲述了Java判断两个日期相差天数的方法。分享给大家供大家参考。具体如下:import java.util.Calendar;pub