Java文档阅读笔记-JPA中getOne()和findById的区别
发布日期:2021-06-30 10:46:13 浏览次数:2 分类:技术文章

本文共 2305 字,大约阅读时间需要 7 分钟。

findById()和getOne()都是从数据库中检索某个对象,不过获取数据的方式是不同的,getOne()是lazy操作,这种操作甚至没有访问数据库。

 

getOne()

返回ID的引用对象,他内部调用的了EntityManager.getReference()方法,这个方法返回proxy而非直接访问数据库(所以叫lazy),如果请求的实体不存在数据库中,那么此方法抛出EntityNotFoundException。

 

findById()

此方法直接访问数据库返回真实的对象,如果这条记录在数据库中不存在,则返回null。

 

何时使用getOne()何时使用findById()

getOne()避免了数据库和JVM的访问,直到返回的proxy的属性是真实的数据库访问。才会去访问数据库。

设计如下场景来说明这2个调用的区别:

Department

@Entity@Table(name = "t_departments")public class Department {    @Id    @GeneratedValue(strategy= GenerationType.AUTO)    private Long id;    private String name;

Employee

@Entity@Table(name = "t_employees")public class Employee {    @Id    @GeneratedValue(strategy= GenerationType.AUTO)    private Long id;    private String name;    @ManyToOne      private Department department;

Employee的department属性和Department类有关。

如下代码:

@Service@Transactional(propagation = Propagation.REQUIRES_NEW)public class HRService {    @Autowired    private DepartmentRepository departmentRepository;    @Autowired    private EmployeeRepository employeeRepository;    public Department createDepartment() {        Department dept = new Department();        dept.setName("Product & Engg");        return departmentRepository.save(dept);    }    public void createEmployee1(long deptId) {        final Department pne = departmentRepository.getOne(deptId);         Employee employee = new Employee();        employee.setName("Foo 1");        employee.setDepartment(pne);        employeeRepository.save(employee);    }

使用getOne()比findById()要好,因为这里面的场景并不需要获取department的对象

生成的SQL如下:

insert into t_employees (department_id, name, id) values (?, ?, ?)

当使用findById()代替getOne()如下代码:

public void createEmployee2(long deptId) {        Optional
pne = departmentRepository.findById(deptId); Employee employee = new Employee(); employee.setName("Foo 1"); pne.ifPresent(department -> { employee.setDepartment(department); }); employeeRepository.save(employee); }

生成的SQL如下:

select department0_.id as id1_4_0_, department0_.name as name2_4_0_ from t_departments department0_ where department0_.id=? insert into t_employees (department_id, name, id) values (?, ?, ?)

总结:

getOne() findById()
lazily loaded目标实体 直接通过ID获取数据库中的实体
只获取对象需要用的属性 快速加载对象的所有属性
如果对象不存在抛出EntityNotEoundException 对象不存在就返回null
更好的性能 传统数据库访问方式

转载地址:https://it1995.blog.csdn.net/article/details/111880381 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring Shell笔记-help方法及exit及其他方法
下一篇:Java笔记-String.format的使用(可用于格式化字符串)

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月07日 14时58分14秒