sqlite setBytes()不适用于Windows上的BLOB数据类型

时间:2011-03-31 18:57:33

标签: windows sqlite jdbc blob

我正在使用sqlite(版本3.7.5)和http://www.xerial.org/trac/Xerial/wiki/SQLiteJDBC提供的sqlite jdbc驱动程序

几个月前,我在xerial论坛(http://groups.google.com/group/xerial/browse_thread/thread/ee19bd855e282f9c)上提出了一个几乎完全相同的问题,但从未得到任何回复。

当我自己构建共享库sqlite.dll / libsqlite.so时,我的示例在Linux上正常工作(opensuse 64位),但在Windows XP专业版32位上无法正常工作。

但是,如果我使用sqlite.org网站(http://sqlite.org/sqlite-dll-win32-x86-3070500.zip)提供的共享库或者与jdbc驱动程序捆绑在一起的共享库( http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/3.7.2/sqlite-jdbc-3.7.2.jar),它在Linux和Windows上运行良好。< / p>

因此我猜测我没有正确构建sqlite库。我正在使用带有Microsoft Platform SDK的cygwin环境来构建sqlite。我使用以下命令集在Windows XP 32位上创建sqlite库。

mycl -32 -O2 / D“NDEBUG”/ MD / D“_WIN32”/ D“_WINDOWS”/ D“_MBCS”/ D“_USRDLL”/ D“SQLITE_ENABLE_COLUMN_METADATA”/ D“SQLITE_ENABLE_FTS3”/ D“SQLITE_THREADSAFE = 1“-c NativeDB.c -o NativeDB.o

mycl -32 -O2 / D“NDEBUG”/ MD / D“_WIN32”/ D“_WINDOWS”/ D“_MBCS”/ D“_USRDLL”/ D“SQLITE_ENABLE_COLUMN_METADATA”/ D“SQLITE_ENABLE_FTS3”/ D“SQLITE_THREADSAFE = 1“-c sqlite3.c -o sqlite3.o

mylink -32 / DLL /lpathpath:../lib/Win32 /out:sqlite.dll NativeDB.o sqlite3.o gdi32.lib vfw32.lib user32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib wbemuuid.lib netapi32.lib ws2_32.lib kernel32.lib

mymt -32 / manifest sqlite.dll.manifest /outputresource:sqlite.dll';#2'

(mycl,mylink和mymt是原始cl.exe,link.exe和mt.exe的包装器,用于转换命令行参数。它们可以与我用它们构建的许多其他项目一起使用。)

我还创建了一个SSCE来演示这个问题。

package org.sqlite;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class MainDriver {


public static void main(String[] args) {
    new MainDriver();
}


public MainDriver() {

    //Buffers to read and write
    byte[] writeBuffer = new byte[10];
    byte[] readBuffer = null;
    for (int i = 1; i < 10; i++) {
        writeBuffer[i] = (byte)i;
    }

    //Database objects
    Connection conn = null;
    Statement stat = null;
    PreparedStatement prep = null;

    //Load the database driver
    try {
        System.loadLibrary("sqlite");
        Class.forName("org.sqlite.JDBC");
    } catch (Exception e) {
        System.err.println("Could not load sqlite library or instantiate the database driver.");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Open a connection to the database
    try {
        conn = DriverManager.getConnection("jdbc:sqlite:" + "file.db");
    } catch (SQLException e) {
        System.err.println("Could not open a connection to the database with name file.db");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Create a table
    try {
        stat = conn.createStatement();
        stat.execute("CREATE TABLE TEST (model BLOB NOT NULL)");
        stat.close();
    } catch (SQLException e) {
        System.err.println("The table could not be created.");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Write buffer into the database
    try {
        conn.setAutoCommit(false);
        prep = conn.prepareStatement("INSERT INTO TEST (model) VALUES(?)");
        prep.setBytes(1, writeBuffer);
        prep.addBatch();
        prep.executeBatch();
        conn.setAutoCommit(true);
        prep.close();
    } catch (SQLException e) {
        System.err.println("The buffer could not be written to the database.");
        System.err.println(e);
        e.printStackTrace();
        return;
    }

    //Read buffer from the database
    try {
        stat = conn.createStatement();
        ResultSet rs = stat.executeQuery("SELECT * FROM TEST");
        readBuffer = rs.getBytes(1);
        rs.close();
        stat.close();
    } catch (SQLException e) {
        System.err.println("The buffer could not be read");
        System.err.println(e);
        e.printStackTrace();
    }

    //Close the database
    try {
        conn.close();
    } catch (SQLException e) {
        System.err.println("Database could not be closed");
        System.err.println(e);
        e.printStackTrace();
    }

    //Print the buffers
    System.out.print("Write buffer = ");
    for (int i = 0; i < writeBuffer.length; i++) {
        System.out.print(writeBuffer[i]);
    }
    System.out.println();
    System.out.print("Read  buffer = ");
    for (int i = 0; i < readBuffer.length; i++) {
        System.out.print(readBuffer[i]);
    }
    System.out.println();

    //Check the md5sum
    try {
        java.security.MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
        byte[] md5sum = null;
        java.math.BigInteger bigInt = null;

        //Write buffer
        digest.reset();
        digest.update(writeBuffer);
        md5sum = digest.digest();
        bigInt = new java.math.BigInteger(1, md5sum);
        System.out.println("MD5 checksum of write buffer = " + bigInt.toString(16));

        //Read buffer
        digest.reset();
        digest.update(readBuffer);
        md5sum = digest.digest();
        bigInt = new java.math.BigInteger(1, md5sum);
        System.out.println("MD5 checksum of read  buffer = " + bigInt.toString(16));
    } catch (Exception e) {
        System.err.println("MD5 checksum not available");
        return;
    }
}

}

我还尝试使用ICU unicode库(版本4.4.2)构建sqlite。我使用以下命令来构建具有unicode支持的sqlite。

cl.exe -32 -O2 / D“NDEBUG”/ MD / D“_WIN32”/ D“_WINDOWS”/ D“_MBCS”/ D“_USRDLL”/ D“SQLITE_ENABLE_COLUMN_METADATA”/ D“SQLITE_ENABLE_FTS3”/ D“ SQLITE_THREADSAFE = 1“/ D”SQLITE_ENABLE_ICU“-I ../ external / icu / win32 / include -I ../ include -c NativeDB.c -o NativeDB.o

cl.exe -32 -O2 / D“NDEBUG”/ MD / D“_WIN32”/ D“_WINDOWS”/ D“_MBCS”/ D“_USRDLL”/ D“SQLITE_ENABLE_COLUMN_METADATA”/ D“SQLITE_ENABLE_FTS3”/ D“ SQLITE_THREADSAFE = 1“/ D”SQLITE_ENABLE_ICU“-I ../ external / icu / win32 / include -I ../ include -c sqlite3.c -o sqlite3.o

link.exe -32 / DLL /libpath:../external/icu/win32/lib /out:sqlite.dll NativeDB.o sqlite3.o icuuc.lib icuin.lib gdi32.lib vfw32.lib user32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib wbemuuid.lib netapi32.lib ws2_32.lib kernel32.lib

mt.exe -32 / manifest sqlite.dll.manifest /outputresource:sqlite.dll';#2'

使用/不使用unicode构建无效。我仍然无法解决问题。我将非常感谢任何帮助或指向可能的解决方案/解决方法。

1 个答案:

答案 0 :(得分:0)

我终于解决了这个问题。罪魁祸首是Visual Studio 6自动添加的“NDEBUG”标志。以下命令集正确构建了sqlite库(构建环境是Microsoft Windows SDK v6.1 - 2008年发布)。

cl.exe / O2 / GL / D“WIN32”/ D“_WINDLL”/ D“_UNICODE”/ D“UNICODE”/ MD / W3 / c / Wp64 / TC / D“SQLITE_ENABLE_COLUMN_METADATA”/ D“SQLITE_ENABLE_FTS3” / D“SQLITE_THREADSAFE = 1”/ D“SQLITE_ENABLE_ICU”/ I“../external/icu/Win32/include”sqlite3.c

cl.exe / O2 / GL / D“WIN32”/ D“_DLL”/ D“_WINDLL”/ D“_UNICODE”/ D“UNICODE”/ MD / W3 / c / Wp64 / TC / D“SQLITE_ENABLE_COLUMN_METADATA” / D“SQLITE_ENABLE_FTS3”/ D“SQLITE_THREADSAFE = 1”/ D“SQLITE_ENABLE_ICU”NativeDB.c

link.exe / INCREMENTAL:NO / DLL / SUBSYSTEM:CONSOLE / OPT:REF / OPT:ICF / LTCG / MACHINE:X86 /LIBPATH:"../external/icu/Win32/lib“”/ out:sqlite .dll“NativeDB.obj sqlite3.obj icuuc.lib icuin.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib

mt.exe / manifest sqlite.dll.manifest /outputresource:sqlite.dll';#2'

我发布命令以防其他人可能遇到同样的问题。