JavaRush /Blog Java /Random-PL /Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierw...
Макс
Poziom 41

Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD (część 3)

Opublikowano w grupie Random-PL
Dzień dobry. W tym artykule chciałbym podzielić się swoim pierwszym spotkaniem z takimi rzeczami jak Maven, Spring, Hibernate, MySQL i Tomcat w procesie tworzenia prostej aplikacji CRUD. To jest trzecia część 4. Artykuł przeznaczony jest przede wszystkim dla tych, którzy przeszli już tutaj 30-40 poziomów, ale jeszcze nie odważyli się wyjść poza czystą Javę i dopiero zaczynają (lub dopiero zaczynają) wkraczać w otwarty świat z wszystkie te technologie, frameworki i inne nieznane słowa. Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD (część 3) - 1To trzecia część artykułu „Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD”. Poprzednie części można zobaczyć pod linkami:

Treść:

Tworzenie i łączenie bazy danych

No cóż, czas zacząć pracę nad bazą danych. Zanim podłączymy Hibernate i zastanowimy się jak to wszystko powinno tam działać, przyjrzyjmy się najpierw samej bazie danych, czyli. Stwórzmy to, połączmy, zróbmy i wypełnijmy znak. Będziemy korzystać z systemu DBMS (Database Management System) MySQL (oczywiście należy najpierw pobrać i zainstalować). SQL (Structured Query Language) to deklaratywny język programowania używany do tworzenia, modyfikowania i manipulowania danymi w relacyjnej bazie danych. W takich bazach dane przechowywane są w formie tabel. W jaki sposób aplikacja komunikuje się z bazą danych (przesyłanie zapytań SQL do bazy i zwracanie wyników). Do tego w Javie istnieje coś takiego jak JDBC (Java DataBase Connectivity) , które w uproszczeniu stanowi zestaw interfejsów i klas do pracy z bazami danych. Aby wejść w interakcję z bazą danych, musisz utworzyć połączenie, w tym celu pakiet java.sqlma klasę Connection. Istnieje kilka sposobów nawiązania połączenia, można na przykład użyć metody getConnectionklasowej DriverManager. Jednak interakcja z bazą danych nie odbywa się bezpośrednio, ponieważ baz danych jest wiele i są one różne. Zatem dla każdego z nich istnieje własny sterownik JDBC, za pomocą którego nawiązywane jest połączenie z bazą danych. Dlatego przede wszystkim, aby nie rozpraszać się tym później, zainstalujmy sterownik MySQL . Dodajmy pom.xmlnastępującą zależność:
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>
Teraz utwórzmy bazę danych. Widok -> Okna narzędzi -> Baza danych - otworzy się panel bazy danych. Nowy (zielony +) -> Źródło danych -> MySQL - otworzy się okno, w którym należy podać nazwę użytkownika i hasło, ustawiamy je podczas instalacji MySQL (dla przykładu użyłem root i root). Port (domyślny dla MySQL 3306), nazwa itp. zostaw to tak jak jest. Możesz przetestować połączenie za pomocą przycisku „ Testuj połączenie ”. Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD (część 3) - 2Kliknij OK i teraz jesteśmy połączeni z serwerem MySQL. Następnie utwórzmy bazę danych. Aby to zrobić, możesz napisać skrypt w konsoli, która się otworzy:
CREATE DATABASE test
Kliknij Wykonaj i baza danych będzie gotowa, możesz ją teraz podłączyć.W tym celu wróć do Właściwości źródła danych i w polu Baza danych wpisz nazwę bazy danych (test), następnie ponownie wprowadź nazwę użytkownika i hasło i kliknij OK. Teraz musimy zrobić stół. Można korzystać z narzędzi graficznych, ale po raz pierwszy chyba warto napisać skrypt odręcznie, żeby zobaczyć jak wygląda:
USE test;

CREATE TABLE films
(
  id int(10) PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(100) NOT NULL,
  year int(4),
  genre VARCHAR(20),
  watched BIT DEFAULT false  NOT NULL
)
COLLATE='utf8_general_ci';
CREATE UNIQUE INDEX films_title_uindex ON films (title);

