一、场景
public class OrderModel { private ListfavorableDescList; }
订单中会存储一些优惠信息,方便页面展示时使用,如:
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 ListfavorableDescList; }
①处使用我们自定义的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 JsonListextends 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条)。
忍者必须死34399账号登录版 最新版v1.0.138v2.0.72
下载勇者秘境oppo版 安卓版v1.0.5
下载忍者必须死3一加版 最新版v1.0.138v2.0.72
下载绝世仙王官方正版 最新安卓版v1.0.49
下载Goat Simulator 3手机版 安卓版v1.0.8.2
Goat Simulator 3手机版是一个非常有趣的模拟游
Goat Simulator 3国际服 安卓版v1.0.8.2
Goat Simulator 3国际版是一个非常有趣的山羊模
烟花燃放模拟器中文版 2025最新版v1.0
烟花燃放模拟器是款仿真的烟花绽放模拟器类型单机小游戏,全方位
我的世界动漫世界 手机版v友y整合
我的世界动漫世界模组整合包是一款加入了动漫元素的素材整合包,
我的世界贝爷生存整合包 最新版v隔壁老王
我的世界MITE贝爷生存整合包是一款根据原版MC制作的魔改整