Hibernate 中<Property>中的formula属性的使用

原创
2014/02/28 16:19
阅读数 4.5K

Hibernate 中 formula属性的好用处在于 无需在数据库有真实的列 只需要写出sql 就可以创建一个虚拟的列 然后在 Dao层的查询中使用 ,比如在表 M_Confirmation 中有两列 Confirmation_Cost Confirmation_Fee 这两列都容许包含null, 我们的query要求取得 Confirmation_Cost 和 Confirmation_Fee的和(暂时命名为Total_Price) 并查出此Total_Price>= 某个前台传进来的某个filter的数据 。

写成sql 就是 select (confirmation_cost + confirmation+fee) from m_confirmation where (confirmation_cost + confirmation+fee) >= ? ;

这时候创建虚拟列 ,formula后面的部分 会自动跟在hibernate发出的sql中 select后面作为一列 就好比 select formula from M_confirmation:

<property name="totalPrice" formula="((CASE WHEN Confirmation_Cost IS NULL THEN 0 ELSE Confirmation_Cost END) + (CASE WHEN Confirmation_Fee IS NULL THEN 0 ELSE Confirmation_Fee END))" />

注意:数据库中任何数+null都是null,所以必须用case when处理, 不能 用 nvl因为 nvl只能用于oracle 不符合hibernate移植到任何数据库的思想。

然后在 持久化对象中 写好对应的 totalPrice 属相:

public class Confirmation extends ConfirmationBase implements BasicModel {
    private BigDecimal totalPrice;

    public BigDecimal getTotalPrice() {
        return totalPrice;
    }

    public void setTotalPrice(BigDecimal totalPrice) {
        this.totalPrice = totalPrice;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, TafToStringStyles.PERSISTENCE_TOSTRING_STYLE);
    }

这样 你就可以灵活使用数据库中任何列 排列组合成一些虚拟列 来做查询了:

        BigDecimal bpsPrice = filter.getBpsPrice();
        DetachedCriteria criteria = DetachedCriteria.forClass(Confirmation.class);
        if (bpsPrice != null) {
            criteria.add(Restrictions.ge("totalPrice", bpsPrice));
        }
        return getHibernateTemplate().findByCriteria(criteria);

这就是属性中 formula属性的用处,最后再提醒一下 formula=配置的内容会自动跟在发出的sql的 select后面作为一列 ,所以很多人 后面写出完整的 select 最后拼出的sql是错误的。这样工作中方便更加区分逻辑 加快代码可读性 对数据库列的数量也没有太多影响,

当然你也可以在 Criteria中直接写 如下:

    BigDecimal bpsPrice = filter.getBpsPrice();
        DetachedCriteria criteria = DetachedCriteria.forClass(Confirmation.class);
        if (bpsPrice != null) {
           criteria
            .add(Restrictions.sqlRestriction("((CASE WHEN Confirmation_Cost IS NULL THEN 0 ELSE Confirmation_Cost END) + (CASE WHEN Confirmation_Fee IS NULL THEN 0 ELSE Confirmation_Fee END)) >=") + bpsPrice );
        }
        return getHibernateTemplate().findByCriteria(criteria);

但是这样的写法严格的公司无法通过代码审核,因为不方便阅读 没有做到好的分层  假设新来的程序员如果改了表的列名而没有看到你写的这句会出现bug 一般这样写会被打回来从新改

如果你公司普遍使用Native sql 或者 HQL来做查询的标准 那这种formula配置就失去作用 没有用处了 完全可以用一些常量替代

展开阅读全文
打赏
0
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部