INSERT INTO `films` (`title`,`year`,`genre`, watched)
VALUES
  ("Inception", 2010, "sci-fi", 1),
  ("The Lord of the Rings: The Fellowship of the Ring", 2001, "fantasy", 1),
  ("Tag", 2018, "comedy", 0),
  ("Gunfight at the O.K. Corral", 1957, "western", 0),
  ("Die Hard", 1988, "action", 1);
Tworzona jest tabela o nazwie filmsz kolumnami itp id. titleDla każdej kolumny wskazany jest typ (maksymalny rozmiar wyjściowy w nawiasach).
  • PRIMARY KEY- jest to klucz podstawowy, służący do jednoznacznej identyfikacji rekordu w tabeli (co implikuje unikalność)
  • AUTO_INCREMENT— wartość zostanie wygenerowana automatycznie (oczywiście będzie różna od zera, więc nie musisz jej podawać)
  • NOT NULL- tutaj też wszystko jest oczywiste, nie może być puste
  • DEFAULT— ustaw wartość domyślną
  • COLLATE- kodowanie
  • CREATE UNIQUE INDEX— uczynić pole wyjątkowym
  • INSERT INTO— dodaj rekord do tabeli
Efektem jest taki znak: Być może warto na razie spróbować się z nim połączyć, niezależnie od naszej aplikacji internetowej. A jeśli pojawią się z tym jakieś problemy, to rozwiążemy je od razu. Inaczej później podłączymy Hibernację , zrobimy coś, skonfigurujemy, majstrujemy, a jak gdzieś coś namieszamy, to przynajmniej będziemy wiedzieć, że tu nie ma problemu. Cóż, aby sprawdzić połączenie, utwórzmy maintymczasowo metodę. W zasadzie możesz go umieścić gdziekolwiek, nawet w klasie kontrolera, nawet w modelu czy konfiguracji, nie ma to znaczenia, wystarczy go użyć, aby upewnić się, że wszystko jest w porządku z połączeniem i można go usunąć. Ale żeby być ostrożniejszym, utwórzmy dla niego osobną klasę Main:
package testgroup.filmography;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Main {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/test";
        String username = "root";
        String password = "root";
        System.out.println("Connecting...");

        try (Connection connection = DriverManager.getConnection(url, username, password)) {
            System.out.println("Connection successful!");
        } catch (SQLException e) {
            System.out.println("Connection failed!");
            e.printStackTrace();
        }
    }
}
Tutaj wszystko jest proste, ustawiamy parametry połączenia z naszą bazą danych i próbujemy nawiązać połączenie. Uruchommy ten maini spójrzmy. Otrzymałem więc wyjątek, problemy ze strefą czasową i inne ostrzeżenie dotyczące protokołu SSL. Przeglądając Internet można się przekonać, że jest to dość powszechny problem, a przy korzystaniu z różnych wersji sterownika (mysql-connector-Java) może kląć inaczej. Dowiedziałem się np. eksperymentalnie, że przy korzystaniu z wersji 5.1.47 nie ma wyjątków ze względu na strefę czasową, połączenie jest nawiązywane normalnie, lecz nadal wyskakuje ostrzeżenie SSL. W przypadku niektórych innych wersji wydawało się, że istnieje wyjątek dotyczący protokołu SSL, a nie tylko ostrzeżenie. OK, nie o to chodzi. Możesz spróbować rozwiązać ten problem osobno, ale nie będziemy się nim teraz zajmować. Rozwiązanie tego problemu jest dość proste, musisz określić dodatkowe parametry w adresie URL , a mianowicie serverTimezone, jeśli problem dotyczy strefy czasowej i useSSLjeśli problem dotyczy protokołu SSL:
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false";
Teraz ustawiliśmy strefę czasową i wyłączyliśmy SSL. Uruchamiamy go ponownie maini voila - połączenie pomyślne! Świetnie, wymyśliliśmy, jak stworzyć połączenie. Klasa Mainw zasadzie wykonała swoje zadanie, możesz ją usunąć.

ORM i JPA

