How to generate entity class without create table automatic
我为系统创建了一些报告,该报告由许多表组成。为此,我创建一个带有@Entity批注的Domain类并实现JpaRepository存储库,我将本机查询与@Query一起使用,如下所示。
我的问题是,对于每个域类,Hibernate正在创建一个表,该如何停止它?
我的域类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | @Entity @Immutable @Data @Builder @NoArgsConstructor @AllArgsConstructor @IdClass(WidgetDailyReportCompositeKey.class) public class WidgetDailyReportDomain{ @Id @Column(updatable = false, insertable = false) private UUID id_construction; @Id @Column(updatable = false, insertable = false) private String name; @Id @Column(updatable = false, insertable = false) private Date dt_cost; @Column(updatable = false, insertable = false) private Double total; } |
我的存储库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public interface WidgetRepository extends JpaRepository<WidgetDailyReportDomain, UUID>{ @Query(value = " SELECT ct.id AS id_construction, " + " ct.name, " + " sm.dt_service AS dt_cost, " + " sum(smi.nu_value * stiv.amount) AS total " + " FROM service_measurement sm " + " INNER JOIN service_measurement_item smi ON smi.id_service_measurement = sm.id " + " INNER JOIN service s ON s.id = sm.id_service " + " INNER JOIN service_type_item_service stiv ON stiv.id_service = sm.id_service " + " AND stiv.id_service_type_item = smi.id_service_item " + " INNER JOIN construction ct ON ct.id = s.id_construction " + " WHERE s.id_construction IN ( " + " select s.id_construction " + " from service_measurement sm " + " INNER JOIN service_measurement_item smi ON smi.id_service_measurement = sm.id " + " INNER JOIN service s ON s.id = sm.id_service " + " INNER JOIN service_type_item_service stiv ON stiv.id_service = sm.id_service " + " AND stiv.id_service_type_item = smi.id_service_item " + " INNER JOIN construction ct on ct.id = s.id_construction " + " WHERE sm.dt_service BETWEEN :minDate AND :maxDate " + " GROUP BY s.id_construction " + " ORDER BY sum(smi.nu_value * stiv.value) DESC " + " limit :limit " + " ) " + " AND sm.dt_service BETWEEN :minDate AND :maxDate " + " GROUP BY ct.id, sm.dt_service " + " HAVING sum(smi.nu_value * stiv.amount) > 0 " + " ORDER BY sm.dt_service;", nativeQuery = true) List<WidgetDailyReportDomain> findTopExpensiveConstruction(@Param("minDate") Date minDate, @Param("maxDate") Date maxDate, @Param("limit") int limit); //.... |
在@Zagarh回答之后,我做了一些关于DTO的搜索,但我想出了一个不太优雅的解决方案,但这是可行的:
Domain类:
1 2 3 4 5 6 7 8 |
我必须创建一个自定义结果映射,为了使JPA能够映射结果,我使用了注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @MappedSuperclass @SqlResultSetMapping( name ="widget_daily_mapping", classes = { @ConstructorResult( targetClass = WidgetDailyReportDomain.class, columns = { @ColumnResult(name="id_construction", type = UUID.class), @ColumnResult(name ="name", type = String.class), @ColumnResult(name ="dt_cost", type = Date.class), @ColumnResult(name ="total", type = Double.class) } ) } ) public abstract class ResultSetMappingConfig { } |
然后我创建Jpa存储库的自定义实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public interface WidgetRepositoryCustom { List<WidgetDailyReportDomain> findTopExpensiveConstruction(Date minDate, Date maxDate, int limit); } @Repository @Transactional(readOnly = true) public class AR_serviceRepositoryImpl implements AR_serviceRepositoryCustom{ @PersistenceContext private EntityManager em; @Override public List<AR_serviceDomain> getListOfService(UUID id_construction) { Query query = em.createNativeQuery(" //Native Query Here... ","widget_daily_mapping");// Put the result mapping Here query.setParameter(1, id_construction //..Parameters Here); return query.getResultList(); } } |
Ps:1)如果有人有更好的解决方案,请告诉我。 2)对不起,我使用英语,我正在使用Google翻译。
由于问题中的
如果您使用的是Spring Boot,则可以添加
1 2 3 4 | spring: jpa: hibernate: ddl-auto: none |
到您的
1 | spring.jpa.hibernate.ddl-auto=none |
到您的
如果您使用的是
1 | <property name="hibernate.hbm2ddl.auto" value="none"/> |
以这种方式禁用模式表的生成意味着您必须确保通过其他方式创建了它们,然后您的应用程序才能运行。
您可以删除所有
然后,您可以将WidgetDailyReportDomain对象用作DTO进行投影,而不必将其附加到EntityManager:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections.dtos
EDIT:另外,不要忘记为该对象构建一个构造函数,这样Spring JPA会将值加载到该对象中(如文档中所述)。
如果您不想构建构造函数,则可以将其更改为接口并将其用作投影:https://docs.spring.io/spring-data/jpa/docs/current/reference/html /#projections.interfaces
您的WidgetDailyReportDomain实际上是投影。您无需将其标记为@Entity。
您的@Query可以属于任何其他实际存在的存储库。