当我的项目中没有任何实体时,如何将原生查询映射到POJO?

时间:2015-06-02 11:58:04

标签: java mysql hibernate jpa

我正在将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"/>

3 个答案:

答案 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一样的注释。

更多信息:http://mybatis.github.io/mybatis-3/