Есть две сущности Персона и Адрес.Существует отношение 1: M от человека к адресу.(Предполагается, что человек имеет временный и постоянный адрес).
Ключевые свойства класса Person:
- personId (pk)
- пол
Ключевые свойства класса Address:
- addressId (pk)
- personId (fk)
- пол
Ниже приведен фрагмент кода дескриптора для классов Person и Address:
public RelationalDescriptor buildPersonDescriptor() {
RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaClass(Person.class);
descriptor.addTableName("PERSON");
descriptor.addPrimaryKeyFieldName("PERSON.PID");
// RelationalDescriptor properties.
descriptor.useSoftCacheWeakIdentityMap();
descriptor.setIdentityMapSize(100);
descriptor.useRemoteSoftCacheWeakIdentityMap();
descriptor.setRemoteIdentityMapSize(100);
descriptor.setSequenceNumberFieldName("PERSON.PID");
descriptor.setSequenceNumberName("PERSON_SEQ");
descriptor.setAlias("person");
// Query manager.
descriptor.getDescriptorQueryManager().checkCacheForDoesExist();
descriptor.getDescriptorQueryManager().setAdditionalJoinExpression(new ExpressionBuilder().get("gender").equal('N'));
// Query manager.
// Mappings.
DirectToFieldMapping pIDMapping = new DirectToFieldMapping();
pIDMapping.setAttributeName("personId");
pIDMapping.setFieldName("PERSON.PID");
descriptor.addMapping(pIDMapping);
DirectToFieldMapping genderMapping = new DirectToFieldMapping();
genderMapping.setAttributeName("gender");
genderMapping.setFieldName("PERSON.GENDER");
descriptor.addMapping(genderMapping);
OneToManyMapping addressMapping = new OneToManyMapping();
addressMapping.setAttributeName("address");
addressMapping.setReferenceClass(Address.class);
addressMapping.useTransparentCollection();
addressMapping.useCollectionClass(IndirectList.class);
addressMapping.addTargetForeignKeyFieldName("ADDRESS.PID", "PERSON.PID");
descriptor.addMapping(addressMapping);
return descriptor;
}
public RelationalDescriptor buildAddressDescriptor() {
RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaClass(com.tropics.application.products.domain.costingandpricing.SellingPriceAddOn.class);
descriptor.addTableName("ADDRESS");
descriptor.addPrimaryKeyFieldName("ADDRESS.AID");
// Descriptor properties.
descriptor.useSoftCacheWeakIdentityMap();
descriptor.setIdentityMapSize(100);
descriptor.useRemoteSoftCacheWeakIdentityMap();
descriptor.setRemoteIdentityMapSize(100);
descriptor.setSequenceNumberFieldName("ADDRESS.AID");
descriptor.setSequenceNumberName("ADDRESS_SEQ");
descriptor.setAlias("address");
// Query manager.
descriptor.getDescriptorQueryManager().checkCacheForDoesExist();
//Mappings
DirectToFieldMapping genderMapping = new DirectToFieldMapping();
genderMapping.setAttributeName("gender");
genderMapping.setFieldName("ADDRESS.GENDER");
descriptor.addMapping(genderMapping);
DirectToFieldMapping personIDMapping = new DirectToFieldMapping();
personIDMapping.setAttributeName("personId");
personIDMapping.setFieldName("ADDRESS.PID");
descriptor.addMapping(personIDMapping);
DirectToFieldMapping addressIDMapping = new DirectToFieldMapping();
addressIDMapping.setAttributeName("addressId");
addressIDMapping.setFieldName("ADDRESS.AID");
descriptor.addMapping(addressIDMapping);
}
Ниже приведен фрагмент кода для создания динамического запроса:
ExpressionBuilder expBuilder = new ExpressionBuilder();
ReportQuery query = new ReportQuery(Person.class, expBuilder);
//Getting the MVSelling DetailsID and the number of Selling price add ons for each of them
query.addAttribute("personId", expBuilder.get("personId"));
query.addAttribute
("addressCounter", expBuilder.anyOfAllowingNone("address").get("addressId").count());
Expression addressExp = expBuilder.anyOfAllowingNone("address");
expBuilder.leftJoin(addressExp, addressExp.get("gender").equal('M'));
query.addNonFetchJoin(addressExp);
query.addGrouping("personId");
resultCollection = (Vector)clientSessionHolder.eclipselinkClientSession().executeQuery(query);
При запуске этой программы,запрос, который генерируется по журналам:
SELECT t0.PID, COUNT(t1.AID)
FROM PERSON t0 LEFT OUTER JOIN ADDRESS t1
ON (t1.PID = t0.PID)
LEFT OUTER JOIN ADDRESS t2
ON ((t2.PID = t0.PID)
AND (t2.gender = 'M'))
WHERE (t0.gender = 'M')) GROUP BY t0.PID ;
Как написать выражение для добавления полового условия (тип данных char в db) в самом первом предложении соединения и избавиться от второго предложения соединения?
Ожидаемый запрос: SELECT t0.PID, COUNT (t1.AID) ОТ ЧЕЛОВЕКА t0 ВЛЕВО НАРУЖНЫЙ АДРЕС СОЕДИНЕНИЯ t1 ВКЛ (t1.PID = t0.PID AND (t2.gender = 'M')) WHERE t0.gender = 'M' GROUP BY t0.PID