`
jinnianshilongnian
  • 浏览: 21504040 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2418678
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3008775
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5639489
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:259916
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597314
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250217
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5858950
Group-logo
跟我学Nginx+Lua开...
浏览量:702003
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785224
社区版块
存档分类
最新评论

Hibernate自定义类型 对象--->序列化为字符串 存储

 
阅读更多

在有些时候 我们可能序列化存储对象为字符串形式,比如会话序列化存储到数据库。(当然数据量小没问题 大了还是存如memcached这种缓存中)。

 

具体代码:

/**
 * Copyright (c) 2005-2012 https://github.com/zhangkaitao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.sishuok.es.common.repository.hibernate.type;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import org.apache.commons.codec.binary.Hex;
import org.apache.shiro.web.util.SavedRequest;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

import java.io.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;

/**
 * Object序列化/反序列化
 * 数据库中以hex字符串存储
 * 参考http://jinnianshilongnian.iteye.com/blog/1497791
 * <p>User: Zhang Kaitao
 * <p>Date: 13-3-20 下午4:46
 * <p>Version: 1.0
 */
public class ObjectSerializeUserType implements UserType, Serializable {

    @Override
    public int[] sqlTypes() {
        return new int[] {Types.VARCHAR};
    }

    @Override
    public Class returnedClass() {
        return Object.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 names
     * @param owner
     * @return
     * @throws HibernateException
     * @throws SQLException
     */
    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
        ObjectInputStream ois = null;
        try {
            String hexStr = rs.getString(names[0]);
            ois = new ObjectInputStream(new ByteArrayInputStream(Hex.decodeHex(hexStr.toCharArray())));
            return ois.readObject();
        } catch (Exception e) {
            throw new HibernateException(e);
        } finally {
            try {
                ois.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * 本方法将在Hibernate进行数据保存时被调用
     * 我们可以通过PreparedStateme将自定义数据写入到对应的数据库表字段
     */
    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
        ObjectOutputStream oos = null;
        if(value == null) {
            st.setNull(index, Types.VARCHAR);
        } else {
            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(bos);
                oos.writeObject(value);
                oos.close();

                byte[] objectBytes = bos.toByteArray();
                String hexStr = Hex.encodeHexString(objectBytes);

                st.setString(index, hexStr);
            } catch (Exception e) {
                throw new HibernateException(e);
            } finally {
                try {
                    oos.close();
                } catch (IOException e) {
                }
            }
        }
    }



    /**
     * 提供自定义类型的完全复制方法
     * 本方法将用构造返回对象
     * 当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;
        return o;
    }

    /**
     * 本类型实例是否可变
     * @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;
    }

}

 

1、deepCopy 直接返回我们的对象  因为我们修改会话后会直接update下 所以此处没必要复制

2、Hex.encodeHexString 我们把数据保存成16进制形式

 

使用代码:

    @Type(type = "com.sishuok.es.common.repository.hibernate.type.ObjectSerializeUserType")
    private OnlineSession session;

 

 github

0
2
分享到:
评论
1 楼 2006204shao 2013-10-08  
                

相关推荐

    张开涛 hibernate杂谈

    1.4 Hibernate自定义类型 对象---&gt;序列化为字符串 存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 1.5 Hibernate自定义类型 集合---&gt;字符串 存储 . . . . . . . . . . . . . . ....

    hibernate杂谈

    序列化为字符串 存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .48 1.5 Hibernate自定义类型 集合---&gt;字符串 存储 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....

    hibernate 杂谈

    当需要将对象序列化为字符串存储时,可以创建一个自定义的Hibernate类型,如示例中的`JsonType`。这个类型实现了`UserType`接口,将对象转换成JSON字符串存储在数据库中,然后在需要时反序列化回对象。这种方法适用...

    hibernate-json:Json 用户类型Hibernate

    在`nullSafeSet()`方法中,将Java对象序列化为JSON字符串,然后设置到PreparedStatement中。 4. **注册UserType**:在Hibernate配置文件中,你需要为使用自定义JSON类型的属性指定这个UserType。这通常通过在实体类...

    json-lib-2.3-jdk15基础jar包合辑

    - **数据存储**:在持久化框架如Hibernate中,JSON Lib可以用于将Java对象转换成JSON字符串,方便存储到数据库的JSON字段。 - **前端交互**:后端开发中,通过JSON格式与前端JavaScript进行数据交互,JSON Lib简化了...

    google-gson-2.2.1

    GSON库的核心功能在于它能将Java对象序列化为JSON字符串,以及将JSON字符串反序列化为等效的Java对象。这对于开发者来说,极大地简化了数据存储、网络传输和API交互的过程。在2.2.1这个版本中,GSON已经相当成熟且...

    J-JSon:用于 JSON 序列化反序列化的 Java 库

    例如,将一个Java对象序列化为JSON字符串,只需调用`toJson()`方法;反之,将JSON字符串反序列化为Java对象,则使用`fromJson()`方法。 2. **类型安全**:J-JSon库支持泛型,这意味着在反序列化时可以保留原始数据...

    Xstream 相关jar包

    Xstream是一款轻量级、高性能的Java库,用于将Java对象序列化为XML,反之亦然。这个库因其简单易用的API和高度灵活性而受到许多开发者青睐。在Java应用程序中,特别是在处理网络数据交换或者持久化对象时,Xstream...

    xstream-1.4-API

    XStream 是一个强大的 Java 库,它的主要功能是将 Java 对象序列化为 XML,并能够从 XML 数据中反序列化回原来的对象。这个库的设计目标是提供简单易用的 API,同时保持高性能和安全性。在 XStream 1.4 版本中,它...

    json-lib.rar 完整的,经测试了

    JSON库如`json-lib`则提供了将Java对象转换为JSON格式和从JSON字符串反序列化为Java对象的功能,这对于Java开发者来说是极其重要的工具。 `json-lib`是一个Java库,它提供了一种简单的方式来处理JSON格式的数据。这...

    Jackson 框架

    Jackson框架的核心功能在于它能够将Java对象序列化为JSON格式的字符串,同时也能够将JSON字符串反序列化为Java对象。这对于数据交换、存储或传输非常有用。例如,当你需要将一个Java对象发送到服务器或者从服务器...

    json相关包

    1. **序列化(Serialization)** - 将Java对象转换为JSON字符串,方便在网络间传输或存储。 2. **反序列化(Deserialization)** - 将JSON文本解析为Java对象,便于在Java程序中使用。 3. **支持复杂类型** - 包括...

    XStream完整jar

    通常,这样的示例会创建一个Java对象,然后使用XStream的`toXML()`方法将其转换为XML字符串,接着再用`fromXML()`方法从XML字符串恢复原始对象。 6. **集成性**:XStream与其他Java框架如Spring、Hibernate等有很好...

    JAVA自学指南.docx

    - **序列化**: 通过实现`Serializable`接口可以使对象被序列化为字节流,方便在网络中传输或持久化到磁盘。 #### 三、Java高级应用 **3.1 Java高级特性** - **泛型**: 提供了类型安全的集合类和容器,避免了强制...

    jackson2.6 (3个包)

    例如,你可以创建一个`ObjectMapper`实例,然后使用`writeValueAsString()`方法将Java对象转化为JSON字符串,或者使用`readValue()`方法将JSON字符串转化为指定类型的Java对象。 2. **注解支持** Jackson 2.6引入...

    xml的一个解析工具castor

    它提供了一种简单的方法来将复杂的XML文档映射为Java对象,并且能够反向操作,将Java对象序列化为XML格式。这个工具在处理XML数据时极大地简化了开发流程,尤其在需要频繁进行XML与Java对象之间转换的场景下,比如...

    json所需的所有jar包

    2. **生成JSON**: 反之,也可以将Java对象序列化为JSON格式的字符串,方便在网络上传输或者存储。 3. **多框架支持**: json-lib支持多种Java框架,如Spring、Hibernate、Struts等,使得在这些框架下处理JSON更加便捷...

    springmvc 增删改查 上传文件 登陆

    反之,也可以将JSON字符串反序列化为Java对象。 总结来说,这个项目涉及了Spring MVC的基本使用,包括数据操作、用户认证与授权、文件上传和JSON数据交互,这些都是构建Web应用的常见场景。通过学习和实践这些知识...

    SQLBlox-开源

    SQLBlox的独特之处在于它允许将实例信息序列化为SQL语句,这意味着开发者可以更加灵活地管理和操作数据。 在Java开发中,数据库交互通常是通过ORM(对象关系映射)框架来实现的,如Hibernate或MyBatis。然而,...

Global site tag (gtag.js) - Google Analytics