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) { Optionalpne = 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月07日 14时58分14秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
redis使用--pattern选项遍历查询
2019-04-30
详细记录一次Tomcat服务器和Nginx服务器的缺省banner的修改全过程
2019-04-30
Linux下不同后缀的压缩包的解压命令
2019-04-30
linux命令tee
2019-04-30
linux安装docker
2019-04-30
Docker Compose安装
2019-04-30
批处理命令传递参数
2019-04-30
apache访问php文件报403权限问题
2019-04-30
Java连接access数据库demo
2019-04-30
ORA-01000: 超出打开游标的最大数 问题的分析和解决
2019-04-30
SVN环境中add命令详解
2019-04-30
SVN的提交和更新和删除
2019-04-30
SVN命令diff、mkdir、cat
2019-04-30
SVN工作副本还原命令revert
2019-04-30
SVN锁定lock和解锁unlock
2019-04-30
SVN强制解锁操作
2019-04-30
SVN命令list
2019-04-30