這聽起來像你的Java源文件編碼爲UTF-8,所以當cityName
字符串包含LEÓN
時,它被編碼爲
L E Ó N
-- -- ----- --
4C 45 C3 93 4E
這不是Access如何存儲該值。 Access將字符存儲爲Unicode,但不使用UTF-8編碼。它使用UTF-16LE編碼的變體,其中代碼點U + 00FF及以下的字符存儲在單個字節中,代碼點大於U + 00FF的字符存儲爲空(0x0)值,後跟UTF-16LE字節對。在這種情況下Ó
是U + 00D3,低於U + 00FF,因此訪問存儲的字符串作爲單字節的所有四個字符:
的淨效應是,該字符串在訪問數據庫中的編碼與ISO 8859-1字符集相同。
這可以通過使用JDBC-ODBC Bridge的以下Java代碼進行確認。它未能找到當Java源文件編碼爲UTF-8
所需的記錄,但是當Java源文件在Eclipse中編碼爲cp1252
它的工作原理:
import java.sql.*;
public class accentTestMain {
public static void main(String[] args) {
String connectionString =
"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};" +
"DBQ=C:\\__tmp\\test\\accented.accdb;";
try {
Connection con = DriverManager.getConnection(connectionString);
PreparedStatement stmt = con.prepareStatement("SELECT * FROM localities WHERE locName=?");
String cityName = "LEÓN";
stmt.setString(1, cityName);
stmt.execute();
ResultSet rs = stmt.getResultSet();
if (rs.next()) {
System.out.println(String.format("Record found, ID=%d", rs.getInt("ID")));
}
else {
System.out.print("Record not found.");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
如果你可以用僅支持重音字符做用cp1252
字符集表示,那麼您應該可以簡單地使用cp1252
作爲Java源文件的編碼設置。
另一方面,如果您確實需要使用Access數據庫完全支持Unicode字符,那麼JDBC-ODBC Bridge將不會爲您完成工作。這是JDBC-ODBC Bridge和Access ODBC驅動程序之間長期存在的互操作性問題,它不會被修復。 (更多詳細信息here。)
在這種情況下,您可能需要考慮使用UCanAccess,它是Access的純Java JDBC驅動程序。使用UCanAccess用UTF-8編碼的源文件中的對應的代碼將是
// assumes...
// import java.sql.*;
Connection conn=DriverManager.getConnection(
"jdbc:ucanaccess://C:/__tmp/test/accented.accdb");
PreparedStatement ps = conn.prepareStatement(
"SELECT ID FROM localities WHERE locName=?");
ps.setString(1, "LEÓN");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
System.out.println(String.format(
"Record found, ID=%d",
rs.getInt("ID")));
}
else {
System.out.println("Record not found.");
}
有關詳細信息有關使用UCanAccess,請參閱相關問題here。
另一種解決方案是使用Jackcess操縱Access數據庫像這樣(再次,Java源文件編碼爲UTF-8):
import java.io.File;
import java.io.IOException;
import com.healthmarketscience.jackcess.*;
public class accentTestMain {
public static void main(String[] args) {
Database db;
try {
db = DatabaseBuilder.open(new File("C:\\__tmp\\test\\accented.accdb"));
try {
Table tbl = db.getTable("localities");
Cursor crsr = CursorBuilder.createCursor(tbl.getIndex("locName"));
if (crsr.findFirstRow(tbl.getColumn("locName"), "LEÓN")) {
System.out.println(String.format("Record found, ID=%d", crsr.getCurrentRowValue(tbl.getColumn("ID"))));
}
else {
System.out.println("Record not found.");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
db.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
那麼,你得到這個整理出來? –