【问题标题】:Joing two tables in JPA repository在 JPA 存储库中连接两个表
【发布时间】:2021-09-13 15:38:20
【问题描述】:

在 JPA 存储库中连接两个表

我要抛出 spring boot 教程并得到这个要求

    @Entity
    @Table(name = "transiction")
    public class Transictions {
        
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long Id;
        
        @Column(name = "userId")
        private Long userId;
        
        @Column(name = "productName")
        private String productName;
        
        @Column(name = "quantity")
        private int quantity;
        
        @Column(name = "price")
        private double price;
        
        @Column(name = "transictionDate")
        private Date transictionDate;
    
// Getter and Setter method with constructor.

我的第二个模型课

@Entity
@Table(name = "product")
public class product {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "product")
    private String productName;
    
    @Column(name = "ltp")
    private float LTP;
    
    @Column(name = "exchange")
    private String exchange;

以同样的方式,我创建了不同的控制器和两个不同的 JPA 存储库来从每个表中获取数据并且工作正常。

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.springboot.Ole.Model.Transictions;

public interface TransictionRepository extends JpaRepository<Transictions, Long>{
    
    
}

产品的模型类

package com.springboot.Ole.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.springboot.Ole.Model.Product;

@Repository
public interface ProducttRepository extends JpaRepository<Instrument, Long>{

}

现在我得到了需要加入这两个表的 secanrio。

MySql 命令

SELECT transiction.user_id, transiction.quantity,transiction.product_name, transiction.Price,product.LTP             
FROM product
INNER JOIN transiction
ON product.product=transiction.product_name;

我可以在 sql 中看到适当的数据。但是我不知道如何用 Java 代码编写这个查询。

我打算抛出这个教程https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections,但没有太多想法。

这就是我在我的存储库中尝试的内容

package com.springboot.Ole.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.springboot.Ole.Model.Transictions;

public interface TransictionRepository extends JpaRepository<Transictions, Long>{
    
    @Query(value = "SELECT transiction.user_id, transiction.quantity,transiction.product_name, transiction.Price,product.LTP"
            + "FROM product"
            + "INNER JOIN transiction"
            + "ON product.product=transiction.product_name")
            
}

但没有运气,因为我没有将它存储到某个列表中,或者其他不确定的东西。

我有问题

  1. 我是否需要编写服务类或类似的东西。

谁能帮帮我。

【问题讨论】:

  • 您必须使用@OneToMany@ManyToOne 在模型类中显式定义连接映射
  • @Mr_Thorynque 我已经完成了,我可以看到库也在 mysql 中创建。现在想知道如何获取数据。

标签: java mysql spring spring-boot jpa


【解决方案1】:

所以您正在查询本机查询,因此您需要将 nativeQuery = true 传递给查询参数。此外,您需要在 TransictionRepository 接口中添加 @Repository 注释。那不过是你的道层。

package com.overflow.overflow.service;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import com.overflow.overflow.models.Transictions;

@Repository
public interface TransictionRepository extends JpaRepository<Transictions, Long> {
    @Query(nativeQuery = true,
            value = "SELECT transiction.user_id, transiction.quantity,transiction.instrument_name, transiction.Price,instrument.LTP"
            + "FROM instrument"
            + "INNER JOIN transiction"
            + "ON instrument.instrument=transiction.instrument_name")
    public List<Object[]> getTransictionsAndInstruments();
}

【讨论】:

  • 以及我需要在控制器中写入的内容@GetMapping("/getTransictionData") public List&lt;Transictions&gt; getAllTransiction(){ return transictionrepository.getTransictionsAndInstruments(); }
  • 所以在这种情况下,我在对象数组中得到响应。但我需要的是我想要作为键值对,所以我需要为此做些什么。因为有些列在transiction中不可用
【解决方案2】:

为了扩展 Mr_Thorynque 的评论,如果两个实体之间存在 FK 关系,那么您可以在实体本身中定义它。

这是一个例子。

@Entity
    @Table(name = "transiction")
    public class Transiction {
        
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long Id;
        
        @Column(name = "userId")
        private Long userId;
        
        @Column(name = "productName")
        private String productName;
        
        @Column(name = "quantity")
        private int quantity;
        
        @Column(name = "price")
        private double price;
        
        @Column(name = "transictionDate")
        private Date transictionDate;

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "product_id")
        private Product product;
    
...
}

@Entity
@Table(name = "product")
public class product {
    
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "product")
    private String productName;
    
    @Column(name = "ltp")
    private float LTP;
    
    @Column(name = "exchange")
    private String exchange;

    @OneToMany(mappedBy = "product", fetch = FetchType.LAZY)
    private List<Transiction> transictions

...
}

我在这里做了一些假设。

  • 一个产品有多个与之关联的事务
  • transiction 有一个与之关联的产品
  • transiction 和 product 之间存在严格的 PK/FK 关系

无论如何,鉴于上述情况,如果您获取一个 Transiction,那么它将返回一个 Transiction,并填充其随附的 Product 对象。

顺便说一句,如果你喜欢这个答案,也请给 Mr_Thorynque 的评论点个赞。

【讨论】:

  • 查询怎么样,如果我这样做会起作用吗?让我试试,但我对查询有点好奇。
【解决方案3】:

如果要在 spring jpa 中使用 table join,则必须使用 spring 提供的关系模型,即众所周知的一对一、一对多和多对多。在spring data rest relationships 中解释了您可以在项目中使用的不同类型的关节。

例如,如果您想要一对一的关系,您的代码将如下所示:

@Entity
@Table(name = "transiction")
public class Transictions {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long Id;
    
    @Column(name = "userId")
    private Long userId;
    
    @OneToOne(mappedBy = "transiction")
    private Product product;
    
    @Column(name = "quantity")
    private int quantity;
    
    @Column(name = "price")
    private double price;
    
    @Column(name = "transictionDate")
    private Date transictionDate;
    
@Entity
@Table(name = "product")
public class Product {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    
    @Column(name = "product")
    private String productName;
    
    @Column(name = "ltp")
    private float LTP;
    
    @Column(name = "exchange")
    private String exchange;
    
    @OneToOne
    @JoinColumn(name = "transiction_id")
    @RestResource(path = "product-transiction", rel="transiction")
    private Transictions transiction;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 2017-07-04
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 2013-12-01
    • 2013-11-27
    相关资源
    最近更新 更多