原先有个系统是用delphi进行开发的,使用了firebird数据库,建库的时候没有选择编码,当然,在delphi中,读写中文都是正常的。现在需要给原系统加个从别的数据库同步数据的功能,因为是远程同步,同步的数据量也不大,频率一天四次,就打算用嵌入式jetty,写个简单的handler实现这个功能,客户端采用httpclient进行数据上传。客户端与服务器之间用https双向认证的方式。
稀里哗啦一顿乱写,终于把基本代码写完了,一运行,晕了,同步过来的数据,写到firebird中,居然都是乱码。按firebird的jdbc驱动jaybird手册中说的,给jdbc连接串添加?lc_ctype=GBK也没有用,乱码依旧。
经过反复的测试,证明要写正确的字符到数据库中,别的方法我不知道,但下面的应急方法,还是有点用处,主要思路就是用preparestatement,字段内容以参数的方式写入,凡是字符串字段,不用setString方法,而是采用setBytes的方式,参数用GBK转码。
上代码片段:
class.forName("org.firebirdsql.jdbc.FBDriver");
Connection conn = DriverManager.getConnection(
"jdbc:firebirdsql://localhost:3050/D:/db/card.fdb",
"sysdba", "masterkey");
conn.setAutoCommit(false);
PreparedStatement pstmt = conn.prepareStatement("insert into CARDLOGCOPY values(?, ?, ?, ?, ?)");
try {
//循环插入新记录
for(int i = 0, n = records.size(); i < n; ++i) {
JSONArray record = records.getJSONArray(i);
for(int j = 0, m = record.size(); j < m; ++j) {
Object val = record.get(j);
if(val instanceof String)
pstmt.setBytes(j + 1, ((String)val).getBytes("GBK"));
else if(val instanceof Date)
pstmt.setString(j + 1, String.format("%tF %<tT", val));
else
pstmt.setObject(j + 1, val);
}
pstmt.execute();
pstmt.clearParameters();
}
conn.commit();
}
catch (Exception e) {
rollback(conn); //回滚事务
logger.error("数据库操作出错,事务回滚.", e);
throw e;
}
finally {
pstmt.close;
conn.close;
}