W dobrym sensie, dla lepszego zrozumienia, lepiej zacząć zapoznawanie się z bazami danych po kolei, od samego początku, bez żadnych hibernacji i innych rzeczy. Dlatego warto byłoby sięgnąć po jakieś poradniki i najpierw spróbować popracować z klasami JDBC, ręcznie pisać zapytania SQL itd. Cóż, przejdźmy od razu do modelu ORM . Co to znaczy? Oczywiście ponownie warto przeczytać o tym osobno, ale spróbuję to krótko opisać. ORM (Object-Relational Mapping, czyli mapowanie obiektowo-relacyjne) to technologia służąca do mapowania obiektów w struktury relacyjnych baz danych, tj. do reprezentowania naszego obiektu Java jako wiersza tabeli. Dzięki ORM nie musisz martwić się pisaniem skryptów SQL i skupić się na pracy z obiektami. Jak tego użyć. Java ma jeszcze jedną świetną rzecz, JPA (Java Persistence API), która implementuje koncepcję ORM. JPA jest taką specyfikacją, opisuje wymagania stawiane obiektom, definiuje różne interfejsy i adnotacje do pracy z bazą danych. JPA to w zasadzie opis, standard. Dlatego istnieje wiele konkretnych implementacji, z których jedną (i jedną z najpopularniejszych) jest Hibernate, będący istotą tego frameworka. Hibernate jest implementacją specyfikacji JPA zaprojektowaną do rozwiązywania problemów związanych z mapowaniem obiektowo-relacyjnym (ORM). Musimy to wszystko połączyć z naszym projektem. Dodatkowo, aby nasz Spring nie stał z boku i także brał udział w całym tym ruchu z bazami danych, musimy podłączyć jeszcze kilka modułów, bo wszystko, co otrzymaliśmy z zależności spring-webmvc, już do tego nie wystarczy. Będziemy także potrzebować spring-jdbc do pracy z bazą danych, spring-tx do obsługi transakcji i spring-orm do pracy z Hibernacją. Dodajmy zależności do pom.xml:
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>5.1.1.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.3.7.Final</version>
</dependency>
Te dwie zależności wystarczą. javax.persistence-apipojawi się wraz z hibernate-core oraz spring-jdbc i spring-tx wraz z spring-orm .

Podmiot

Chcemy więc, aby obiekty klas Filmmogły być przechowywane w bazie danych. Aby było to możliwe, klasa musi spełniać szereg warunków. W JPA istnieje coś takiego jak Entity . Klasa encji to zwykła klasa POJO z prywatnymi polami oraz funkcjami pobierającymi i ustawiającymi. Musi mieć konstruktor nieprywatny bez parametrów (lub konstruktor domyślny) i musi mieć klucz podstawowy, tj. coś, co jednoznacznie identyfikuje każdy rekord tej klasy w bazie danych. Możesz także przeczytać o wszystkich wymaganiach dla takiej klasy osobno. Uczyńmy naszą klasę Filmjednostką za pomocą adnotacji JPA:
package testgroup.filmography.model;

import javax.persistence.*;

@Entity
@Table(name = "films")
public class Film {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "title")
    private String title;

    @Column(name = "year")
    private int year;

    @Column(name = "genre")
    private String genre;

    @Column(name = "watched")
    private boolean watched;

    // + getters and setters
}
  • @Entity- wskazuje, że ta klasa jest bytem.
  • @Table- wskazuje konkretną tabelę, aby wyświetlić tę encję.
  • @Id— wskazuje, że pole to jest kluczem podstawowym, tj. ta właściwość będzie używana do identyfikacji każdego unikalnego wpisu.
  • @Column— łączy pole z kolumną tabeli. Jeśli nazwy pól i kolumn tabeli są takie same, możesz je pominąć.
  • @GeneratedValue— właściwość zostanie wygenerowana automatycznie, w nawiasach możesz określić sposób. Nie będziemy teraz rozumieć, jak dokładnie działają różne strategie. Wystarczy wiedzieć, że w tym przypadku każda nowa wartość będzie zwiększać się o 1 w stosunku do poprzedniej.
