JPA+Hibernate...关联不是单个查询,而是执行多个查询进行连接

Man*_*hah 6 mysql hibernate jpa

我有两个名为 Banners 和 BannerGroup 的类。

\n\n

我已经创建了双向关系。\n就我而言,一个 BannerGroup 可以有许多横幅,并且许多横幅属于同一个 BannerGroup。

\n\n

Mysql 表是...

\n\n
mysql> desc Banners;\n+------------------+--------------+------+-----+---------+-----------------------------+\n| Field            | Type         | Null | Key | Default | Extra                       |\n+------------------+--------------+------+-----+---------+-----------------------------+\n| banner_id        | int(11)      | NO   | PRI | NULL    | auto_increment              | \n| banner_name      | varchar(255) | YES  |     | NULL    |                             | \n| banner_group_id  | int(11)      | YES  | MUL | NULL    |                             | \n+------------------+--------------+------+-----+---------+-----------------------------+\n\nmysql> desc Banner_Group;\n+---------------------+--------------+------+-----+----------------+-----------------------------+\n| Field               | Type         | Null | Key | Default        | Extra                       |\n+---------------------+--------------+------+-----+----------------+-----------------------------+\n| group_id            | int(11)      | NO   | PRI | NULL           | auto_increment              | \n| group_name          | varchar(255) | NO   | MUL | NULL           |                             | \n+---------------------+--------------+------+-----+----------------+-----------------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的模型类是这样的......

\n\n
Class Banners\n{\n    private Integer bannerId;\n    private String bannerName;\n    private BannerGroup bannerGroupDO;\n\n    @Id\n    @GeneratedValue(strategy=GenerationType.AUTO)\n    @Column(name = "banner_id")\n    public Integer getBannerId() {\n        return bannerId;\n    }\n\n    public void setBannerId(Integer bannerId) {\n        this.bannerId = bannerId;\n    }\n\n    @Column(name = "banner_name")\n    public String getBannerName() {\n        return bannerName;\n    }\n\n    public void setBannerName(String bannerName) {\n        this.bannerName = bannerName;\n    }\n\n    @ManyToOne(fetch = FetchType.EAGER, optional=false)\n    @JoinColumn(name = "banner_group_id",  nullable = false)\n    public BannerGroup getAffiliateBannerGroup() {\n        return bannerGroupDO;\n    }\n\n    public void setAffiliateBannerGroup(BannerGroup bannerGroupDO) {\n        this.bannerGroupDO = bannerGroupDO;\n    }\n}\n\nClass BannerGroup{\n\n    private int group_id;\n    private int group_name;\n    private List<Banners> banners;\n\n    @Id\n    @GeneratedValue(strategy=GenerationType.AUTO)\n    @Column(name = "group_id")\n    public Integer getGroupId() {\n        return groupId;\n    }\n\n    public void setGroupId(Integer groupId) {\n        this.groupId = groupId;\n    }\n\n    @Column(name = "group_name")\n    public String getGroupName() {\n        return groupName;\n    }\n\n    public void setGroupName(String groupName) {\n        this.groupName = groupName;\n    }\n\n    @OneToMany(mappedBy="bannerGroupDO", fetch = FetchType.LAZY)\n    public List<Banners> getBanners() {\n        return banners;\n    }\n\n    public void setBanners(List<Banners> banners) {\n    this.banners = banners;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,当我尝试获取横幅时(急切地加载了横幅组)

\n\n
Query q = session.createQuery("from com.abc.xyz.model.Banners where bannerId = 123");\n
Run Code Online (Sandbox Code Playgroud)\n\n

我懂了...

\n\n
Hibernate: select b.banner_id as banner1_294_, b.banner_name as banner2_294_ from Banners b where b.banner_id=?\nHibernate: select bg.group_id as group1_295_0_, bg.group_name as group9_295_0_ from Banner_Group bg where bg.group_id=?\n
Run Code Online (Sandbox Code Playgroud)\n\n

我想要什么:Hibernate 应该执行单个查询 而不是 多个(两个)查询。\n我希望 hibernate 应该触发“内部联接”查询...类似...

\n\n
select b.*, bg.* from Banners b INNER JOIN Banner_Group bg ON b.banner_group_id=bg.group_id;\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的问题是...

\n\n

1.) 为什么 hibernate 执行多个查询而不是单个查询,即使我已经指定了关联。?

\n\n

2.)我应该怎么解决这个问题?

\n\n

我不想执行 JPQL/HQL。我的意思是说,我只想从关联中获得行为。我只想通过执行类似的查询得到结果...from com.abc.xyz.model.Banners where bannerId = 123;

\n\n

3.)我知道...单独执行两个查询和单个查询的结果是相同的。但我认为这会影响数据库的性能。或者可能是数据库的一个粗鲁。我错了吗?

\n\n

在 Radim K\xc3\xb6hler 的回答之后...我在 Banners.java 中编辑了我的代码...(问题仍然没有解决)

\n\n
@ManyToOne(fetch = FetchType.EAGER, optional=false)\n    @JoinColumn(name = "banner_group_id",  nullable = false)\n    @Fetch(FetchMode.JOIN)\n    public AffiliateBannerGroup getAffiliateBannerGroup() {\n        return affiliateBannerGroup;\n    }\n\n    public void setAffiliateBannerGroup(AffiliateBannerGroup affiliateBannerGroup) {\n        this.affiliateBannerGroup = affiliateBannerGroup;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

Rad*_*ler 1

缺少的映射是

@Fetch(FetchMode.JOIN)
Run Code Online (Sandbox Code Playgroud)

在这里查看更多信息:JPA eager fetch does not join

EAGER 设置以不同的方式指示 Hibernate:不要等待加载实体及其引用。因此,即使在进一步处理中不使用该引用,也会加载该引用。LAZY加载,是大多数场景下首选且最合适的方式