使用自定义对象属性序列化java类

时间:2013-07-26 15:36:49

标签: java mysql serialization ebean

我想使用Ebean ORM在我的MySQL数据库上序列化一个Java类。

我的课程定义类似于以下内容:

public class Test implements Serializable
{
    @Id
    private Long id;
    ...
    ...
    ...
    @Lob
    private MyClass1 obj1;
    @Lob
    private MyClass2 obj2;
    ...
    ...
    //getters and setters
}

我的类MyClass1和MyClass2基本上是

的包装器
float[] 

Hashmap<String, Float> 

并且都实现了Serializable接口。

我不想创建一个类:

@Lob
byte[] obj1bytes;
@Transient
MyClass1 obj1Obj;
@Lob
byte[] obj2bytes;
@Transient
MyClass2 obj2Obj;
//getters and setters

我想要获得的是自动序列化和反序列化此类,而不必使用byte []数组将我的Test类中的obj1和obj2保存到两个LongBlob字段中的MySQL表中

Ebean.save(testClassInstance);
Ebean.find(Test.class, ID);

EDIT1:MyClass1定义如下:

public class MyClass1 implements Interface1 {
    private float[] vector;
    public MyClass1 () {
    }
    public MyClass1 (float[] vector) {
        this.vector = vector;
    }
    public float[] getVector() {
        return vector;
    }
    public void setVector(float[] vector) {
       this.vector = vector;
    }
    @Override
    public byte[] serialize() throws Exception {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(object);
        out.close();            
        return byteOut.toByteArray();
    }
    @Override
    public void deserialize(byte[] bytes) throws Exception {
        ByteArrayInputStream byteInt = new ByteArrayInputStream(bytes);
        ObjectInputStream out = new ObjectInputStream(byteInt);
        vector = (float[])out.readObject();
    }
    @Override
    public float cossim(MyClass1 v) throws Exception {
        method logic
    }
    @Override
    public MyClass1 add(MyClass1 v) throws Exception {
        method logic
   }
}

MyClass2被定义为MyClass1,只有而不是float [] vector我有一个HashMap&lt; String,Float&gt; ()。唯一值得注意的差异是serialize()和deserialize():

@Override
public byte[] serialize() throws Exception {
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    DataOutputStream out = new DataOutputStream(outStream);
    out.writeInt(map.size());
    Iterator<String> iterator = map.keySet().iterator();
    while (iterator.hasNext()) {
        String key = iterator.next();
        out.writeUTF(key);
        out.writeFloat(map.get(key));
    }
    return outStream.toByteArray();
}

@Override
public void deserialize(byte[] bytes) throws Exception {
    try {
      ByteArrayInputStream inStream = new ByteArrayInputStream(bytes);
      DataInputStream in = new DataInputStream(inStream);
      this.map = new HashMap<>();
      int n = in.readInt();
      for (int i = 0; i < n; i++) {
        map.put(in.readUTF(), in.readFloat());
      }
    } catch (Exception ex) {
      throw ex;
    }
}

2 个答案:

答案 0 :(得分:0)

实际上没有必要包装float[]HashMap<String,float>,因为它们本身是可序列化的。

另一件事是,如果MyClass1MyClass2可序列化,则可以使用@Lob。根据{{​​3}},

  

默认情况下,JPA中的任何Serializable属性都不是   关系或基本类型(字符串,数字,时间,原语),   将被序列化为BLOB字段。

在该wikibook中,还有一个使用@Lob作为课程Image的示例。

@Entity
public class Employee {
    ...
    @Basic(fetch=FetchType.LAZY)
    @Lob
    private Image picture;
    ...
}

希望这对你有所帮助。

答案 1 :(得分:0)

我回复后做了一些编码。

条件:ClassB的字段应该是可序列化的,字段的字段应该是可序列化的......

ClassB的:

import java.io.Serializable;

public class ClassB implements Serializable{
    private static final long serialVersionUID = 1L;
    String b;

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }

}

ClassA的:

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;

@Entity
public class ClassA implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    String a;
    @Lob
    ClassB b;

    public String getA() {
        return a;
    }
    public void setA(String a) {
        this.a = a;
    }
    public ClassB getB() {
        return b;
    }
    public void setB(ClassB b) {
        this.b = b;
    }

}

这里,ClassA包含ClassB对象。您可以在ClassB中添加任何逻辑,它可以工作。我对覆盖序列化和反序列化的问题很小。我想你不需要这样做。它将在序列化时默认完成。最后,这些代码确实可以正常运行。

希望这会对你有所帮助。