|
Blob(/Clob) as linked listThis is the implementation of storing a variable length blob/clob using a list of fixed length arrays. For more details concerning the idea see: http://forum.hibernate.org/viewtopic.php?t=936233 Hibernate Mapping file:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="nl.chess.it.argus.core.db.blob.MyFile">
<id name="dbId" type="java.lang.Long">
<generator class="native" />
</id>
<property
name="name"
not-null="true"
type="string"
/>
<list
cascade="all-delete-orphan"
lazy="false"
name="dataparts"
>
<key column="DBID_MYFILE" />
<index column="NR" type="integer" />
<element type="binary" >
<!--
PostgreSql
<column name="dataaa" sql-type="bytea" length="10024"/>
-->
<!--
MySql
<column name="dataaa" sql-type="LONGBLOB" length="518576"/>
-->
<!--
Oracle
<column name="dataaa" sql-type="raw"/>
-->
<column name="dataaa" sql-type="LONGBLOB" length="518576"/>
</element>
</list>
</class>
</hibernate-mapping>
Note: the java was generated with Hibernate Synchronizer in Eclipse, only the parts after the [CONSTRUCTOR MARKER END] are my work.
package nl.chess.it.argus.core.db.model;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import nl.chess.it.argus.core.db.impl.LinkedListBlobPersister;
import nl.chess.it.argus.core.db.model.base.BaseLinkedListBlob;
/**
* This class provides a generic blob as linked-list implementation that other classes can use.
*
*/
public class LinkedListBlob extends BaseLinkedListBlob implements LinkedListBlobPersister {
private static int BUFFER_SIZE = 0;
/*[CONSTRUCTOR MARKER BEGIN]*/
public LinkedListBlob () {}
/**
* Constructor for primary key
*/
public LinkedListBlob (java.lang.Long _dbId) {
super(_dbId);
}
/*[CONSTRUCTOR MARKER END]*/
/**
* Set the bytes of this Object.
* @param bytes the bytes to set, may not be null, but may be new byte[0];
*/
public void setData(byte[] bytes) {
int length = bytes.length;
if ( length <= BUFFER_SIZE) {
List partsList = new ArrayList();
if ( length > 0 ) {
partsList.add(bytes);
}
setDataparts(partsList);
return;
}
int parts = length / BUFFER_SIZE;
List partsList = new ArrayList(parts);
for (int i = 0; i < parts; i++) {
byte[] buffer = new byte[BUFFER_SIZE];
System.arraycopy(bytes, i * BUFFER_SIZE, buffer, 0, BUFFER_SIZE );
partsList.add(buffer);
}
int lastPartLength = length % BUFFER_SIZE;
if ( lastPartLength != 0 ) {
byte[] buffer = new byte[lastPartLength];
System.arraycopy(bytes, parts * BUFFER_SIZE, buffer, 0, lastPartLength );
partsList.add(buffer);
}
setDataparts(partsList);
}
/**
* Gets the bytes that are stored by this object.
* @return the data, not null but may be a new byte[0];
*/
public byte[] getData() {
int parts = getDataparts().size();
if ( parts == 0) {
return new byte[0];
}
if ( parts == 1) {
return (byte[])getDataparts().get(0);
}
int lastPartLength = ((byte[])getDataparts().get(parts-1)).length;
int dataLength = BUFFER_SIZE * (parts - 1) + lastPartLength;
byte[] bytes = new byte[dataLength];
int count = 0;
for (Iterator i = getDataparts().iterator(); i.hasNext();) {
byte[] part = (byte[]) i.next();
System.arraycopy(part, 0, bytes, count * BUFFER_SIZE, part.length );
count ++;
}
return bytes;
}
public void setBufferSize(int _bufferSize) {
BUFFER_SIZE = _bufferSize;
}
public int getBufferSize() {
return BUFFER_SIZE;
}
}
|
||||||||||||||||||||||||||||