初学者:代码存在于使用JPA的Java-Webapp中并且对它很满意,因此完全切换JPA是没有解决方案的。
但我的部分是关于动态数据查询。比方说,管理员可以编写用户可以触发的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-Application中使用EclipseLink的直接和特定方法是错误的和非常脏的。我可以确定应用程序将保留在SQL上,但不会保留在EclipseLink上。
所以我似乎必须自己写一个ResultSet,包含像columncount和列名这样的元数据,而且我无法从数据库结果中读取列的数据类型。但是编写除JPA之外的ResultSet类来记忆SQL-String中的部分信息也感觉不对。
在JPA-Application中打开一个额外的JDBC-Connection似乎可以解决问题,但我甚至没有从JPA中获取连接数据,并且两个单独的配置迟早会导致死命。
我的用例是否太奇怪或者JPA太有限,或者我只是对正确的解决方案视而不见?
SQL 是一种非常强大而简单的复杂数据关系语言,所以我想知道为什么JPA会害怕它(当然,大量典型的Object-Write和Object-Read也是如此)痛苦的jdbc)。
有没有人知道JPA的现有ResultSet-Implementation,还是有任何我看不到的正确解决方案?
感谢您的帮助。
答案 0 :(得分:1)
因为我只看过评论,所以我会尝试提供答案,但由于问题没有非常具体的编程问题,我的答案也是一样的。
JPA是一个ORM,意味着它将数据库事物映射到Java对象,并提供更多功能(事务,将EntityManager
操作转换为SQL查询,命名查询,...)。因为ORM根据定义是JDBC之上的层,所以它没有您需要的目的。
你是对的:
EntityManager
实例获取JDBC连接的标准方法,虽然它不是很好,但它也不像你想象的那么脏:创建一个静态方法,从EntityManager返回JDBC连接,这将是唯一的脏地方。如果您将切换到Hibernate,则只会更改几行。 但在 JPA 2.0 中有一种JPA特定方式:
Connection conn = em.unwrap(Session.class).connection();
您应该在JPA事务中以这种方式访问Connection。否则,您将负责释放连接。 (引自here)
或者使用常规JPQL查询来检索所有需要的数据,然后您将直接获得正确的类型。这里的限制是:它不像SQL那么灵活,但远远不够(例如你可以在JPA 2.1中使用JOIN ON)。
答案 1 :(得分:0)
如果我理解正确,你需要的是一个本机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 injection之类的内容可能会发生。最好尝试定义一些可能的构建块(使用预处理语句和绑定变量而不是String-concatenated SQL),您可以单独测试它们并让用户从中进行选择。