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ęść 1)

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 pierwsza część 4. Artykuł przeznaczony jest przede wszystkim dla tych, którzy przeszli już tutaj 30-40 poziomów, ale nie odważyli się jeszcze poza czystą Javę i dopiero zaczynają (lub wkrótce rozpoczną) wkraczanie do otwartego świata z wszystkie te technologie, frameworki i inne nieznane słowa. Wprowadzenie do Mavena, Springa, MySQL, Hibernate i pierwszej aplikacji CRUD (część 1) - 1

Treść:

Wstęp

Zacząłem poznawać nowe dla mnie technologie i frameworki studiując różne przykłady ich użycia, bo zazwyczaj najlepiej rozumiem coś, gdy widzę to w akcji na przykładzie pełnoprawnej aplikacji. Zazwyczaj takimi przykładami są aplikacje CRUD ( Utwórz , Odczyt , Aktualizuj , Usuń ), w Internecie jest pełno takich przykładów o różnym stopniu złożoności. Problem w tym, że zazwyczaj nie wyjaśniają szczegółowo jak, co i dlaczego tam zrobiono, po co dodano taką a taką zależność, po co potrzebna jest taka a taka klasa itp. W większości przypadków biorą całkowicie gotową aplikację, z finalnym plikiem POM, z finalnymi wersjami klas i po prostu przeglądają każdą z nich, nie skupiając się na drobiazgach, które dla doświadczonej osoby pewnie wydają się oczywiste. Przyjrzałem się wielu takim przykładom i zwykle jest jasne, jak wszystko działa, ale jak do tego doszli, nie jest do końca jasne. Dlatego uznałem, że taki przykład będzie przydatny nie z pozycji doświadczonego programisty, ale z pozycji początkującego, który nigdy nie miał styczności ze Springiem, Hibernate i innymi rzeczami.
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 2
Postaram się opisać możliwie najdokładniej (na ile moje zrozumienie pozwala) całą moją drogę tworzenia aplikacji CRUD zaczynając od czegoś na najprostszym poziomie Hello World. Przede wszystkim robię to dla siebie, bo kiedy próbujesz coś opisać, opowiedzieć, wyjaśnić, jest to znacznie lepiej przyswojone i uporządkowane w Twojej głowie. Ale jeśli komuś się to przyda i pomoże coś znaleźć, będę bardzo zadowolony. W tym przykładzie spróbujmy stworzyć prostą aplikację CRUD przy użyciu Maven , Tomcat , Spring , Hibernate i MySQL . Wstępne kroki takie jak instalacja Mavena , MySQL , wykorzystanie pomysłu w wersji Ultimate itp. Myślę, że nie ma potrzeby opisywać szczegółowo, nie powinno być z tym problemów. Warto zaznaczyć, że w tym przykładzie konfiguracja zostanie skonfigurowana przy użyciu klas Java (tzw. JavaConfig) bez użycia XML.

Tworzenie projektu

