利用Hibernate储存大对象到达梦数据库中

开发者在线 Builder.com.cn 更新时间:2007-11-14作者:徐欣 来源:开发者在线

本文关键词: Hibernate 对象 达梦 数据库

使用达梦数据库的大字段前不得不说一下数据库大字段的性能问题在数据库中,经常需要用到大字段类型,如OraclelongblobclobSQLServertextimageMySql中的textlongtextclobblob以及达梦数据库中的clobblob类型。存储的信息大概主要是两类,一类是长文本,如大段的文字,普通的varchar最长只能存储4K的数据,已经不能满足要求;另一类是存储二进制信息,如上传的文件等不过通常情况下,大字段不意味着保存很大的文件,例如很长的文章,图标,小图片等等。数据过大保存在数据库有诸多的问题:

    1.速度慢:影响一张表的查询速度的,除了行数,还包括表所占的物理空间的大小。此表在数据量较小时,在查询方面感觉不到明显的差异。但是如果某个字段所存储的数据都是大段文本或较大的文件时,会导致表的物理空间迅速变大,该字段所占用的空间有可能达到整表所占空间的90%以上。在此基础上,如果行数再增加到数十万、上百万级时,整个表所占的空间将达到一个惊人的数字,查询的速度亦会受到非常大的影响

    2.操作不方便:必须把数据库打开一个流,构造一个Buffer,然后再输出一个ServletOutputStream。占用数据库连接,加重数据库访问负载不说,如果用户突然中断下,还需要处理数据库关闭动作,容易造成性能问题。如果把整个数据读入内存再输出,则内存占用非常观。如果是硬盘文件,只要返回一个URL 就可以了。即使你不希望用户直接访问到文件,你也可以构造一个IOStream来输出文件,既不会占用数据库资源,传输速度也快。
    3.
性能有问题:特别的情况是,如果并发很多用户来下载大文件的时候,应用服务器要占用非常多的内存来缓存文件内容,假设并发
10个用户,下载10MB的文件,JVM的峰值就至少需要100MB内存来支撑,很容易造成JVM崩溃。

    所以说数据库大字段并不适合存储过大的数据,数据过大可能会影响到数据库存储的性能。

    下面言归正传,使用Hibernate操作达梦数据库中的大字段应该有如下几步:

    1 首先需要一张表存储大字段数据:包括内容,类型;

    2 必须得到一个代表上传文件的数据流;

    3 进行保存操作

好了我们先建一张表,里面包括达梦数据库的2个大字段类型(CLOBBLOB)字段

--创建表

create table TESTLOB(

   ID int primary key,

   TITLE varchar(50),

   CLOBNAME varchar(50),

   CLOBCONTENT clob,

   BLOBNAME varchar(50),

   BLOBCONTENT blob

);

在建立一个序列用于处理表的流水ID:

--创建序列

CREATE SEQUENCE "TESTLOB"."SEQ_TESTLOB_ID"

INCREMENT BY 1 START WITH 1 MAXVALUE 100000 MINVALUE 1

NOCYCLE

然后编写关于这2个大字段的Java对象文件TestLob.java,分别定义类型为CLOBBLOB属性字段为Stringbyte[]类型,其中由于CLOB是处理大文本类型所以它对应了Java中的String类型,BLOB是处理一些以二进制流形势存储没有严格定义的大文件所以让它使用byte[]类型然后分别定义这2个属性的GetterSetter方法,相关代码如下:

package com.dm.lobtest.vo;

 

public class TestLob {

    private int id;

    private String title;        //记录标题

    private String clobName;     //clob文件名称

    private String clobContent;  //clob文件

    private byte[] blobContent;  //blob文件

    private String blobName;     //blob文件名称

       

    public byte[] getBlobContent() {

        return blobContent;

    }

    public void setBlobContent(byte[] blobContent) {

        this.blobContent = blobContent;

    }

     

    public String getClobContent() {

        return clobContent;

    }

    public void setClobContent(String clobContent) {

        this.clobContent = clobContent;

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getTitle() {

        return title;

    }

    public void setTitle(String title) {

        this.title = title;

    }

    public String getBlobName() {

        return blobName;

    }

    public void setBlobName(String blobName) {

        this.blobName = blobName;

    }

    public String getClobName() {

        return clobName;

    }

    public void setClobName(String clobName) {

        this.clobName = clobName;

    }

}

 

对象的映射文件中主健字段<id>元素的内置生成器指定为sequence,并与达梦数据库重的内置序列(sequence)关联,最后指定CLOB类型的属性为"string"类型,BLOB类型的属性为"binary"类型

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

 

    <class name="com.dm.lobtest.vo.TestLob" table="TESTLOB">

        <id name="id" column="ID" type="int">

            <generator class="sequence">

                <param name="sequence">SEQ_TESTLOB_ID</param>

            </generator>

        </id> 

        <property name="title" column="TITLE" type="string" />

        <property name="clobName" column="CLOBNAME" type="string" />

        <property name="blobName" column="BLOBNAME" type="string" />

        <property name="clobContent" column="CLOBCONTENT" type="string" />

        <property name="blobContent" column="BLOBCONTENT" type="binary" />             

</class>

 

</hibernate-mapping>