如何透過ResultTransformer和原生SQL或JPQL生成DTO?
獲取超出需要的資料更容易導致效能損失。使用DTO可以讓我們只提取所需的資料。在這個應用程式中,我們依賴於Hibernate ResultTransformer和原生SQL生成DTO?
對於不可變的DTO值物件和可變的DTO物件使用不同的方式,不可變的DTO值物件是final欄位,因此不能有setter欄位:
public class CarDtoNoSetters implements Serializable { private static final long serialVersionUID = 1L; private final String name; private final String color; public CarDtoNoSetters(String name, String color) { this.name = name; this.color = color; } public String getName() { return name; } public String getColor() { return color; } @Override public String toString() { return "CarDtoNoSetters{" + "name=" + name + ", color=" + color + '}'; } } |
可變的DTO物件:
public class CarDtoWithSetters implements Serializable { private static final long serialVersionUID = 1L; private String name; private String color; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public String toString() { return "CarDtoWithSetters{" + "name=" + name + ", color=" + color + '}'; } } |
編寫自己的DAO類,對於不可變的DTO值物件使用ResultTransformer+AliasToBeanConstructorResultTransformer,可變的使用ResultTransformer+Transformers.aliasToBean():
@Repository @Transactional public class Dao<T, ID extends Serializable> implements GenericDao<T, ID> { @PersistenceContext private EntityManager entityManager; @Transactional(readOnly = true) public List<CarDtoNoSetters> fetchCarsNoSetters() { Query query = entityManager .createNativeQuery("select name, color from car") .unwrap(org.hibernate.query.NativeQuery.class) .setResultTransformer( new AliasToBeanConstructorResultTransformer( CarDtoNoSetters.class.getConstructors()[0] ) ); List<CarDtoNoSetters> result = query.getResultList(); return result; } @Transactional(readOnly = true) public List<CarDtoWithSetters> fetchCarsWithSetters() { Query query = entityManager .createNativeQuery("select name, color from car") .unwrap(org.hibernate.query.NativeQuery.class) .setResultTransformer( Transformers.aliasToBean(CarDtoWithSetters.class) ); List<CarDtoWithSetters> result = query.getResultList(); return result; } protected EntityManager getEntityManager() { return entityManager; } } |
使用EntityManager.createNativeQuery()和unwrap(org.hibernate.query.NativeQuery.class)- 從Hibernate 5.2開始,ResultTransformer不推薦使用,但是直到可以使用替換(在Hibernate 6.0中)它可以使用(進一步閱讀)
使用JPQL和原生SQL在SQL語句上稍微有點不同:
@Transactional(readOnly = true) public List<CarDtoNoSetters> fetchCarsNoSetters() { Query query = entityManager .createQuery("select c.name as name, c.color as color from Car c") .unwrap(org.hibernate.query.Query.class) .setResultTransformer( new AliasToBeanConstructorResultTransformer( CarDtoNoSetters.class.getConstructors()[0] ) ); List<CarDtoNoSetters> result = query.getResultList(); return result; } @Transactional(readOnly = true) public List<CarDtoWithSetters> fetchCarsWithSetters() { Query query = entityManager .createQuery("select c.name as name, c.color as color from Car c") .unwrap(org.hibernate.query.Query.class) .setResultTransformer( Transformers.aliasToBean(CarDtoWithSetters.class) ); List<CarDtoWithSetters> result = query.getResultList(); return result; } |
相關文章
- 如何透過建構函式和JPQL生成DTO?函式
- 如何透過javax.persistence.Tuple和原生SQL生成DTO?JavaSQL
- 如何透過javax.persistence.Tuple和JPQL提取DTO?Java
- 如何透過SqlResultSetMapping和NamedNativeQuery生成DTO?SQLAPP
- 如何透過Hibernate/JPA的SqlResultSetMapping生成需要資料的DTO?SQLAPP
- 透過shell指令碼定位效能sql和生成報告指令碼SQL
- 如何透過Spring Data/EntityManager/Session直接獲取DTO資料?SpringSession
- 透過shell和sql結合查詢效能sqlSQL
- 何時使用Entity或DTO
- 透過shell指令碼生成查詢表資料的sql指令碼SQL
- OceanBase學習之路46|如何透過 SQL 語句或 OCP 建立資源單元?SQL
- Java值物件或DTO克隆工具Java物件
- 詳解Dart中如何透過註解生成程式碼Dart
- 透過shell解析dump生成parfile
- 如何透過babel去操作ast, 並生成對應的程式碼。BabelAST
- 透過sql語句分析足彩SQL
- 如何使用Spring Projections和Join實現DTO?SpringProject
- Spark SQL 教程: 透過示例瞭解 Spark SQLSparkSQL
- JPA透過表反向生成相關類
- 通過shell指令碼定位效能sql和生成報告指令碼SQL
- Oracle透過AWR的SQL ordered by Gets和SQL ordered by Reads診斷問題OracleSQL
- 透過 3.0 Preview 看 Dubbo 的雲原生變革View
- Oracle 透過rowid秒優SQLOracleSQL
- 9i and 10g 透過SQL_ADDRESS 或sql_id查詢執行計劃SQL
- MySQL InnoDB Cluster如何定位或找出超過事務大小的SQL?MySql
- 【譯】透過新的 WinUI 工作負荷和模板改進,深入原生 Windows 開發UIWindows
- ?透過系統pid檢視sqlSQL
- 透過ADDM進行SQL調優SQL
- 如何使用Hibernate/JPA的JPQL/HQL查詢提取?
- 回到基礎:如何用原生 DOM API 生成表格API
- 如何透過DBeaver 連線 TDengine?
- 透過SQL_ID檢視SQL歷史執行資訊SQL
- 微服務之間如何共享DTO?微服務
- 如何透過設計提升網站的氣質和品質?網站
- 透過top命令抓取cpu高消耗的sqlSQL
- 透過java來格式化sql語句JavaSQL
- 透過使用hint unnest調優sql語句SQL
- 透過MySQL Workbench 將 SQL Server 遷移到GreatSQLMySqlServer