W dzisiejszym tutorialu zaprezentujemy porównanie metod wyciągania danych z bazy danych porównując dwa podejścia. W obydwu przypadkach wykorzystamy Framework Spring’a. W pierwszym przypadku użyjemy klasy JdbcTemplate, która upraszcza klasyczny sposób wykorzystania interfejsu JDBC. W drugim zaprezentujemy wykorzystanie Object-Relational Mapping (ORM) z wykorzystaniem biblioteki Spring Data JPA. Na potrzeby tutorialu pominiemy konfigurację połączenia z serwerem bazy danych.
Aby móc skorzystać z obydwu rozwiązań skorzystamy z repozytorium SpringBoot:
@Data @AllArgsConstructor @NoArgsConstructor @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String firstName; private String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }
Aby zredukować nadmierną liczbę kodu, wykorzystujemy annotacje z biblioteki lombok do generowania getterów oraz setterów jak również konstruktorów. Widać również annotacje @Entity, @Id oraz @GeneratedValue – wykorzystywane przez ORM o czym później.
W przypadku wykorzystania jdbcTemplate wszystkie annotacje z pakietu javax.persistence są zbędne.
private final RowMapper<Person> personRowMapper = (rs, i) -> new Person(
rs.getLong("id"),
rs.getString("first_name"),
rs.getString("last_name")
);
Potrzebujemy również samo zapytanie, które w przykładzie chcemy żeby zwróciło wszystkie osoby z tabeli Person. Zapytanie jest bardzo proste i skonstruowane w SQL-u:
private static final String PG_FIND_ALL_PERSONS = "SELECT id, first_name, last_name FROM person";
Teraz można już stworzyć metodę zwracającą pożądany wynik:
public List<Person> findAll() { return jdbcTemplate.query(PG_FIND_ALL_PERSONS, personRowMapper); }
@Repository
public interface SprintDataJpaPersonRepository extends JpaRepository<Person, Long> {
}
Interfejs rozszerzamy o JpaRepository, gdzie wskazujemy Encję której mają dotyczyć nasze query oraz klucz główny. To wystarczy do tego, żeby dysponować gotowymi metodami do wszystkich operacji CRUD i tak przykładowo metoda List findAll() znajduje się w interfejsie JpaRepository tak więc do wyciągnięcia wszystkich wpisów z tabeli person wystarczy wykorzystać gotową już metodę. Lista dostępnych metod z JpaRepository znajduje się poniżej:
@NoRepositoryBean public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { List<T> findAll(); List<T> findAll(Sort var1); List<T> findAllById(Iterable<ID> var1); <S extends T> List<S> saveAll(Iterable<S> var1); void flush(); <S extends T> S saveAndFlush(S var1); void deleteInBatch(Iterable<T> var1); void deleteAllInBatch(); T getOne(ID var1); <S extends T> List<S> findAll(Example<S> var1); <S extends T> List<S> findAll(Example<S> var1, Sort var2); }
Jeśli zamierzamy manipulować na danych w reprezentacji klas-relacja to zdecydowanie wygodniejszym sposobem jest wykorzystanie ORM. Wykorzystanie biblioteki Spring Data JPA przyśpiesza nam proces budowania warstwy dostępu do danych. W sytuacji w której potrzebujemy stworzyć skomplikowane zapytanie i niekoniecznie potrzebujemy potem uzyskać reprezentację obiektową, JdbcTemplate może okazać się lepszym i wygodniejszym rozwiązaniem.
Projekt dostępny pod adresem:
$ git clone git clone https://bitbucket.org/ptmsoft/ptm-blog.git