Ponieważ jestem nowicjuszem, nie będziemy używać żadnych nieznanych archetypów. Spring inicjalizator nadal brzmi zbyt przerażająco. Dlatego stworzymy najzwyklejszy prosty projekt Maven. Nie mam nazwy domeny, więc w groupid napiszę po prostu testgroup, a w artefakcie napiszę np. nazwę filmography(będzie to lista filmów). Tworzymy projekt i wybieramy Enable auto-import, kiedy podpowiada to pomysł. Dzięki temu za każdym razem gdy dokonamy jakichkolwiek zmian w pliku POM (Project Object Model, plik ten opisuje całą strukturę projektu Maven), wszystko od razu zostanie automatycznie zastosowane do projektu. Biblioteki zostaną pobrane z naszego lokalnego repozytorium, jeśli już je posiadamy, lub jeśli wykorzystamy jakieś nowe zależności, z którymi wcześniej się nie uporaliśmy, Maven po prostu pobierze je przez Internet z centralnego repozytorium. Maven posiada również funkcję pobierania źródeł i dokumentacji (Pobieranie źródeł i/lub dokumentacji). Jest to również bardzo wygodne, jeśli coś nie jest jasne z jakąś klasą lub metodą, możesz przejść do kodu źródłowego i zobaczyć, jak to wszystko działa w środku. Dodajmy kilka szczegółów. Będzie to aplikacja internetowa i będziemy używać Tomcata . Aby wdrożyć aplikację w Tomcat, musisz przenieść ją tam w formie archiwum wojennego (Web Application Resource, specjalny format dla aplikacji internetowych). Aby to zrobić, dodaj następującą linię do pliku POM, aby aplikacja została skompilowana do archiwum wojennego:
<packaging>war</packaging>
Cóż, będziesz także potrzebował specjalnego katalogu dla źródeł internetowych, w naszym przypadku będą to strony jsp i niektóre zasoby internetowe. Stwórzmy mainkatalog webapp. Powinien się dokładnie tak nazywać i znajdować dokładnie w mainten sam sposób java, co , resourcesponieważ jest to standardowa struktura katalogów Mavena. Gdy już zainstalujemy pakiet wari ustalimy, że jest to projekt internetowy, katalog webappzostanie automatycznie oznaczony jako źródła aplikacji internetowych (będzie na nim niebieska kropka) i wszystko, co jest związane z siecią, będzie przeszukiwane w tym folderze. I jedna chwila. Domyślnie Maven korzysta z wersji językowej 1.5, ale ja chcę używać np. wersji 1.8 - Java 8 (Możesz wziąć 10, albo 11, ale nadal nie ma planów wykorzystania stamtąd jakichkolwiek funkcji, więc niech będzie 8 ). Można to rozwiązać bardzo prosto, piszemy w Google coś w rodzaju „Maven java 8” i sprawdzamy, co trzeba dodać do pliku POM, aby Maven skompilował nasze klasy do wymaganej wersji. W efekcie mamy co następuje: Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 3

Połączenie Spring MVC

Od czegoś trzeba zacząć. Zgodnie z planem podłączymy bazę danych i skorzystamy z Hibernacji, ale na razie to wszystko brzmi trochę zbyt strasznie. Najpierw musimy zrobić coś prostszego. Spring MVC, to jest już lepsze, wzorzec MVC znamy od dawna, był używany w połowie dużych zadań kursu. Od tego momentu zaczniemy tańczyć. Aby stworzyć aplikację internetową przy użyciu Spring MVC, potrzebujemy również Servlet-API, tj. rzecz, za pomocą której nastąpi interakcja żądanie-odpowiedź. Spróbujmy to połączyć. Wchodzimy do Google, szukamy niezbędnych zależności w repozytorium Mavena i dodajemy je do pliku pom.xml. Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 4W sekcji Biblioteki zewnętrzne możesz zobaczyć, że załadowano nie tylko spring-webmvc , ale także kilka innych rzeczy. Te. nie musimy dodatkowo dołączać zależności dla rdzenia sprężyny , kontekstu , fasoli itp. czego potrzebowaliśmy, wszystko, czego potrzebowaliśmy, zostało ściągnięte wraz z spring-webmvc .

Musimy poczynić małe zastrzeżenie. Zwykle zaleca się dodanie zależności osobno dla każdej używanej biblioteki, nawet jeśli są one już dołączone do już dodanych, ponieważ może to pomóc uniknąć pewnych problemów i usterek.

Prosty przykład. Powiedzmy, że dodaliśmy zależność korzystającą z jakiegoś API i jednocześnie pobierzemy jakąś implementację dla tego API. Następnie dodaliśmy kolejną zależność, która korzysta z tego samego interfejsu API i również pobiera w tym celu część jego implementacji, ale tym razem jest inaczej. W ten sposób będziemy mieli 2 różne implementacje tego samego API. A jeśli sami będziemy chcieli gdzieś zastosować jakieś metody tego API, to pojawi się problem, bo system nie będzie wiedział, z której implementacji skorzystać, wybierze losowo, być może nie tę, której się spodziewaliśmy. A jeśli wyraźnie określisz zależność dla jednej z implementacji, wówczas zostanie jej nadany priorytet.

Nie jest to jednak aż tak rygorystyczne zalecenie, dotyczy głównie dużych projektów, w których wykorzystuje się wiele różnych bibliotek różnych firm. Tutaj tego nie zrobimy, żeby nie ładować pliku POM za bardzo, nie spodziewamy się żadnych problemów. Ale mimo wszystko warto o tym pamiętać.

