hibernate存取json数据的代码分析
作者:动力节点 发布时间:2022-01-18 15:00:08
一、场景
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数据的代码分析网站的支持!
来源:http://blog.sina.com.cn/s/blog_9c6852670102wvqd.html


猜你喜欢
- JAVA是面向对象的语言,开发者在操作数据的时候,通常更习惯面对一个特定类型的对象,如一个用户就是一个User类的对象。DAO层需要做的,就
- Java常用API介绍API概念什么是API?API(Application Programming interface) 应用程序编程接口
- 简介Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩
- 最近在机顶盒上做一个gridview,其焦点需要在item的子控件上,但gridview的焦点默认在item上,通过android:desc
- 一、什么是JMSJMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(M
- 一:日志:1、配置日志级别日志记录器(Logger)的行为是分等级的。如下表所示:分为:OFF、FATAL、ERROR、WARN、INFO、
- 在之前讨论 ListView 滚动相关需求的文章中(UWP: ListView 中与滚动有关的两个需求的实现)曾经提到了获取元素相对位置的方
- IO感觉上和多线程并没有多大关系,但是NIO改变了线程在应用层面使用的方式,也解决了一些实际的困难。而AIO是异步IO和前面的系列也有点关系
- 本文实例为大家分享了Android利用Canvas类绘制图形的具体代码,供大家参考,具体内容如下首先介绍一下相关基础知识。1.画笔(pain
- 在学习集合框架的时候,初学者很容易练习到学生管理系统、雇员管理体统等练习题。在学习集合框架之前,基本上Java基本语法都学完了,集合框架也从
- 本文实例讲述了C#简单聊天程序实现方法。分享给大家供大家参考。具体如下:假如有服务器端程序,ChatServer和客户端程序ChatClie
- java Long类型转为String类型1、Long.ValueOf("String")返回Long包装类型数据包装类
- 折半插入排序折半插入排序是对直接插入排序的简单改进。此处介绍的折半插入,其实就是通过不断地折半来快速确定第i个元素的插入位置,这实际上是一种
- Spring security记住我基本原理:登录的时候,请求发送给过滤器UsernamePasswordAuthenticationFil
- 本文实例为大家分享了Android仿微信长按录制视频并播放功能的具体代码,供大家参考,具体内容如下一、点击按钮进行录制首先要获取摄像拍照的权
- Spring Boot读取yml文件的主要方式有以下几种:1.@Value注解? 我们可以在bean的属性上使用@Value注解,直接读取y
- Android 使用FragmentTabhost代替Tabhost前言:现在Fragment使用越来越广了,虽然Fragment寄生在Ac
- merge标签合并标记需要两个或两个以上的列表作为参数,并把它们合并在一起,如下所示:<s:merge var="myMer
- 我们使用控件AutoCompleteTextView 自动提示时,有时需要设置BaseAdapter,设置BaseAdapter时,需要实现
- 从Handler.post()说起Handler.post()是用来发送消息的,我们看下Handler源码的处理:public final