我使用的是SQLite,我无法将图像保存到数据库中。 这是我的代码:
File file = new File(url);
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {}
fileLenght = (int) file.length();
stat.executeUpdate("create table "+tableName+" (id int,name String ,image Blob, features String);");
prep = conn.prepareStatement("insert into "+tableName+" values (?, ?, ?, ?);");
prep.setBinaryStream(3, fis, fileLenght);
这是我得到的错误:
java.sql.SQLException: not implemented by SQLite JDBC driver
at org.sqlite.Unused.unused(Unused.java:29)
at org.sqlite.Unused.setBinaryStream(Unused.java:58)
我正在使用以下jar:sqlitejdbc-v056.jar。
有什么想法吗? 感谢
答案 0 :(得分:14)
您正在使用的SQLite JDBC实现未实现setBinaryStream
(因此SQLite JDBC驱动程序错误消息未实现准确的)。
您需要改为使用setBytes
方法。
答案 1 :(得分:9)
您可以非常轻松地将图像插入数据库,说SQLite请参阅以下代码。 我确实使用了DBase Connection的属性文件,你可以放在任何地方。
public class JDBCSqliteConn
{
public static void main(String args[]) throws FileNotFoundException, IOException
{
Connection connection = null;
//ResultSet resultSet = null;
PreparedStatement ps = null;
String file = "C:\\Fingerprint\\histoImg_med.png";
Properties prop = new Properties();
int s = 0;
byte[] person_image = null;
File image = new File(file);
FileInputStream fis = new FileInputStream(image);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fis.read(buf)) != -1;)
{
bos.write(buf, 0, readNum);
//no doubt here is 0
/*Writes len bytes from the specified byte array starting at offset
off to this byte array output stream.*/
System.out.println("read " + readNum + " bytes,");
}
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
person_image = bos.toByteArray();
try {
prop.load(new FileInputStream("C:\\dbconfig.properties"));
Class.forName(prop.getProperty("driver"));
connection = DriverManager.getConnection(prop.getProperty("url"));
ps = connection.prepareStatement("INSERT INTO epmc_tbl_test_img (hhld_photo) VALUES (?)");
ps.setBytes(1, person_image);
s = ps.executeUpdate();
if (s > 0)
{
System.out.println("Image Uploaded");
}
ps.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ps.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
背后的逻辑是将图像转换为bytearray然后存储到数据库,SQLite接受Image类型BLOB的字节数组
这是我的dbconfig.properties文件
driver = org.sqlite.JDBC
url = jdbc:sqlite:C:\\Ronald\\Personal\\epmc\\JavaJ2EE\\EPMC.db
尝试使用此代码。
答案 2 :(得分:2)
要在Hibernate中使用它,您必须使用正确的UserType:
public class PersistentFileAsBlob implements EnhancedUserType, Serializable {
public static final PersistentFileAsBlob INSTANCE = new PersistentFileAsBlob();
private static final int[] SQL_TYPES = new int[] { Types.BLOB };
@Override
public int[] sqlTypes() {
return SQL_TYPES;
}
@Override
public Class<?> returnedClass() {
return File.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
}
if (x == null || y == null) {
return false;
}
File dtx = (File) x;
File dty = (File) y;
return dtx.equals(dty);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
throws HibernateException, SQLException {
if (owner == null) {
return null;
}
FileOutputStream fos = null;
GzipCompressorInputStream cis = null;
try {
File file = File.createTempFile(String.valueOf(owner.hashCode()),
"");
byte[] bytes = rs.getBytes(names[0]);
System.out.println(bytes.length);
fos = new FileOutputStream(file);
cis = new GzipCompressorInputStream(new BufferedInputStream(
new ByteArrayInputStream(bytes)));
int n = 0;
final byte[] buffer = new byte[1024];
while (-1 != (n = cis.read(buffer))) {
fos.write(buffer, 0, n);
}
fos.close();
return file;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (fos != null)
try {
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (cis != null)
try {
cis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
if (value == null) {
StandardBasicTypes.BINARY.nullSafeSet(st, null, index);
return;
}
File file = (File) value;
FileInputStream fis = null;
ByteArrayOutputStream bos = null;
GzipCompressorOutputStream cos = null;
try {
fis = new FileInputStream(file);
bos = new ByteArrayOutputStream();
cos = new GzipCompressorOutputStream(new BufferedOutputStream(bos));
int n = 0;
final byte[] buffer = new byte[1024];
while (-1 != (n = fis.read(buffer))) {
cos.write(buffer, 0, n);
}
cos.close();
StandardBasicTypes.BINARY.nullSafeSet(st, bos.toByteArray(), index);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
if (cos != null)
try {
cos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
@Override
public String objectToSQLString(Object value) {
throw new UnsupportedOperationException();
}
@Override
public String toXMLString(Object value) {
return value.toString();
}
@Override
public Object fromXMLString(String xmlValue) {
return new File(xmlValue);
}
}
然后您注释键入,请参阅此UserType:
@Entity
public class Mensagem {
@Column(nullable = false)
@Type(type = "package.to.class.PersistentFileAsBlob")
private File file;
}
正如您所看到的,我在保存和解压缩之前压缩数据,然后再进行检索。看看this site。
答案 3 :(得分:1)
让submitted包含setBinaryStream实现的Xerial补丁。
使用setBytes对我来说不是一个选项,因为我使用hibernate来访问数据库。
diff -r 144ade82d1fe -r 5a141e1b82f0 src/main/java/org/sqlite/PrepStmt.java
--- a/src/main/java/org/sqlite/PrepStmt.java Thu Jun 09 17:15:36 2011 +0900
+++ b/src/main/java/org/sqlite/PrepStmt.java Wed Oct 26 11:02:15 2011 -0700
@@ -16,7 +16,9 @@
package org.sqlite;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Reader;
import java.sql.Date;
import java.sql.ParameterMetaData;
@@ -254,6 +256,38 @@
batch(pos, value);
}
+ @Override
+ public void setBinaryStream(int pos, InputStream istream, int length) throws SQLException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try
+ {
+ int bval = 0;
+
+ while ((bval = istream.read()) != -1)
+ {
+ baos.write(bval);
+ }
+ baos.flush();
+ setBytes(pos, baos.toByteArray());
+ }
+ catch (IOException e)
+ {
+ throw new SQLException("Cannot read from binary stream, exception message: " + e.getMessage());
+ }
+ finally
+ {
+ try
+ {
+ baos.close();
+ }
+ catch (IOException e)
+ {
+ throw new SQLException("Can't close stream");
+ }
+ }
+ }
+
public void setCharacterStream(int pos, Reader reader, int length) throws SQLException {
try {
// copy chars from reader to StringBuffer
答案 4 :(得分:0)
您似乎没有绑定语句中的所有四个参数。