好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

JPA findById方法和getOne方法的区别说明

findById方法和getOne方法区别

Jpa基础的CRUD方法继承自接口CrudRepository<T, ID>,包含以下方法:

?

1

2

3

4

5

6

7

8

9

10

11

<S extends T> S save(S entity);

<S extends T> Iterable<S> saveAll(Iterable<S> entities);

Optional<T> findById(ID id);

boolean existsById(ID id);

Iterable<T> findAll();

Iterable<T> findAllById(Iterable<ID> ids);

long count();

void deleteById(ID id);

void delete(T entity);

void deleteAll(Iterable<? extends T> entities);

void deleteAll();

getOne()方法是JpaRepository接口中定义的

源码如下:

?

1

2

3

4

5

6

7

8

9

10

11

/**

  * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is

  * implemented this is very likely to always return an instance and throw an

  * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers

  * immediately.

  *

  * @param id must not be {@literal null}.

  * @return a reference to the entity with the given identifier.

  * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown.

  */

T getOne(ID id);

网上找的源码:

?

1

2

3

4

public T getOne(ID id) {

     Assert.notNull(id, "The given id must not be null!" );

     return this .em.getReference( this .getDomainClass(), id);

}

由getOne方法的源码可见,getOne方法会返回一个和给定id匹配的实体的引用,方法实际是调用getReference方法,也就是说加载策略是延迟加载,直到调用这个对象的时候才真正从数据库中进行查询(x_x)。

再看findById()方法

?

1

2

3

4

5

6

7

8

9

10

11

public Optional<T> findById(ID id) {

     Assert.notNull(id, "The given id must not be null!" );

     Class<T> domainType = this .getDomainClass();

     if ( this .metadata == null ) {

         return Optional.ofNullable( this .em.find(domainType, id));

     } else {

         LockModeType type = this .metadata.getLockModeType();

         Map<String, Object> hints = this .getQueryHints().withFetchGraphs( this .em).asMap();

         return Optional.ofNullable(type == null ? this .em.find(domainType, id, hints) : this .em.find(domainType, id, type, hints));

     }

}

findById实际上调用的是find方法,采用立即加载方式,执行这条查询语句的时候就会立刻从数据库中进行查询,不过findById方法返回的是一个Optional,需要对这个Optional调用.get()方法才能得到需要的实体。

总结就是getOne方法是懒加载,直到调用它返回的实体时才会对数据库进行查询,findById是立即加载,主要调用方法就会去数据库查询。getOne方法直接返回一个实体,findById方法返回一个Optional,需要调用.get()方法获取实体。

spring-data-jpa中findById()的使用

springboot 2.x 版本后,较之前的版本在此方法的使用上有差:

如果找到匹配的id数据,则赋值给foo;否则则将括号中的对象赋值给foo。

?

1

2

3

4

Foo foo = repository.findById(id)

                     .orElse( null );

Foo foo = repository.findById(id)

                     .orElse( new Object());

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_42026590/article/details/112364798

查看更多关于JPA findById方法和getOne方法的区别说明的详细内容...

  阅读:14次