Java对数据库的字符串字段进行压缩保存

核心提示:数据字段一般都是保存原文的,一来方便在数据库修改和维护,而来有一些查询要用到它。但是在有些时候,我们无需保存原文了,比如在论坛,博客等数据里的内容字段,一般使用Clob类型,其很少参与搜索,而且就算要全文检索,我们也不推荐使用数据库的like 等,

    数据字段一般都是保存原文的,一来方便在数据库修改和维护,而来有一些查询要用到它。但是在有些时候,我们无需保存原文了,比如在论坛,博客等数据里的内容字段,一般使用Clob类型,其很少参与搜索,而且就算要全文检索,我们也不推荐使用数据库的like 等,而应该用第三方的全文检索工具,比如lucene等实现。

    这类数据都是大量的文本数据,有很大的可压缩性。由于一些原因,我的数据库已经超过我能容忍的大小了,所以想到了是否可以把这个数据压缩存储来节省空间,于是有了如下的尝试。

    压缩算法就先不过多考虑了,就用Zip进行尝试就可以了。先看看如何把字符串压缩和解压缩的算法。

  1. package com.laozizhu.article.util;      
  2. import java.io.ByteArrayInputStream;      
  3. import java.io.ByteArrayOutputStream;      
  4. import java.util.zip.GZIPInputStream;      
  5. import java.util.zip.GZIPOutputStream;      
  6. /**    
  7.  * 把字符串使用ZIP压缩和解压缩的代码。    
  8.  *     
  9.  * @author JAVA世纪网(java2000.net, laozizhu.com)    
  10.  */     
  11. public class StringZip {      
  12.   public static String zipString(String str) {      
  13.     try {      
  14.       ByteArrayOutputStream bos = null;      
  15.       GZIPOutputStream os = null;      
  16.       byte[] bs = null;      
  17.       try {      
  18.         bos = new ByteArrayOutputStream();      
  19.         os = new GZIPOutputStream(bos);      
  20.         os.write(str.getBytes());      
  21.         os.close();      
  22.         bos.close();      
  23.         bs = bos.toByteArray();      
  24.         return new String(bs, "iso-8859-1");      
  25.       } finally {      
  26.         bs = null;      
  27.         bos = null;      
  28.         os = null;      
  29.       }      
  30.     } catch (Exception ex) {      
  31.       return str;      
  32.     }      
  33.   }      
  34.   public static String unzipString(String str) {      
  35.     ByteArrayInputStream bis = null;      
  36.     ByteArrayOutputStream bos = null;      
  37.     GZIPInputStream is = null;      
  38.     byte[] buf = null;      
  39.     try {      
  40.       bis = new ByteArrayInputStream(str.getBytes("ISO-8859-1"));      
  41.       bos = new ByteArrayOutputStream();      
  42.       is = new GZIPInputStream(bis);      
  43.       buf = new byte[1024];      
  44.       int len;      
  45.       while ((len = is.read(buf)) != -1) {      
  46.         bos.write(buf, 0, len);      
  47.       }      
  48.       is.close();      
  49.       bis.close();      
  50.       bos.close();      
  51.       return new String(bos.toByteArray());      
  52.     } catch (Exception ex) {      
  53.       return str;      
  54.     } finally {      
  55.       bis = null;      
  56.       bos = null;      
  57.       is = null;      
  58.       buf = null;      
  59.     }      
  60.   }      
  61. }    

 

  1. package com.laozizhu.article.util;   
  2. import java.io.ByteArrayInputStream;   
  3. import java.io.ByteArrayOutputStream;   
  4. import java.util.zip.GZIPInputStream;   
  5. import java.util.zip.GZIPOutputStream;   
  6. /**  
  7.  * 把字符串使用ZIP压缩和解压缩的代码。  
  8.  *   
  9.  * @author JAVA世纪网(java2000.net, laozizhu.com)  
  10.  */  
  11. public class StringZip {   
  12.   public static String zipString(String str) {   
  13.     try {   
  14.       ByteArrayOutputStream bos = null;   
  15.       GZIPOutputStream os = null;   
  16.       byte[] bs = null;   
  17.       try {   
  18.         bos = new ByteArrayOutputStream();   
  19.         os = new GZIPOutputStream(bos);   
  20.         os.write(str.getBytes());   
  21.         os.close();   
  22.         bos.close();   
  23.         bs = bos.toByteArray();   
  24.         return new String(bs, "iso-8859-1");   
  25.       } finally {   
  26.         bs = null;   
  27.         bos = null;   
  28.         os = null;   
  29.       }   
  30.     } catch (Exception ex) {   
  31.       return str;   
  32.     }   
  33.   }   
  34.   public static String unzipString(String str) {   
  35.     ByteArrayInputStream bis = null;   
  36.     ByteArrayOutputStream bos = null;   
  37.     GZIPInputStream is = null;   
  38.     byte[] buf = null;   
  39.     try {   
  40.       bis = new ByteArrayInputStream(str.getBytes("ISO-8859-1"));   
  41.       bos = new ByteArrayOutputStream();   
  42.       is = new GZIPInputStream(bis);   
  43.       buf = new byte[1024];   
  44.       int len;   
  45.       while ((len = is.read(buf)) != -1) {   
  46.         bos.write(buf, 0, len);   
  47.       }   
  48.       is.close();   
  49.       bis.close();   
  50.       bos.close();   
  51.       return new String(bos.toByteArray());   
  52.     } catch (Exception ex) {   
  53.       return str;   
  54.     } finally {   
  55.       bis = null;   
  56.       bos = null;   
  57.       is = null;   
  58.       buf = null;   
  59.     }   
  60.   }   
  61. }  


 然后就是如何压缩和解压缩,应该放在哪里的问题。我考虑了一下,发现JavaBean这东西真的有趣,竟然可以实现透明压缩和解压缩。看代码:

  1. private String content;      
  2. // 增加一个是否压缩的字段,没办法,有些字段压缩了反到更长了      
  3. private boolean ziped;      
  4. public boolean isZiped() {      
  5.   return ziped;      
  6. }      
  7. public void setZiped(boolean ziped) {      
  8.   this.ziped = ziped;      
  9. }      
  10. **      
  11.  * 读取内容。      
  12.  * @return the content      
  13.  */      
  14. public String getContent() {      
  15.   // 解码      
  16.   if (isZiped()) {      
  17.     return StringZip.unzipString(content);      
  18.   }      
  19.   return content;      
  20. }      
  21. /**    
  22.  * 设置新的内容    
  23.  * @param content the content to set    
  24.  */     
  25. public void setContent(String content) {      
  26.   if (content == null || content.length() < 512) {      
  27.     this.content = content;      
  28.   } else {      
  29.     // 尝试编码      
  30.     this.content = StringZip.zipString(content);      
  31.     // 如果编码后的数据更长      
  32.     if (this.content.length() > content.length()) {      
  33.       this.content = content;      
  34.       ziped = false;      
  35.     } else {      
  36.       ziped = true;      
  37.     }      
  38.   }      
  39. }     
  40.   private String content;   
  41.   // 增加一个是否压缩的字段,没办法,有些字段压缩了反到更长了   
  42.   private boolean ziped;   
  43.   public boolean isZiped() {   
  44.     return ziped;   
  45.   }   
  46.   public void setZiped(boolean ziped) {   
  47.     this.ziped = ziped;   
  48.   }   
  49.  /**  
  50.    * 读取内容。  
  51.    * @return the content  
  52.    */  
  53.   public String getContent() {   
  54.     // 解码   
  55.     if (isZiped()) {   
  56.       return StringZip.unzipString(content);   
  57.     }   
  58.     return content;   
  59.   }   
  60.   /**  
  61.    * 设置新的内容  
  62.    * @param content the content to set  
  63.    */  
  64.   public void setContent(String content) {   
  65.     if (content == null || content.length() < 512) {   
  66.       this.content = content;   
  67.     } else {   
  68.       // 尝试编码   
  69.       this.content = StringZip.zipString(content);   
  70.       // 如果编码后的数据更长   
  71.       if (this.content.length() > content.length()) {   
  72.         this.content = content;   
  73.         ziped = false;   
  74.       } else {   
  75.         ziped = true;   
  76.       }   
  77.     }   
  78.   }    


增加了一个是否压缩的属性。

在读取时,根据是否压缩的标志进行操作,在设置时,根据数据长度和压缩的效果更新数据,并设置压缩标志。

通过这个,数据将被压缩保存,一般的文本压缩率还是很高的,到底有多高,你自己测试看看就知道了。

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页