2013-01-12 29 views
5

Piszę aplikację Java, która używa Hibernate do pobierania danych, w mojej aplikacji mam wejściowy obszar tekstowy, który pobiera wpisywany przez użytkownika ciąg znaków polecenia sql i uruchamia go przez Hibernate, aby uzyskać dowolne dane, które użytkownik prosi, więc nie wiem wcześniej, jak tabela wyników może wyglądać i dlatego nie zna nazw kolumn, ale muszę wyświetlić wynik zapytania użytkownika w tabeli z nazwami kolumn odnoszą się do pól danych, w jaki sposób osiągnąć to w Hibernacja? Próbowałem następujący kod:Jak uzyskać nazwy kolumn z wyniku zapytania Hibernate w Javie?

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()); 

Dało mi się następujący komunikat o błędzie: Wyjątek w wątku „AWT-EventQueue-0” java.lang.ClassCastException: sakila.entity.Actor nie mogą być oddane do java. util.Map

Wskazuje na pierwszą pętlę for, ponieważ jestem nowy w Hibernate, nie wiem, czy jest to wykonalne, jak naprawić powyższy kod? Czy ktoś może mi pokazać przykładowy kod, który działa w moim przypadku?

Edycja: Jak wspomniano poniżej Marcel Stör, muszę mieć możliwość wystąpienia obu sytuacji i nie ograniczać możliwości wyszukiwania danych przez użytkowników, jaki jest najlepszy sposób na zrobienie tego?

Odpowiedz

1

ja nie bardzo rozumiem, ale wciąż ośmielają się odpowiedzieć ...

Jeśli używasz HQL jak ten Query q=session.createQuery(hql); sugeruje wrócisz obiektów a nie poszczególnych pól domyślnie. Oznacza to, że i tak masz pecha, próbując odwzorować wyniki na zapytanie, ALE możesz po prostu użyć nazw pól obiektu jako nazw kolumn.

Jeśli to, co dostajesz z obszaru tekstowego, to zwykły SQL, musisz użyć session.createSQLQuery(sql). To, co otrzymasz, to list of object arrays. Jednak także tutaj otrzymujesz tylko dane. Użytkownik musiałby zabronić użytkownikom korzystania z zapytań o numer select *. Następnie możesz użyć nazwy pola/kolumny w zapytaniu jako nazwy kolumn wyjściowych.

0

Czy użytkownik wpisuje zapytanie SQL lub HQL? Między nimi jest duża różnica.

Jeśli użytkownik wpisze zapytanie HQL, można zadzwonić pod numer hqlQuery.getReturnTypes(), a następnie dla każdego typu można wykonać whatever suggested in this post, aby znaleźć metadane tabeli.

0

Mam ten sam rodzaj problemu dla zapytania HQL jak

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

że mogę używać jako widok DTO

z jednym lub większą liczbą zapisów mogę iterację mapie, która jest elementem List<Map<String, Object> . Problem występuje tylko wtedy, gdy muszę zarządzać sytuacją z pustym zbiorem danych. W tym przypadku coś jak

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; 
}