我有以下查询和方法
private static final String FIND = "SELECT DISTINCT domain FROM Domain domain LEFT OUTER JOIN FETCH domain.operators LEFT OUTER JOIN FETCH domain.networkCodes WHERE domain.domainId = :domainId";
@Override
public Domain find(Long domainId) {
Query query = getCurrentSession().createQuery(FIND);
query.setLong("domainId", domainId);
return (Domain) query.uniqueResult();
}
使用< code >域作为
@Entity
@Table
public class Domain {
@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(name = "domain_id")
private Long domainId;
@Column(nullable = false, unique = true)
@NotNull
private String name;
@Column(nullable = false)
@NotNull
@Enumerated(EnumType.STRING)
private DomainType type;
@OneToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}, fetch = FetchType.EAGER)
@JoinTable(joinColumns = {
@JoinColumn(name = "domain_id")
}, inverseJoinColumns = {
@JoinColumn(name = "code")
})
@NotEmpty
@Valid // needed to recur because we specify network codes when creating the domain
private Set<NetworkCode> networkCodes = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(joinColumns = {
@JoinColumn(name = "parent", referencedColumnName = "domain_id")
}, inverseJoinColumns = {
@JoinColumn(name = "child", referencedColumnName = "domain_id")
})
private Set<Domain> operators = new HashSet<>();
// more
}
我希望这个查询能够获取Set
Hibernate: select distinct domain0_.domain_id as domain1_1_0_, domain2_.domain_id as domain1_1_1_, networkcod4_.code as code2_2_, domain0_.name as name1_0_, domain0_.type as type1_0_, domain2_.name as name1_1_, domain2_.type as type1_1_, operators1_.parent as parent1_0__, operators1_.child as child4_0__, networkcod3_.domain_id as domain1_1_1__, networkcod3_.code as code5_1__ from domain domain0_ left outer join domain_operators operators1_ on domain0_.domain_id=operators1_.parent left outer join domain domain2_ on operators1_.child=domain2_.domain_id inner join domain_network_codes networkcod3_ on domain0_.domain_id=networkcod3_.domain_id inner join network_code networkcod4_ on networkcod3_.code=networkcod4_.code where domain0_.domain_id=?
Hibernate: select operators0_.parent as parent1_1_, operators0_.child as child4_1_, domain1_.domain_id as domain1_1_0_, domain1_.name as name1_0_, domain1_.type as type1_0_ from domain_operators operators0_ inner join domain domain1_ on operators0_.child=domain1_.domain_id where operators0_.parent=?
Hibernate: select networkcod0_.domain_id as domain1_1_1_, networkcod0_.code as code5_1_, networkcod1_.code as code2_0_ from domain_network_codes networkcod0_ inner join network_code networkcod1_ on networkcod0_.code=networkcod1_.code where networkcod0_.domain_id=?
Hibernate: select operators0_.parent as parent1_1_, operators0_.child as child4_1_, domain1_.domain_id as domain1_1_0_, domain1_.name as name1_0_, domain1_.type as type1_0_ from domain_operators operators0_ inner join domain domain1_ on operators0_.child=domain1_.domain_id where operators0_.parent=?
Hibernate: select networkcod0_.domain_id as domain1_1_1_, networkcod0_.code as code5_1_, networkcod1_.code as code2_0_ from domain_network_codes networkcod0_ inner join network_code networkcod1_ on networkcod0_.code=networkcod1_.code where networkcod0_.domain_id=?
我猜这是因为我加入了operators
Domain
元素,但是它们必须加入自己。
有没有我可以执行的HQL查询可以两者兼得?
您标记了您的协会渴望。因此,无论您在查询中执行什么操作,Hibernate 都将加载所有关联的域和已加载域的网络代码。它将加载其他域的域和网络代码等,直到所有集合加载返回已加载的空集合或实体。
为避免这种情况,请使您的集合变懒(默认情况下是这样)。然后加载一个包含其运算符和网络代码的域将加载它。
Hibernate关系适用于不同的获取策略..!!
Hibernate提供了4种检索数据的策略:
选择
@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id")
@Fetch(FetchMode.SELECT)
在这个方法中,有多个SQL被触发。第一个被触发是为了检索父表中的所有记录。其余的被触发是为了检索每个父记录的记录。这基本上是N 1问题。第一个查询从数据库中检索N条记录,在这种情况下是N条父记录。对于每个父级,一个新的查询检索子级。因此对于N个父级,N个查询从子级表中检索信息。
加入
@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id")
@Fetch(FetchMode.JOIN)
这与SELECT读取策略类似,只是所有数据库检索都在JOIN读取中预先进行,这与SELECT中根据需要进行的检索不同。这可能成为一个重要的性能考虑因素。
订阅
@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id")
@Fetch(FetchMode.SUBSELECT)
两个SQL被触发。一个用于检索所有父级,第二个使用WHERE子句中的SUBSELECT查询来检索具有匹配父级ID的所有子级。
批次
@OneToMany(mappedBy="tableName", cascade=CascadeType.ALL)
@Column(name="id")
@@BatchSize(size=2)
批次大小映射到检索其子级的父级的数量。因此,我们可以指定一次要提取的记录数。但将执行多个查询。!!
一对多
多对一
Hibernate还区分(何时获取关联)
1.Immediate迷人-
加载Parent时,会立即获取关联、集合或属性。(惰性=“false”)
2.Lazy收集-
当应用程序调用集合上的操作时,会获取该集合。(这是集合的默认值。(lazy="true ")
3.“超懒惰”集合取数-
根据需要从数据库中访问集合的各个元素。Hibernate 尝试不将整个集合提取到内存中,除非绝对需要(适用于非常大的集合)(懒惰=“额外”)
4.代理提取-
当在关联对象上调用标识符getter以外的方法时,将获取单值关联。(惰性="代理")
5.“无代理”获取-
访问实例变量时会获取单值关联。与代理获取相比,这种方法不那么懒惰。(懒="no-agent")
6.Lazy属性获取-
访问实例变量时,将提取属性或单值关联。(懒惰=“真”)
一对多
多对一
如果你知道你的树只有两层,你是否想过加入更深的一层。像下面这样的?
SELECT DISTINCT domain FROM Domain domain
LEFT OUTER JOIN FETCH domain.operators operators1
LEFT OUTER JOIN FETCH domain.networkCodes
LEFT OUTER JOIN FETCH operators1.operators operators2
LEFT OUTER JOIN FETCH operators1.networkCodes
WHERE domain.domainId = :domainId
问题内容: 我有以下查询和方法 与作为 我希望这个查询可以获取and >关系,但事实并非如此。假设I查询有两个运算符,Hibernate将执行1 + 2 * 2 = 5个查询 我猜这是因为我加入了operator 元素,但他们必须加入自己的行列。 我可以执行同时执行的HQL查询吗? 问题答案: 如果您知道树中只有两个级别,那么您是否考虑过加入更深的一个级别。像下面的东西?
我在使用LEFT JOIN FETCH时遇到了一个问题。请参考我下面的实体和存储库。 考虑一个场景,可选的课程不会在任何时间点从表中删除。但是学生信息可以被删除。数据库中的两个表之间没有主键和外键关系。只是我们有一个共同的栏目“学生ID”。 不带事务的服务方法: 具有事务性的服务方法: 尽管我使用了LEFT JOIN FETCH,但当我调用依赖实体(即oc)时,为什么在学生记录不存在的情况下(即学
我有一个结构如下的表格,其中包含有关俱乐部会员的信息 我对后来重新加入的成员感兴趣。对于上述数据,在整个期间,这样做了一次,没有,而这样做了两次。 每次发生这种情况,从他们的会员资格结束到他们重新加入的时间是多少?对于上述数据,这将是: 我很乐意得到使用R(理想情况下使用dplyr)或SQL(MySQL)的答案
这是我的命名查询: @NamedQuery(name=“User.findOneWithLists”,query=“从用户u中选择u”“左连接获取u.aTemplates”“左连接获取u.bTemplates”“左连接获取u.bp”“左连接获取u.aCredentials”“左连接获取u.st WHERE(st.deleted=false)”“左连接获取u.bCredentials”“左连接获取u
null 如何在employee实体中只取Dept.name列而不是整个Department行(需要避免对Department进行的大量集合进行急切的取数)?如果是,我应该使用什么注释? 如何在此方案中处理级联?
我试图提取JSOUP中给定元素中的链接。这里我做了什么但它不起作用: 我正在尝试做的事情是获得所有的链接与文章类。我想,也许首先我必须选择section class=“row”,然后从article类派生链接,但我无法使其工作。