JPA मानदंड बिल्डर का उपयोग करके अतिरिक्त गिनती कॉलम के साथ क्वेरी कैसे लिखें

Aug 18 2020

मैं एक जेपीए क्वेरी लिखने के लिए संघर्ष कर रहा हूं जो सभी पी ऑब्जेक्ट्स को डेटाबेस में वापस कर देगा और उनके बगल में मैं अपने एस बच्चों की गिनती करना चाहता हूं जिनके पास प्रॉपर्टी = 1 है।

SQL क्वेरी

P_table p से s। * S का चयन करें। (s का चयन करें (s.id), जहां से p_id = s.p_id और s.propertyA = 1 का चयन करें)

मानचित्रण:

@Entity
@Table(name = "t_table")
public class PTable{
    @Id
    private String id;

    @Version
    private Long version;

    private String subject;
   
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
    @JoinColumn(name = "p_id", referencedColumnName = "id")
    private Set<STable> sSet = new HashSet<>();
}
 
@Entity
@Table(name = "s_table")
public class STable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "p_id")
    private String pId;
  
    private String propertyA;
}

इसके अलावा, क्या आप जेपीए में जटिल प्रश्नों को लिखने के लिए किसी अच्छे ट्यूटोरियल को इंगित करना चाहेंगे।

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<PTable> q = cb.createQuery(PTable.class);
Root<PTable> c = q.from(PTable.class);

जवाब

JLazar0 Aug 19 2020 at 09:57
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<MyPojo> cq = cb.createQuery(MyPojo.class);

Root<PTable> rootPTable = cq.from(PTable.class);
Join<PTable, STable> joinSTable = rootPTable.join(PTable_.sSet);

Subquery<Long> sqCount = cq.subquery(Long.class);
Root<STable> sqRootSTable = sqCount.from(STable.class);
Join<STable, PTable> sqJoinPTable = sqRootSTable.join(STable_.pSet);

sqCount.where(cb.and(
    cb.equal(sqJoinPTable.get(PTable_.id),rootPTable.get(PTable_.id)),
    cb.equal(sqRootSTable.get(STable_.propertyA),"1")));

sqCount.select(cb.count(sqRootSTable));

cq.multiselect(
    rootPTable.get(PTable_.id),
    rootPTable.get(PTable_.version),
    rootPTable.get(PTable_.subject),
    joinSTable.get(STable_.id),
    sqCount.getSelection(),
);

आपको एक परिणाम प्राप्त करने के लिए एक पोजो की आवश्यकता होगी जो कि एक कंस्ट्रक्टर के पास क्रम में मेल खाता है और मल्टीसेप्ट मापदंडों के साथ टाइप करता है:

public MyPojo(String pId, Long version, String subject, Long sId, Long count){
    [...]
}

आपको रिश्ते को सही ढंग से मैप करने के लिए अपनी संस्थाओं को बदलना होगा, इस प्रकार प्रदर्शन को बेहतर बनाने के लिए द्विदिश और आलसी होना चाहिए:

PTable

@OneToMany(mappedBy="p",fetch = FetchType.LAZY)
private Set<STable> sSet;

स्थिर

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="id")
private PTable p;