spring-boot - Spring Boot JPA 关联与普通 SQL 连接
问题描述
我有三张桌子:
- 公司:
+--------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| company_id | int(11) | NO | PRI | NULL | |
| company_name | varchar(45) | YES | | NULL | |
+--------------+-------------+------+-----+---------+-------+
- 合法的:
+-------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| company_id | int(11) | YES | | NULL | |
| legal_price | double | YES | | NULL | |
+-------------+---------+------+-----+---------+----------------+
- 价格
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| company_id | int(11) | YES | | NULL | |
| price | int(11) | YES | | NULL | |
+------------+---------+------+-----+---------+----------------+
company
->legal
和company
->之间有两个一对多的关联price
。中的公司数据company
很少更改。另外两个表中的数据每天都被持久化。对应的实体如下:
@Entity
@Table(name = "company")
public class CompanyEntity {
@Id
@Column(name = "company_id", nullable = false)
private Integer companyID;
@Column(name = "company_name")
private String companyName;
@OneToMany(mappedBy = "company", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private Set<LegalEntity> legal;
@OneToMany(mappedBy = "company", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private Set<PriceEntity> price;
======
@Entity
@Table(name = "legal")
public class LegalEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "company_id", nullable = false)
private CompanyEntity company;
@Column(name = "legal_price")
private Double legalPrice;
======
@Entity
@Table(name = "price")
public class PriceEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "company_id", nullable = false)
private CompanyEntity company;
@Column(name = "price")
private Integer price;
legal
为了在or中保存新数据,我首先使用 findBycompanyIDprice
获取实体中的相应字段:company
CompanyEntity cmp = crep.findBycompanyID(13);
LegalEntity leg = new LegalEntity(cmp, 523.5);
lrep.save(leg);
对于查询数据,我使用 CriteriaBuilder API:
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<LegalEntity> criteriaQuery = criteriaBuilder.createQuery(LegalEntity.class);
Root<LegalEntity> root = criteriaQuery.from(LegalEntity.class);
criteriaQuery = criteriaQuery.select(root);
TypedQuery<LegalEntity> typedQuery = em.createQuery(criteriaQuery);
List<LegalEntity> results = typedQuery.getResultList();
for (LegalEntity legalEntity : results) {
log.info(legalEntity.toString());
}
这个过程可以通过一个简单的本地 SQL 查询来完成:
SELECT c.company_name, l.legal_price from legal l
JOIN company c
ON l.company_id = c. company_id;
当我调查 Hibernate SQL 命令时,我看到:
Hibernate:
select
legalentit0_.id as id1_1_,
legalentit0_.company_id as company_3_1_,
legalentit0_.legal_price as legal_pr2_1_
from
legal legalentit0_
Hibernate:
select
companyent0_.company_id as company_1_0_0_,
companyent0_.company_name as company_2_0_0_
from
company companyent0_
where
companyent0_.company_id=?
Hibernate:
select
companyent0_.company_id as company_1_0_0_,
companyent0_.company_name as company_2_0_0_
from
company companyent0_
where
companyent0_.company_id=?
Hibernate:
select
companyent0_.company_id as company_1_0_0_,
companyent0_.company_name as company_2_0_0_
from
company companyent0_
where
companyent0_.company_id=?
Hibernate:
select
companyent0_.company_id as company_1_0_0_,
companyent0_.company_name as company_2_0_0_
from
company companyent0_
where
companyent0_.company_id=?
我的问题是,哪种方法更有效?我更喜欢使用 CriteriaBuilder API,因为编码更容易且不易出错,但我必须在每次持久化之前查询公司字段。
解决方案
推荐阅读
- c - 为什么 pthread_join 不阻塞并等待线程完成?
- java - 使用快速/慢速 ptrs 找到链表的中间,当我不应该出现 nullptr 错误时(fast.next.next 检查)
- coldfusion - Coldfusion Query OF Query 生成的记录多于预期
- sql - 从另外两个表插入到一个表中
- django - 上传图片时基于id/用户名的Django动态文件夹名称
- python - tkinter 按钮功能调用:多次按下多次调用相同的功能
- c# - 使用方法调用作为已建立方法的参数
- c++ - 使用 Visual Studio 在 cmake 项目中没有配置
- php - Nginx 用户更改导致 Chrome 出现黑屏和 200 错误
- laravel - 计算 Laravel 中为空的 Created_at 日期