Zadanie z wzorcem projektowym DAO

Zadanie z wzorcem projektowym DAO
Maciek_SK8
  • Rejestracja:prawie 3 lata
  • Ostatnio:około miesiąc
  • Postów:72
0

Cześć!
Napisałem taki prosty progam, w którym wykorzystałem wzorzec DAO. Program operuje na bazie Library, która przechowuje tabelę books (id ,title, authorFirstName, authorLastName). Tabeli tej odpowiada klasa Book. Program ten napisałem w celu przećwiczenia tego wzorca na przykładzie książek. Możliwe, że rozszerzę go o obsługę plików JSON. Jednak najpierw chce się dowiedzieć, czy zmierzam w dobrym kierunku.

Tutaj link: https://github.com/MaciekSm19/BooksLibrary

A tutaj struktura tabeli w phpmyadmin: screenshot-20250323115233.png

SL
  • Rejestracja:około 7 lat
  • Ostatnio:około 3 godziny
  • Postów:901
1

public class Book implements Serializable {

Z tego co czytam to Hibernate nie wymaga Serializable. Jako, że Serializable jest kontrowersyjne to nie trzymałbym się tego rozwiązania

Kopiuj
public interface DAO<T extends Serializable> {
    void persist(T entity);
    T findById(Integer id);
    List<T> findAll();
    void update(T entity);
    void delete(T entity);
    void deleteAll();
}

Za bardzo nie widzę sensu posiadania takiego interfejsu. Jak często potrzebujesz generycznego kodu, który powinien działać jednocześnie dla DAO<User> i DAO<Order>? Interfejs to narzut, jeśli nikt nie korzysta z abstrakcji, to nie ma to sensu. Jeśli chcesz go zatrzymać to warto go IMO rozbić. Rzadko w prawdziwej aplikacji chcesz implementować wszystkie metody

Kopiuj
    private Session openSession() {
        sessionFactory = getSessionFactory();
        session = sessionFactory.openSession();
        return session;
    }

Ten kod nie jest bezpieczny do wywołania z wielu wątków, bo modyfikujesz pole w klasie DAO. Lepiej po prostu użyć zmiennych lokalnych

Kopiuj
 T findById(Integer id);

Lepiej zwrócić Optional<T> przez co dla użytkownika API oczywistym jest, że wartości może nie być

Maciek_SK8
  • Rejestracja:prawie 3 lata
  • Ostatnio:około miesiąc
  • Postów:72
0

Za bardzo nie widzę sensu posiadania takiego interfejsu. Jak często potrzebujesz generycznego kodu, który powinien działać jednocześnie dla DAO<User> i DAO<Order>? Interfejs to narzut, jeśli nikt nie korzysta z abstrakcji, to nie ma to sensu. Jeśli chcesz go zatrzymać to warto go IMO rozbić. Rzadko w prawdziwej aplikacji chcesz implementować wszystkie metody

Czyli lepiej będzie rozdzielić ten interfejs na 4 interfejsy do odczytu, dodawania, aktualizacji, usuwania rekordów?

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4709
2

to openSession() i closeSession() to tragedia:

Kopiuj
    public List<Book> findAll() {
        String hql = "FROM Book";
        List<Book> books = openSession().createQuery(hql, Book.class).list();
        closeSession();
        return books;
    }

Wystarczy, że poleci wyjątek i lądujesz z niezamkniętą sesją.
Użyj try with resources
Do tego nie trzymaj sessji w polu -> do niczego tego nie potrzebujesz. Metody closeSession nie powinno tu być.

W wersji bardziej wypasionej mógłbyś napisać lambdę:

Kopiuj
  public <RESULT> RESULT doInSession(Function<Session,RESULT> action) {
      try (Session session = openSession()) {
         return action(session);
      }
  }

jeden i pół terabajta powinno wystarczyć każdemu
edytowany 5x, ostatnio: jarekr000000
Maciek_SK8
  • Rejestracja:prawie 3 lata
  • Ostatnio:około miesiąc
  • Postów:72
0

Użyj try with resources
Do tego nie trzymaj sessji w polu -> do niczego tego nie potrzebujesz. Metody closeSession nie powinno tu być.

To znaczy w każdej metodzie dać try with resources otwierający sesję?

Maciek_SK8
  • Rejestracja:prawie 3 lata
  • Ostatnio:około miesiąc
  • Postów:72
0

tutaj poprawiony kod: https://github.com/MaciekSm19/BooksLibrary/tree/main

Teraz to lepiej wyglada?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.