【问题标题】:Does Spring Data Jdbc enables join foreign key rather than id's?Spring Data Jdbc 是否启用连接外键而不是 id?
【发布时间】:2021-01-05 06:31:54
【问题描述】:

尝试了很多选项,但我一直都错了。存储库不是通过在供应商合同表的“状态”列中填充的 ID 获取实际的状态名称,而是返回 2 个表的连接 ID。那么如何通过状态列supplierContractRepository.findById(3L)的int检索status_name?

状态实体

 CREATE TABLE `contract_statuses` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
);

public class ContractStatuses {
  
    @Id
    Integer id;
    String name;

    public ContractStatuses(int id, String name) {
        this.id = id;
        this.name = name;
    }
} 

合同实体

    CREATE TABLE `suppliers_contracts` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `supplier` bigint(20) NOT NULL,
      `cabs_id` int(11) DEFAULT NULL,
      `start_date` date DEFAULT NULL,
      `end_date` date DEFAULT NULL,
      `attorny_end_date` date DEFAULT NULL,
      `number_of_payments` int(11) DEFAULT NULL,
      `payment_amount` int(11) DEFAULT NULL,
      `comments` varchar(2000) DEFAULT NULL,
      `close_date` timestamp NULL DEFAULT NULL,
      `status` int(11) NOT NULL,
      `created_on` timestamp NOT NULL DEFAULT current_timestamp(),
      PRIMARY KEY (`id`)
    );

@Table("suppliers_contracts")
public class SupplierContract {
    @Id
    Long id;
    Long supplier;
    Long cabsId;
    Date startDate;
    Date endDate;
    int paymentAmount;
    Date attornyEndDate;
    int numberOfPayments;
    String comments;
    Date closeDate;
    @MappedCollection(idColumn = "id")
    ContractStatuses status;
   
    public SupplierContract(Long id, Long supplier, Long cabsId, Date startDate, Date endDate,Date attornyEndDate, int numberOfPayments, int paymentAmount,
                            String comments, Date closeDate,ContractStatuses status) {
        this.id = id;
        this.supplier = supplier;
        this.cabsId = cabsId;
        this.startDate = startDate;
        this.endDate = endDate;
        this.attornyEndDate = attornyEndDate;
        this.numberOfPayments = numberOfPayments;
        this.paymentAmount = paymentAmount;
        this.comments = comments;
        this.closeDate = closeDate;
        this.status = status;

    }
}
        //Getters and setters here

@GetMapping("/getContracts")
    public Optional<SupplierContract> getSupp(){
       Optional<SupplierContract>  contract = supplierContractRepository.findById(3L);
        return contract ;
    }

【问题讨论】:

    标签: java spring spring-data spring-data-jdbc


    【解决方案1】:

    您有多种选择:

    1. 默认变体是通过单独调用单独的ContractStatusRepository 来加载状态。由于这些状态可能不会经常更改,因此您可以考虑为此进行缓存。

    2. 如果您只想要状态而不关心合同,您可以使用 @Query 注释向您的存储库添加一个附加方法,该注释根据合同的 id 选择状态的两个字段,使用SQL 连接。

    3. 这一项仅适用于只读访问权限! 您可以创建另一个实体ReadOnlyContract,其中包含ContractStatuses 引用,标记为嵌入属性。您现在可以将其映射到包含其他状态字段的视图。 为了避免意外使用写入方法,您应该让存储库继承自 Repository,并仅添加您实际需要的读取方法。

    【讨论】:

    • 谢谢你,但我显然遗漏了一些东西,因为当我添加@Embedded(onEmpty = USE_NULL) ContractStatuses statuses; 时,我得到A database object name must not be null or emptyUnknown column 'suppliers_contracts.name' in 'field list' 取决于我如何塑造对象..
    • 听起来视图与预期的结构不匹配。你能用对象结构、视图和堆栈跟踪创建一个新问题吗?
    【解决方案2】:

    您应该使用SupplierContractContractStatuses 类之间的数据库关系。

    即使用ContractStatuses contractStatuses; 而不是int status; 并在此之后使用一对多关系,当您查询findAll() 时,您将获得ContractStatuses,您可以从那里获得status_name

    【讨论】:

    • 但是这种关系是多对一的,因为SupplierContract在某个时间点只能有一个status_id,而某些status_id显然可能有很多合同..所以当我想执行supplierContract时如何反映。 findAll() 并获取 status_name 列?
    • 您必须在 SupplierContract 端声明 @ManyToOne 和在 ContractStatuses 端声明 @OneToMany 双方的关系。请参阅 (baeldung.com/spring-data-rest-relationships) 了解更多信息
    • Spring data jdbc中没有@ManyToOne注解
    • 这个答案似乎假设问题中没有使用 JPA。
    猜你喜欢
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    相关资源
    最近更新 更多