Java 使用Hibernate的Spring Boot应用程序如何与多个结构相同的表交互?

Java 使用Hibernate的Spring Boot应用程序如何与多个结构相同的表交互?,java,mysql,hibernate,spring-boot,jpa,Java,Mysql,Hibernate,Spring Boot,Jpa,我有一个名为“currency”的MySQL数据库,有100多个表,每一个表对应一种货币,所有表的结构都相同(2列,一个datetime代表时间戳,一个float代表速率) Spring引导应用程序如何与此结构交互 我想要一个带有字段和getter/setter方法的CurrencyRate类。如果我将此类标记为@Entity,@Table,那么我只能访问一个表。我已经研究了@SecondaryTable标记,但它似乎只适用于我们希望同时与多个表交互的情况,而不是只与一个表交互的情况 impor

我有一个名为“currency”的MySQL数据库,有100多个表,每一个表对应一种货币,所有表的结构都相同(2列,一个datetime代表时间戳,一个float代表速率)

Spring引导应用程序如何与此结构交互

我想要一个带有字段和getter/setter方法的CurrencyRate类。如果我将此类标记为
@Entity
@Table
,那么我只能访问一个表。我已经研究了
@SecondaryTable
标记,但它似乎只适用于我们希望同时与多个表交互的情况,而不是只与一个表交互的情况

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Id;
import javax.validation.constraints.NotBlank;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.DateSerializer;
import com.fasterxml.jackson.databind.ser.std.NumberSerializers.FloatSerializer;

public abstract class CurrencyRate implements Serializable {

    @Id
    @JsonSerialize(using=DateSerializer.class)
    private Date datetime;

    @NotBlank
    @JsonSerialize(using=FloatSerializer.class)
    private float rate;

    Date getDate () { return this.datetime; }
    void setDate (Date timestamp) { this.datetime = timestamp; }
    float getRate () { return this.rate; }
    void setRate (float rate) { this.rate = rate; } 
}
我的想法是,我可以使CurrencyRate成为一个抽象类(如图所示),然后为从该类继承的每种货币创建一个类。这将是非常乏味的,但至少它可能会工作。然而,似乎我不仅要为每个货币模型创建一个类,还要为每个存储库创建一个类

除非有一种方法可以在不做这些的情况下为这个结构服务?有什么想法吗?目前正在查看文档并搜索其他有此问题的文档,但这种结构似乎并不常见

编辑:

我想添加控制器,因为我相信它是区分抽象类的子类的逻辑问题发生的位置

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/rates")
class CurrencyRateController {

    @Autowired
    private CurrencyRateService service;

    @GetMapping("/allEUR")
    public List<CurrencyRate> getAllEUR() {
        return service.findAll();
    }

    @GetMapping("/allCAD")
    public List<CurrencyRate> getAllCAD() {
        return service.findAll();
    }
}

import java.util.List;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RestController;
@RestController
@请求映射(“/rates”)
类CurrencyRateController{
@自动连线
私人货币服务;
@GetMapping(“/allEUR”)
公共列表getAllEUR(){
return service.findAll();
}
@GetMapping(“/allCAD”)
公共列表getAllCAD(){
return service.findAll();
}
}

上面的控制器返回/allCAD和/allEUR的CAD值,我假设是因为CurrencyRateService使用CurrencyRateRepository。在某些地方,Hibernate试图区分EUR子类和CAD子类,但它们是相同的。因此,为所有请求提供CAD值。

可能您必须使用正确的继承策略。像这样:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class CurrencyRate {
  (... omitted for brevity ...)
}
子类:

@Entity
@Table(name="USDOLLAR")
public class UnitedStatesDollar extends CurrencyRate {
}

@Entity
@Table(name="EURO")
public class Euro extends CurrencyRate {
}
其他货币也是如此。您应该能够查询
CurrencyRate
类,从所有表中检索所有结果,并且必须使用
instanceof
来区分货币。您还可以对单一货币执行查询


如果您想了解有关继承的更多信息,请看一看。

可能您必须使用正确的继承策略。像这样:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class CurrencyRate {
  (... omitted for brevity ...)
}
子类:

@Entity
@Table(name="USDOLLAR")
public class UnitedStatesDollar extends CurrencyRate {
}

@Entity
@Table(name="EURO")
public class Euro extends CurrencyRate {
}
其他货币也是如此。您应该能够查询
CurrencyRate
类,从所有表中检索所有结果,并且必须使用
instanceof
来区分货币。您还可以对单一货币执行查询


如果您想了解有关继承的更多信息,请看一看。

在您的场景中,我认为应该使用单表策略,因为它将为每个类层次结构创建一个表。如果我们没有明确指定一种策略,这也是JPA选择的默认策略。 您可以通过向超类添加@Inheritation注释来定义要使用的策略: 母公司:-

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class CurrencyRate  {
    @Id
    @JsonSerialize(using=DateSerializer.class)
    private Date datetime;

    @NotBlank
    @JsonSerialize(using=FloatSerializer.class)
    private float rate;

    // constructor, getters, setters
}
没有字段的子类:-

@Entity
public class Rupee extends CurrencyRate {

}

@Entity
public class Dollar extends CurrencyRate {

}
由于所有实体的记录都在同一个表中,Hibernate提供了一种区分这些表行的方法。 在本例中,添加了一个名为DTYPE的鉴别器列,该列的值为实体的名称


您可以为CurrencyRate创建存储库,然后根据数据类型列查询CurrencyRate表。

在您的场景中,我认为应该使用单表策略,因为它将为每个类层次结构创建一个表。如果我们没有明确指定一种策略,这也是JPA选择的默认策略。 您可以通过向超类添加@Inheritation注释来定义要使用的策略: 母公司:-

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class CurrencyRate  {
    @Id
    @JsonSerialize(using=DateSerializer.class)
    private Date datetime;

    @NotBlank
    @JsonSerialize(using=FloatSerializer.class)
    private float rate;

    // constructor, getters, setters
}
没有字段的子类:-

@Entity
public class Rupee extends CurrencyRate {

}

@Entity
public class Dollar extends CurrencyRate {

}
由于所有实体的记录都在同一个表中,Hibernate提供了一种区分这些表行的方法。 在本例中,添加了一个名为DTYPE的鉴别器列,该列的值为实体的名称


您可以为CurrencyRate创建存储库,然后根据数据类型列查询CurrencyRate表。

谢谢您的回复。我正在努力实施你提出的解决方案。但是,我看不到RESTAPI和对特定货币表的调用之间的连接。例如,我们转到mysite/resources/findAllEURO。我们希望得到欧元表中的所有数据。我们有一个CurrencyRate服务,它使用CurrencyRate存储库,扩展了JpaRepository。该存储库如何知道查询EURO表?谢谢你的帮助。编辑:它似乎只处理抽象类CurrencyRate的一个子类。我将进一步询问。要查询单一货币,您应该为该货币创建一个特定的存储库。一个存储库不能处理多个表吗?我们正在查看每种货币一个存储库,并且有很多货币。是的,您拥有的CurrencyRate存储库应该完全可以处理您的所有货币。感谢您的回复。我正在努力实施你提出的解决方案。但是,我看不到RESTAPI和对特定货币表的调用之间的连接。例如,我们转到mysite/resources/findAllEURO。我们希望得到欧元表中的所有数据。我们有一个CurrencyRateService,使用Curre