JDBC读取MySQL的BLOB类型
2016-08-05 11:15
567 查看
JDBC读取MySQL的BLOB类型
今天写了个SQL查数据库,需要根据id分组,然后将同一分组中某几列的值都平铺开来,网络上查了下,MySQL中的 GROUP_CONCAT 函数,还是很好用的,SQL 大致写成如下:
select `id` , GROUP_CONCAT(concat(`key`,':',`value`) ORDER BY `key` SEPARATOR ",") as prefs from `table_name` GROUP BY `id`
效果还算不错,但是在Java程序中查询这条SQL时,却出现了一些小意外,分组排列的字段显示不出来,我当时使DBUtils 查的,用MapListHandler 来读出的该字段,读出来全是乱码, 于是跟到源码里,调了半天不知道问题,后来同事提示才发现,由于同一组中,个数太多,导致这些值产生的字符串很长,于是MySQL会自动把这列的结果类型转换成BLOB,这种类型读取的方式很特别,若用JDBC中 getObject(int index)方法读取的话,就会是乱码(DBUtils这里就是用的JDBC中的 getObject(int
index) 来读取数据)。
读取数据库中BLOB数据类型的方法,我在网上找了一下,找到两种,根据自身情况也实现了一下,我需要将BLOB类型 转换成String,代码如下
第一种方法:
public String getBlob(String SQL){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();//c3p0连接池
stmt = conn.prepareStatement(SQL);//SQL: select info from table1 (其中info字段是blob类型)
rs = stmt.executeQuery();
InputStream in = rs.getBinaryStream(1);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[4096];
int count = -1;
while((count = in.read(data,0,4096)) != -1)
outStream.write(data, 0, count);
data = null;
String result = new String(outStream.toByteArray(),"utf-8");
} catch (SQLException sqle) {
log.warn("Exception XXX", sqle);
}finally{
conn.close();
stmt.close();
}
}
第二种方法:
public String getBlob(String SQL){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();//c3p0连接池
stmt = conn.prepareStatement(SQL);//SQL: select info from table1 (其中info字段是blob类型)
rs = stmt.executeQuery();
Blob bb = rs.getBlob(i);
byte[] b = bb.getBytes(1, (int)bb.length());
String result = new String(b,"utf-8");
} catch (SQLException sqle) {
log.warn("Exception XXX", sqle);
}finally{
conn.close();
stmt.close();
}
}
这里看第二种方法要简单点,但是第一种貌似是用来直接将结果写入文件中,因为我这里需要转换成String,所以偏第二种。
最后我想在 DBUtils里面读取的时候就直接帮我转换的,研究了一下源代码后,貌似这么改可以做到,加一层判断,若结果类型为BLOB 则用上述读法。若不是还是按原来的逻辑走,修改的是以修改 org.apache.commons.dbutils.BasicRowProcessor 中的将结果封装诚Map的方法为例(RowProcessor为用于处理数据封装的,还有封装其他数据结构的方法你也可以根据需要改),改的不好,见笑了:
public Map<String, Object> toMap(ResultSet rs) throws SQLException {
Map<String, Object> result = new CaseInsensitiveHashMap();
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
for (int i = 1; i <= cols; i++) {
//通过ResultSetMetaData类,可判断该列数据类型
if(rsmd.getColumnTypeName(i).equals("BLOB")){
Blob bb = rs.getBlob(i);
byte[] b = bb.getBytes(1, (int)bb.length());
try {
//将结果放到Map中
result.put(rsmd.getColumnName(i), new String(b,"utf-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
//不是则按原来逻辑运算
result.put(rsmd.getColumnName(i), rs.getObject(i));
}
}
return result;
}
今天写了个SQL查数据库,需要根据id分组,然后将同一分组中某几列的值都平铺开来,网络上查了下,MySQL中的 GROUP_CONCAT 函数,还是很好用的,SQL 大致写成如下:
select `id` , GROUP_CONCAT(concat(`key`,':',`value`) ORDER BY `key` SEPARATOR ",") as prefs from `table_name` GROUP BY `id`
效果还算不错,但是在Java程序中查询这条SQL时,却出现了一些小意外,分组排列的字段显示不出来,我当时使DBUtils 查的,用MapListHandler 来读出的该字段,读出来全是乱码, 于是跟到源码里,调了半天不知道问题,后来同事提示才发现,由于同一组中,个数太多,导致这些值产生的字符串很长,于是MySQL会自动把这列的结果类型转换成BLOB,这种类型读取的方式很特别,若用JDBC中 getObject(int index)方法读取的话,就会是乱码(DBUtils这里就是用的JDBC中的 getObject(int
index) 来读取数据)。
读取数据库中BLOB数据类型的方法,我在网上找了一下,找到两种,根据自身情况也实现了一下,我需要将BLOB类型 转换成String,代码如下
第一种方法:
public String getBlob(String SQL){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();//c3p0连接池
stmt = conn.prepareStatement(SQL);//SQL: select info from table1 (其中info字段是blob类型)
rs = stmt.executeQuery();
InputStream in = rs.getBinaryStream(1);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] data = new byte[4096];
int count = -1;
while((count = in.read(data,0,4096)) != -1)
outStream.write(data, 0, count);
data = null;
String result = new String(outStream.toByteArray(),"utf-8");
} catch (SQLException sqle) {
log.warn("Exception XXX", sqle);
}finally{
conn.close();
stmt.close();
}
}
第二种方法:
public String getBlob(String SQL){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();//c3p0连接池
stmt = conn.prepareStatement(SQL);//SQL: select info from table1 (其中info字段是blob类型)
rs = stmt.executeQuery();
Blob bb = rs.getBlob(i);
byte[] b = bb.getBytes(1, (int)bb.length());
String result = new String(b,"utf-8");
} catch (SQLException sqle) {
log.warn("Exception XXX", sqle);
}finally{
conn.close();
stmt.close();
}
}
这里看第二种方法要简单点,但是第一种貌似是用来直接将结果写入文件中,因为我这里需要转换成String,所以偏第二种。
最后我想在 DBUtils里面读取的时候就直接帮我转换的,研究了一下源代码后,貌似这么改可以做到,加一层判断,若结果类型为BLOB 则用上述读法。若不是还是按原来的逻辑走,修改的是以修改 org.apache.commons.dbutils.BasicRowProcessor 中的将结果封装诚Map的方法为例(RowProcessor为用于处理数据封装的,还有封装其他数据结构的方法你也可以根据需要改),改的不好,见笑了:
public Map<String, Object> toMap(ResultSet rs) throws SQLException {
Map<String, Object> result = new CaseInsensitiveHashMap();
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
for (int i = 1; i <= cols; i++) {
//通过ResultSetMetaData类,可判断该列数据类型
if(rsmd.getColumnTypeName(i).equals("BLOB")){
Blob bb = rs.getBlob(i);
byte[] b = bb.getBytes(1, (int)bb.length());
try {
//将结果放到Map中
result.put(rsmd.getColumnName(i), new String(b,"utf-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
//不是则按原来逻辑运算
result.put(rsmd.getColumnName(i), rs.getObject(i));
}
}
return result;
}
相关文章推荐
- JDBC读取MySQL的BLOB类型
- JDBC读取MySQL的BLOB类型
- JDBC读取MySQL的BLOB类型
- Java JDBC读取二进制类型数据(BLOB)
- mybatis中插入和读取mysql的blob/text类型数据
- Jdbc-mysql二进制blob类型读写
- 读取MySQL存储二进制的语音、图片(Blob类型)
- MySQL 中Blob类型数据的插入和读取
- JDBC读取BLOB类型
- ThinkPHP读取excel中的图片并以blob类型存入mysql,以及从mysql读取二进制流在页面显示图片
- MYSQL中如何用JDBC存取BLOB类型?
- JDBC 使用 mysql Blob类型
- mysql jdbc驱动的一个bug:datetime型数据'0000-00-00 00:00:00' 的读取
- 通过OracleDataReader来读取BLOB类型的数据 (转载)
- MySQL有四种BLOB类型:
- 使用mysql的blob类型存取图片
- jdbc hibernate ibatis 操作Blob 和Clob类型字段(不断更新)
- java实现插入mysql二进制文件,blob类型,遇到问题及解决办法
- Hibernate操作Blob类型字段出现java.lang.AbstractMethodError: oracle.jdbc.driver.OracleResultSetImpl.getBlob(Ljava/lang/String;)Ljava/sql/
- 往Blob类型字段插入图片,使用与MySql或者Oracle