Dla każdej właściwości można dodatkowo określić wiele innych rzeczy, np. co ma być niezerowe lub unikalne, określić wartość domyślną, maksymalny rozmiar itp. Będzie to przydatne, jeśli chcesz wygenerować tabelę na podstawie tej klasy; Hibernate ma tę opcję. Ale sami stworzyliśmy już tabelę i skonfigurowaliśmy wszystkie właściwości, więc możemy się bez niej obejść. Mała uwaga.Dokumentacja Hibernate zaleca używanie adnotacji nie na polach, ale na modułach pobierających. Jednak różnica między tymi podejściami jest dość subtelna i w naszej prostej aplikacji nie będzie to miało żadnego wpływu. Poza tym większość ludzi i tak umieszcza adnotacje nad polami. Dlatego zostawmy to tak, wygląda schludniej.

Właściwości hibernacji

Cóż, zacznijmy konfigurować naszą hibernację. Przede wszystkim umieśćmy pewne informacje, takie jak nazwa użytkownika i hasło, adres URL i inne informacje w osobnym pliku. Można je oczywiście określić jako zwykłą linię bezpośrednio w klasie, tak jak to zrobiliśmy podczas sprawdzania połączenia ( String username = "root";a następnie przekazaliśmy to do metody tworzenia połączenia). Ale nadal bardziej poprawne jest przechowywanie takich statycznych danych w jakimś propertypliku. A jeśli na przykład będziesz musiał zmienić bazę danych, to nie będziesz musiał przeglądać wszystkich klas i szukać, gdzie jest ona używana, wystarczy raz zmienić wartość w tym pliku. Utwórzmy plik db.properties w katalogu zasobów :
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false
jdbc.username=root
jdbc.password=root

hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
hibernate.show_sql=true
No cóż, od góry wszystko jasne, parametry połączenia z bazą danych, tj. nazwa klasy sterownika, adres URL, nazwa użytkownika i hasło. hibernate.dialect- ta właściwość jest potrzebna, aby wskazać Hibernate, która konkretna wersja języka SQL jest używana. Faktem jest, że w każdym DBMS-ie, aby rozszerzyć możliwości, dodać jakąś funkcjonalność lub coś zoptymalizować, zwykle nieco unowocześnia się język. W rezultacie okazuje się, że każdy DBMS ma swój własny dialekt SQL. To tak jak z angielskim, wydaje się, że język jest ten sam, ale w Australii, USA czy Wielkiej Brytanii będzie nieco inny, a niektóre słowa mogą mieć inne znaczenie. A żeby uniknąć problemów ze zrozumieniem, trzeba bezpośrednio powiedzieć Hibernacji, z czym dokładnie ma się uporać. hibernate.show_sql— dzięki tej właściwości zapytania do bazy danych będą wyświetlane w konsoli. Nie jest to konieczne, ale dzięki tej rzeczy możesz przynajmniej spojrzeć na to, co się dzieje, w przeciwnym razie może się wydawać, że Hibernacja robi jakąś magię. No cóż, oczywiście nie będzie to do końca jasne do wyświetlenia, lepiej użyć do tego jakiegoś rejestratora, ale to już inna sprawa, na razie wystarczy.

Konfiguracja hibernacji

Przejdźmy do ustawienia konfiguracji. configStwórzmy klasę w pakiecie HibernateConfig:
package testgroup.filmography.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@ComponentScan(basePackages = " testgroup.filmography")
@EnableTransactionManagement
@PropertySource(value = "classpath:db.properties")
public class HibernateConfig {
    private Environment environment;

