#java #blob
#java #большой двоичный объект
Вопрос:
У меня есть процедура DB, которая возвращает большой двоичный объект. Кто-нибудь может сказать мне, как управлять большим двоичным объектом? Существует ли какой-либо конкретный API для этого?
Комментарии:
1. Например, API для java.sql.Blob?
Ответ №1:
Существует ли какой-либо конкретный API для этого?
Конечно, API JDBC.
Вы получаете доступ к Blob
экземпляру так же, как и к любому значению из результирующего набора. Затем вы должны использовать get...
set...
для этого методы — and Blob
.
Здесь у вас в основном есть два варианта:
-
Работа с байтовым массивом:
- Получить
byte[]
доступ к файлу, содержащему данные, с помощьюBlob.getBytes
- Манипулировать этим байтовым массивом
- Установите его обратно с помощью
Blob.setBytes
.
- Получить
-
Работа с
InputStream
/OutputStream
:- Получить удержание
InputStream
черезBlob.getBinaryStream
- Управляйте этим потоком по своему усмотрению
- Используйте
Blob.setBinaryStream
.
- Получить удержание
Альтернативный подход заключается в том, чтобы Blob
в первую очередь не связываться с ним, а вместо этого использовать второй подход (с потоками) непосредственно через ResultSet
-interface .
Комментарии:
1. Мой опыт показывает, что
ResultSet.getBinaryStream()
это более надежно, чем работа с экземплярамиBlob
2. @aioobe: Спасибо за ответы. Но может кто-нибудь сказать мне, насколько «ResultSet.getBinaryStream ()» надежен по сравнению с «Blob.getBinaryStream»?
3. Если ваш драйвер поддерживает
ResultSet.getBlob
иBlob.getBinaryStream
, и вы достаточно уверены, что не будете переключаться на другую базу данных, просто выберите ту, которую вы считаете наиболее читаемой.
Ответ №2:
Это зависит от того, какой тип большого двоичного объекта содержит (изображение, видео) и его расширение. Я написал простую программу для извлечения изображения из базы данных и отображения его на странице JSP. Надеюсь, это поможет.
Страница JSP
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<image src="blobAction"/>
</body>
Страница сервлета
byte[] imgData = blobDao.getInstance().getPhoto();
response.setContentType("image/gif");
OutputStream o = response.getOutputStream();
o.write(imgData);
o.flush();
o.close();
Вызывающая процедура
public byte[] getPhoto() {
byte[] imgData = null;
Blob img = null;
ResultSet rs = null;
Statement stmt = null;
try {
conn = getConnection();
String sqlQ = "SELECT CONTENT_FILE FROM CONTENT where id = 'something';
stmt = conn.createStatement();
rs = stmt.executeQuery(sqlQ);
while (rs.next()) {
img = rs.getBlob("CONTENT_FILE");
imgData = img.getBytes(1, (int) img.length());
}
rs.close();
stmt.close();
conn.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
return imgData;
}
}
Ответ №3:
С помощью простого Java JDBC Api вы можете получить java.sql.Blob
ответ от a ResultSet
.
ResultSet.getBlob(index)
илиResultSet.getBlob(String columnName)
.
Оба возвращают a Blob
.
Как только вы получите a Blob
, вы можете получить byte[]
его обратно из Blob.getBytes()
метода или установить с помощью setBytes()
метода.
Обновление: видя, что некоторые поставщики драйверов баз данных не поддерживают Blob
, вы можете использовать ResultSet.getBinaryStream()
.
Комментарии:
1. Почему бессмысленно? Существование типа данных большого двоичного объекта в базе данных не имеет ничего общего с поддержкой драйвером. Не все драйверы поддерживают
ResultSet.getBlob()
, некоторые поддерживают толькоResultSet.getInputStream()
2. @All: Спасибо, ребята, за ответы. Если getBlob() поддерживается не всеми, то какой метод лучше использовать? Blob.getBinaryStream() ?
3. Я обычно делаю
ResultSet.getBytes()
и работаюbyte[]
вместо этого.
Ответ №4:
Вы можете использовать javax.sql.rowset.serial.SerialBlob.
Я использую его в своем приложении SpringBoot amp; Angular4 следующим образом:
- получить Base64String из приложения Angular4
- декодировать строку base64 в байт[]
- создайте SerialBlob следующим образом:
SerialBlob serialBlob = new SerialBlob(byte[])
- сохраните его в базе данных с помощью JpaRepository
Ответ №5:
Пример
public void Insert(Object obj){
try {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(byteArray);
oos.writeObject(obj);
PreparedStatement ps= conn1.prepareStatement("insert into vehiculos values(?)");
ps.setBytes(1, byteArray.toByteArray());
ps.execute();
ps.close();
} catch (SQLException ex) {
System.out.println("ERROR:al hacer un Insert");
ex.printStackTrace();
} catch (IOException ex) {
Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void ShowData(){
try {
Statement stmt = conn1.createStatement();
String query = "SELECT * FROM vehiculos";
ResultSet rs = stmt.executeQuery(query);
Object obj;
while(rs.next()){
//Coche c = (Coche)rs.getBlob("coches");
Blob blob = rs.getBlob("coches");
ObjectInputStream ois = new ObjectInputStream(blob.getBinaryStream());
obj = ois.readObject();
System.out.println(obj.toString());
System.out.println("");
/*Blob blob = rs.getBlob("coches");
byte[] data = blob.getBytes(1, (int)blob.length());*/
}
rs.close();
stmt.close();
} catch (SQLException ex) {
System.out.println("ERROR:al consultar");
ex.printStackTrace();
} catch (IOException ex) {
Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Conexion.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void cerrar_Conexion (){
try {
conn1.close();
} catch (SQLException ex) {
System.out.println("ERROR:al cerrar la conexión");
ex.printStackTrace();
}
}