복붙노트

[SPRING] crudrepository findBy 메소드 튜플리스트의 서명

SPRING

crudrepository findBy 메소드 튜플리스트의 서명

나는 이와 같은 엔티티 클래스가있다 :

@Entity
@Table(name = "CUSTOMER")
class Customer{
    @Id
    @Column(name = "Id")
    Long id;
    @Column(name = "EMAIL_ID")
    String emailId;
    @Column(name = "MOBILE")
    String mobile;
}

crudrepository spring data jpa를 사용하여 아래 쿼리에 findBy 메소드를 작성하는 방법은 무엇입니까?

select * from customer where (email, mobile) IN (("a@b.c","8971"), ("e@f.g", "8888"))

나는 뭔가를 기대하고있다.

List<Customer> findByEmailMobileIn(List<Tuple> tuples);

주어진 쌍으로부터 고객 목록을 얻고 싶습니다.

해결법

  1. ==============================

    1.나는 이것이 org.springframework.data.jpa.domain.Specification으로 할 수 있다고 생각한다. 튜플 목록을 전달하고 이런 식으로 진행할 수 있습니다 (튜플이 엔티티가 아니지만이 클래스를 정의해야 함).

    나는 이것이 org.springframework.data.jpa.domain.Specification으로 할 수 있다고 생각한다. 튜플 목록을 전달하고 이런 식으로 진행할 수 있습니다 (튜플이 엔티티가 아니지만이 클래스를 정의해야 함).

    public class CustomerSpecification implements Specification<Customer> {
    
        // names of the fields in your Customer entity
        private static final String CONST_EMAIL_ID = "emailId";
        private static final String CONST_MOBILE = "mobile";
    
        private List<MyTuple> tuples;
    
        public ClaimSpecification(List<MyTuple> tuples) {
            this.tuples = tuples;
        }
    
        @Override
        public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            // will be connected with logical OR
            List<Predicate> predicates = new ArrayList<>();
    
            tuples.forEach(tuple -> {
                List<Predicate> innerPredicates = new ArrayList<>();
                if (tuple.getEmail() != null) {
                     innerPredicates.add(cb.equal(root
                         .<String>get(CONST_EMAIL_ID), tuple.getEmail()));
                }
                if (tuple.getMobile() != null) {
                     innerPredicates.add(cb.equal(root
                         .<String>get(CONST_MOBILE), tuple.getMobile()));
                }
                // these predicates match a tuple, hence joined with AND
                predicates.add(andTogether(innerPredicates, cb));
            });
    
            return orTogether(predicates, cb);
        }
    
        private Predicate orTogether(List<Predicate> predicates, CriteriaBuilder cb) {
            return cb.or(predicates.toArray(new Predicate[0]));
        }
    
        private Predicate andTogether(List<Predicate> predicates, CriteriaBuilder cb) {
            return cb.and(predicates.toArray(new Predicate[0]));
        }
    }
    

    귀하의 레포는 인터페이스 JpaSpecificationExecutor <고객>을 확장해야합니다.

    그런 다음 튜플 목록을 사용하여 사양을 구성하고이를 customerRepo.findAll (Specification ) 메서드에 전달합니다. 그러면 고객 목록이 반환됩니다.

  2. ==============================

    2.투영법을 사용하면 더 깨끗할 수 있습니다.

    투영법을 사용하면 더 깨끗할 수 있습니다.

    @Entity
    @Table(name = "CUSTOMER")
    class CustomerQueryData {
        @Id
        @Column(name = "Id")
        Long id;
        @OneToOne
        @JoinColumns(@JoinColumn(name = "emailId"), @JoinColumn(name = "mobile"))
        Contact contact;
    }
    

    접촉 개체 :

    @Entity
    @Table(name = "CUSTOMER")
    class Contact{
        @Column(name = "EMAIL_ID")
        String emailId;
        @Column(name = "MOBILE")
        String mobile;
    }
    

    엔터티를 지정하면 repo :

    CustomerJpaProjection extends Repository<CustomerQueryData, Long>, QueryDslPredicateExecutor<CustomerQueryData> {
        @Override
        List<CustomerQueryData> findAll(Predicate predicate);
     }
    

    그리고 레포 호출 :

    ArrayList<Contact> contacts = new ArrayList<>();
    contacts.add(new Contact("a@b.c","8971"));
    contacts.add(new Contact("e@f.g", "8888"));
    customerJpaProjection.findAll(QCustomerQueryData.customerQueryData.contact.in(contacts));
    

    테스트 된 코드가 아닙니다.

  3. from https://stackoverflow.com/questions/48032920/crudrepository-findby-method-signature-for-list-of-tuples by cc-by-sa and MIT license