    @Autowired
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        return properties;
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
        dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
        dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
        dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("testgroup.filmography.model");
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(sessionFactory().getObject());
        return transactionManager;
    }
}
Nowości jest tu całkiem sporo, dlatego najlepiej jest dodatkowo szukać informacji na temat każdego przedmiotu w różnych źródłach. Omówmy to krótko tutaj.
  • @ConfigurationJuż ustaliliśmy @ComponentScan, kiedy odrabialiśmy zajęcia WebConfig.
  • @EnableTransactionManagement— umożliwia wykorzystanie go TransactionManagerdo zarządzania transakcjami. Hibernacja współpracuje z bazą danych za pomocą transakcji, są one potrzebne, aby określony zestaw operacji mógł zostać wykonany jako jedna całość, tj. jeśli metoda ma problemy z którąś operacją, to wszystkie pozostałe nie zostaną wykonane, więc nie stanie się tak jak w klasycznym przykładzie z przelewem, gdy operacja wypłaty pieniędzy z jednego rachunku została zakończona, ale operacja zapisu do innego nie zadziałała, w rezultacie pieniądze zniknęły.
  • @PropertySource— podłączenie pliku właściwości, który niedawno utworzyliśmy.
  • Environment- w celu pobrania właściwości z propertypliku.
  • hibernateProperties- ta metoda jest potrzebna do reprezentowania właściwości Hibernate jako obiektu Properties
  • DataSource— służy do tworzenia połączenia z bazą danych. Jest to alternatywa dla DriverManagera , z którego korzystaliśmy wcześniej, tworząc plik main. Dokumentacja mówi, że DataSourcelepiej jest używać. Tak oczywiście zrobimy, nie zapominając o przeczytaniu w Internecie, jakie są różnice i zalety. Szczególną korzyścią jest możliwość utworzenia puli połączeń bazy danych (DBCP).
  • sessionFactory— do tworzenia sesji, za pomocą których przeprowadzane są operacje na obiektach encji. Tutaj ustawiamy źródło danych, właściwości Hibernate i w jakim pakiecie mamy szukać klas jednostek.
  • transactionManager— aby skonfigurować menedżera transakcji.
Mała uwaga dot DataSource. Dokumentacja mówi, że korzystanie ze standardowej implementacji, a mianowicie DriverManagerDataSource, nie jest zalecane, ponieważ zastępuje on jedynie normalne łączenie połączeń i ogólnie nadaje się tylko do testów i tym podobnych. W przypadku normalnej aplikacji lepiej jest użyć jakiejś biblioteki DBCP. Cóż, dla naszej aplikacji oczywiście wystarczy to, co mamy, ale dla uzupełnienia obrazu być może nadal zastosujemy inną implementację zgodnie z zaleceniami. Dodajmy pom.xmlnastępującą zależność:
<dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-dbcp</artifactId>
            <version>9.0.10</version>
</dependency>
A w metodzie dataSourceklasowej HibernateConfigzastępujemy ją DriverManagerDataSourcejedną BasicDataSourcez pakietu org.apache.tomcat.dbcp.dbcp2:
BasicDataSource dataSource = new BasicDataSource();
No cóż, wszystko wydaje się gotowe, konfiguracja gotowa, pozostaje tylko dodać ją do naszego AppInitializera :
protected Class<?>[] getRootConfigClasses() {
        return new Class[]{HibernateConfig.class};
    }

Warstwa dostępu do danych

Nadszedł czas, aby w końcu zacząć korzystać z naszego DAO. Idziemy na zajęcia FilmDAOImpli przede wszystkim usuwamy stamtąd listę próbną, nie jest nam już potrzebna. Dodajmy fabrykę sesji i przepracujmy ją.
private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }
Na początek stworzymy metodę wyświetlania strony z listą filmów, w niej otrzymamy sesję i złożymy zapytanie do bazy danych (wyciągając wszystkie rekordy i tworząc listę):
public List<Film> allFilms() {
        Session session = sessionFactory.getCurrentSession();
        return session.createQuery("from Film").list();
    }
