2011-08-28 56 views
36

Hãy tưởng tượng tôi có một truy vấn nhưJDBC ResultSet có được cột với bảng bí danh

SELECT * from table1 a, table2 b where (WHATEVER) 

Có lẽ cả hai bảng có tên cùng một cột. Vì vậy, tôi mặc dù sẽ thật tuyệt khi truy cập dữ liệu qua số

resultSet.getString("a.columnName"); 
resultSet.getString("b.columnName"); 

Nhưng điều này phản tác dụng đối với tôi và tôi không nhận được gì. Tôi đọc API, nhưng họ không thực sự nói về trường hợp này. Là một nhà cung cấp tính năng phụ thuộc?

Trả lời

39

JDBC sẽ chỉ đơn giản là đặt tên cho các cột bởi những gì được quy định trong truy vấn - nó không biết về tên bảng, vv

Bạn có hai lựa chọn:

Lựa chọn 1: Tên các cột khác nhau trong truy vấn, tức là

SELECT 
    a.columnName as columnNameA, 
    b.columnName as columnNameB, 
    ... 
from table1 a, table2 b where (WHATEVER) 

sau đó trong mã java bạn tham khảo các bí danh cột:

resultSet.getString("columnNameA"); 
resultSet.getString("columnNameB"); 


Phương án 2: Tham khảo cột vị trí trong lệnh gọi API JDBC:

resultSet.getString(1); 
resultSet.getString(2); 

Lưu ý rằng API JDBC sử dụng một dựa trên chỉ số - tức là họ đếm từ 1 (không phải từ 0 như chỉ mục java), do đó hãy sử dụng 1 cho cột đầu tiên, 2 cho cột thứ hai, v.v.


Tôi khuyên bạn nên chọn tùy chọn 1, vì an toàn hơn để tham chiếu đến các cột được đặt tên: Ai đó có thể thay đổi thứ tự của các cột trong truy vấn và nó sẽ tự động ngắt mã của bạn (bạn sẽ truy cập sai cột nhưng không biết), nhưng nếu họ thay đổi tên cột, ít nhất bạn sẽ nhận được ngoại lệ "không có cột đó" khi chạy.

+0

vẻ rồi như tôi sẽ phải quên đi những đẹp * và tên tất cả mọi thứ và sử dụng một bản đồ thêm. –

8

Sử dụng bí danh cột như SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B... và chỉ định tất cả các cột bạn đang truy xuất (là phương pháp hay).

0

Bạn có thể sử dụng bí danh trên cấp SQL. Sau đó, bạn truy xuất dữ liệu theo chỉ mục. (Tuy nhiên, phương pháp này sẽ làm cho bảo trì một cơn ác mộng thực)

SELECT a.column, b.column FROM table1 a, table2 b 

String value = rs.getString(1); 
0

Một ý tưởng tôi đã là sử dụng getTableName(iCol) để lấy bảng tên cho các cột duplicately tên, sau đó quấn một hash của các phím riêng của bạn (với tiền tố tên bảng) sẽ chỉ cho bạn chỉ mục cột chính xác và tham chiếu cột-giá trị của bạn theo cách đó. Điều này sẽ yêu cầu một vòng lặp ban đầu thông qua các dữ liệu meta lúc đầu để thiết lập. Vấn đề duy nhất tôi thấy với điều này là bạn đang bí danh tên bảng. Tôi chưa tìm được cách để nhận các bí danh tên bảng đó từ jdbc mà không tự quản lý nó khi bạn xây dựng câu lệnh sql. Giải pháp này sẽ phụ thuộc vào việc trả tiền cú pháp sẽ là gì đối với bạn.

+0

@Bohemian - bạn có thể sử dụng hàm ResultSetMetaData :: getTableName (int) để lấy tablename. Tôi không chắc chắn nếu kết quả phụ thuộc vào việc thực hiện jdbc, mặc dù. https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSetMetaData.html#getTableName(int) – inyourcorner

0

Ok, có vẻ như không có phương pháp như resultSet.getString("a.columnName"); và bạn phải bí danh cột của bạn ở mức sql, nhưng nhân vì có một phương pháp getTableName(iCol) Tôi hy vọng chàng trai tại java.sql.ResultSet thêm một tính năng như vậy.

9

ResultSetMetadata.getColumnLabel() là những gì bạn cần

(chỉnh sửa) mẫu ví dụ, như đã nói bởi cừu bharal trong bình luận

SELECT * from table1 a, table2 b where (WHATEVER) 

ResultSetMetaData rsmd = rset.getMetaData(); 
rsmd.getColumnLabel(1); 
+1

tại sao và như thế nào và ví dụ về cách làm việc này là gì? – bharal

+0

ở đó bạn đã chỉnh sửa câu trả lời bằng đoạn mã mẫu – Mateen

2

Nếu bạn đang sử dụng MySQL chỉ cần thêm

&useOldAliasMetadataBehavior=true 

đến connectionString của bạn.

Sau đó bạn có thể sử dụng Helper này chút:

import java.sql.ResultSet; 
import java.sql.ResultSetMetaData; 
import java.sql.SQLException; 
import java.util.HashMap; 
import java.util.Map; 

public class ResultSetHelper { 

    private final Map<String, Integer> columnMap; 

    public ResultSetHelper(ResultSet rs) throws SQLException { 
     this.columnMap = new HashMap<>(); 
     ResultSetMetaData md = rs.getMetaData(); 
     int columnCount = md.getColumnCount(); 
     for (int index = 1; index <= columnCount; index++) { 
      String columnName = md.getColumnLabel(index); 
      if (!columnMap.containsKey(columnName)) { 
       columnMap.put(columnName, index); 
      } 

      String tableAlias = md.getTableName(index); 
      if (tableAlias != null && !tableAlias.trim().isEmpty()) { 
       columnMap.put(tableAlias + "." + columnName, index); 
      } 
     } 
    } 

    public Integer getColumnIndex(String columnName) { 
     return columnMap.get(columnName); 
    } 

    public Integer getColumnIndex(String tableAlias, String columnName) { 
     return columnMap.get(tableAlias + "." + columnName); 
    } 

} 
Các vấn đề liên quan