Jeszcze jedna uwaga. Co oznacza provideduzależnienie javax.servlet-api? Zasięg to zakres zależności, providedco oznacza, że ​​zależność będzie dostępna na etapie kompilacji i testowania aplikacji, ale nie będzie archiwizowana. Faktem jest, że do wdrożenia aplikacji wykorzystamy kontener serwletów Tomcat, który ma już w sobie takie biblioteki, więc nie ma potrzeby ich tam przenosić i obciążać archiwum niepotrzebnym obciążeniem. Patrząc w przyszłość, z tego samego powodu obejdziemy się bez zwykłej metody main, ponieważ ona już istnieje w Tomcat.

Tworzenie stron i kontrolera

Spróbujmy teraz ugotować coś prostego. Najpierw utwórzmy webappdodatkowy katalog, np pages. w którym będą przechowywane nasze widoki, tj. jsp i utwórz kilka stron. Przydałaby nam się strona, na której w przyszłości będzie wyświetlana lista filmów np films.jsp. , a może uda nam się zrobić osobną stronę do montażu, niech tak będzie editPage.jsp. Nie będziemy ich na razie wypełniać niczym poważnym, na potrzeby testów umieścimy link na jednej stronie do drugiej. Teraz potrzebujemy klasy, która będzie przetwarzać żądania, tj. kontroler. Dodajmy nowy pakiet controlleri utwórzmy w nim klasę FilmController(w sumie nie ma potrzeby pakować wszystkiego w różne pakiety, ta aplikacja będzie bardzo mała i prosta, ale w normalnym projekcie może być wiele kontrolerów, klas konfiguracyjnych, modeli itp., więc nawet zaczynając od małych projektów, lepiej od razu przyzwyczaić się do robienia wszystkiego w sposób uporządkowany i ustrukturyzowany, aby nie było bałaganu). Na tych zajęciach stworzymy metody, które w odpowiedzi na żądania zwrócą nasze widoki.
package testgroup.filmography.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class FilmController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        return modelAndView;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editPage() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("editPage");
        return modelAndView;
    }
}
Jaki jest sens? Spring MVC ma coś o nazwie DispatcherServlet. Działa to jak główny kontroler, wszystkie przychodzące żądania przechodzą przez niego, a następnie przekazuje je do określonego kontrolera. Adnotacja @Controllerpo prostu mówi Spring MVC, że ta klasa jest kontrolerem (no cóż, ogólnie rzecz biorąc logicznym), dyspozytor sprawdzi adnotacje, @RequestMappingaby wywołać odpowiednią metodę. Adnotacja @RequestMappingpozwala na podanie adresów dla metod kontrolera, dzięki którym będą one dostępne w kliencie (przeglądarce). Można go również zastosować do klasy kontrolera, aby ustawić, że tak powiem, adres główny dla wszystkich metod. allFilms()Parametr metody valuejest ustawiony na " /", więc zostanie wywołana natychmiast po wpisaniu w przeglądarce kombinacji http://host:port/ (czyli domyślnie jest to http://localhost:8080/ lub http ://127.0 .0.1:8080/ ). Parametr methodokreśla, jaki typ żądania jest obsługiwany (GET, POST, PUT itp.). Ponieważ tutaj otrzymujemy tylko dane, używany jest GET. Później, gdy pojawią się metody dodawania i edycji, będą już żądania POST. (Nawiasem mówiąc, zamiast adnotacji @RequestMappingwskazującej metodę, można użyć adnotacji itp. @GetMappingrównoważnie ) ). W naszych metodach tworzymy obiekt i ustalamy nazwę widoku, który ma zostać zwrócony. @PostMapping@GetMapping@RequestMapping(method = RequestMethod.GETModelAndView

Konfiguracja

Przejdźmy do ustawienia konfiguracji. configStwórzmy klasę w pakiecie WebConfig. Będzie miał tylko jedną metodę, która zwraca obiekt typu ViewResolver. Jest to interfejs niezbędny do znalezienia reprezentacji według nazwy.
package testgroup.filmography.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "testgroup.filmography")
public class WebConfig {

