2013-03-05 13 views
6

Mam metodę Java w obiekcie dostępu do danych. Ta bardzo prosta metoda wstawia dwie liczby całkowite do bazy danych.Czy metoda w obiekcie dostępu do danych (DAO) powinna rzucić lub przechwycić wyjątek?

public void saveHourMin(int hour, int min) throws SQLException{ 
psInsert.setInt(1, hour); 
psInsert.setInt(2, min); 
psInsert.executeUpdate(); 
} 

Gdyby ta metoda, lub, mówiąc ogólnie, wszelkie metody DAO, gdy wyjątek SQLException jest wyrzucane, czy też powinna złapać i logowania wyjątek, a następnie informuje użytkownika za pomocą kodu powrotu? Jakie jest właściwe podejście do aplikacji używającej Springa?

+5

Nie ma jednej uzgodnionej "najlepszej praktyki" w tym zakresie. –

+0

@MattBall - Jestem tego pewien. Ale jestem w tym nowy i muszę zrobić zdjęcie, jak rozwiązać te sytuacje. – Artegon

+0

W rzeczywistości najczęstszą praktyką w obsłudze wyjątków DAO jest zawijanie ich w niestandardowe klasy wyjątków DAO. Przeczytaj ten bardzo dobry i popularny samouczek BalusC, który omawia m.in. obsługę wyjątków DAO i inne dobre praktyki: [Samouczek DAO - warstwa danych] (http://balusc.blogspot.com/2008/07/dao-tutorial-data -layer.html) – informatik01

Odpowiedz

1

Powiedziałbym, że nie. Złap wyjątek SQLException, a następnie wyrzuć wyjątek RuntimeException lub jeden w przypadku potomków. Nie chcesz zanieczyszczać aplikacji wyjątkami dostępu do danych. Na przykład nie powinno się przechwytywać SQLExceptions w warstwie GUI. Nie zbudowałbym też aplikacji opartej na kodach powrotu.

Wrzucając wyjątek RuntimeException, nie zmuszaj rozmówców do przechwytywania.

4

Nie możesz liczyć na to, że osoba dzwoniąca będzie konsekwentnie sprawdzać kody powrotne, lepiej wyrzucić wyjątek.

Jeśli rzucisz wyjątek SQLException, to będzie brudny, prawdopodobnie skończysz z wyższymi warstwami, dodając "wyjątki rzutów" dla każdej metody lub po prostu jedząc wyjątki. Żadna z tych alternatyw nie jest dobra.

Sposób, w jaki robi to Spring, dostarcza tłumacza wyjątków, który przyjmuje oryginalny wyjątek SQLException i generuje podklasę klasy RuntimeException, która zawiera oryginalny wyjątek SQLException i która stara się podać jak najwięcej informacji o błędzie, w tym używanie kodów błędów dostawcy do decydowania, którą konkretną podklasę wyrzucić. Jeśli korzystasz z dowolnego z jdbcTemplates programu Spring, otrzymasz funkcję tłumaczenia wyjątków, więc nie będziesz musiał włączać wyjątków do obiektów dostępu do danych.

Jeśli nie chcesz używać Spring, możesz uchwycić wyjątek SQLException w środowisku DAO i wygenerować wyjątek RuntimeException, w tym oryginalny wyjątek SQLException. Nic nie można zrobić z większością SQLExceptions, po prostu chcesz szybko zawieść i uzyskać wyjątek zalogowany.

+0

Używam Springa. Czy możesz podać mi więcej informacji, jak rozwiązać ten problem w Spring Framework? – Artegon

+2

@ user1315357 zacznij tutaj: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/dao.html. użyj szablonu jdbc, a uzyskasz dostęp do tłumaczenia wyjątku. http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/jdbc.html –

+0

@ user1315357 Zobacz także ten samouczek, aby dowiedzieć się, ile kodu za pomocą jdbc można zapisać: http://www.dzone.com/tutorials/java/spring/spring-jdbc-tutorial-1.html. Googling "samouczek wiosny jdbc" wywołuje wiele rzeczy. –

1

Utworzę nowy wyjątek o nazwie DAOException, który NIE jest wyjątkiem RuntimeException, i zmusi użytkownika metody do obsługi takich wyjątków, z możliwym wyliczeniem jako członkiem wyjątku DAOException, który opisuje wyjątek (prawdopodobnie dodanie rzeczywistego wyjątek wewnątrz jako wyjątek wewnętrzny).

Więc rzucony wyjątek może wyglądać następująco:

new DAOException(DAOException.TYPE.SQLE, e) 

i metoda saveHourMin rzuca DAOException.

W ten sposób, jeśli masz różne problemy, wszystkie są objęte tym samym wyjątkiem i nie musisz obsługiwać innych.

Powodem, dla którego proponuję użyć ogólnego wyjątku, a nie Runtime, jest to, że nie chcę, aby obsługa była wyjątkowa. Ktokolwiek nazywa tę metodę, musi zdawać sobie sprawę z tego, że taki problem może wystąpić i zapewnić odpowiednią obsługę (nawet jeśli oznacza to wyrzucenie nowego wyjątku RuntimeException, niech Bóg broni, ale teraz to zależy od nich i to jest ich decyzja). Jako ogólną zasadę uniknęłabym użycia Wyrażeń RuntimeException, ponieważ sprawiają, że ścieżka wykonywania jest niejasna ("ktoś prawdopodobnie złapie to gdzieś na ścieżce wykonawczej lub zabije aplikację, więc można ją puścić" nie brzmi dla mnie dobre).