本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《
准备先把以前写的持久层及表示层框架写完再写loonframework-game包(实际上是想自己业余建站用,用现成的框架太无聊,重复发明轮子的最 大意义就在于解闷……),在2005年时写过一个开头,由于自己没有整理文档,现在拿起来就觉得代码很乱,又懒于写文档,于是把一些心得类的东西整理一 下,用以备忘。
在此持久层框架中,我将持久化过程分为两个松耦合模块,第一模块封装jdbc操作,隐藏Connection及相关事务,处理driver差异后执行标准CRUD并释放资源,于第二模块进行实体映射操作。
但 和Spring JdbcTemplate等jdbc封装略有不同的是,我除了直接将结果集转为List和实体返回外,还引入了一个类似CachedRowSet但非继承 CachedRowSet或ResultSet的结果集cache实体(没有提供诸如CachedRowSet的execute功能,原因大家都知 道……PS:05年我用Hibernate还比较少,现在看来和Hierbante的ScrollableResults接口超级类似,颇感java技术 殊途同归|||)。
但在此类get数据时,由于我将所有ResultSet数据无差别以object方式存储,当object为二进制对象时,为实现blob和clob接口就需要进行数据转换,将二进制对象转为blob或clob实现,为此完成代码如下。
比较hibernate的blobimpl而言(hibernate的blobimpl只有getBinaryStream()实现,因为别的对它也没用……),实现了更多的函数以供调用。
BlobImpl.java
package
org.loon.framework.dao.lob;
import
java.io.BufferedInputStream;
import
java.io.ByteArrayInputStream;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.OutputStream;
import
java.sql.Blob;
import
java.sql.SQLException;
import
org.loon.framework.Loon;
import
org.loon.framework.helper.FileHelper;
public
class
BlobImpl
implements
{
private
byte
[] _bytes
=
new
byte
[
0
];
private
int
_length
=
0
;
/**
* 构造函数,以byte[]构建blob
*
*
@param
bytes
*/
public
BlobImpl(
byte
[] bytes)
{
init(bytes);
}
/**
* 构造函数,以InputStream构建blob
*
*
@param
bytes
*/
public
BlobImpl(InputStream input)
{
init(FileHelper.read(input));
}
/**
* 构造函数,以blob重新构建blob
*
*
@param
bytes
*/
public
BlobImpl(Blob blob)
{
init(blobToBytes(blob));
}
/**
* 初始化byte[]
*
*
@param
b
*/
private
void
init(
byte
[] bytes)
{
_bytes
=
bytes;
_length
=
_bytes.length;
}
/**
* 将blob转为byte[]
*
*
@param
blob
*
@return
*/
private
byte
[] blobToBytes(Blob blob)
{
BufferedInputStream is
=
null
;
try
{
is
=
new
BufferedInputStream(blob.getBinaryStream());
byte
[] bytes
=
new
byte
[(
int
) blob.length()];
int
len
=
bytes.length;
int
offset
=
0
;
int
read
=
0
;
while
(offset
<
len
&&
(read
=
is.read(bytes, offset, len
-
offset))
>=
0
)
{
offset
+=
read;
}
return
bytes;
}
catch
(Exception e)
{
return
null
;
}
finally
{
try
{
is.close();
is
=
null
;
}
catch
(IOException e)
{
return
null
;
}
}
}
/**
* 获得blob中数据实际长度
*
*
@return
*
@throws
SQLException
*/
public
long
length()
throws
SQLException
{
return
_bytes.length;
}
/**
* 返回指定长度的byte[]
*
*
@param
pos
*
@param
len
*
@return
*
@throws
SQLException
*/
public
byte
[] getBytes(
long
pos,
int
len)
throws
SQLException
{
if
(pos
==
0
&&
len
==
length())
return
_bytes;
try
{
byte
[] newbytes
=
new
byte
[len];
System.arraycopy(_bytes, (
int
) pos, newbytes,
0
, len);
return
newbytes;
}
catch
(Exception e)
{
throw
new
SQLException(
"
Inoperable scope of this array
"
);
}
}
/**
* 返回InputStream
*
*
@return
*
@throws
SQLException
*/
public
InputStream getBinaryStream()
throws
SQLException
{
return
new
ByteArrayInputStream(_bytes);
}
/**
* 获取此byte[]中start的字节位置
*
*
@param
pattern
*
@param
start
*
@return
*
@throws
SQLException
*/
public
long
position(
byte
[] pattern,
long
start)
throws
SQLException
{
start
--
;
if
(start
<
0
)
{
throw
new
SQLException(
"
start < 0
"
);
}
if
(start
>=
_length)
{
throw
new
SQLException(
"
start >= max length
"
);
}
if
(pattern
==
null
)
{
throw
new
SQLException(
"
pattern == null
"
);
}
if
(pattern.length
==
0
||
_length
==
0
||
pattern.length
>
_length)
{
return
-
1
;
}
int
limit
=
(
int
) _length
-
pattern.length;
for
(
int
i
=
(
int
) start; i
<=
limit; i
++
)
{
int
p;
for
(p
=
0
; p
<
pattern.length
&&
_bytes[i
+
p]
==
pattern[p]; p
++
)
{
if
(p
==
pattern.length)
{
return
i
+
1
;
}
}
}
return
-
1
;
}
/**
* 获取指定的blob中start的字节位置
*
*
@param
pattern
*
@param
start
*
@return
*
@throws
SQLException
*/
public
long
position(Blob pattern,
long
start)
throws
SQLException
{
return
position(blobToBytes(pattern), start);
}
/**
* 不支持操作异常抛出
*
*/
void
nonsupport()
{
throw
new
UnsupportedOperationException(
"
This method is not supported!
"
);
}
/**
* 释放Blob对象资源
*
*
@throws
SQLException
*/
public
void
free()
throws
SQLException
{
_bytes
=
new
byte
[
0
];
_length
=
0
;
}
/**
* 返回指定长度部分的InputStream,并返回InputStream
*
*
@param
pos
*
@param
len
*
@return
*
@throws
SQLException
*/
public
InputStream getBinaryStream(
long
pos,
long
len)
throws
SQLException
{
return
new
ByteArrayInputStream(getBytes(pos, (
int
) len));
}
/**
* 以指定指定长度将二进制流写入OutputStream,并返回OutputStream
*
*
@param
pos
*
@return
*
@throws
SQLException
*/
public
OutputStream setBinaryStream(
long
pos)
throws
SQLException
{
//
暂不支持
nonsupport();
pos
--
;
if
(pos
<
0
)
{
throw
new
SQLException(
"
pos < 0
"
);
}
if
(pos
>
_length)
{
throw
new
SQLException(
"
pos > length
"
);
}
//
将byte[]转为ByteArrayInputStream
ByteArrayInputStream inputStream
=
new
ByteArrayInputStream(_bytes);
ByteArrayOutputStream os
=
new
ByteArrayOutputStream();
byte
[] bytes
=
new
byte
[(
int
) pos];
try
{
bytes
=
new
byte
[inputStream.available()];
int
read;
while
((read
=
inputStream.read(bytes))
>=
0
)
{
os.write(bytes,
0
, read);
}
}
catch
(IOException e)
{
e.getStackTrace();
}
//
返回OutputStream
return
(OutputStream) os;
}
/**
* 设定byte[]
*
*
@param
pos
*
@param
bytes
*
@param
offset
*
@param
size
*
@param
copy
*
@return
*
@throws
SQLException
*/
private
int
setBytes(
long
pos,
byte
[] bytes,
int
offset,
int
size,
boolean
copy)
throws
SQLException
{
//
暂不支持
nonsupport();
pos
--
;
if
(pos
<
0
)
{
throw
new
SQLException(
"
pos < 0
"
);
}
if
(pos
>
_length)
{
throw
new
SQLException(
"
pos > max length
"
);
}
if
(bytes
==
null
)
{
throw
new
SQLException(
"
bytes == null
"
);
}
if
(offset
<
0
||
offset
>
bytes.length)
{
throw
new
SQLException(
"
offset < 0 || offset > bytes.length
"
);
}
if
(size
<
0
||
pos
+
size
>
(
long
) Integer.MAX_VALUE
||
offset
+
size
>
bytes.length)
{
throw
new
SQLException();
}
//
当copy数据时
if
(copy)
{
_bytes
=
new
byte
[size];
System.arraycopy(bytes, offset, _bytes,
0
, size);
}
else
{
//
否则直接替换对象
_bytes
=
bytes;
}
return
_bytes.length;
}
/**
* 设定指定开始位置byte[]
*
*
@param
pos
*
@param
bytes
*
@return
*
@throws
SQLException
*/
public
int
setBytes(
long
pos,
byte
[] bytes)
throws
SQLException
{
//
暂不支持
nonsupport();
return
setBytes(pos, bytes,
0
, bytes.length,
true
);
}
/**
* 设定byte[]
*
*
@param
pos
*
@param
bytes
*
@param
offset
*
@param
len
*
@return
*
@throws
SQLException
*/
public
int
setBytes(
long
pos,
byte
[] bytes,
int
offset,
int
len)
throws
SQLException
{
//
暂不支持
nonsupport();
return
setBytes(pos, bytes, offset, len,
true
);
}
/**
* 截取相应部分数据
*
*
@param
len
*
@throws
SQLException
*/
public
void
truncate(
long
len)
throws
SQLException
{
if
(len
<
0
)
{
throw
new
SQLException(
"
len < 0
"
);
}
if
(len
>
_length)
{
throw
new
SQLException(
"
len > max length
"
);
}
_length
=
(
int
) len;
}
public
static
void
main(String[] args)
{
//
获得一个指定文件的blob
//
PS:天地良心啊,没抄袭hibernate写法,无奈的写一样了,不过比他多实现了点方法……(还特意把函数改名,不然更像|||)……
Blob blob
=
Loon.makeBlob(
"
D:\test.txt
"
);
//
以byte[]获得blob实例
//
Blob blob = new BlobImpl(bytes);
try
{
//
getBytes测试
//
取出0到blob结束范围的byte[]
byte
[] buffer
=
blob.getBytes(
0
, (
int
) blob.length());
//
以gb2312编码将byte[]转为string显示
System.out.println(
new
String(buffer,
"
gb2312
"
));
//
getBinaryStream测试
BufferedInputStream is
=
new
BufferedInputStream(blob
.getBinaryStream());
buffer
=
new
byte
[(
int
) blob.length()];
int
len
=
buffer.length;
int
offset
=
0
;
int
read
=
0
;
while
(offset
<
len
&&
(read
=
is.read(buffer, offset, len
-
offset))
>=
0
)
{
offset
+=
read;
}
System.out.println(
new
String(buffer,
"
gb2312
"
));
//
getBinaryStream范围取值测试,取0to4的byte[]
is
=
new
BufferedInputStream(blob.getBinaryStream(
0
,
4
));
//
将is转为byte[]后转为String显示
System.out.println(FileHelper.readToString(is,
"
gb2312
"
));
}
catch
(Exception e)
{
e.printStackTrace();
}
}
本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/130046