hibernate 1+N 问题

2019-03-25 13:33|来源: 网路

有一个表ID表
@Entity
@Table(name="WF_ID_CH_TBL")
public class WfIdChTbl {
    private Integer acpt_flg;
    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="dep")
    private DepNm dep;
    @Id
    private String id;
    private String id_nm;
    private Date lgin_tm;
    private Integer lginflg;
    private String m_addr;
    private String prv_pswrd;
    private String pswrd;
    private Date pwd_vld;
    private Integer slvl;
    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="zw_id",referencedColumnName="zw_id")
    private ZwTbl zw;
}
id表和dep表zw表建立了多对一关系
dep表
@Entity
@Table(name="DEP_NM")
public class DepNm {
    @Id
    private String dep;
    private String dep_kbn;
    private String dep_nm;
}
zw表
@Entity
@Table(name="ZW_TBL")
public class ZwTbl {
    @Id
    private Integer zw_id;
    private String zw_name;
}
有一个查询
getHibernateTemplate().find("from WfIdChTbl ");
生成的sql为
select id , acpt_flg , dep , id_nm , lgin_tm , lginflg , m_addr , prv_pswrd , pswrd , pwd_vld ,  slvl , zw_id  from WF_ID_CH_TBL
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
select.zw_id ,zw_name  from ZW_TBL where zw_id=?
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
select.zw_id ,zw_name  from ZW_TBL where zw_id=?
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
select.zw_id ,zw_name  from ZW_TBL where zw_id=?
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
select.zw_id ,zw_name  from ZW_TBL where zw_id=?
select.zw_id ,zw_name  from ZW_TBL where zw_id=?
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
select.zw_id ,zw_name  from ZW_TBL where zw_id=?
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
select dep , dep_kbn , dep_nm  from DEP_NM where dep=?
显然查询WF_ID_CH_TBL表时、它是先查询WF_ID_CH_TBL表、
在查WF_ID_CH_TBL表中的每一个dep、和zw
这就是传说的n+1问题了。
在多对一中我已设置了eager、应该来说hibernate应生成一条WF_ID_CH_TBL和DEP_NM 和ZW_TBL三者关联的sql语句
为什么会这样?

问题补充:
Wind_ZhongGang 写道
应该设置的是join属性吧


你的意思是指在
getHibernateTemplate().find("from WfIdChTbl ");
中加inner join吗?

问题补充:
Wind_ZhongGang 写道
不,在配置关系的时候,也就是你的Annotation里

Wind_ZhongGang 写道
不,在配置关系的时候,也就是你的Annotation里

Annotation中该怎么写呢?

问题补充:
Wind_ZhongGang 写道
@ManyToOne(fetch=FetchType.EAGER)在这括号里面应该添加一个join属性,具体值请参见提示,我也记不太清楚了。

找了很久、没找到在哪儿配、
在网上也找了
只有xml中怎么配的、
是不是在annotation中不能配?

问题补充:
jkxydp 写道
EAGER,别用EAGER了,用LAZY,原因是这样的,你第一条查询语句查询出来的值有多个,那么每一条数据分别对应有一个外码关联,那么用EAGER的话就会直接一次性去把多条数据的外码关联的那条数据也查询出来,LAZY的话就在用到的时候再去查询一下。

这是典型的1+n问题。

我现在正要一次取出来主表和关联表
而且想它只发一条SQL语句

相关问答

更多
  • 您可以通过使用以下查询来避免使用IN子句 return find("SELECT DISTINCT m FROM MenuItem m " + "INNER JOIN m.accessGroups ag " + "LEFT OUTER JOIN ag.accessGroupLinks agl " + "LEFT OUTER JOIN agl.device device " + ...
  • 把它归结为1个查询是非常困难的(即我不知道一个可移植的解决方案),但将其归结为2个查询(不论n)是非常简单的: Criteria criteria = this.getSession().createCriteria(Mother.class); criteria.addOrder(Order.asc("title")) .setMaxResults(details.getMaxRows()) .setFirstResult(details.getStartResult()) .se ...
  • 我知道如何做到这一点的唯一方法是为我的课程提供两个属性。 一个作为编程API的布尔值,不包括在映射中。 它是getter和setter引用一个私有char变量,它是Y / N。 然后我有另一个保护属性包含在hibernate映射中,它的getter和setter直接引用private char变量。 The only way I've figured out how to do this is to have two properties for my class. One as the boolean f ...
  • 我建议内部加入帖子,并在group by的帮助下让数据库计数。 然后您不需要实例化帖子。 然后SQL应该如下所示: SELECT users.*, count(posts.id) AS number_posts FROM users LEFT OUTER JOIN posts ON posts.user_id = users.id AND posts.created_at > '2016-02-14 08:31:29' GROUP BY users.id 此外,您可以并利用 ...
  • 听起来你想要一个单向映射,你只能在CrewMovie上有注释。 需要将一列添加到TBL_SPJ_CREWMEMBER表以支持此列。 在我的示例中,我向其添加了列J_CREW_MOVIE_ID。 @Entity @Table(name="TBL_SPJ_CREW_MOVIE") public class CrewMovie implements Serializable { @Id @GeneratedValue(strategy=IDENTITY) @Column(name="CR ...
  • 解决了这个问题:1。从春季中排除公共记录: org.springframework spring-core ${org.springframework.version} commons-logging
  • 请阅读错误消息。 在底部的第4行: resource: sample/Event.hbm.xml not found Please read the error messages. On the 4th line from the bottom :resource: sample/Event.hbm.xml not found
  • RULE是SQL Server保留的关键字 。 如果你需要坚持这个名字,你需要逃避: @Table(name="`rule`") RULE is a SQL Server reserved keyword. If you need to stick to that name you need to escape it with: @Table(name="`rule`")
  • 不 - 我相信你不能覆盖EAGER映射,既不使用查找,查询也不能使用条件查询。 例如,请参阅StackOverflow线程 。 覆盖LAZY虽然容易。 hbm.xml文件,fetch =“select”表示所有关系表的一对多 ...似乎是一个糟糕的默认选择 - 这就是为什么相反的是Hibernate自己的默认选择。 通常,在映射中保持低位和懒惰是一种很好的做法,并在您渴望时使用查询。 No - I believe you cannot override EAGER mappings, neither usi ...
  • 如果您有代表您的关系的映射,您可以获得用户和用户将拥有包含Order类型元素的集合或列表。 然后您可以更新特定订单。 您描述的方法也是正确的,没有一些错误(例如,获取列表的标准上的调用list() )。) If you have mapping that represents your relationship, you can get User and user would have a set or list with elements of type Order. Then you can updat ...