Tutaj są 2 punkty. Najpierw wyświetliło się ostrzeżenie. Dzieje się tak dlatego, że chcemy otrzymać sparametryzowaną wartość List<Film>, ale metoda zwraca po prostu Listdlatego, że w czasie kompilacji nie wiadomo, jakiego typu żądanie zwróci. Pomysł ostrzega nas więc, że dokonujemy niebezpiecznej konwersji, która może skutkować problemami. Istnieje kilka poprawnych sposobów, aby to zrobić, aby takie pytanie nie pojawiło się. Informacje możesz wyszukiwać w Internecie. Ale nie zawracajmy sobie tym teraz głowy. Fakt jest taki, że wiemy dokładnie jaki typ zostanie zwrócony, zatem nie będzie tu żadnych problemów, ostrzeżenie można po prostu zignorować. Ale żeby nie bolały Cię oczy, możesz powiesić adnotację nad metodą @SupressWarning("unchecked"). Robiąc to, w pewnym sensie mówimy kompilatorowi: dziękuję kolego za troskę, ale wiem, co robię i mam wszystko pod kontrolą, więc możesz się zrelaksować i nie martwić tą metodą. Po drugie, pomysł jest podkreślony na czerwono „ from Film”. To tylko zapytanie HQL (Hibernate Query Language) i pomysł nie rozumie, czy wszystko jest poprawne, czy też wystąpił błąd. Możesz przejść do ustawień pomysłu i ręcznie dostosować wszystko (jeśli jesteś zainteresowany, poszukaj w Internecie). Możesz też po prostu dodać obsługę frameworku Hibernate, w tym celu kliknij projekt prawym przyciskiem myszy, wybierz opcję Add Framework Support , zaznacz pole Hibernate i kliknij OK. Następnie najprawdopodobniej w klasie encji ( Film) wiele rzeczy również zostanie podkreślonych na czerwono, np. w miejscu, w którym adnotacja @Table(name = "films")wyświetli ostrzeżenie Nie można rozwiązać tabeli „filmy” . Powtórzę: nie ma tu nic złego, nie jest to błąd projektowy, wszystko się skompiluje i będzie działać. Pomysł jest podkreślany, ponieważ nic nie wie o naszej bazie. Aby to naprawić, zintegrujmy pomysł z bazą danych. Widok -> Okna narzędziowe -> Trwałe (otworzy się zakładka) -> prawy przycisk myszy, wybierz Przypisz źródła danych -> w Źródle danych określ połączenie z bazą danych i kliknij OK . Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD (część 3) - 3Kiedy to wszystko zostało naprawione, nadal coś pozostało. Przejdźmy na wyższy poziom, do serwisu. W klasie metodę spring FilmServiceImploznaczamy allFilmsadnotacją @Transactional, która wskaże, że metoda powinna zostać wykonana w transakcji (bez tego Hibernate odmówi działania):
@Transactional
public List<Film> allFilms() {
    return filmDAO.allFilms();
}
Tutaj wszystko jest gotowe, nie musisz niczego dotykać w kontrolerze. Cóż, wygląda na to, że nadeszła chwila prawdy, kliknij Uruchom i zobacz, co się stanie. Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD (część 3) - 4I oto jest nasz znak, tym razem uzyskany nie z listy, którą sami stworzyliśmy na zajęciach, ale z bazy danych. Świetnie, wygląda na to, że wszystko działa. Teraz wszystkie pozostałe operacje CRUD wykonujemy w ten sam sposób, korzystając z metod sesyjnych. Wynikowa klasa wygląda następująco:
package testgroup.filmography.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import testgroup.filmography.model.Film;

import java.util.List;

@Repository
public class FilmDAOImpl implements FilmDAO {
    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Film> allFilms() {
        Session session = sessionFactory.getCurrentSession();
        return session.createQuery("from Film").list();
    }

    @Override
    public void add(Film film) {
        Session session = sessionFactory.getCurrentSession();
        session.persist(film);
    }

    @Override
    public void delete(Film film) {
        Session session = sessionFactory.getCurrentSession();
        session.delete(film);
    }

    @Override
    public void edit(Film film) {
        Session session = sessionFactory.getCurrentSession();
        session.update(film);
    }

    @Override
    public Film getById(int id) {
        Session session = sessionFactory.getCurrentSession();
        return session.get(Film.class, id);
    }
}
Teraz pozostaje tylko nie zapomnieć przejść do usługi i dodać adnotację do metod @Transactional. To wszystko, gotowe. Możesz teraz uruchomić i sprawdzić. Kliknij linki i przyciski, spróbuj dodać/usunąć/edytować wpisy. Jeżeli wszystko zostało zrobione poprawnie to powinno działać. Teraz jest to pełnoprawna aplikacja CRUD wykorzystująca Hibernate, Spring, MySQL. Ciąg dalszy... Przedstawiamy Mavena, Springa, MySQL, Hibernate i pierwszą aplikację CRUD (część 1) Przedstawiamy Mavena, Springa, MySQL, Hibernate i pierwszą aplikację CRUD (część 2) Przedstawiamy Mavena, Springa, MySQL, Hibernate i pierwsza aplikacja CRUD (część 3) Wprowadzenie do Maven, Spring, MySQL, Hibernate i pierwsza aplikacja CRUD (część 4)
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION