Съставяне на заявка за хибернация в потребителски клас

1. Общ преглед

Когато използваме Hibernate за извличане на данни от базата данни, по подразбиране той използва извлечените данни, за да изгради цялата графика на обекта за заявения обект. Но понякога може да искаме да извлечем само част от данните, за предпочитане в плоска структура.

В този бърз урок ще видим как можем да постигнем това в хибернация с помощта на персонализиран клас.

2. Субектите

Първо, нека разгледаме обектите, които ще използваме за извличане на данните:

@Entity public class DeptEmployee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String employeeNumber; private String designation; private String name; @ManyToOne private Department department; // constructor, getters and setters } @Entity public class Department { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; private String name; @OneToMany(mappedBy="department") private List employees; public Department(String name) { this.name = name; } // getters and setters  }

Тук имаме две образувания - DeptEfficiee и Department . За простота, нека приемем, че служител на отдел може да принадлежи само на един отдел.

Но в отдел може да има множество служители на отдел .

3. Персонализиран клас резултат на заявката

Да кажем, че искаме да отпечатаме списък на всички служители само с тяхното име и името на техния отдел.

Обикновено бихме извлекли тези данни с подобна заявка:

Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee"); List deptEmployees = query.list();

Това ще извлече всички служители, всички техни свойства, свързания отдел и всички негови свойства.

Но в конкретния случай това може да е малко скъпо, тъй като ни трябва само името на служителя и името на отдела.

Един от начините да извлечем само информацията, от която се нуждаем, е чрез посочване на свойствата в клаузата за избор.

Но когато правим това, Hibernate връща списък с масиви вместо списък с обекти:

Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m"); List managers = query.list(); Object[] manager = (Object[]) managers.get(0); assertEquals("John Smith", manager[0]); assertEquals("Sales", manager[1]);

Както виждаме, върнатите данни са малко тромави за обработка. Но за щастие можем да накараме Hibernate да попълни тези данни в клас.

Нека разгледаме класа Result , който ще използваме, за да попълним извлечените данни в:

public class Result { private String employeeName; private String departmentName; public Result(String employeeName, String departmentName) { this.employeeName = employeeName; this.departmentName = departmentName; } public Result() { } // getters and setters }

Имайте предвид, че класът не е обект, а просто POJO. Можем обаче да използваме и обект, стига да има конструктор, който приема всички параметри, които искаме да попълним.

Ще видим защо конструкторът е важен в следващия раздел.

4. Използване на конструктор в HQL

Сега, нека разгледаме HQL, който използва този клас:

Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name)" + " from com.baeldung.hibernate.entities.DeptEmployee m"); List results = query.list(); Result result = results.get(0); assertEquals("John Smith", result.getEmployeeName()); assertEquals("Sales", result.getDepartmentName());

Тук използваме конструктора, който сме дефинирали в класа Result, заедно със свойствата, които искаме да извлечем. Това ще върне списък с обекти Резултат с данните, попълнени от колоните.

Както виждаме, върнатият списък е по-лесен за обработка, отколкото използването на списък с масиви от обекти.

Важно е да се отбележи, че трябва да използваме пълното име на класа в заявката.

5. Използване на ResultTransformer

Алтернатива на използването на конструктор в HQL заявката е използването на ResultTransformer:

Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName" + " from com.baeldung.hibernate.entities.DeptEmployee m"); query.setResultTransformer(Transformers.aliasToBean(Result.class)); List results = query.list(); Result result = results.get(0); assertEquals("John Smith", result.getEmployeeName()); assertEquals("Sales", result.getDepartmentName());

Ние използваме трансформаторите. aliasToBean () метод за използване на извлечените данни за попълване на обектите Result .

Следователно трябва да се уверим, че имената на колоните или техните псевдоними в оператора select съответстват на свойствата на класа Result .

Обърнете внимание, че Query.setResultTransformer ( ResultTransformer ) е остарял след Hibernate 5.2.

6. Заключение

В тази статия видяхме как персонализиран клас може да се използва за извличане на данни във форма, която е лесна за четене.

Изходният код, придружаващ тази статия, е достъпен в GitHub.