日期:2014-05-16  浏览次数:20318 次

Hibernate存取JSON数据(换一种思路来存取数据)

?


一、场景

public class OrderModel {

private List<String> favorableDescList;

}

?

订单中会存储一些优惠信息,方便页面展示时使用,如:

1、满10050

2、参与【老会员真情回馈——精品课程体验活动】,仅需支付200.00学币

3、【Oracle + PL/SQL?实战】套装课程的【抢购】活动,优惠120.00学币

……等等

?

如图所示,我们在页面给用户展示他们参与的优惠信息:


二、分析

如上优惠信息有如下特点:

1、只用于展示,不会涉及修改;

2、一旦订单支付成功,不会再改变;

3、数据量不会很大。

三、解决方案

1、最简单的解决方案是关联表:


?但这种解决方案需要连表进行查询,感觉是没有必要的,毕竟只是展示数据,用关联表有点杀鸡用牛刀的感觉。

?

?

2JSON解决方案:

?

通过如上思路我们可以解决许多类似的问题。

?

?

3、代码示例:

?

1、模型类:

public class OrderModel {
    @Type(type = "cn.javass.framework.hibernate.type.JsonType")  //①
    private List<String> favorableDescList;
}

?①处使用我们自定义的Hibernate类型来进行转换,上边代码只有一部分

?

2、自定义JsonType

package cn.javass.framework.hibernate.type;
//省略import
public class JsonType implements UserType, Serializable {
    private String json;
    @Override
    public int[] sqlTypes() {
        return new int[] {Hibernate.STRING.sqlType()};
    }
    @Override
    public Class returnedClass() {
        return JsonList.class;
    }
    @Override
    public boolean equals(Object o, Object o1) throws HibernateException {
        if (o == o1) {
            return true;
        }
        if (o == null || o == null) {
            return false;
        }

        return o.equals(o1);
    }

    @Override
    public int hashCode(Object o) throws HibernateException {
        return o.hashCode();
    }


    /**
  * 从JDBC ResultSet读取数据,将其转换为自定义类型后返回
  * (此方法要求对克能出现null值进行处理)
  * names中包含了当前自定义类型的映射字段名称
  * @param resultSet
  * @param names
  * @param owner
  * @return
  * @throws HibernateException
  * @throws SQLException
  */
    @Override
    public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
        String json = resultSet.getString(names[0]);
        if(json == null || json.trim().length() == 0) {
            return new JsonList();
        }
        return JSONArray.toList(JSONArray.fromObject(json), JsonList.class);
    }

     /**
  * 本方法将在Hibernate进行数据保存时被调用
  * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段
  * @param p