hibernate存取json数据的代码分析
一、场景 public class OrderModel { private List<String> favorableDescList; } 订单中会存储一些优惠信息,方便页面展示时使用,如: 1、满100减50 2、参与【老会员真情回馈――精品课程体验活动】,仅需支付200.00学币 3、【Oracle + PL/SQL 实战】套装课程的【抢购】活动,优惠120.00学币 如图所示,我们在页面给用户展示他们参与的优惠信息: 二、分析 如上优惠信息有如下特点: 1、只用于展示,不会涉及修改; 2、一旦订单支付成功,不会再改变; 3、数据量不会很大。 三、解决方案 1、最简单的解决方案是关联表: 但这种解决方案需要连表进行查询,感觉是没有必要的,毕竟只是展示数据,用关联表有点杀鸡用牛刀的感觉。 2、JSON解决方案: 通过如上思路我们可以解决许多类似的问题。 3、代码示例: 1、模型类: Java代码 public class OrderModel { @Type(type = "com.bjpowernode.framework.hibernate.type.JsonType") //① private List<String> favorableDescList; } ①处使用我们自定义的Hibernate类型来进行转换,上边代码只有一部分 2、自定义JsonType Java代码 package com.bjpowernode.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 preparedStatement * @param value * @param i * @throws HibernateException * @throws SQLException */ @Override public void nullSafeSet(PreparedStatement preparedStatement,Object value,int i) throws HibernateException,SQLException { if(value == null) { preparedStatement.setNull(i,Hibernate.STRING.sqlType()); } else { preparedStatement.setString(i,JSONArray.fromObject(value).toString()); } } /** * 提供自定义类型的完全复制方法 * 本方法将用构造返回对象 * 当nullSafeGet方法调用之后,我们获得了自定义数据对象,在向用户返回自定义数据之前, * deepCopy方法将被调用,它将根据自定义数据对象构造一个完全拷贝,并将此拷贝返回给用户 * 此时我们就得到了自定义数据对象的两个版本,第一个是从数据库读出的原始版本,其二是我们通过 * deepCopy方法构造的复制版本,原始的版本将有Hibernate维护,复制版由用户使用。原始版本用作 * 稍后的脏数据检查依据;Hibernate将在脏数据检查过程中将两个版本的数据进行对比(通过调用 * equals方法),如果数据发生了变化(equals方法返回false),则执行对应的持久化操作 * * @param o * @return * @throws HibernateException */ @Override public Object deepCopy(Object o) throws HibernateException { if(o == null) return null; JsonList jsonList = new JsonList(); jsonList.addAll((List)o); return jsonList; } /** * 本类型实例是否可变 * @return */ @Override public boolean isMutable() { return true; } /* 序列化 */ @Override public Serializable disassemble(Object value) throws HibernateException { return ((Serializable)value); } /* 反序列化 */ @Override public Object assemble(Serializable cached,Object owner) throws HibernateException { return cached; } @Override public Object replace(Object original,Object target,Object owner) throws HibernateException { return original; } } JSON框架使用的是json-lib 2.1。 3、自定义JsonList Java代码 package com.bjpowernode.framework.hibernate; public class JsonList<T> extends ArrayList implements Cloneable { } 就这么简单,欢迎大家讨论。 有人说有性能问题,我写了个测试用例: 测试机器:CPU:p8700(双核@2.53GHZ) 内存:2G 一、插入 1、JSON方式插入10w条 create 100000 elapsed time(millis):21031 2、关联表插入10w条 create 100000 elapsed time(millis):79219 JSON性能远远好于关联表,关联表要插入两个表。 二、查询 1、JSON方式分页(100条一页)查询10w条 select 100000 elapsed time(millis):146047 2、关联表分页(100条一页)查询10w条 select 100000 elapsed time(millis):275375 JSON性能远远好于关联表,关联表需要join连表查询。 JSON方式的缺点:分析统计等查询是鸡肋、大数据量是鸡肋(一列存储数据量不可能太大)。 我的应用场景:优惠信息、购物车持久化(每个用户购物车最多50条)。 总结 以上所述是小编给大家介绍的hibernate存取json数据的代码分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |