对于Spring JPA,有没有一种简单的方法来使用原生查询,同时又保持数据库的独立性,例如,通过使用最适合的查询?
目前,我通过检查Environment
中当前设置的Dialect
并调用我的Repository
的正确方法来实现这一点
public Foo fetchFoo() {
if (POSTGRES_DIALECT.equals(env.getRequiredProperty("hibernate.dialect"))) {
return repo.postgresOptimizedGetFoo();
}
return repo.getFoo();
}
这是有效的,但我有一种感觉,有更好的方法,或者我错过了什么。特别是因为(Spring) JPA允许它非常容易地使用原生查询,但这破坏了它的一大优势:数据库独立性。
发布于 2015-11-02 19:30:28
这只是一个想法:我不知道它是否有效:
我的想法是使用子接口,一个普通的Spring-Data-JPA接口,其中包含一个实体的所有方法(没有本机查询提示)。然后我会为每个数据库创建一个子接口,“覆盖”数据库特定的本机语句。(如果没有特定于DB的语句,则此接口将为空)。然后,我会尝试使用一些配置文件来配置Spring-JPA,以加载正确的特定接口(例如,通过类名或包名模式)
发布于 2015-12-10 19:55:32
这似乎是一种复杂的方法,可以让查询正常工作。
如果你真的想使用优化的查询,至少让它对你的代码是透明的。我建议使用命名查询并为每个数据库创建一个orm.xml
(非常类似于Spring Boot为不同数据库加载schema.xml
)。
在代码中,您可以简单地执行以下操作
public interface YourRepository extends JpaRepository<YourEntity, Long> {
List<YourEntity> yourQueryMethod();
}
这将查找名称为YourEntity.yourQueryMethod
的命名查询。现在,在orm.xml
中添加命名查询(默认查询,在另一个查询中添加优化查询)。
然后,您需要配置您的LocalContainerEntityManagerFactory
来加载所需的特定your。假设您有一个定义所使用的数据库的属性,让我们将其命名为database.type
,您可以执行类似以下操作
<bean class="LocalContainerEntityManagerFactoryBean">
<property name="mappingResources" value="classpath:META-INF/orm-${database.type}.xml" />
... other config ...
</bean>
通过这种方式,您可以保持代码中if/then/else结构的整洁,并在需要的地方应用。很好的清理你的代码。
https://stackoverflow.com/questions/33475886
复制相似问题