【问题标题】:Hibernate mapping One class to two tables (the two tables have many to one relationship)Hibernate 映射一个类到两个表(两个表有多对一的关系)
【发布时间】:2015-04-17 14:32:00
【问题描述】:

我使用的是 Hibernate 4.3.6
我有一个名为 StudyCase 的实体,映射到数据库中名为 StudyCase 的表 ,我还得到了另一个实体名称 Measurement 映射到数据库中名为 Measurement 的表。每个 StudyCase 对象都可以与许多 Measurement 对象相关联,问题是这样的。 我想将这两个表映射到一个名为 mergeEntity 的新实体中,并使用两个表中的 clumns 查询它,结果将是与具有相同约束的测量对象具有一对一关系但也将分配的对象列表他们所属的 StudyCase 对象的信息。

我在 spring jpa 中做了一些类似的工作:

public List<MergeObject> searchMeasurement(String actualConditions)
{   
    jdbcTemplate = new JdbcTemplate(dataSource);
    String sql = "select  *  from Measurement  INNER JOIN StudyCase ON Measurement.study_case_number=StudyCase.study_case_number where "+actualConditions  ;
    List<MergeObject> result =  this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<MergeObject>(MergeObject.class)) ;

    return result ; 
}

有什么方法可以让我使用 hibernate 实现同样的目标。 谢谢 !

【问题讨论】:

  • 我有类似的要求,我想将两个表(具有一对多关系)映射到一个类以处理结果。这些表已经创建(由第三方应用程序),我想从两个表中获取数据(即在非规范化视图中)并进行一些处理。我希望这是有效的用例。尝试使用 但它没有给出结果。直接在 DB 上触发时生成的 HQL 查询工作正常。

标签: java spring hibernate jpa


【解决方案1】:

使用 Hibernate 文档所说的,你必须这样做

@Entity
public class Troop {
    @OneToMany(mappedBy="troop")
    public Set<Soldier> getSoldiers() {
    ...
}

@Entity
public class Soldier {
    @ManyToOne
    @JoinColumn(name="troop_fk")
    public Troop getTroop() {
    ...
}           

这建立了双向关系

【讨论】:

    【解决方案2】:

    最后我最终使用了 spring-jpa,但我想说的是一种更紧凑的方式。 这是额外的代码:

    private DriverManagerDataSource dataSource;
    private JdbcTemplate jdbcTemplate;
    

    我创建了一个手动初始化数据源的方法:

    public void initDataSource()
        {
        String url  = "jdbc:sqlserver://localhost:1433;DatabaseName=testdb" ;
        Properties properties = new Properties()  ; 
        properties.setProperty("username", "actualUsername") ; 
        properties.setProperty("password", "actualpassowrd") ; 
        properties.setProperty("driverClassName", "com.microsoft.sqlserver.jdbc.SQLServerDriver") ;  
        properties.setProperty("dialect", "org.hibernate.dialect.SQLServerDialect") ; 
        dataSource = new DriverManagerDataSource(url, properties) ; 
    }
    

    我是这样使用它的:

        initDataSource() ; 
        jdbcTemplate = new JdbcTemplate(dataSource);
        String sql = "select  *  from Measurement  INNER JOIN StudyCase ON Measurement.study_case_number=StudyCase.study_case_number where "  ;
        List<DaoObject> result =  this.jdbcTemplate.query(sql, new BeanPropertyRowMapper<DaoObject>(DaoObject.class)) ;
    

    【讨论】:

      【解决方案3】:

      是的,使用 Hibernate,您可以创建如下所示的模型/实体对象

       @Entity
          @Table(name="StudyCase")
          public class StudyCase {
          @Id
          @GeneratedValue
          @Column(name = "id")
          private Long id;
          @Column(name="study_case_number")
          private Long study_case_number; //You might try to use Integer of String as per your requirement
              ... getter setter
          }
      
          @Entity
          @Table(name="StudyCase")
          public class Measurement {
              @Id
              @GeneratedValue
              @Column(name = "id")
              private Long id;
      
              @ManyToOne
              @JoinColumn(name="StudyCase")
              private StudyCase studyCaseId
      
             ... getter setter
          }     
      

      现在使用 Hibernate Query 你可以像下面这样写 Query

      String sql = "from Measurement as measurement "
                      + "inner join measurement.studyCaseId as studyCaseId "
                      + "where studyCaseId.study_case_number= :studyCaseNumber";
              Query query = getCurrentSession().createQuery(sql);
              query.setParameterList("studyCaseNumber", studyCaseNumberLong);
              List<Measurement> measurementList = query.list();
      

      希望以上示例对您有所帮助 万事如意!!!

      【讨论】:

      • 感谢您的帮助,但我认为您可能错过了这里的重点!我问的不是如何在两个实体之间创建一二多关系,而是问是否有可能创建一个对象,该对象将具有两个实体的文件,并且只提供查询服务。例如,让我们假设存在一个 studycase 对象和 5 个与它相关联的 Measurement 对象,当我希望能够作为查询的结果获得 5 个类型(mergeObject)的对象时,Studcase 对象的字段将重复测量字段的不同值的 5 倍。
      • 对不起,我正在尝试,只是有点难以准确解释!
      • 你好@Nikolis.Py,好的,我明白你的意思,但是为什么你要创建一个新的合并实体,当你可以从测量实体(子)中获取 StudyCase 实体(父)时,看看你是否想要创建一个 MargeEntity ,您可以从中获取 StudyCase 以及 Measurement 对象...所以基本上您正在创建一个新表来存储 mergeEntity ,该表将具有 StudyCase 和 Measurement 表的外键(如果我犯了任何错误,请纠正我),所以我的问题是,当您可以使用两个表(StudyCase、Measurement)获得相同的结果时,为什么要创建一个新表(mergedEntity)!!!
      • 好吧,我必须拥有这个对象,因为我需要将它们作为一个整体呈现(这不取决于我),而 Spring 使查询我解释的方式成为可能,这大大降低了我的复杂性代码所以我在问是否有可能使用我现在坚持的休眠实现同样的事情。
      • 重点是避免在数据库中创建额外的表!
      猜你喜欢
      • 2010-12-12
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 2014-01-15
      • 1970-01-01
      • 2012-05-28
      • 2020-05-20
      • 2011-08-10
      相关资源
      最近更新 更多