如何透過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
- 如何透過Spring Data/EntityManager/Session直接獲取DTO資料?SpringSession
- OceanBase學習之路46|如何透過 SQL 語句或 OCP 建立資源單元?SQL
- 何時使用Entity或DTO
- Java值物件或DTO克隆工具Java物件
- 詳解Dart中如何透過註解生成程式碼Dart
- 9i and 10g 透過SQL_ADDRESS 或sql_id查詢執行計劃SQL
- 如何生成文字: 透過 Transformers 用不同的解碼方法生成文字ORM
- Spark SQL 教程: 透過示例瞭解 Spark SQLSparkSQL
- 如何使用Spring Projections和Join實現DTO?SpringProject
- 如何透過babel去操作ast, 並生成對應的程式碼。BabelAST
- MySQL InnoDB Cluster如何定位或找出超過事務大小的SQL?MySql
- JPA透過表反向生成相關類
- HarmonyOS開發:透過文字生成碼圖
- 透過 3.0 Preview 看 Dubbo 的雲原生變革View
- 透過MySQL Workbench 將 SQL Server 遷移到GreatSQLMySqlServer
- ASH可以生成指定的session或sql_id的報告,ASH和AWR的區別SessionSQL
- 如何使用Hibernate/JPA的JPQL/HQL查詢提取?
- 【譯】透過新的 WinUI 工作負荷和模板改進,深入原生 Windows 開發UIWindows
- EF中使用SQL語句或儲存過程SQL儲存過程
- oracle 透過pid 找到sid 再找出執行sqlOracleSQL
- java使用bytebuddy動態生成帶泛型的DTOJava泛型
- 使用IDEA+groovy快速生成entity、dto、dao、service、serviceImplIdea
- 如何在 GNU Linux 上透過 Nvm 安裝 Node 和 Npm?LinuxNPM
- 如何透過DBeaver 連線 TDengine?
- 如何透過kubernetes-部署RabbitMQMQ
- Springboot透過谷歌Kaptcha 元件,生成圖形驗證碼Spring Boot谷歌APT元件
- CMakeFile.txt透過sysroot方式後生成makefile報錯
- 回到基礎:如何用原生 DOM API 生成表格API
- 微服務之間如何共享DTO?微服務
- 如何透過分解和增量更改將單體遷移到微服務?微服務
- 使用AI識別語音和B站影片並透過GPT生成思維導圖AIGPT
- 原生SQL查詢SQL
- OceanBase學習之路36|如何透過 SQL 語句刪除不再使用的資源池?SQL