一、场景
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、模型类:
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 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
package cn.javass.framework.hibernate;
public class JsonList<T> extends ArrayList implements Cloneable {
}
就这么简单,欢迎大家讨论。
订单Model属于公司机密,不方便附上,其他两个类请附件下载(JsonType和JsonList的源代码)。
有人说有性能问题,我写了个测试用例:
测试机器: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条)。
附件中的 performance.rar是测试用例,欢迎测试拍砖。。
下载地址:performance.rar
hibernate.rar
///////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////新场景补充///////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
购物车持久化:
1、用户没有登录:存储到cookie中
2、用户登录后: 存储到数据库中
分析:
购物车是用户绑定的,一个用户一个
购物车最多只允许存50个(因为cookie大小有限)
实现:
1、关联表:购物车-----购物车明细,又是典型一对多,,需要频繁操作关联表
2、JSON:只要一张购物车表,用户数据通过JSON存数据库(如 [{productUuid:1, number:2}, {productUuid:2, number:2}])
使用JSON方式效率肯定是最高的,虽然有转换过程但是在内存中,比读写磁盘肯定快的多。看上边的测试用例。这种方式的好处不需要单独的关联表,省了一张表,何乐而不为。
分享到:
相关推荐
标题中的“hibernate存取json数据的代码分析”指的是在Java开发中,使用Hibernate框架来存储和检索JSON格式的数据。Hibernate是一个强大的ORM(对象关系映射)框架,它允许开发者将Java对象直接映射到数据库表,但在...
1.1 Hibernate存取JSON数据(换一种思路来存取数据) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Hibernate 关系映射 总结整理 . . . . . . . . . . . . . . . . . . . . ...
1.1 Hibernate存取JSON数据(换一种思路来存取数据) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Hibernate 关系映射 总结整理 . . . . . . . . . . . . . . . . . . . . ...
1. **Hibernate存取JSON数据(换一种思路来存取数据)** 在某些场景下,如订单系统中存储优惠信息,这些信息可能是只读且不需频繁变更的文本数据。传统的做法可能涉及创建关联表,但这可能导致不必要的复杂性。一个...
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在Ajax请求中,JSON常用于传输数据: 1. **数据交换**:在服务器端,数据通常被转换为JSON格式发送...
在本项目中,我们主要探讨的是使用Hibernate框架来开发一个租房系统。Hibernate是一个强大的Java对象关系映射(ORM)框架,它简化了数据库操作,使开发者可以更专注于业务逻辑而不是繁琐的数据访问层代码。结合Ajax...
在级联操作中,Hibernate可能被用来处理省市县和年月日的数据存取,通过HQL(Hibernate Query Language)或者Criteria API来执行SQL查询,获取级联选择的数据。 级联操作的核心在于数据间的关联,例如选择一个省后...
电影后台管理系统是一个典型的Web应用程序,它使用了Spring、Struts2和Hibernate这三大框架,以及前端的EasyUI组件库来实现高效、稳定的管理功能。这个系统没有采用Maven作为项目构建工具,而是采取了传统的手动依赖...
在IT行业中,数据库操作是应用程序开发的核心部分,而DAO(Data Access Object)模式是一种常见的用于封装数据访问逻辑的设计模式。本篇文章将详细讲解如何将HTTP请求中的数据映射到封装的DAO层,以便高效地处理数据...
Struts、Spring和Hibernate是Java开发中非常重要的三个框架,它们各自解决了一部分软件开发中的问题,而将它们结合使用可以构建出强大的企业级应用。MySQL则是常用的开源关系型数据库,常常与这些框架搭配使用。 ...
Java 数据集工具是Java编程中不可或缺的一部分,它们主要用于数据处理、存储和分析。在Java中,数据集通常指的是集合框架,包括ArrayList、LinkedList、HashSet、HashMap等类,以及相关的接口和工具类。这些工具帮助...
在本实例中,Hibernate负责将Java类与数据库表进行映射,使得数据的存取变得更加简洁。通过配置Hibernate的XML映射文件,可以定义实体类与数据库表的关系,以及它们之间的关联。此外,Hibernate还提供了Session接口...
通过这个SSH小项目,学习者可以了解到如何整合这三个框架来构建一个完整的Web应用,涉及的技术点包括但不限于:Struts的Action配置、Spring的Bean管理、Hibernate的实体映射、JSON数据的处理以及项目开发的流程和...
映射模式,是一种在软件设计中常见的编程模式,特别是在数据处理和对象关系映射(ORM)领域。这种模式主要用于将复杂的数据结构或者对象与简单的数据存储格式之间建立联系,以便于数据的存取和转换。在本文中,我们...
通过配置文件和注解,Hibernate可以将Java类自动映射到数据库表,使得开发者无需关注SQL语句,只需操作对象即可完成数据存取。它的主要功能包括:持久化对象、级联操作、事务管理、缓存机制等。Hibernate还提供了...
对于简单的数据类型,可以直接使用JDBC操作SQL来存取。 另外,Java提供了一种叫做序列化(Serialization)的机制,允许对象的状态被转换为字节流,然后保存到磁盘或通过网络传输。要实现序列化,类必须实现...
2. **后端开发**:使用Hibernate来操作数据库,创建对应的实体类和映射文件,以便于存取树结构数据。同时,编写Struts Action,处理Ajax请求,根据需求动态生成树的JSON数据。 3. **前端展示**:在HTML页面中,引入...
Hibernate jar 包通常包含框架的核心库和其他依赖,使得开发者能够轻松地集成Hibernate到他们的项目中,进行数据的存取操作。在家教网项目中,Hibernate 可能用于管理教师、学生、课程等实体对象的生命周期,提供...