JPA:具有类似resultset访问的动态查询/ SQL-JPA



初步说明:代码存在于使用JPA的Java-Webapp中,并且对它很满意,因此完全放弃JPA不是解决方案。

但是我的部分是关于动态数据查询。例如,管理员可以编写sql查询,用户可以触发sql查询来生成csv-exports。

有了JDBC,我得到了很多关于ResultSet的元数据,我可以在我知道的地方获取字符串和整数。

JPA允许直接SQL查询,但我可以获取那些只有getResultList()作为List<Object>,这真的是一个List<Object[]>List<Object>取决于选择的列数(据我所知),并给出了一些丑陋的警告对List<Object>List<Object[]>

我确实理解JPA一般不能提供ResultSet或JDBCConnection,因为它可以访问文本或大数据或memcache而不是SQL。但是我没有发现像SQL-JPA这样的东西。

在jpa应用程序中使用EclipseLink的直接和特定方法是错误的,而且非常肮脏。我可以肯定的是,应用程序将留在SQL,但不是,它将留在EclipseLink。

所以似乎我必须自己写一个ResultSet,有元数据,如columncount和列的名称,我不能从数据库结果中读取列的数据类型。但是写一个ResultSet类除了JPA,从SQL-String记忆信息的一部分感觉也是错误的。

在JPA应用程序中打开一个额外的jdbc连接似乎可以解决问题,但我甚至没有从JPA中获得连接数据,两个单独的配置迟早会导致厄运。

是我的用例太奇怪还是JPA太有限,还是我只是对正确的解决方案视而不见?

SQL 对于复杂的数据关系来说是一种非常强大和简单的语言,所以我想知道为什么JPA如此害怕它(当然,大量典型的Object-Write和Object-Read对于jdbc来说太痛苦了)。

是否有人知道JPA的现有ResultSet-Implementation,或者是否有我看不到的正确解决方案?

谢谢你的帮助

因为我只看到了评论,我将尽量提供一个答案,但由于这个问题没有非常具体的编程问题,我的答案将是相似的。

JPA是一个ORM,这意味着它将数据库内容映射到Java对象,并提供了一些更多的特性(事务,将EntityManager操作转换为SQL查询,命名查询,…)。因为根据定义,ORM是JDBC之上的一层,所以它没有您需要的目的。

你是对的:

    JPA 1.0中的
  • 没有从EntityManager实例获得JDBC连接的标准方法,尽管它不太好,但也不像您想象的那么脏:创建一个从EntityManager返回JDBC连接的静态方法,这将是唯一脏的地方。如果切换到Hibernate,只需要更改几行代码。
  • 但是在JPA 2.0中有一个JPA特定的方式:

    Connection conn = em.unwrap(Session.class).connection();

    您应该在JPA事务中以这种方式访问Connection。否则,您将负责释放连接。

或者使用常规的JPQL查询来检索所有需要的数据,然后您将直接获得正确的类型。这里的限制是:它不像SQL那么灵活,但是远(例如,您可以从JPA 2.1使用JOIN ON)。

如果我理解正确的话,您需要的是一个本地SQL查询(您可以与JPA一起使用),然后将结果放入一些数据结构中进行操作,但不需要在实体内事先映射,对吗?

那么查询语言结果映射器(Query Language Result Mapper, QLRM)项目可能对您有用,因为它允许您从本机查询创建结果对象,唯一的要求是参数具有相同的数量和类型:

Query q = em.createNativeQuery("SELECT ID, NAME FROM EMPLOYEE");
List<EmployeeTO> list = jpaResultMapper.list(q, EmployeeTO.class);

如果您真的不知道输入的结果,因为它们是通用的,那么除了使用普通JDBC并检查元数据之外,您没有太多选择。

但是请记住,让用户构建自己的通用查询是潜在的危险,因为可能会发生SQL注入之类的事情。最好尝试定义一些可能的构建块(使用准备好的语句和绑定变量而不是字符串连接的SQL),您可以单独测试并让用户从中选择。

最新更新