    @Bean
    ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
@Configurationmówi Springowi, że ta klasa jest klasą konfiguracyjną i zawiera definicje oraz zależności beankomponentów. Fasola to obiekty zarządzane przez Springa. Adnotacja służy do definiowania komponentu bean @Bean. @EnableWebMvcumożliwia importowanie konfiguracji Spring MVC z pliku WebMvcConfigurationSupport. Można też zaimplementować np. interfejs WebMvcConfigurer, który ma całą masę metod i dostosować wszystko do własnych upodobań, ale nie musimy się jeszcze w to zagłębiać, wystarczą standardowe ustawienia. @ComponentScanmówi Springowi, gdzie ma szukać komponentów, którymi powinien zarządzać, tj. klasy oznaczone adnotacją @Componentlub jej pochodnymi takimi jak @Controller, @Repository, @Service. Te adnotacje automatycznie definiują komponent bean klasy. W metodzie viewResolver()tworzymy jej implementację i określamy, gdzie dokładnie szukać reprezentacji w webapp. Dlatego gdy w metodzie kontrolera ustawimy nazwę " films" widok zostanie znaleziony jako " /pages/films.jsp" Mamy więc klasę konfiguracyjną, ale na razie jest to tylko jakaś osobna klasa, nie wpływa to w żaden sposób na naszą aplikację . Musimy zarejestrować tę konfigurację w kontekście Spring. Do tego potrzebna jest klasa AbstractAnnotationConfigDispatcherServletInitializer. W pakiecie configtworzymy jego następcę, powiedzmy AppInitializer i implementujemy jego metody.
package testgroup.filmography.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
Ostatnia metoda rejestruje adresy, a są jeszcze 2 metody rejestrowania klas konfiguracyjnych. Konfiguracje internetowe, w których ViewResolverzdefiniowano „i tym podobne”, są umieszczane w plikach getServletConfigClasses(). Lepiej o tym wszystkim przeczytać w dokumentacji i różnych przewodnikach, ale w naszym przypadku nie trzeba się jeszcze w to zagłębiać, nasze WebConfigw zasadzie można RootClasseszdefiniować w obu, można nawet zdefiniować oba naraz, nadal będzie działać . Jeszcze jedna rzecz. Mogą wystąpić problemy z kodowaniem, gdy przy wysyłaniu z formularza wartości zawierających znaki rosyjskie efektem będą bazgroły. Aby rozwiązać ten problem, dodamy filtr, który będzie wstępnie przetwarzał żądania. Przechodzimy do klasy AppInitializer i nadpisujemy metodę getServletFilters, w której wskazujemy pożądane kodowanie, powinno ono oczywiście być takie samo jak wszędzie indziej, tak na stronach jak i w bazie:
protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[] {characterEncodingFilter};
    }
Cóż, wszystko wydaje się być skonfigurowane, możesz spróbować uruchomić i zobaczyć, co się stanie. Uruchom -> Uruchom -> Edytuj konfiguracje -> Dodaj nową konfigurację -> Serwer Tomcat -> Lokalny Następnie musisz wybrać artefakt do wdrożenia. Sam pomysł będzie podpowiedzią. Ostrzeżenie: nie oznaczono żadnych artefaktów do rozmieszczenia . Kliknij przycisk naprawy i wybierz ...: wybuchła wojna . Możesz też przejść do Wdrożenie -> dodaj -> Artefakt -> ...: wybuchła wojna . Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 5Musisz także przejść do Wdrożenia i ustawić pole kontekstu Applecation (będzie to część adresu URL, pod którym aplikacja będzie dostępna w przeglądarce) na „ /”. Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 6Wtedy nasza aplikacja będzie od razu dostępna pod adresem http://localhost:8080/ (ale tam też możesz coś określić, np. " /filmography", a wtedy wystarczy, że dodasz to do wszystkich adresów, czyli np. nie będzie „http://localhost:8080/edit” , ale będzie to „http://localhost:8080/filmography/edit” ). Kliknij Uruchom i poczekaj, aż się uruchomi. Oto co otrzymałem: Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 7Wszystko wydaje się być w porządku, ale jest jedno zastrzeżenie. Faktem jest, że nasze strony są teraz publicznie dostępne i można uzyskać do nich bezpośredni dostęp, wpisując ścieżkę w pasku adresu. Wchodzimy pod adres http://localhost:8080/pages/films.jsp i już bez wiedzy administratora otrzymaliśmy naszą stronę. Jakoś nie jest to zbyt poprawne, więc utworzymy webappspecjalny katalog WEB-INF. To, co jest w środku, będzie ukryte przed opinią publiczną i będzie można uzyskać do niego dostęp wyłącznie za pośrednictwem kontrolera. Katalog z naszymi widokami ( pages) umieszczamy w WEB-INFi ViewResolverodpowiednio dodajemy do przedrostka:
viewResolver.setPrefix("/WEB-INF/pages/");
Teraz otrzymamy naszą stronę pod adresem http://localhost:8080 , ale jeśli spróbujemy bezpośrednio wejść na http://localhost:8080/WEB-INF/pages/films.jsp, otrzymamy błąd 404. Cóż, świetnie, mamy najprostsza aplikacja internetowa, jak mówią Hello World. Struktura projektu wygląda obecnie następująco:
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 8

