Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Hibernate的@query注释中,有没有办法使用@params中的表名?_Java_Sql_Spring_Spring Data Jpa_Spring Data - Fatal编程技术网

Java 在Hibernate的@query注释中,有没有办法使用@params中的表名?

Java 在Hibernate的@query注释中,有没有办法使用@params中的表名?,java,sql,spring,spring-data-jpa,spring-data,Java,Sql,Spring,Spring Data Jpa,Spring Data,我正在使用Hibernate和SpringDataJPA构建一个web项目 在Eclipse链接中,我们可以使用本机查询,如 String tableName = "sometablename"; String query = "SELECT * FROM " +tableName +"WHERE id > 10"; 在Hibernate中,我使用@Query注释 @Query(value = "SELECT COUNT(r.id) as resultsCount FROM #{

我正在使用Hibernate和SpringDataJPA构建一个web项目

在Eclipse链接中,我们可以使用本机查询,如

String tableName = "sometablename";
String query = "SELECT * FROM " +tableName +"WHERE id > 10";
在Hibernate中,我使用@Query注释

    @Query(value = "SELECT COUNT(r.id) as resultsCount FROM #{#resultTable} r WHERE r.customerId= :customerId AND r.is_deleted=0 AND r.is_ignored=0 ", nativeQuery = true)
Integer getResultsCount(@Param("customerId") int customerId,
            @Param("resultTable") String resultTable);
我尝试了#{#resultatable},但这被替换为带引号的字符串,我得到了一个异常

You have a error in your SQL Syntax

我想从参数中动态使用表名。可能吗?如果是,请告诉我你自己的观察结果如何回答你的问题:

我尝试了#{#resultable},但这被替换为带引号的字符串,我得到了一个异常

@Query
查询字符串中使用的占位符旨在用文字值填充。因此,表名最终以文本字符串的形式出现在单引号中。这意味着幕后的
@Query
和Spring可能正在使用JDBC准备的语句。无法绑定表的名称。允许这样做将是一个重大的安全漏洞


这里唯一可能的解决方法是将查询字符串连接在一起,然后尝试将该字符串与
@query
一起使用。但是请注意,这不是一个安全的选项。

这是不可能的,
@org.springframework.data.jpa.repository.Query
只接受jpql,您无法传递表的名称,因为它不被识别为任何实体

它说明了
查询的javadoc

/**
 * Defines the JPA query to be executed when the annotated method is called.
 */
String value() default "";

最好的解决方案不是将tablename作为字符串传递,而是使用例如继承()来解析它,或者以某种方式重新构建数据模型。作为一个快速而肮脏的解决方案,我建议创建一个自定义存储库,并使用
EntityManager.createNativeQuery
将sql传递到那里。但是请记住验证您正在编写的查询(验证用户输入,使用枚举作为表名),因为这会导致sql注入。

您所做的是错误的,您将业务逻辑混合到DAO层,我建议您创建两个DAO,每个DAO都有自己的表和查询,然后进入业务/服务层调用所需的。

谢谢@Andronicus,你能建议一个更好的方法(或方法)来处理这个问题吗?@RakeshKumar没问题。查看我的编辑。虽然实际答案(“不可能”)是正确的,但没有进行预处理的说法是错误的。实际上,您可以在Spring数据JPA的参数位置使用SpEL表达式。@jenschauder非常感谢,这很有趣。Rakesh Kumar似乎认为,可以使用实体名来代替spel中的表名。