JPA Criteria api 多重连接与顺序
JPA Criteria api Mulitple join with orderby
正在尝试编写条件 api 查询。
cardholder id
假设作为参数传递并且可以更改。我已经在我的代码中添加了实体。
感谢任何帮助或指导。
select tx.id,tx.date,tx.settled,tx.settledDate,te.debit,te.amount,te.account,tx.card, acc.accountType, pl.name,mer.id, mer.name , ch.id
from cardholder ch
join txn_entry te on ch.id=te.cardholder
join txn tx on te.txn = tx.id
join merchant mer on tx.merchant=mer.id
join account acc on te.account = acc.id
join plan pl on acc.plan= pl.id
where te.cardholder= ? and tx.retcode = 00 and te.valid='Y'
order by tx.date desc;
这是我目前拥有的:
public List<CardHolderEntity> createCriteriaQuery(String cardHolderId) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
char valid = 'Y';
String returnCode = "00";
CriteriaQuery<CardHolderEntity> cq = cb.createQuery(CardHolderEntity.class);
Root<CardHolderEntity> cardHolder = cq.from(CardHolderEntity.class);
Join<CardHolderEntity, TransactionEntryEntity> transactionEntries = cardHolder
.join(CardHolderEntity_.transactionEntryEntity);
Join<TransactionEntryEntity, AccountEntity> account = transactionEntries
.join(TransactionEntryEntity_.accountEntity);
Join<AccountEntity, PlanEntity> plans = account.join(AccountEntity_.planEntity);
Join<TransactionEntryEntity, TransactionEntity> transaction = transactionEntries
.join(TransactionEntryEntity_.transactionEntity);
Join<TransactionEntity, CardEntity> cards = transaction.join(TransactionEntity_.cardEntity);
Join<TransactionEntity, MerchantEntity> merchants = transaction.join(TransactionEntity_.merchantEntity);
Predicate p1 = cb.equal(cardHolder.get(CardHolderEntity_.id), cardHolderId);
Predicate p2 = cb.equal(transactionEntries.get(TransactionEntryEntity_.valid), valid);
Predicate p3 = cb.equal(transaction.get(TransactionEntity_.retcode), returnCode);
cq.select(cardHolder).where(cb.and(p1, p2, p3))
.orderBy(cb.desc(transactionEntries.get(TransactionEntryEntity_.id)));
TypedQuery<CardHolderEntity> qry = entityManager.createQuery(cq);
return qry.getSingleResult();
}
我现在可以获取正确的数据,但列表未排序。这是我在日志中看到的,生成了两个查询,一个有顺序,另一个没有。
Hibernate: select cardholder0_.id as id1_2_, cardholder0_.email as email2_2_, cardholder0_.firstname as firstnam3_2_, cardholder0_.issuer as issuer6_2_, cardholder0_.lastname as lastname4_2_, cardholder0_.phone as phone5_2_ from cardholder cardholder0_ inner join txn_entry transactio1_ on cardholder0_.id=transactio1_.cardholder inner join account accountent2_ on transactio1_.account=accountent2_.id inner join plan planentity3_ on accountent2_.plan=planentity3_.id inner join txn transactio4_ on transactio1_.txn=transactio4_.id inner join card cardentity5_ on transactio4_.card=cardentity5_.id inner join merchant merchanten6_ on transactio4_.merchant=merchanten6_.id where cardholder0_.id=? and transactio1_.valid=? and transactio4_.retcode=? order by transactio1_.id desc
Hibernate: select transactio0_.cardholder as cardhold6_2_6_, transactio0_.id as id1_8_6_, transactio0_.id as id1_8_5_, transactio0_.account as account5_8_5_, transactio0_.amount as amount2_8_5_, transactio0_.cardholder as cardhold6_8_5_, transactio0_.debit as debit3_8_5_, transactio0_.txn as txn7_8_5_, transactio0_.valid as valid4_8_5_, accountent1_.id as id1_0_0_, accountent1_.accounttype as accountt2_0_0_, accountent1_.active as active3_0_0_, accountent1_.enddate as enddate4_0_0_, accountent1_.plan as plan5_0_0_, planentity2_.id as id1_6_1_, planentity2_.onlineaccess as onlineac2_6_1_, planentity2_.enddate as enddate3_6_1_, planentity2_.name as name4_6_1_, transactio3_.id as id1_7_2_, transactio3_.card as card6_7_2_, transactio3_.date as date2_7_2_, transactio3_.merchant as merchant7_7_2_, transactio3_.retcode as retcode3_7_2_, transactio3_.settled as settled4_7_2_, transactio3_.settleddate as settledd5_7_2_, cardentity4_.id as id1_1_3_, cardentity4_.active as active2_1_3_, cardentity4_.cardholder as cardhold8_1_3_, cardentity4_.number as number3_1_3_, cardentity4_.createddate as createdd4_1_3_, cardentity4_.enddate as enddate5_1_3_, cardentity4_.issueddate as issuedda6_1_3_, cardentity4_.startdate as startdat7_1_3_, merchanten5_.id as id1_5_4_, merchanten5_.name as name2_5_4_ from txn_entry transactio0_ left outer join account accountent1_ on transactio0_.account=accountent1_.id left outer join plan planentity2_ on accountent1_.plan=planentity2_.id left outer join txn transactio3_ on transactio0_.txn=transactio3_.id left outer join card cardentity4_ on transactio3_.card=cardentity4_.id left outer join merchant merchanten5_ on transactio3_.merchant=merchanten5_.id where transactio0_.cardholder in (select cardholder0_.id from cardholder cardholder0_ inner join txn_entry transactio1_ on cardholder0_.id=transactio1_.cardholder inner join account accountent2_ on transactio1_.account=accountent2_.id inner join plan planentity3_ on accountent2_.plan=planentity3_.id inner join txn transactio4_ on transactio1_.txn=transactio4_.id inner join card cardentity5_ on transactio4_.card=cardentity5_.id inner join merchant merchanten6_ on transactio4_.merchant=merchanten6_.id where cardholder0_.id=? and transactio1_.valid=? and transactio4_.retcode=? )
这就是我最终做的事情,而不是通过 cardHolder table 我通过了 TransactionEntry 并且能够订购列表。当我通过持卡人 table 时,我仍然没有找到任何可以订购的东西。希望这对某人有所帮助。
public List<TransactionEntryEntity> createCriteriaQuery(String cardHolderId, String accountId, int pageNumber,
int pageSize, Map<String, String> allRequestParams) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<TransactionEntryEntity> cq = cb.createQuery(TransactionEntryEntity.class);
// Root<CardHolderEntity> cardHolder = cq.from(CardHolderEntity.class);
Root<TransactionEntryEntity> transactionEntry = cq.from(TransactionEntryEntity.class);
Join<TransactionEntryEntity, TransactionEntity> transaction = transactionEntry
.join(TransactionEntryEntity_.transactionEntity);
List<Predicate> predicates = new ArrayList<Predicate>();
// Default Predicates for transactions
predicates
.add(cb.equal(transactionEntry.get(TransactionEntryEntity_.cardHolderEntity).get(CardHolderEntity_.id),
cardHolderId));
predicates.add(cb.equal(transactionEntry.get(TransactionEntryEntity_.valid), 'Y'));
predicates.add(cb.equal(transaction.get(TransactionEntity_.retcode), "00"));
// For Transaction API with acountId Path Variable
if ((accountId != null) && (!accountId.trim().isEmpty())) {
Join<TransactionEntryEntity, AccountEntity> account = transactionEntry
.join(TransactionEntryEntity_.accountEntity);
predicates.add(cb.equal(account.get(AccountEntity_.id), accountId));
}
if (!allRequestParams.isEmpty()) {
String startDate = allRequestParams.get("minDate");
String endDate = allRequestParams.get("maxDate");
String merchantName = allRequestParams.get("merchantName");
String date = allRequestParams.get("date");
// Filter for Transactions with specific Date or with Start/End
// date.
if ((date != null) && !date.trim().isEmpty()) {
predicates.add(cb.between(transaction.get(TransactionEntity_.date), DateUtil.getSqlStartDate(date),
DateUtil.getSqlEndDate(date)));
} else if ((startDate != null) && (!startDate.trim().isEmpty()) && (endDate != null)
&& (!endDate.trim().isEmpty())) {
predicates.add(cb.between(transaction.get(TransactionEntity_.date), DateUtil.getSqlStartDate(startDate),
DateUtil.getSqlEndDate(endDate)));
} else if (((null == endDate) || (endDate.trim().isEmpty())) && (startDate != null)
&& (!startDate.trim().isEmpty())) {
predicates.add(cb.greaterThanOrEqualTo(transaction.get(TransactionEntity_.date),
DateUtil.getSqlStartDate(startDate)));
} else if (((null == startDate) || (startDate.trim().isEmpty())) && (endDate != null)
&& (!endDate.trim().isEmpty())) {
predicates.add(cb.lessThanOrEqualTo(transaction.get(TransactionEntity_.date),
DateUtil.getSqlEndDate(endDate)));
}
// Filter by merchant name
if (((merchantName != null) && !merchantName.trim().isEmpty())) {
Join<TransactionEntity, MerchantEntity> merchant = transaction.join(TransactionEntity_.merchantEntity);
predicates.add(
cb.like(cb.lower(merchant.get(MerchantEntity_.name)), "%" + merchantName.toLowerCase() + "%"));
}
}
cq.select(transactionEntry).where(predicates.toArray(new Predicate[] {}));
cq.orderBy(cb.desc(transaction.get(TransactionEntity_.date)));
TypedQuery<TransactionEntryEntity> qry = entityManager.createQuery(cq);
// For Paging of Transactions
if ((pageNumber > 0) && (pageSize > 0)) {
qry.setFirstResult((pageNumber - 1) * pageSize);
qry.setMaxResults(pageSize);
}
return qry.getResultList();
}
正在尝试编写条件 api 查询。
cardholder id
假设作为参数传递并且可以更改。我已经在我的代码中添加了实体。
感谢任何帮助或指导。
select tx.id,tx.date,tx.settled,tx.settledDate,te.debit,te.amount,te.account,tx.card, acc.accountType, pl.name,mer.id, mer.name , ch.id
from cardholder ch
join txn_entry te on ch.id=te.cardholder
join txn tx on te.txn = tx.id
join merchant mer on tx.merchant=mer.id
join account acc on te.account = acc.id
join plan pl on acc.plan= pl.id
where te.cardholder= ? and tx.retcode = 00 and te.valid='Y'
order by tx.date desc;
这是我目前拥有的:
public List<CardHolderEntity> createCriteriaQuery(String cardHolderId) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
char valid = 'Y';
String returnCode = "00";
CriteriaQuery<CardHolderEntity> cq = cb.createQuery(CardHolderEntity.class);
Root<CardHolderEntity> cardHolder = cq.from(CardHolderEntity.class);
Join<CardHolderEntity, TransactionEntryEntity> transactionEntries = cardHolder
.join(CardHolderEntity_.transactionEntryEntity);
Join<TransactionEntryEntity, AccountEntity> account = transactionEntries
.join(TransactionEntryEntity_.accountEntity);
Join<AccountEntity, PlanEntity> plans = account.join(AccountEntity_.planEntity);
Join<TransactionEntryEntity, TransactionEntity> transaction = transactionEntries
.join(TransactionEntryEntity_.transactionEntity);
Join<TransactionEntity, CardEntity> cards = transaction.join(TransactionEntity_.cardEntity);
Join<TransactionEntity, MerchantEntity> merchants = transaction.join(TransactionEntity_.merchantEntity);
Predicate p1 = cb.equal(cardHolder.get(CardHolderEntity_.id), cardHolderId);
Predicate p2 = cb.equal(transactionEntries.get(TransactionEntryEntity_.valid), valid);
Predicate p3 = cb.equal(transaction.get(TransactionEntity_.retcode), returnCode);
cq.select(cardHolder).where(cb.and(p1, p2, p3))
.orderBy(cb.desc(transactionEntries.get(TransactionEntryEntity_.id)));
TypedQuery<CardHolderEntity> qry = entityManager.createQuery(cq);
return qry.getSingleResult();
}
我现在可以获取正确的数据,但列表未排序。这是我在日志中看到的,生成了两个查询,一个有顺序,另一个没有。
Hibernate: select cardholder0_.id as id1_2_, cardholder0_.email as email2_2_, cardholder0_.firstname as firstnam3_2_, cardholder0_.issuer as issuer6_2_, cardholder0_.lastname as lastname4_2_, cardholder0_.phone as phone5_2_ from cardholder cardholder0_ inner join txn_entry transactio1_ on cardholder0_.id=transactio1_.cardholder inner join account accountent2_ on transactio1_.account=accountent2_.id inner join plan planentity3_ on accountent2_.plan=planentity3_.id inner join txn transactio4_ on transactio1_.txn=transactio4_.id inner join card cardentity5_ on transactio4_.card=cardentity5_.id inner join merchant merchanten6_ on transactio4_.merchant=merchanten6_.id where cardholder0_.id=? and transactio1_.valid=? and transactio4_.retcode=? order by transactio1_.id desc
Hibernate: select transactio0_.cardholder as cardhold6_2_6_, transactio0_.id as id1_8_6_, transactio0_.id as id1_8_5_, transactio0_.account as account5_8_5_, transactio0_.amount as amount2_8_5_, transactio0_.cardholder as cardhold6_8_5_, transactio0_.debit as debit3_8_5_, transactio0_.txn as txn7_8_5_, transactio0_.valid as valid4_8_5_, accountent1_.id as id1_0_0_, accountent1_.accounttype as accountt2_0_0_, accountent1_.active as active3_0_0_, accountent1_.enddate as enddate4_0_0_, accountent1_.plan as plan5_0_0_, planentity2_.id as id1_6_1_, planentity2_.onlineaccess as onlineac2_6_1_, planentity2_.enddate as enddate3_6_1_, planentity2_.name as name4_6_1_, transactio3_.id as id1_7_2_, transactio3_.card as card6_7_2_, transactio3_.date as date2_7_2_, transactio3_.merchant as merchant7_7_2_, transactio3_.retcode as retcode3_7_2_, transactio3_.settled as settled4_7_2_, transactio3_.settleddate as settledd5_7_2_, cardentity4_.id as id1_1_3_, cardentity4_.active as active2_1_3_, cardentity4_.cardholder as cardhold8_1_3_, cardentity4_.number as number3_1_3_, cardentity4_.createddate as createdd4_1_3_, cardentity4_.enddate as enddate5_1_3_, cardentity4_.issueddate as issuedda6_1_3_, cardentity4_.startdate as startdat7_1_3_, merchanten5_.id as id1_5_4_, merchanten5_.name as name2_5_4_ from txn_entry transactio0_ left outer join account accountent1_ on transactio0_.account=accountent1_.id left outer join plan planentity2_ on accountent1_.plan=planentity2_.id left outer join txn transactio3_ on transactio0_.txn=transactio3_.id left outer join card cardentity4_ on transactio3_.card=cardentity4_.id left outer join merchant merchanten5_ on transactio3_.merchant=merchanten5_.id where transactio0_.cardholder in (select cardholder0_.id from cardholder cardholder0_ inner join txn_entry transactio1_ on cardholder0_.id=transactio1_.cardholder inner join account accountent2_ on transactio1_.account=accountent2_.id inner join plan planentity3_ on accountent2_.plan=planentity3_.id inner join txn transactio4_ on transactio1_.txn=transactio4_.id inner join card cardentity5_ on transactio4_.card=cardentity5_.id inner join merchant merchanten6_ on transactio4_.merchant=merchanten6_.id where cardholder0_.id=? and transactio1_.valid=? and transactio4_.retcode=? )
这就是我最终做的事情,而不是通过 cardHolder table 我通过了 TransactionEntry 并且能够订购列表。当我通过持卡人 table 时,我仍然没有找到任何可以订购的东西。希望这对某人有所帮助。
public List<TransactionEntryEntity> createCriteriaQuery(String cardHolderId, String accountId, int pageNumber,
int pageSize, Map<String, String> allRequestParams) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<TransactionEntryEntity> cq = cb.createQuery(TransactionEntryEntity.class);
// Root<CardHolderEntity> cardHolder = cq.from(CardHolderEntity.class);
Root<TransactionEntryEntity> transactionEntry = cq.from(TransactionEntryEntity.class);
Join<TransactionEntryEntity, TransactionEntity> transaction = transactionEntry
.join(TransactionEntryEntity_.transactionEntity);
List<Predicate> predicates = new ArrayList<Predicate>();
// Default Predicates for transactions
predicates
.add(cb.equal(transactionEntry.get(TransactionEntryEntity_.cardHolderEntity).get(CardHolderEntity_.id),
cardHolderId));
predicates.add(cb.equal(transactionEntry.get(TransactionEntryEntity_.valid), 'Y'));
predicates.add(cb.equal(transaction.get(TransactionEntity_.retcode), "00"));
// For Transaction API with acountId Path Variable
if ((accountId != null) && (!accountId.trim().isEmpty())) {
Join<TransactionEntryEntity, AccountEntity> account = transactionEntry
.join(TransactionEntryEntity_.accountEntity);
predicates.add(cb.equal(account.get(AccountEntity_.id), accountId));
}
if (!allRequestParams.isEmpty()) {
String startDate = allRequestParams.get("minDate");
String endDate = allRequestParams.get("maxDate");
String merchantName = allRequestParams.get("merchantName");
String date = allRequestParams.get("date");
// Filter for Transactions with specific Date or with Start/End
// date.
if ((date != null) && !date.trim().isEmpty()) {
predicates.add(cb.between(transaction.get(TransactionEntity_.date), DateUtil.getSqlStartDate(date),
DateUtil.getSqlEndDate(date)));
} else if ((startDate != null) && (!startDate.trim().isEmpty()) && (endDate != null)
&& (!endDate.trim().isEmpty())) {
predicates.add(cb.between(transaction.get(TransactionEntity_.date), DateUtil.getSqlStartDate(startDate),
DateUtil.getSqlEndDate(endDate)));
} else if (((null == endDate) || (endDate.trim().isEmpty())) && (startDate != null)
&& (!startDate.trim().isEmpty())) {
predicates.add(cb.greaterThanOrEqualTo(transaction.get(TransactionEntity_.date),
DateUtil.getSqlStartDate(startDate)));
} else if (((null == startDate) || (startDate.trim().isEmpty())) && (endDate != null)
&& (!endDate.trim().isEmpty())) {
predicates.add(cb.lessThanOrEqualTo(transaction.get(TransactionEntity_.date),
DateUtil.getSqlEndDate(endDate)));
}
// Filter by merchant name
if (((merchantName != null) && !merchantName.trim().isEmpty())) {
Join<TransactionEntity, MerchantEntity> merchant = transaction.join(TransactionEntity_.merchantEntity);
predicates.add(
cb.like(cb.lower(merchant.get(MerchantEntity_.name)), "%" + merchantName.toLowerCase() + "%"));
}
}
cq.select(transactionEntry).where(predicates.toArray(new Predicate[] {}));
cq.orderBy(cb.desc(transaction.get(TransactionEntity_.date)));
TypedQuery<TransactionEntryEntity> qry = entityManager.createQuery(cq);
// For Paging of Transactions
if ((pageNumber > 0) && (pageSize > 0)) {
qry.setFirstResult((pageNumber - 1) * pageSize);
qry.setMaxResults(pageSize);
}
return qry.getResultList();
}