2009-08-11 10 views
18

Jaki jest zalecany sposób obcięcia tabeli za pomocą hibernacji/hql?Użycie hibernacji/hql do obcięcia tabeli?

Próbowałem to:

 
Query query = session.createQuery("truncate table MyTable"); 
query.executeUpdate(); 

Ale to nie działa (truncate nie wydaje się nie być udokumentowane gdziekolwiek w HQL ...)

+2

Usunięcie zawartości nie jest standardowym DML lub poleceń DDL, więc to normalne, że nie jest obsługiwane. –

Odpowiedz

11

Chyba jest okropny sposób prowadzenia to usunie wszystko.

public int hqlTruncate(String myTable){ 
    String hql = String.format("delete from %s",myTable); 
    Query query = session.createQuery(hql); 
    return query.executeUpdate(); 
} 
+0

Skończyło się na tym, ponieważ zwykle mam tylko dwadzieścia rekordów do usunięcia w tym samym czasie ... Dzięki! – user149100

+14

truncat! = Usuń –

+2

@stunaz Sure truncat! = Usuń, ale rozwiązaniem jest tutaj kompromis – Stephan

33

Można użyć session.createSQLQuery() zamiast:

session.createSQLQuery("truncate table MyTable").executeUpdate(); 

trzeba dodawać, że to nie jest idealny pod względem przenośności. Dobrym pomysłem jest zdefiniowanie tego zapytania w odwzorowaniu i pobranie go w kodzie jako zapytanie nazwane.

+2

Uwaga 'createNativeQuery' jest preferowany po wersji 5.2 – aristotll

5

Użyłem składni delete w HQL, aby zachować przenośność. Działa świetnie:

public abstract class GenericDAOImpl<T, ID extends Serializable> implements GenericDAO<T, ID> { 

private Class<T> persistentClass; 

// Balance of dao methods snipped... :) 

/** 
* Clears all records from the targetted file. 
* @throws DAOException 
*/ 
public int truncate() throws DAOException { 
    Session s = getSession(); 
    int rowsAffected = 0; 
    try { 
     Class c = getPersistentClass(); 
     String hql = "delete from " + c.getSimpleName(); 
     Query q = s.createQuery(hql); 
     rowsAffected = q.executeUpdate(); 
    } catch (HibernateException e) { 
     throw new DAOException("Unable to truncate the targetted file.", e); 
    } 
    return rowsAffected; 
} 
/** 
* Returns a Class object that matches target Entity. 
* 
* @return Class object from constructor 
*/ 
public Class<T> getPersistentClass() { 
    return persistentClass; 
} 

Działa świetnie i całkowicie obcina docelowy stół. Należy zachować ostrożność, ponieważ serwer db wykona to polecenie z dużą wydajnością ... :)

13

należy zachować ostrożność, skracać i usuwać są całkowicie oddzielnymi instrukcjami sql: - usuwanie jest DML, a obcięcie to DDL, co oznacza, że ​​można usunąć być wycofanym i skrócone nie może być wycofane - delete musi znaleźć każdy wiersz jeden po drugim. obciąć jest natychmiastowa - usunięcie zastosowania cofnąć dzienniki i obciąć nie

jeśli umieścić je wszystkie razem: 1/jeśli ma to być rollbackable, nie chcesz używać obciąć 2/jeśli używasz usuwać , biorąc pod uwagę rozmiar tabeli, którą chcesz opróżnić: - jeśli tabela jest mała, nie zobaczysz żadnej różnicy - jeśli tabela jest średniej wielkości, wystąpi zła wydajność - jeśli stół będzie duży, zabraknie Ci spacja w przestrzeni tabel cofania, a nie będziesz w stanie opróżnić niczego, co jest konieczne, aby zachować ostrożność w odniesieniu do stwierdzenia, którego naprawdę chcesz użyć.

co do obcięcia tabeli z hql, powinno być zabronione uruchamianie DDL (obcięcie, tworzenie tabeli, upuszczenie tabeli, itd ...) z aplikacji. Powinieneś użyć delete. Ale jeśli stół jest duży, to też nie zadziała. Dlatego opróżnianie tabeli w aplikacji jest generalnie złym pomysłem. Jeśli chcesz wykonać pewne czyszczenie, często lepiej jest skracać skrypt sql raz na dobę.

Zauważ, że nie wiem, specyfiki aplikacji i że mówi tylko w ogólnym

Powiązane problemy