【问题标题】:Fetch records from Multiple tables having different type of primary key. Hibernate从具有不同类型主键的多个表中获取记录。休眠
【发布时间】:2022-01-12 11:35:09
【问题描述】:

我有一个用例,我需要根据 emailAddress 从不同的表中获取记录,并且这些表中的每一个都有不同类型的主键(字符串、整数等)

@Entity
Class A{
@Id
Integer ID;
String emailAddress;
}

@Entity
Class  B{
@Id
String ID;
String emailAddress;
}

@Entity
Class C{
@Id
Long ID;
String emailAddr;
}

现在假设我有电子邮件地址:test@gmail.com

我的用例是从每个表中获取与此电子邮件地址关联的记录并对主键进行一些处理。

类似

for each table
   get list records with the given emailAddress from that table
   do some processing on primary key

My main problem is fetching the id of the result, since it is of different type for each table. I want do it in a loop.

I'm using JpaRepository for fetching data from database

【问题讨论】:

    标签: java hibernate for-loop generics design-patterns


    【解决方案1】:

    您可以在需要时使用 Java 类型转换来执行特定操作。 首先,您将所有三个实体类放在一个保护伞中。然后创建同一个父类的子类。

    package com.solution.domain;
    
    public class Domain {
    }
    

    实体类 A

    package com.solution.domain;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    
    @Entity
    public class A extends Domain{
        @Id
        private Integer id;
        @Column (name="EMAILADDRESS")
        private String emailAddress;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getEmailAddress() {
            return emailAddress;
        }
    
        public void setEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
        }
    
    
    }
    

    实体类 B

    package com.solution.domain;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    
    @Entity
    public class B extends Domain{
        @Id
        String ID;
        @Column (name="EMAILADDRESS")
        String emailAddress;
    
        public String getID() {
            return ID;
        }
    
        public void setID(String ID) {
            this.ID = ID;
        }
    
        public String getEmailAddress() {
            return emailAddress;
        }
    
        public void setEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
        }
    }
    

    实体类 C

    package com.solution.domain;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    @Entity
    public class C extends Domain{
        @Id
        Long ID;
       @Column (name="EMAILADDRESS")
        String emailAddress;
    
        public Long getID() {
            return ID;
        }
    
        public void setID(Long ID) {
            this.ID = ID;
        }
    
        public String getEmailAddress() {
            return emailAddress;
        }
    
        public void setEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
        }
    
        @Override
        public String toString() {
            return "C{" +
                    "ID=" + ID +
                    ", emailAddress='" + emailAddress + '\'' +
                    '}';
        }
    }
    

    访问所有三个 JPA Repos 的类整理结果并发送列表

    package com.solution.repo;
    
    import com.solution.domain.A;
    import com.solution.domain.B;
    import com.solution.domain.C;
    import com.solution.domain.Domain;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;
    
        @Component
        public class DomainRepository {
        
            @Autowired
            ARepository aRepository;
            @Autowired
            BRepository bRepository;
            @Autowired
            CRepository cRepository;
        
            public List<Domain> findDomains(String email) {
                List<Domain> result = new ArrayList<>();
                List<A> aList;
                List<B> bList;
                List<C> cList;
                aList = aRepository.findByEmailAddress(email);
                if (Objects.nonNull(aList))
                    result.addAll(aList);
                bList = bRepository.findByEmailAddress(email);
                if (Objects.nonNull(bList))
                    result.addAll(bList);
                cList = cRepository.findByEmailAddress(email);
                if (Objects.nonNull(cList))
                    result.addAll(cList);
                return result;
        
            }
        }
    

    关于如何使用 CommandLineRunner spring 示例操作代码的示例

    package com.solution;
    
    import com.solution.domain.A;
    import com.solution.domain.B;
    import com.solution.domain.C;
    import com.solution.domain.Domain;
    import com.solution.repo.DomainRepository;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    
    import java.util.List;
    
    
    @SpringBootApplication
    public class SpringBootConsoleApplication implements CommandLineRunner {
    
    
        private static Logger LOG = LoggerFactory
                .getLogger(SpringBootConsoleApplication.class);
    
    
    
        public static void main(String[] args) {
            LOG.info("STARTING THE APPLICATION");
            SpringApplication.run(SpringBootConsoleApplication.class, args);
            LOG.info("APPLICATION FINISHED");
            LOG.info("EXECUTING : command line runner");
    
        }
    
        @Bean
        public DomainRepository getDomainRepository(){
            return new DomainRepository();
    
        }
        @Override
        public void run(String... args) {
            LOG.info("EXECUTING : command line runner");
            List<Domain> result=getDomainRepository().findDomains("raj@com");
            for(Domain entity: result){
                if(entity instanceof A){
                    System.out.println(((A) entity).getId());
                    //Do your operations here.
                }
                else if(entity instanceof B){
                    System.out.println(((B) entity).getID());
                    //Do your operations here.
                }
                else if(entity instanceof C){
                    System.out.println(((C) entity).getID());
                    //Do your operations here.
                }
            }
        }
    }
    

    【讨论】:

    • 是否需要让所有实体都继承自Domain 类?为什么不直接使用 Object 呢?
    • 是的 fladdimir,您可以使用 Object 代替,但拥有它通常是一个好习惯,它提供了很大的灵活性,例如使用 @Embeddable,您实际上可以将 emailAddress 变量移动到 Domain 类,然后可以跨实体通用
    猜你喜欢
    • 1970-01-01
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    相关资源
    最近更新 更多