Java JPQL/Hibernate查询的动态表名

Java JPQL/Hibernate查询的动态表名,java,hibernate,jpa,spring-data-jpa,Java,Hibernate,Jpa,Spring Data Jpa,我的数据库中有数千个表,这些表已经(并将继续)使用命名策略创建—每个日历日一个表: 数据\u 2010\u 01\u 01 数据\u 2010\u 01\u 02 数据(2020)01(01) 所有表格都包含来自同一系统、形状相同的传感器数据。因此,单个实体(我们称之为SensorRecord)将绝对映射到所有表 我想象这样的事情会奏效: @Query(nativeQuery = true, value = "SELECT * FROM \"?1\"") Collection<Sen

我的数据库中有数千个表,这些表已经(并将继续)使用命名策略创建—每个日历日一个表:

  • 数据\u 2010\u 01\u 01
  • 数据\u 2010\u 01\u 02
  • 数据(2020)01(01)
所有表格都包含来自同一系统、形状相同的传感器数据。因此,单个实体(我们称之为SensorRecord)将绝对映射到所有表

我想象这样的事情会奏效:

@Query(nativeQuery = true, value = "SELECT * FROM \"?1\"")
Collection<SensorRecord> findSensorDataForDate(String tableName);
@Query(nativeQuery=true,value=“SELECT*FROM\”?1\”)
集合findSensorDataForDate(字符串表名);
但事实并非如此,围绕这个话题阅读似乎表明我走错了路。大多数关于动态命名的文章似乎都明确指出,每个表需要一个实体,但生成数千个重复实体似乎也是错误的


如果表名遵循命名约定并且可以作为查询的一部分进行更改,那么如何使用JPA(JPQL?)处理这些数据

这可能只是语法错误吗

这对我起了作用:

    @Query(value = "select * from job where job.locked = 1 and job.user = ?1", nativeQuery = true)
    public List<JobDAO> getJobsForUser(@Param("user") String user);
@Query(value=“select*from job,其中job.locked=1,job.user=1”,nativeQuery=true)
公共列表getjobsforser(@Param(“user”)字符串user);

可能只是语法错误吗

这对我起了作用:

    @Query(value = "select * from job where job.locked = 1 and job.user = ?1", nativeQuery = true)
    public List<JobDAO> getJobsForUser(@Param("user") String user);
@Query(value=“select*from job,其中job.locked=1,job.user=1”,nativeQuery=true)
公共列表getjobsforser(@Param(“user”)字符串user);

参数仅在where子句中允许。 您可以创建自定义存储库方法返回
SensorRecord
dto的集合。不需要映射这么多实体。您应该将
列表
作为查询结果,并手动创建dto对象

    @Autowired 
    EntityManager entityManager;    

    public List<SensorRecord> findSensorDataForDate(LocalDate date) {
           DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy_MM_dd");
           String tableName = "data_" + date.format(formatter);

           Query query = entityManager.createNativeQuery(
                             "select t.first_column, t.second_column from " + tableName + " t");

           List<Object[]> queryResults = query.getResultList();

           List<SensorRecord> sensorRecords = new ArrayList<>();
           for (Object[] row : queryResults) {
               SensorRecord record = new SensorRecord();
               record.setFirstParameter((Integer) row[0]);
               record.setSecondParameter((String) row[1]);

               sensorRecords.add(record);
           }

           return sensorRecords;
   }
@Autowired
实体管理器实体管理器;
公共列表findSensorDataForDate(LocalDate){
DateTimeFormatter formatter=模式的DateTimeFormatter.of(“yyyy_-MM_-dd”);
字符串tableName=“data”+date.format(格式化程序);
Query Query=entityManager.createNativeQuery(
从“+tableName+“t”中选择t.first_列,t.second_列;
List queryResults=query.getResultList();
List sensorRecords=new ArrayList();
对于(对象[]行:queryResults){
SensorRecord记录=新的SensorRecord();
record.setFirstParameter((整数)行[0]);
record.setSecondParameter((字符串)行[1]);
sensorRecords.add(记录);
}
返回记录;
}

参数仅在where子句中允许。 您可以创建自定义存储库方法返回
SensorRecord
dto的集合。不需要映射这么多实体。您应该将
列表
作为查询结果,并手动创建dto对象

    @Autowired 
    EntityManager entityManager;    

    public List<SensorRecord> findSensorDataForDate(LocalDate date) {
           DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy_MM_dd");
           String tableName = "data_" + date.format(formatter);

           Query query = entityManager.createNativeQuery(
                             "select t.first_column, t.second_column from " + tableName + " t");

           List<Object[]> queryResults = query.getResultList();

           List<SensorRecord> sensorRecords = new ArrayList<>();
           for (Object[] row : queryResults) {
               SensorRecord record = new SensorRecord();
               record.setFirstParameter((Integer) row[0]);
               record.setSecondParameter((String) row[1]);

               sensorRecords.add(record);
           }

           return sensorRecords;
   }
@Autowired
实体管理器实体管理器;
公共列表findSensorDataForDate(LocalDate){
DateTimeFormatter formatter=模式的DateTimeFormatter.of(“yyyy_-MM_-dd”);
字符串tableName=“data”+date.format(格式化程序);
Query Query=entityManager.createNativeQuery(
从“+tableName+“t”中选择t.first_列,t.second_列;
List queryResults=query.getResultList();
List sensorRecords=new ArrayList();
对于(对象[]行:queryResults){
SensorRecord记录=新的SensorRecord();
record.setFirstParameter((整数)行[0]);
record.setSecondParameter((字符串)行[1]);
sensorRecords.add(记录);
}
返回记录;
}

这是否回答了您的问题?部分地。一个答案是“你不能”,另一个答案是实体管理器代码剪贴,没有说明为什么这是首选解决方案。亚历克斯下面的回答是一个相当完整和有用的回答。这回答了你的问题吗?部分地。一个答案是“你不能”,另一个答案是实体管理器代码剪贴,没有说明为什么这是首选解决方案。下面Alex的回答是一个更加完整和有用的回答。这个例子有一个固定的表名“job”。我需要能够更改表名。因此,在您的示例中:选择*from job_123或选择*from job_456…这个示例有一个固定的表名“job”。我需要能够更改表名。因此,在您的示例中:从job_123中选择*或从job_456中选择*谢谢您的示例。这很有帮助。似乎没有办法将表名作为JPQL参数,所以这就是我需要的。感谢您提供的示例。这很有帮助。似乎没有办法将表名作为JPQL参数,所以这就是我需要的。