2013-01-12 33 views
5

Tôi đang viết một ứng dụng Java có sử dụng Hibernate để lấy dữ liệu, trong ứng dụng của tôi, tôi có một vùng văn bản đầu vào để người dùng nhập chuỗi lệnh sql và chạy thông qua Hibernate để nhận bất kỳ dữ liệu nào mà người dùng truy vấn, vì vậy tôi không biết trước bảng kết quả có thể trông như thế nào và do đó không biết tên cột, nhưng tôi cần hiển thị kết quả truy vấn người dùng trong bảng có tên cột liên quan đến trường dữ liệu, cách đạt được điều đó trong Hibernate? Tôi đã thử đoạn mã sau:Cách lấy tên cột từ kết quả truy vấn Hibernate trong Java?

Session session=HibernateUtil.getSession(); 
    session.beginTransaction(); 
    Query q=session.createQuery(hql); 

    AliasToEntityMapResultTransformer INSTANCE=new AliasToEntityMapResultTransformer(); 
    q.setResultTransformer(INSTANCE); 
    List<Map<String,Object>> aliasToValueMapList=q.list(); 

    for (Map<String,Object> map : aliasToValueMapList) 
    for (Map.Entry<String,Object> entry : map.entrySet()) System.out.println(entry.getKey()+" - "+entry.getValue()); 

Nó đã cho tôi thông báo lỗi sau: Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: sakila.entity.Actor không thể được đúc để java. util.Map

Nó trỏ đến vòng 1 cho vòng lặp, vì tôi mới dùng Hibernate, không biết nếu nó có thể thực hiện được trong đó, cách sửa mã trên? Ai đó có thể chỉ cho tôi một số mã mẫu hoạt động trong trường hợp của tôi không?

Chỉnh sửa: Như Marcel Stör đã đề cập bên dưới, tôi cần có khả năng cho phép cả hai tình huống xảy ra và không giới hạn khả năng truy vấn dữ liệu của người dùng, cách tốt nhất để làm điều đó là gì?

Trả lời

1

Tôi hoàn toàn không hiểu nhưng vẫn dám trả lời ...

Nếu bạn sử dụng HQL như Query q=session.createQuery(hql); điều này cho thấy bạn trở lại đối tượng và không lĩnh vực cá nhân theo mặc định. Điều này có nghĩa là bạn không may mắn khi cố gắng ánh xạ lại kết quả cho truy vấn NHƯNG bạn chỉ có thể sử dụng tên trường của đối tượng làm tên cột.

Nếu nội dung bạn nhận được từ vùng văn bản là SQL thuần túy, thì bạn phải sử dụng session.createSQLQuery(sql). Những gì bạn nhận được là list of object arrays. Tuy nhiên, ở đây bạn cũng chỉ nhận được dữ liệu. Bạn sẽ phải cấm người dùng của mình sử dụng các truy vấn select *. Sau đó, bạn có thể sử dụng tên của trường/cột trong truy vấn làm tên cột đầu ra của bạn.

0

Người dùng có nhập truy vấn SQL hoặc HQL không? Có sự khác biệt lớn giữa chúng.

Nếu người dùng nhập truy vấn HQL, bạn có thể gọi hqlQuery.getReturnTypes() và sau đó cho từng loại bạn có thể làm whatever suggested in this post để tìm hiểu siêu dữ liệu bảng.

0

Tôi đã có cùng một loại vấn đề cho HQL truy vấn như

select new Map(id as id, name as name) from Person 

mà tôi sử dụng như xem DTO

Với một hoặc nhiều hồ sơ tôi có thể lặp qua các bản đồ đó là yếu tố List<Map<String, Object> . Sự cố chỉ khi tôi cần quản lý tình huống với trống tập dữ liệu. Đối với trường hợp đó , chẳng hạn như

public List<String> getAliases(String queryString) { 
    ArrayList<String> list = 
     new ArrayList<String>(Arrays.asList(queryString.split("as "))); 
    List<String> result = new ArrayList<String>(); 
    list.remove(0); 
    for (String str : list) { 
     StringTokenizer st = new StringTokenizer(str, ",) "); 
     result.add(st.nextToken()); 
    } 
    return result; 
} 
Các vấn đề liên quan