![](/img/trans.png)
[英]How to best map results from an SQL query to a non-entity Java object using Hibernate?
[英]How to map results of a Hibernate Query to a DTO object?
我的Java
項目中有以下 3 個Hibernate
實體:
公司狀況
@Entity(name = "company_status")
@Table(name = "company_status")
public class CompanyStatus implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@JsonProperty
@Column(name = "company_status_id")
private Integer companyStatusId;
@JsonProperty
@Column(name = "company_status_label")
private String companyStatusLabel;
}
員工身份
@Entity(name = "employee_status")
@Table(name = "employee_status")
public class EmployeeStatus implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty
@Column(name = "employee_status_id")
private Integer employeeStatusId;
@JsonProperty
@Column(name = "employee_status_name")
private String employeeStatusName;
// many other fields
}
CompanyStatusEmployeeStatus (鏈接 2 個實體的實體 - 一對一關系)
@Entity(name = "company_status_employee_status")
@Table(name = "company_status_employee_status")
public class CompanyStatusEmployeeStatus implements Serializable {
// int(20)
@Id
@JsonProperty
@Column(name = "company_status_id")
private Integer companyStatusId;
// int(20)
@JsonProperty
@Column(name = "employee_status_id")
private Integer employeeStatusId;
}
我只想將我的 JSON 響應中的必要字段返回給前端,因此為了做到這一點,我創建了一個較小的CompanyStatusDTO
object,它還嵌套了一個EmployeeStatusDTO
列表
公司狀況DTO
public class CompanyStatusDTO {
@JsonProperty
private Integer companyStatusId;
@JsonProperty
private String companyStatusLabel;
@JsonProperty
private List <EmployeeStatusDTO> employeeStatusDTOs;
}
員工狀態DTO
public class EmployeeStatusDTO {
@JsonProperty
private Integer employeeStatusId;
@JsonProperty
private String employeeStatusName;
}
但是,我對使用 Hibernate 比較陌生 - 有沒有一種方法可以創建一個查詢,將 map 結果直接從我的MySQL
數據庫發送到我的CompanyStatusDTO
object?
如果是這樣,我該怎么做?
您可以使用 NativeQuery 直接將 map 查詢結果查詢到您想要的 DTO(數據類型必須匹配)
String q = "select ... from table"; // your sql query
Query query = getEntityManager().createNativeQuery(q, "EmployeeStatusDTO");
EmployeeStatusDTO data = (EmployeeStatusDTO) query.getSingleResult();
return data;
這是Blaze-Persistence Entity Views的完美用例。
我創建了庫以允許在 JPA 模型和自定義接口之間輕松映射或抽象 class 定義的模型,類似於類固醇上的 Spring 數據投影。 這個想法是,您按照自己喜歡的方式定義目標結構(域模型),並通過 JPQL 表達式將 map 屬性(getter)定義為實體 model。
如果您稍微調整CompanyStatus
和CompanyStatusEmployeeStatus
實體並添加以下內容:
public class CompanyStatus implements Serializable {
//...
@OneToMany(mappedBy = "companyStatus")
private Set<CompanyStatusEmployeeStatus> employeeStatuses;
}
public class CompanyStatusEmployeeStatus implements Serializable {
//...
@JsonProperty
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "company_status_id", insertable = false, updatable = false)
private CompanyStatus companyStatus;
@JsonProperty
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "employee_status_id", insertable = false, updatable = false)
private EmployeeStatus employeeStatus;
}
您的 model 可能如下所示:
@EntityView(CompanyStatus.class)
public interface CompanyStatusDTO {
@IdMapping
Integer getCompanyStatusId();
String getCompanyStatusLabel();
@Mapping("employeeStatuses.employeeStatus")
List<EmployeeStatusDTO> getEmployeeStatusDTOs();
}
@EntityView(EmployeeStatus.class)
public interface EmployeeStatusDTO {
@IdMapping
Integer getEmployeeStatusId();
String getEmployeeStatusName();
}
查詢是將實體視圖應用於查詢的問題,最簡單的就是通過 id 進行查詢。
CompanyStatusDTO c = entityViewManager.find(entityManager, CompanyStatusDTO.class, id);
Spring 數據集成允許您幾乎像 Spring 數據投影一樣使用它: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
你可以試試這個:
public class Dao{
private SessionFactory sessionFactory;
public Dao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public <T> T save(final T o){
return (T) sessionFactory.getCurrentSession().save(o);
}
public void delete(final Object object){
sessionFactory.getCurrentSession().delete(object);
}
public <T> T get(final Class<T> type, final Long id){
return (T) sessionFactory.getCurrentSession().get(type, id);
}
public <T> List<T> getAll(final Class<T> type) {
final Session session = sessionFactory.getCurrentSession();
final Criteria crit = session.createCriteria(type);
return crit.list();
}
// and so on, you should get the idea
然后您可以在服務層中像這樣訪問:
private Dao dao;
@Transactional(readOnly = true)
public List<MyEntity> getAll() {
return dao.getAll(MyEntity.class);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.