在Oracle中我有一个分区表。分区大小不同,数据分布不同。
我想让hibernate发出SQL语句,其中包含分区键列的文字值而不是绑定变量。当然,它应该对任何其他值使用绑定变量。
使用分区键的文字将允许Oracle提供特定于已知分区和收集的统计信息的计划。对于具有偏斜数据的直方图的列,这可能也很有用。
最好在实体中指定它,否则我们将需要在每个查询中执行此操作。有没有办法在休眠中执行此操作?
我们正在使用Oracle 10g方言进行hibernate 3.6.1。
如果没有办法在Hibernate中本地执行此操作,我可以创建用户类型或方言或其他内容来实现这一目标吗?
答案 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
的值来计算执行计划,因此它可能会产生干扰。但我认为至少值得一试。