如何透過Hibernate/JPA的SqlResultSetMapping生成需要資料的DTO?
獲取比你實際所需要的更多資料並不好,此外,當您不打算修改實體時,獲取實體(透過在持久化上下文中加入的方式獲取實體)是最常見的錯誤之一,它隱含效能損失。
因此,使用DTO可允許我們僅提取所需的資料。在這個應用程式中,我們依賴 @SqlResultSetMapping和EntityManager來實現。
假設三個實體TopCategory和MiddleCategory是一對多關係,MiddleCategory和BottomCategory 是一對多關係,現在需要分別從TopCategory、MiddleCategory和BottomCategory 中提取各自的namet、namem和nameb欄位組成CategoryDto:
TopCategory程式碼如下,我們使用了註釋@SqlResultSetMapping構造獲得CategoryDto的欄位,TopCategory是父級根實體(DDD聚合中的實體根)。
@SqlResultSetMapping(name = "CategoryDtoMapping", classes = { @ConstructorResult( targetClass = CategoryDto.class, columns = { @ColumnResult(name = "namet"), @ColumnResult(name = "namem"), @ColumnResult(name = "nameb") } )} ) @Entity @Table(name = "top_category") public class TopCategory implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @OneToMany(cascade = CascadeType.ALL, mappedBy = "topCategory", orphanRemoval = true) private List<MiddleCategory> middleCategories = new ArrayList<>(); // helper methods public void addMiddleCategory(MiddleCategory middleCategory) { middleCategories.add(middleCategory); middleCategory.setTopCategory(this); } public void removeMiddleCategory(MiddleCategory middleCategory) { middleCategory.setTopCategory(null); middleCategories.remove(middleCategory); } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<MiddleCategory> getMiddleCategories() { return middleCategories; } public void setMiddleCategories(List<MiddleCategory> middleCategories) { this.middleCategories = middleCategories; } } |
然後實現自己的DAO倉儲,在其中呼叫EntityManager的createNativeQuery,其他方式點選標籤#DTO可看到更多EntityManager呼叫方式。
@Repository @Transactional public class Dao<T, ID extends Serializable> implements GenericDao<T, ID> { @PersistenceContext private EntityManager entityManager; @Override public <S extends T> S persist(S entity) { Objects.requireNonNull(entity, "Cannot persist a null entity"); entityManager.persist(entity); return entity; } @Transactional(readOnly=true) public List<CategoryDto> fetchCategories() { Query query = entityManager.createNativeQuery( "SELECT t.name AS namet, m.name AS namem, b.name AS nameb " + "FROM middle_category m " + "INNER JOIN top_category t ON t.id=m.top_category_id " + "INNER JOIN bottom_category b ON m.id=b.middle_category_id", "CategoryDtoMapping"); List<CategoryDto> result = query.getResultList(); return result; } protected EntityManager getEntityManager() { return entityManager; } } |
下面是Dao客戶端Service的呼叫方式:
@Service public class CategoryService { private final Dao dao; public CategoryService(Dao dao) { this.dao = dao; } public List<CategoryDto> fetchCategories() { return dao.fetchCategories(); } } |
原始碼可以在這裡找到
相關文章
- 如何透過SqlResultSetMapping和NamedNativeQuery生成DTO?SQLAPP
- 如何透過建構函式和JPQL生成DTO?函式
- 如何透過ResultTransformer和原生SQL或JPQL生成DTO?ORMSQL
- 如何透過Hibernate/JPA在MySQL中儲存UTC時區?MySql
- 如何透過javax.persistence.Tuple和原生SQL生成DTO?JavaSQL
- 如何透過Spring Data/EntityManager/Session直接獲取DTO資料?SpringSession
- Hibernate/JPA如何保證不生成多餘的SQL語句?SQL
- JPA透過表反向生成相關類
- 如何在SpringBoot中使用Hibernate/JPA的@NaturalId?Spring Boot
- 如何使用Hibernate/JPA的JPQL/HQL查詢提取?
- 如何透過javax.persistence.Tuple和JPQL提取DTO?Java
- JPA與hibernate-------JPA01
- 如何在Hibernate/JPA中配置具有兩個連線池的兩個資料來源
- Hibernate/JPA中@OneToOne和@MapsId的使用
- 使用JPA和Hibernate呼叫儲存過程的最佳方法 - Vlad Mihalcea儲存過程
- hibernate及SpringBoot整合Jpa實現對資料庫操作Spring Boot資料庫
- 解鎖你的資料庫:JPA和Hibernate的樂觀鎖與悲觀鎖資料庫
- Hibernate/JPA中如何合併實體集合?
- 使用Hibernate、JPA、Lombok遇到的有趣問題Lombok
- Hibernate批處理如何透過“datasource-proxy”檢視詳細資訊?
- 如何生成文字: 透過 Transformers 用不同的解碼方法生成文字ORM
- 淺談JPA二:聊聊Hibernate
- 如何在Hibernate/JPA的實體和查詢中使用Java 8 Optional?Java
- 如何透過資料分析來支援TPM模式的決策?模式
- 如何透過SQLyog分析MySQL資料庫MySql資料庫
- 【Mysql】如何透過binlog恢復資料MySql
- JPA和Hibernate的樂觀鎖與悲觀鎖
- 如何透過holer從外網訪問本地的資料庫?資料庫
- 控制你的DTO資料結構 - DZone資料結構
- 如何透過babel去操作ast, 並生成對應的程式碼。BabelAST
- Oracle資料庫與JPA和Hibernate 結合使用時的九個高效能技巧 - vladmihalceaOracle資料庫
- 使用 mock.js 給前端生成需要的資料MockJS前端
- 如何透過資料文化加速企業管理的轉型升級?
- 勒索軟體攻擊:如何透過加密保護您的資料加密
- 透過 ETL 匯出 Hive 中的資料Hive
- 如何透過一條資料庫語句做資料分析資料庫
- Hibernate/JPA中避免save()冗餘呼叫
- 【SpringBoot Demo】MySQL + JPA + Hibernate + Springboot + Maven DemoSpring BootMySqlMaven