我正在将ETL过程从工具转换为Java批处理API应用程序。在这个ETL过程中。在当前版本(使用该工具)中,我们有许多连接不同表的SQL语句,以便生成所需的输出。现在可以转换为Java,JPA。
我想使用原生查询。这样会很好,因为它不需要为查询中使用的每个表创建实体,我可以使用POJO来查询结果(我也不需要重写查询)。阅读this answer我知道我可以使用@SqlResultSetMapping
。问题是我的项目中没有任何实体,所以我不知道在哪里放这个注释。我可以在任何地方放置这个注释,以便实体经理找到它吗?
PS:在我的概念证明中,我目前正手动从一组对象转换为POJO,但我真的不喜欢这种方法。
将@Entity
注释添加到POJO将导致我的应用程序无法启动:
引起:org.hibernate.HibernateException:缺少表:MyTable
我不确定(现在正在搜索),但我认为这可能是由我的persistence.xml中的这个属性引起的
<property name="hibernate.hbm2ddl.auto" value="validate"/>
答案 0 :(得分:8)
实际上我找到了answer I was looking for:
我可以在orm.xml中使用XML定义@SqlResultSetMapping
的行为,所以这个定义:
@SqlResultSetMapping(
name = "BookValueMapping",
classes = @ConstructorResult(
targetClass = BookValue.class,
columns = {
@ColumnResult(name = "id", type = Long.class),
@ColumnResult(name = "title"),
@ColumnResult(name = "version", type = Long.class),
@ColumnResult(name = "authorName")}))
将在XML中定义如下:
<sql-result-set-mapping name="BookValueMappingXml">
<constructor-result target-class="org.thoughts.on.java.jpa.value.BookValue">
<column name="id" class="java.lang.Long"/>
<column name="title"/>
<column name="version" class="java.lang.Long"/>
<column name="authorName"/>
</constructor-result>
</sql-result-set-mapping>
允许我在不需要实体的情况下定义它。
答案 1 :(得分:4)
您可以使用JPA将本机sql映射到POJO。 POJO只需要@Entity和@Id。一个简单的例子:
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class TodoQueryModel {
@Id
private Long id;
private String description;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "TodoQueryModel [id=" + id + ", description=" + description
+ "]";
}
}
JPA impl中的一些方法:
private void queryWithNativeSQL() {
List<TodoQueryModel> todoList = em.createNativeQuery("SELECT id, description FROM [whatever you want as long as it returns 'id' and 'description' as column names]", TodoQueryModel.class)
.setParameter(1, "foobar");
.getResultList();
for (TodoQueryModel todo : todoList) {
System.out.println(todo);
}
System.out.println("Size: " + todoList.size());
}
您还可以使用@Column(name =&#34; barfoo&#34;)将列映射到名称不匹配的属性。
@Id列需要在JPA上下文中唯一标识实例。
答案 2 :(得分:1)
在过去(JPA之前),我们使用iBatis作为ORM工具(现在称为Mybatis)。我仍然是它的忠实粉丝,因为你在编写SQL方面有很大的灵活性。您可以真正优化您的查询,特别是如果您想要决定执行连接的顺序。所有SQL语句和映射(POJO的列,反之亦然)都在XML文件中完成。在当前版本中,也可以使用我认为与JPA一样的注释。