有没有办法让Hibernate使用文字值而不是绑定变量?

时间:2011-11-23 23:49:21

标签: oracle hibernate database-partitioning

在Oracle中我有一个分区表。分区大小不同,数据分布不同。

我想让hibernate发出SQL语句,其中包含分区键列的文字值而不是绑定变量。当然,它应该对任何其他值使用绑定变量。

使用分区键的文字将允许Oracle提供特定于已知分区和收集的统计信息的计划。对于具有偏斜数据的直方图的列,这可能也很有用。

最好在实体中指定它,否则我们将需要在每个查询中执行此操作。有没有办法在休眠中执行此操作?

我们正在使用Oracle 10g方言进行hibernate 3.6.1。

如果没有办法在Hibernate中本地执行此操作,我可以创建用户类型或方言或其他内容来实现这一目标吗?

3 个答案:

答案 0 :(得分:1)

不,Hibernate不支持文字值。我怀疑你是否可以解决方法,但我想你正在寻找另一种解决方案。

答案 1 :(得分:1)

您可以使用namedNativeQuery 这是一个示例实现。

实体类是

@Entity
@Table(catalog = DBCatalog)
@org.hibernate.annotations.NamedNativeQuery(name="partitionTR1",query ="SELECT * FROM DATAMARTTRANSACTIONHISTORY PARTITION (tr1) where id=?",resultClass=DataMartTable.class)
public class DataMartTransactionHistory implements TransactionHistory {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Enumerated(EnumType.ORDINAL)
    private TransactionStatus transactionStatus;
... other props...
}

这是一个dao实现。

public DataMartTransactionHistory findDataMartTransactionHistoryTR1(Long id) {
    Query namedQuery = getSessionFactory().getCurrentSession().getNamedQuery("partitionTR1");
    namedQuery.setLong(0, id);
    return (DataMartTransactionHistory)namedQuery.list().get(0);
}

答案 2 :(得分:0)

作为一种解决方法,您可以在每个“有趣”的调用站点设置一个唯一的注释,这样您就可以控制Oracle的绑定变量偷看。

...
query = session.createQuery("...");
...
query.setString("param1", "FOO");
query.setInteger("param2", param2Value);
...
query.setComment("param1 = \"FOO\"");
...

通过这种方式,优化器将在硬解析时看到"FOO"(像往常一样)。在将来的调用中,Oracle将搜索SQL的精确副本以重用执行计划。由于评论使查询有效,因此这将为您提供使用"FOO"计算的相同执行计划,而不是param1的任何其他值。

您必须小心,因为优化器还将使用param2Value的值来计算执行计划,因此它可能会产生干扰。但我认为至少值得一试。