J'utilise la requête de critères dans mon code. Il déclenche toujours select * from ...
Au lieu de cela, je veux négliger une colonne (champ) de ma requête car ce champ contient un grand nombre de données stockées dans des octets. Et ce problème de performance causant.
Quelqu'un peut-il en donner une idée?
Quelques mises à jour
J'ai ajouté une projection dans ma requête et il a créé une requête comme ...
select
this_.TEMPLATE_ID as y0_,
this_.TEMPLATE_NAME as y1_,
this_.CREATE_DATE as y2_,
this_.UPDATE_DATE as y3_,
this_.STATUS_CODE as y4_,
this_.USER_ID as y5_,
this_.UPDATED_BY as y6_,
this_.CATEGORY_ID as y7_,
this_.PRACTICE_ID as y8_
from
templates this_
inner join
user user1_
on this_.USER_ID=user1_.USER_ID
inner join
template_categories category2_
on this_.CATEGORY_ID=category2_.CATEGORY_ID
where
y4_=?
and y8_=?
and y5_ in (
?, ?
)
order by
y1_ asc limit ?
Et maintenant, le problème est comme .. Unknown column 'y4_' in 'where clause'
Et la même erreur pour y8_, y5_ signifie pour tous où près donnait une erreur.
Je l'ai modifié pour Query comme ...
select
this_.TEMPLATE_ID as y0_,
this_.TEMPLATE_NAME as y1_,
this_.CREATE_DATE as y2_,
this_.UPDATE_DATE as y3_,
this_.STATUS_CODE as y4_,
this_.USER_ID as y5_,
this_.UPDATED_BY as y6_,
this_.CATEGORY_ID as y7_,
this_.PRACTICE_ID as y8_
from
templates this_
inner join
user user1_
on this_.USER_ID=user1_.USER_ID
inner join
template_categories category2_
on this_.CATEGORY_ID=category2_.CATEGORY_ID
where
this_.STATUS_CODE=1
and this_.PRACTICE_ID=1
and this_.USER_ID in (
1, 2
)
order by
y1_ asc limit ?
et cela a fonctionné. Mais je ne sais pas comment le modifier dans HQL?
Utilisez Projections pour spécifier les colonnes que vous souhaitez renvoyer.
Exemple
Requête SQL
SELECT user.id, user.name FROM user;
Alternative Hibernate
Criteria cr = session.createCriteria(User.class)
.setProjection(Projections.projectionList()
.add(Projections.property("id"), "id")
.add(Projections.property("Name"), "Name"))
.setResultTransformer(Transformers.aliasToBean(User.class));
List<User> list = cr.list();
Vous pouvez utiliser JPQL ainsi que l'API JPA Criteria pour tout type de projection DTO (mappage des colonnes sélectionnées vers une classe DTO). Regardez ci-dessous des extraits de code montrant comment sélectionner sélectivement diverses colonnes au lieu de Sélectionner toutes les colonnes. Ces exemples montrent également comment sélectionner différentes colonnes de Joignant plusieurs colonnes. J'espère que ça aide .
Code JPQL:
String dtoProjection = "new com.katariasoft.technologies.jpaHibernate.college.data.dto.InstructorDto"
+ "(i.id, i.name, i.fatherName, i.address, id.proofNo, "
+ " v.vehicleNumber, v.vechicleType, s.name, s.fatherName, "
+ " si.name, sv.vehicleNumber , svd.name) ";
List<InstructorDto> instructors = queryExecutor.fetchListForJpqlQuery(
"select " + dtoProjection + " from Instructor i " + " join i.idProof id " + " join i.vehicles v "
+ " join i.students s " + " join s.instructors si " + " join s.vehicles sv "
+ " join sv.documents svd " + " where i.id > :id and svd.name in (:names) "
+ " order by i.id , id.proofNo , v.vehicleNumber , si.name , sv.vehicleNumber , svd.name ",
CollectionUtils.mapOf("id", 2, "names", Arrays.asList("1", "2")), InstructorDto.class);
if (Objects.nonNull(instructors))
instructors.forEach(i -> i.setName("Latest Update"));
DataPrinters.listDataPrinter.accept(instructors);
Code API JPA Criteria:
@Test
public void fetchFullDataWithCriteria() {
CriteriaBuilder cb = criteriaUtils.criteriaBuilder();
CriteriaQuery<InstructorDto> cq = cb.createQuery(InstructorDto.class);
// prepare from expressions
Root<Instructor> root = cq.from(Instructor.class);
Join<Instructor, IdProof> insIdProofJoin = root.join(Instructor_.idProof);
Join<Instructor, Vehicle> insVehicleJoin = root.join(Instructor_.vehicles);
Join<Instructor, Student> insStudentJoin = root.join(Instructor_.students);
Join<Student, Instructor> studentInsJoin = insStudentJoin.join(Student_.instructors);
Join<Student, Vehicle> studentVehicleJoin = insStudentJoin.join(Student_.vehicles);
Join<Vehicle, Document> vehicleDocumentJoin = studentVehicleJoin.join(Vehicle_.documents);
// prepare select expressions.
CompoundSelection<InstructorDto> selection = cb.construct(InstructorDto.class, root.get(Instructor_.id),
root.get(Instructor_.name), root.get(Instructor_.fatherName), root.get(Instructor_.address),
insIdProofJoin.get(IdProof_.proofNo), insVehicleJoin.get(Vehicle_.vehicleNumber),
insVehicleJoin.get(Vehicle_.vechicleType), insStudentJoin.get(Student_.name),
insStudentJoin.get(Student_.fatherName), studentInsJoin.get(Instructor_.name),
studentVehicleJoin.get(Vehicle_.vehicleNumber), vehicleDocumentJoin.get(Document_.name));
// prepare where expressions.
Predicate instructorIdGreaterThan = cb.greaterThan(root.get(Instructor_.id), 2);
Predicate documentNameIn = cb.in(vehicleDocumentJoin.get(Document_.name)).value("1").value("2");
Predicate where = cb.and(instructorIdGreaterThan, documentNameIn);
// prepare orderBy expressions.
List<Order> orderBy = Arrays.asList(cb.asc(root.get(Instructor_.id)),
cb.asc(insIdProofJoin.get(IdProof_.proofNo)), cb.asc(insVehicleJoin.get(Vehicle_.vehicleNumber)),
cb.asc(studentInsJoin.get(Instructor_.name)), cb.asc(studentVehicleJoin.get(Vehicle_.vehicleNumber)),
cb.asc(vehicleDocumentJoin.get(Document_.name)));
// prepare query
cq.select(selection).where(where).orderBy(orderBy);
DataPrinters.listDataPrinter.accept(queryExecutor.fetchListForCriteriaQuery(cq));
}
Vous pouvez mapper une autre entité en fonction de cette classe (vous devez utiliser nom-entité afin de distinguer les deux) et la seconde sera une sorte de dto (n'oubliez pas que dto a des problèmes de conception ). Vous devez définir le second comme étant en lecture seule et lui donner un bon nom afin de préciser que ce n’est pas une entité régulière. en passant, sélectionner seulement quelques colonnes est appelé projection, alors google avec ce sera plus facile.
alternative - vous pouvez créer une requête nommée avec la liste des champs dont vous avez besoin (vous les mettez dans la sélection) ou utiliser des critères avec projection