列出结果映射Spring JPA

时间:2016-06-11 18:11:16

标签: java spring postgresql jpa

我使用PostgreSQL,我在product_media的产品上有这些表,product和product_media与关系OneToMany。我想检索一个带有产品的列表,每个产品都包含product_media列表。 我有两个选择,以便从DB中检索它们。

首先解决方案是检索产品列表,然后迭代检索到的列表并执行查询以检索product_media列表。

查询1:

select * from product as p where p.status=1;

检索列表然后迭代此列表并执行此查询:

select * from product_media as pm where pm.product_id=?

其次是在查询中实现连接并从我的数据库中检索所有数据。 查询:

select * from product as p Join product_media as pm on (p.id=pm.product_id)

检索包含所有数据的复杂列表。 第二种选择的问题是不知道将此列表映射到具有以下格式的对象的优雅方式。你知道如何将结果自动映射到这种格式吗?

product:[
    {
       id:1,
       name:'Pro1',
       medias:[
         {
            id:1,
            uuid:'asdfi-asdf-rg-fgsdf-do'
         },
         {
            id:2,
            uuid:'asdfi-asdf-rg-fgsdf-do'
         }    
       ]
    },
    {
       id:2,
       name:'Pro2',
       medias:[
         {
            id:5,
            uuid:'asdfi-asdf-rg-fgsdf-do'
         },
         {
             id:7,
             uuid:'asdfi-asdf-rg-fgsdf-do'
         }    
       ]
    }
]

2 个答案:

答案 0 :(得分:2)

我认为第二种变体是更好的选择。从数据库中获取对象树后,您可以执行以下操作来实现上面发布的内容:

  1. 假设您的实体定义如下:

    Product.java

    public class Product {
    
        private long id;
        private String name;
        private List<ProductMedia> mediaList;
    
    
        public Product() {
            mediaList = new ArrayList<ProductMedia>();
        }
    
        public Product(long id, String name) {
            this.id = id;
            this.name = name;
            mediaList = new ArrayList<ProductMedia>();
        }
        // getters + setters
    }
    

    ProductMedia.java

    public class ProductMedia {
        private long id;
        private String uuid;
    
        public ProductMedia() { }
    
        public ProductMedia(long id, String uuid) {
            this.uuid = uuid;
        }
        // getters + setters
    }
    
  2. 使用Jackson库,您可以按如下方式生成输出:

    public class JsonTest {
    
        public static void main(String[] args) throws IOException {
    
            ObjectMapper mapper = new ObjectMapper();
    
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
    
            Product prod = new Product(1, "p1");
    
            ProductMedia pm = new ProductMedia(1, "uuid1");
            ProductMedia pm2 = new ProductMedia(2, "uuid2");
    
            prod.getMediaList().add(pm);
            prod.getMediaList().add(pm2);
    
    
            Product prod1 = new Product(2, "p2");
    
            ProductMedia pm3 = new ProductMedia(3, "uuid3");
            ProductMedia pm4 = new ProductMedia(4, "uuid4");
    
            prod1.getMediaList().add(pm3);
            prod1.getMediaList().add(pm4);
    
            Product[] pList = {prod, prod1};
    
            mapper.writeValue(System.out, pList);
        }
    }
    

    在这个例子中,我将输出写入控制台。但你并不局限于此;您可以写入传入FileOutputStream的文件。

  3. 为了能够运行此示例,您需要添加依赖项;如果你使用Maven,你可以将以下内容添加到你的POM中:

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.4</version>
        </dependency>
    

    否则,将依赖项的jar添加到项目构建路径中。

答案 1 :(得分:2)

如果您的回复不是json格式,可以尝试以下

ProductMedia之间存在多对多关系。

Product_Media是一个帮助程序表,用于维护ProductMedia个实体之间的多对多关系。

产品实体:

@Entity(name = "product")
public class Product {

    @Id
    @GeneratedValue
    private Long product_id;

    @Column
    private String name;

    @ManyToMany(cascade = { CascadeType.MERGE }, fetch = FetchType.EAGER)
    @JoinTable(name = "product_media", joinColumns = {
            @JoinColumn(name = "product_id", table = "product") }, inverseJoinColumns = {
                    @JoinColumn(name = "media_id", table = "media") })
    List<Media> medias;

}

媒体实体

@Entity(name = "media")
public class Media {

    @Id
    @GeneratedValue
    private Long media_id;

    @Column
    private String name;

}

Hibernate生成的SQL

select
    product0_.product_id as product_1_1_0_,
    product0_.name as name2_1_0_,
    medias1_.product_id as product_1_1_1_,
    media2_.media_id as media_id2_2_1_,
    media2_.media_id as media_id1_0_2_,
    media2_.name as name2_0_2_ 
from
    product product0_ 
left outer join
    product_media medias1_ 
        on product0_.product_id=medias1_.product_id 
left outer join
    media media2_ 
        on medias1_.media_id=media2_.media_id 
where
    product0_.product_id=?

如果关系一对多,请更改下面的实体

媒体实体

@Entity(name = "media")
public class Media {

    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String name;

    @ManyToOne
    @JoinColumn(name = "product_id", referencedColumnName = "id", nullable = false, updatable = false)
    private Product product;

    public Media() {

    }
}

产品实体

@Entity(name = "product")
public class Product {

    @Id
    @GeneratedValue
    private Long id;

    @Column
    private String name;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "product")
    List<Media> medias;
}

Hibernate生成SQL

select
    product0_.id as id1_2_0_,
    product0_.name as name2_2_0_,
    medias1_.product_id as product_3_2_1_,
    medias1_.id as id1_0_1_,
    medias1_.id as id1_0_2_,
    medias1_.name as name2_0_2_,
    medias1_.product_id as product_3_0_2_ 
from
    product product0_ 
left outer join
    media medias1_ 
        on product0_.id=medias1_.product_id 
where
    product0_.id=?