序列化存取数据库(spring+mybatis+oracle) 以及可能会遇到的数据库取出的数据反序列化失败问题

1.需要序列化的类需要实现Serializable方法

例如下面需要序列化的类
 1 import java.io.Serializable;
 2 
 3 public class Topic implements Serializable{
 4     private static final long serialVersionUID = 1L;
 5     private Integer id;
 6     private String topic;
 7    private byte[] messageData;      
 8 
 9    public byte[] getMessageData(){
10       return messageData;
11   }
12   public void setMessageData(String messageData){           //其中messageData是在数据库中以CLOB字段存储的,将类序列化后存入二进制数组
13        this.messageData = HexTool.decode(messageData);  
      //将数据库中取出的CLOB数据类型,实则为二进制数组字符串String进行解码(十六进制字符串-->byte[]) 否则mybatis取出来的字符串无法反序列化!!!!!
14   } 15 public Integer getId() { 16 return id; 17 } 18 public void setId(Integer id) { 19 this.id = id; 20 } 21 public String getTopic() { 22 return topic; 23 } 24 public void setTopic(String topic) { 25 this.topic = topic; 26 } 27 @Override 28 public String toString() { 29 return "Topic [id=" + id + ", topic=" + topic + "]"; 30 } 31 public Topic(Integer id, String topic) { 32 super(); 33 this.id = id; 34 this.topic = topic; 35 } 36 public Topic() { 37 super(); 38 // TODO Auto-generated constructor stub 39 } 40 }

 

public class HexTool{

    //解码:十六进制字符串转换为byte[]
    public static byte[] decode(String hexString) {
        if((hexString.length()%2)!=0) {
            throw new IllegalArgumentException("A HexBinary string must have even length");
        }
        
        byte[] result = new byte[hexString.length()/2];
        int j = 0;
        for(int i=0;i<hexString.length();) {
            byte b;
            char c = hexString.charAt(i++);
            char d = hexString.charAt(i++);
            if(c > = '0' && c<='9') {
                b = (byte)((c - '0') << 4);
            }else if(c > = 'A' && c <= 'F') {
                b=(byte)((c-'A'+10)<<4);
            }else if(c >= 'a' && c<='f') {
                b=(byte)((c-'a'+10)<<4);
            }else {
                throw new IllegalArgumentException("Invalid hex digit:" + c);
            }
            result[j++] = b;
        }
        return result;
    }
}

 

 

 

 1 public class MessageData {
 2 
 3     private String destinationChannel;
 4     
 5     private String messageId;
 6     
 7     private Date absTime;
 8 
 9     public String getDestinationChannel() {
10         return destinationChannel;
11     }
12 
13     public void setDestinationChannel(String destinationChannel) {
14         this.destinationChannel = destinationChannel;
15     }
16 
17     public String getMessageId() {
18         return messageId;
19     }
20 
21     public void setMessageId(String messageId) {
22         this.messageId = messageId;
23     }
24 
25     public Date getAbsTime() {
26         return absTime;
27     }
28 
29     public void setAbsTime(Date absTime) {
30         this.absTime = absTime;
31     }
32 
33     @Override
34     public String toString() {
35         return "MessageData [destinationChannel=" + destinationChannel + ", messageId=" + messageId + ", absTime="
36                 + absTime + "]";
37     }
38     
39 }

 

  

2.将类序列化后写入二进制数组存入数据库,再取出来反序列化

   

 1 import java.io.ByteArrayInputStream;
 2 import java.io.ByteArrayOutputStream;
 3 import java.io.IOException;
 4 import java.io.ObjectInputStream;
 5 import java.io.ObjectOutputStream;
 6 
 7 
 8 @RunWith(SpringRunner.class)
 9 @SpringBootTest(classes=启动类.class)
10 public class SerializeTest {
11     
12     public static final String INSERTSTOREMESSAGE = "storefoward.intoresendmessage";
13     public static final String SELECTRESENDMESSAGE = "storefoward.selectresendmessage";
14     
15     @Test
16     public void serializeTest() throws IOException,ParseException,ApplicationNotFoundException,ClassNotFoundException{
17     
18         ByteArrayOutputStream bos = null;
19         ObjectOutputStream oos =null;
20         byte[] serializeTranslateMessage =null;
21         
22         MessageData message = MessageData();
23         
24         message.setDestinationChannel("ABC");
25         message.setmessageId("1433");
26         message.setabsTime("2019.04.01 10:57:34");
27         
//以下是将类序列化成二进制数组存入数据库 28 try { 29 oos = new ObjectOutputStream(bos=new ByteArrayOutputStream()); 30 oos.writeObject(message); 31 }finally { 32 serializeTranslateMessage = bos.toByteArray(); 33 try { 34 oos.close(); 35 bos.close(); 36 }catch(IOException e) { 37 e.printStackTrace(); 38 } 39 } 40 41 Map<String,Object> map = new HashMap<>; 42 43 map.put("id","1"); 44 map.put("topic","method1"); 45 map.put("messageData",serializeTranslateMessage) //其中messageData在数据库是以CLOB字段存储 46 try { 47 int result = DBUtil.insert(INSERTSTOREMESSAGE,map); 48 }catch(){ 49 e.printStackTrace(); 50 } 51 52 //以上是序列化Topic类并存入数据库的操作 53 54 //以下是从数据库中取出Topic并反序列化 55 56 List<Topic>queryTopicList = null ; 57 Map<String,Object> map2 = new HashMap<>; 58 59 map2.put("id","1"); 60 map2.put("topic","method1"); 61 try { 62 queryTopicList = DBUtil.selectList(SELECTRESENDMESSAGE,map2); 63 }catch(Exception e) { 64 e.printStackTrace(); 65 } 66 67 ObjectInputStream ois = null; 68 ByteArrayInputStream bas = null; 69 for(int j=0;j<queryTopicList.size();j++) { 70 Topic tmpMessage=queryTopicList.get(j); 71 try{ 72 ois = new ObjectInputStream(bas=new ByteArrayInputStream(tmpMessage.getMessageData())); 73 Topic deserializeMessage=(Topic)ois.readObject();    //将反序列化后的数据实例化为Topic类 74 }catch(IOException e) { 75 e.printStackTrace(); 76 try { 77 ois.close(); 78 bas.close(); 79 } 80 catch(IOException E) { 81 E.printStackTrace(); 82 } 83 } 84 85 } 86 87 } 88 }

 

3.mybatis中语句为

 1 <select id = "selectresendmessage" resultType="路径.Topic" parameterType = "java.util.Map">
 2     SELECT 
 3         ID,
 4         TOPIC,
 5         MESSAGEDATA
 6     FROM 
 7         STORE_MESSAGE
 8     WHERE
 9       ID = #{id}
10     AND
11       TOPIC = #{topic}
12 </select>
13 
14 <insert id = "intoresendmessage">
15     INSERT
16     INTO  STORE_MESSAGE
17     VALUES(#{id},#{topic},#{messageData}
18             )
19 </insert>

 

posted @ 2020-04-01 20:12  xajh00789  阅读(811)  评论(0编辑  收藏  举报