Model

Mamy już widoki i kontroler, ale w MVC jest też trzecia litera, więc dla uzupełnienia obrazu dodamy jeszcze model. W pakiecie modelutwórzmy klasę Filmnp. z polami: int id, String title(tytuł), int year(rok premiery), String genre(gatunek) oraz boolean watched(czyli czy oglądałeś już ten film czy nie).
package testgroup.filmography.model;

public class Film {
    private int id;
    private String title;
    private int year;
    private String genre;
    private boolean watched;
// + Getters and setters
}
Nic specjalnego, po prostu zwykła klasa, prywatne pola, pobierające i ustawiające. Obiekty takich klas nazywane są także POJO(Plain Old Java Object), cóż, tj. „prosty obiekt Java”. Spróbujmy teraz stworzyć taki obiekt i wyświetlić go na stronie. Na razie nie będziemy się zbytnio martwić, jak go utworzyć i zainicjować. Aby to wypróbować, po prostu głupio utwórzmy to bezpośrednio w kontrolerze, na przykład tak:
public class FilmController {
    private static Film film;

    static {
        film = new Film();
        film.setTitle("Inception");
        film.setYear(2010);
        film.setGenre("sci-fi");
        film.setWatched(true);
    }
I dodaj ten obiekt do naszego ModelAndViewza pomocą metody addObject:
@RequestMapping(method = RequestMethod.GET)
    public ModelAndView allFilms() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("films");
        modelAndView.addObject("film", film);
        return modelAndView;
    }
Teraz możemy wyświetlić ten obiekt na naszej stronie. Zamiast films.jspHello World napiszemy ${film}i obiekt odpowiadający nazwie atrybutu „ film” zostanie tutaj podstawiony. Spróbujmy go uruchomić i zobaczmy, co się stanie (dla wyraźnego wyniku obiektu klasa Filmzostała przedefiniowana toString()):
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 9

Kontroler widoku modelu

Na tym etapie wydaje się, że mamy już pełnoprawną aplikację Spring MVC. Zanim przejdziemy dalej, dobrze byłoby jeszcze raz przyjrzeć się wszystkiemu i dowiedzieć się, jak to wszystko działa. W Internecie można znaleźć wiele zdjęć i schematów na ten temat, podoba mi się ten:
Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 1) - 10
Gdy zapiszemy żądanie w linii przeglądarki, zostaje ono zaakceptowane Dispatcher Servlet, następnie znajduje odpowiedni kontroler, za pomocą którego może przetworzyć to żądanie HandlerMapping(jest to interfejs wyboru kontrolera, sprawdza, który z dostępnych kontrolerów posiada metodę akceptującą taki adres) , wywołuje odpowiednią metodę i Controllerzwraca informację o widoku, następnie dyspozytor znajduje żądany widok po nazwie za pomocą ViewResolver'a, po czym dane modelu są przesyłane do tego widoku i jako wynik otrzymujemy naszą stronę. Coś takiego. 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