2012-12-23 30 views
7

Tôi đang gặp sự cố khi đọc trường VARBINARY của MySQL dưới dạng Chuỗi sử dụng JdbcTemplate. Chúng tôi đang lưu trữ các từ viết tắt chuỗi ("ABC", "XYZ", "LMN" và các loại tương tự) làm VARBINARYs (không hỏi tôi tại sao). Kỳ lạ, đủ, khi tôi sử dụng các kết nối lớp/PreparedStatement tuyến đường, và đồng bằng cũ ResultSets vs SqlRowSet, tôi không có vấn đề đọc String. Đó là để nói,JdbcTemplate: truy cập trường MySQL VARBINARY dưới dạng Chuỗi

Mã này hoạt động:

String sql = "select MY_VARBINARY_FIELD from MY_TABLE where KEY1=? and KEY2=?"; 
PreparedStatement stmt = connectionDev.prepareStatement(sql); 
prepStmt1.setInt(1, key1); 
prepStmt1.setInt(2, key2); 
ResultSet rs = stmt.executeQuery(); 

while (rs.next()) { 
    String s = rs.getString("MY_VARBINARY_FIELD"); 
    System.out.print(s + " "); 
} 

**Output:** AHI-1 DKFZp686J1653 FLJ14023 FLJ20069 JBTS3 ORF1 dJ71N10.1 

Nhưng mã này không:

String sql = "select MY_VARBINARY_FIELD from MY_TABLE where KEY1=? and KEY2=?"; 
Object[] params = {key1, key2}; 
SqlRowSet rows = getJdbcTemplate().queryForRowSet(sql, params); 

while (rows.next()) { 
    String s = rows.getString("MY_VARBINARY_FIELD"); 
    System.out.print(s + " "); 
} 

**Output:** [[email protected] [[email protected] [[email protected] [[email protected] [[email protected] [[email protected] [[email protected] 

Tại sao SqlRowSet và ResultSet tạo ra một đại diện chuỗi khác nhau cho các VARBINARY? Và làm thế nào tôi có thể có được "chính xác" đại diện bằng cách sử dụng JdbcTemplate/SqlRowSet?

Cảm ơn!

SOLUTION

Đánh dấu Rotteveel (dưới đây) đã trả lời câu hỏi. Tôi đã nhận nó để làm việc với điều này:

String sql = "select MY_VARBINARY from MY_TABLE where KEY=VALUE"; 

SqlRowSet rows = getJdbcTemplate().queryForRowSet(sql); 

while (rows.next()) { 
    byte[] varbinary = (byte[]) rows.getObject("MY_VARBINARY"); 
    System.out.println(new String(varbinary)); 
} 

Trả lời

6

Các [[email protected] vv là kết quả của một toString() trên một mảng byte. Một VARBINARY được biểu diễn bằng cách sử dụng một byte[] trong JDBC. Nhiều khả năng khi bạn truy cập trực tiếp vào số PreparedStatement, trình điều khiển thực hiện new String(getBytes(idx)), trong khi JdbcTemplate có thể thực hiện thay thế getObject(idx).toString(), dẫn đến kết quả đầu ra như [[email protected].

Vì vậy, để khắc phục điều này, làm một getBytes() trên JdbcTemplate, và chuyển nó sang chuỗi cho bản thân hoặc (tốt hơn), sử dụng các mảng byte trực tiếp hoặc thay đổi kiểu dữ liệu cột VARCHAR để thay thế.

+0

+1 vị trí tốt. Ngoài ra, có lẽ là một ý tưởng tốt để xác định mã hóa ký tự để tránh sự khác biệt nền tảng – artbristol

+0

@artbristol Đúng, nhưng tôi nghi ngờ người lái xe cũng đang làm việc đó mà không có ký tự rõ ràng. –

+0

+1 Điều này làm cho rất nhiều ý nghĩa và bạn có thể đúng. Tôi sẽ kiểm tra sau ngày hôm nay. – ktm5124

0

Nếu tôi sử dụng như dưới đây, nó là tốt.

  • org.mybatis 3.2.8
  • mysql-connector-java 5.1.38 || mariadb-connector-java
  • Java Bean, chuỗi riêng myVarbinary;

my_varbinary(64) là dành cho SessionID/NameOfEnglis h vì vậy mà tôi không cần phải xem xét character_set và mã hóa/giải mã.