3

ネイティブ sql に次のようなクエリがあります。

SQLQuery query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee");

クエリ結果を使用して、従業員オブジェクトを設定できます。同様の行で、addscalar(entity_colname) が追加された同じクエリがあります。

query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee")
        .addScalar("emp_id", new LongType())
        .addScalar("emp_name", new StringType())
        .addScalar("emp_salary", new DoubleType());

ここでも同様の方法で結果を取得する必要がありますが、addscalar を使用する利点は何ですか?

よろしくジェイ

4

1 に答える 1

1

addScalar が不要な場合

あなたの例では、実際に使用する必要はありませんaddScalar

次のように、応答を DTO にマップする場合EmployeeDTO:

public class EmployeeDTO {
    private final Long id;
    private final String name;
    private final Double salary;

    public EmployeeDTO(Long id, String name, Double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Double getSalary() {
        return salary;
    }
}

次に、次の SQL クエリEmployeeDTOで問題なくフェッチできます。

List<EmployeeDTO> employeeDTOs = entityManager
.createNativeQuery(
    "SELECT " +
    "   emp_id AS id, " +
    "   emp_name AS name, " +
    "   emp_salary AS salary " +
    "FROM employee ")
.getResultList();

Hibernate が設定したい DTO プロパティと一致できるように、列エイリアスを使用したことに注意してください。

addScalar が必要な場合

BookJSONproperties属性を持つエンティティがあるとします。

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(typeClass = JsonNodeBinaryType.class, defaultForType = JsonNode.class)
public static class Book {

    @Id
    @GeneratedValue
    private Long id;

    @NaturalId
    private String isbn;

    @Column(columnDefinition = "jsonb")
    private JsonNode properties;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public JsonNode getProperties() {
        return properties;
    }

    public void setProperties(JsonNode properties) {
        this.properties = properties;
    }
}

は、オープンソース プロジェクトJsonNodeBinaryTypeによって提供されます。hibernate-types

propertiesここで、JSON列をフェッチしたネイティブ SQL クエリを実行すると、次のようになります。

JsonNode properties = (JsonNode) entityManager
.createNativeQuery(
    "SELECT properties " +
    "FROM book " +
    "WHERE isbn = :isbn")
.setParameter("isbn", "978-9730228236")
.getSingleResult();

Hibernate は次の例外をスローします。

org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

これは、Hibernate ネイティブの JSONがないため、Hibernate がjsonb列をJava オブジェクトに変換する方法を認識していないためです。JsonNodeType

しかしaddScalar、Hibernate を呼び出して提供すると、次のようになりTypeます。

JsonNode properties = (JsonNode) entityManager
.createNativeQuery(
    "SELECT properties " +
    "FROM book " +
    "WHERE isbn = :isbn")
.setParameter("isbn", "978-9730228236")
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("properties", JsonNodeBinaryType.INSTANCE)
.getSingleResult();

その後、クエリは問題なく実行されます。

于 2015-06-22T06:48:15.057 に答える