JavaRush /Java Blogu /Random-AZ /Maven, Spring, MySQL, Hibernate və ilk CRUD tətbiqinə gir...
Макс
Səviyyə

Maven, Spring, MySQL, Hibernate və ilk CRUD tətbiqinə giriş (4-cü hissə)

Qrupda dərc edilmişdir
Günortanız Xeyir. Bu yazıda sadə CRUD tətbiqi yaratma prosesində Maven, Spring, Hibernate, MySQL və Tomcat kimi şeylərlə ilk tanışlığımı bölüşmək istərdim. Bu son hissədir. Məqalə ilk növbədə burada 30-40 səviyyəni tamamlamış, lakin hələ təmiz Java-dan kənara çıxmamış və bütün bu texnologiyalar, çərçivələr və digər tanış olmayan sözlərlə açıq dünyaya yenicə girməyə başlayanlar (və ya başlamaq üzrə olanlar) üçün nəzərdə tutulub. . Bu, “Maven, Spring, MySQL, Hibernate və ilk CRUD tətbiqinə giriş” məqaləsinin sonuncu dördüncü hissəsidir. Əvvəlki hissələrə aşağıdakı linklərdən baxmaq olar:

Məzmun:

Dizayn və veb resursları

Tətbiqimiz işləyir, ancaq göz yaşları, darıxdırıcı yazılar, çirkin linklər, boş ağ fon olmadan baxa bilməzsiniz. Bunu düzəltmək və müxtəlif gözəlliklər əlavə etmək lazımdır. Bunu necə edirik? Yaxşı, ilk növbədə, siz sadəcə olaraq səhifələrlə oynaya və HTML imkanlarından istifadə edərək hər cür şey edə bilərsiniz . Ancaq yalnız HTML-dən istifadə edərək fonları, rəngləri, ölçüləri, elementlərin düzülməsini və s. dəyişdirməyə çalışsanız. və s. sonra sonda səhifədən elə bir qarışıqlıq yarada bilərsiniz ki, sonradan orada heç nə çıxara bilməyəcəksiniz. Bundan əlavə, HTML-nin dizayn variantları olduqca məhduddur. Bunun üçün CSS (Cascading Style Sheets) istifadə etmək daha yaxşıdır. Sonra dizaynla əlaqəli hər şey bir yerdə toplana bilər və sonra səhifənin istədiyiniz elementinə tətbiq oluna bilər. CSS kodu birbaşa JSP səhifəsində xüsusi etiketdə yazıla bilər , lakin onu ayrı bir fayla yerləşdirmək və sonra sadəcə lazımi səhifələrə tətbiq etmək daha rahatdır. Stilləri və digər statik veb resursları olan faylları yerləşdirmək üçün biz webapp daxilində ayrıca kataloq yaradacağıq . Veb resurslarını adi resurslarla qarışdırmamaq üçün (burada bizdə db.properties var ), gəlin bu kataloqu res adlandıraq və bütün CSS fayllarını, şəkilləri və s.-ni orada yerləşdirək:
Maven, Spring, MySQL, Hibernate və ilk CRUD tətbiqinə giriş (4-cü hissə) - 1
Bu faylları istifadə etmək üçün konfiqurasiyada onların yerini göstərməliyik. Gəlin sinifimizə gedək WebConfig. Əvvəllər annotasiyadan @EnableWebMvcheç nəyi konfiqurasiya etməmək üçün istifadə edirdik, sadəcə olaraq standart konfiqurasiyadan istifadə edirdik. Ancaq indi nəyisə konfiqurasiya etməyə ehtiyac var. WebMvcConfigurerBunu etmək üçün konfiqurasiya üsullarını ləğv etməyə imkan verən interfeysdən istifadə edirik . Bu. biz standart konfiqurasiyadan istifadə edə bilərik, lakin eyni zamanda bəzi aspektləri özümüz üçün fərdiləşdirə bilərik. Bu vəziyyətdə addResourceHandlers, statik veb resurslarının yerini göstərdiyimiz bir üsula ehtiyacımız var. Hər halda, bütün sinif belə görünür:
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.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

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

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/res/**").addResourceLocations("/res/");
    }

    @Bean
    ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}
İndi səhifədə CSS-imizdən istifadə etmək üçün etiket daxilində ona keçid etməlisiniz head:
<head>
    <link href="<c:url value="/res/style.css"/>" rel="stylesheet" type="text/css"/>
</head>
Sadəcə bu sətri əlavə edin və məsələn, bu sadə CSS faylını yaradın:
table {
    border-spacing: 0 10px;
    font:  bold 100% Georgia, serif;
    margin: 40px auto;
    text-shadow: 5px 5px 5px #3F3F7F;
    background: #B1B9D9;
    text-align: center;
    vertical-align: middle;
    width: 50%;
    border: 10px solid blue;
}
Və bu, cədvəlimizi tamamilə dəyişəcək (əlbəttə ki, axmaq görünür, amma məsələn, belədir): Maven, Spring, MySQL, Hibernate və ilk CRUD tətbiqinə giriş (4-cü hissə) - 2Yaxşı, məncə CSS haqqında ətraflı danışmağa ehtiyac yoxdur, hər şey olduqca sadədir. İnternetdə masaların və formaların dizaynı üçün bir çox hazır variant tapa bilərsiniz. Ancaq dizaynı özünüz etmək daha yaxşıdır, əlbəttə ki, dizayner olmaq lazım deyil, axı bu bir növ mürəkkəb sayt deyil. İlk tanışlıqdan bir neçə saat sonra belə sadə bir səhifə üçün kifayət qədər gözəl və səliqəli dizayn yaratmaq kifayət edəcəkdir. Bundan əlavə, İnternet hər cür dərslər, nümunələrlə doludur, HTML, CSS-ni eyni vaxtda bir ekranda redaktə edə biləcəyiniz və hamısının necə göründüyünü dərhal görə biləcəyiniz xüsusi saytlar var. Bir az təcrübə ilə əsl sənət yarada bilərsiniz. Düzdür, burada da çox da başını götürməməlisən (əlbəttə ki, dizayner olmaq planın yoxdursa), əks halda dizayn belə bir şeydir, burada çox uzun müddət ilişib qala bilərsən. CSS-i ilk dəfə anlamağa başlayanda ilişib qaldım. Mən hər şeyi, hər bir əmlakı sınamaq, nəyisə bükmək, onunla işləmək, sınaqdan keçirmək, bəzi saytların səhifələrini götürmək və onları tanınmayacaq şəkildə yenidən düzəltmək istəyirdim. Mən yəqin ki, bir həftə bu oyuncaqla əyləndim, başqa heç nə etmədim, o məni buraxana qədər :) Yaxşı, ümumiyyətlə, əlbəttə ki, bunu aşmamalı və anlaşılmaz rəngarəng möcüzə yaratmalısınız, bunu sadə etmək lazımdır və zövqlə. Qeyd etməyə dəyər yeganə şey. Siz başa düşməlisiniz ki, CSS dizaynın təsviri , HTML isə işarələmədir . CSS vasitəsilə tamamilə hər şeyi etməyə çalışmamalısınız; HTML-də bu bir neçə əlavə sətir və ya etiketdə sadəcə bir atributla edildikdə bəzi aspektləri etmək çox çətin olacaq, bəziləri isə sadəcə mümkün deyil. Onları birləşdirməli, CSS-də hər cür rənglər, fonlar, şriftlər yaratmalısınız və məsələn, bir neçə cədvəl xanasını birləşdirməlisinizsə, HTML alətlərindən istifadə etmək daha asandır. Məsələn, CSS və HTML ilə bir neçə saat məşğul olaraq səhifələrlə nə edə bildim (burada buna nail olmaq üçün etdiyim qarışıqlıq haqqında ətraflı məlumat verməyəcəyəm, sonunda baxa biləcəyiniz bu layihənin GitHub-a keçidi): Maven, Spring, MySQL, Hibernate və ilk CRUD tətbiqinə giriş (4-cü hissə) - 3Əlbəttə ki, orada hər şeyi nə qədər bacarıqla etdiyimi bilmirəm, amma CSS-ni ilk dəfə bir həftə əvvəl gördüyümü nəzərə alsaq, bunun çox yaxşı alındığını düşünürəm.

Səhifələmə

İndi hər şey işləyir, yaxşı görünür, lakin indiyə qədər cədvəldə yalnız bir neçə qeyd var. Bəs onda yüz və ya min film varsa, belə uzun siyahıda vərəqləmək o qədər də rahat deyil. Siyahı, məsələn, 10 girişdən ibarət səhifələrdə göstərildikdə daha rahatdır. Buna görə də, indi siyahının səhifələrə bölünməsini həyata keçirməyə çalışacağıq (bəzən buna "paging" və ya "pagination" da deyilir ( İngiliscə səhifələşdirmə )). Bu müxtəlif yollarla edilə bilər. Məsələn, tam siyahını jsp səhifəsinə köçürə və orada lazımi sayda qeydlər üçün cədvəl yarada bilərsiniz. Və ya, məsələn, xidmətdəki ümumi siyahıdan tələb olunan qeydləri çıxara və sonra bu mini siyahını nümayiş üçün jsp səhifəsinə göndərə bilərsiniz. Ancaq ən yaxşısı, əlbəttə ki, bunu verilənlər bazası səviyyəsində etməkdir. İdeya verilənlər bazasından tam siyahı götürüb sonra onu parçalara ayırmaq deyil, hər şeyə toxunmadan ilkin olaraq verilənlər bazasından tələb olunan parçanı əldə etməkdir. Axı niyə bir anda verilənlər bazasından yüzlərlə və ya minlərlə qeydi çıxartmalıyıq, əgər bizə lazım olan ilk ondadırsa, yalnız bu onluğu çıxarmaq daha yaxşıdır. Gəlin DAO- ya gedək və metoda allFilmsbir parametr əlavə edək int page, səhifə nömrəsinə cavabdeh olacaq (xidmətdə, əlbəttə ki, biz də eyni şeyi edirik). Gəlin bu metodun tətbiqini bir az dəyişdirək, əgər əvvəllər bütün siyahını çıxarmışdıqsa, indi yalnız bir hissəsini çıxaracağıq. setFirstResultMetodlar (cədvəlin hansı sətirindən başlamaq lazımdır) və setMaxResults(nə qədər qeyd göstərmək lazımdır) bu işdə bizə kömək edəcək :
@SuppressWarnings("unchecked")
public List<Film> allFilms(int page) {
    Session session = sessionFactory.getCurrentSession();
    return session.createQuery("from Film").setFirstResult(10 * (page - 1)).setMaxResults(10).list();
}
Bunlar. əgər bu 1-ci səhifədirsə, biz 0-dan başlayaraq maksimum 10 qeyd göstəririk; əgər bu 5-ci səhifədirsə, 40-dan başlayaraq 10 qeyd (bazada nömrələnmənin 0-dan başladığını unutmayın). Əlavə olaraq cədvəldəki qeydlərin sayını qaytaracaq bir üsul yaradacağıq. Bütün səhifələrin sayını bilmək və jsp səhifəmizdə onlar üçün keçidlər yaratmaq üçün bizə bu lazımdır:
public int filmsCount() {
     Session session = sessionFactory.getCurrentSession();
     return session.createQuery("select count(*) from Film", Number.class).getSingleResult().intValue();
 }
intBelə bir sorğudan istifadə edərək, qeydlərin özlərini çıxarmadan cədvəldəki bütün qeydlərin sayını (dəyər kimi) alacağıq . İndi nəzarətçiyə keçək və filmlərin siyahısı ilə əsas səhifəni qaytaran üsul üzərində işləyək:
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView allFilms(@RequestParam(defaultValue = "1") int page) {
    List&ltFilm> films = filmService.allFilms(page);
    int filmsCount = filmService.filmsCount();
    int pagesCount = (filmsCount + 9)/10;
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("films");
    modelAndView.addObject("page", page);
    modelAndView.addObject("filmsList", films);
    modelAndView.addObject("filmsCount", filmsCount);
    modelAndView.addObject("pagesCount", pagesCount);
    return modelAndView;
}
Burada yeni annotasiya peyda oldu @RequestParamvə bu, bu dəyəri sorğu parametrindən əldə etdiyimizi göstərir. İndi, məsələn, http://localhost:8080/ ?page=4 parametri olan ünvana getsək , müvafiq olaraq 4-cü səhifəni alacağıq. Defolt dəyəri " 1 " olaraq təyin etdik ki, proqram başlayanda http://localhost:8080/ parametri olmayan ünvana gedəndə ilk səhifəni alırıq. Metodda bütün qeydlərin sayını alırıq, sonra bu sadə şəkildə səhifələrin sayını hesablayırıq. Bunlar. 10 qeydimiz varsa, bu 1 səhifədir və 11 varsa, bu artıq 2-dir. Yaxşı, biz bütün bunları modelə köçürürük. Bir dövrədə hamısı üçün keçidlər yaratmaq üçün səhifələrin sayını bilməlisiniz və filmlərin sayının orada olmasına icazə verin, məsələn, bu məlumatı səhifənin bir yerində göstərmək istəyirsinizsə. İndi qalan şey films.jsp- ə getmək və bu konstruksiyadan istifadə edərək hər səhifəyə keçidlər əlavə etməkdir:
<c:forEach begin="1" end="${pagesCount}" step="1" varStatus="i">
    <c:url value="/" var="url">
        <c:param name="page" value="${i.index}"/>
    </c:url>
    <a href="${url}">${i.index}</a>
</c:forEach>
Sayğac 1, 2, 3, ... ilə bağlantılar yaradırıq və parametri indeks dəyəri ilə təyin edirik.

Yeri gəlmişkən, səhifələmə ilə eyni şəkildə, çeşidləmə, filtrləmə və axtarış kimi digər funksiyaları da əlavə edə bilərsiniz. Biz sadəcə olaraq DAO metoduna müxtəlif parametrləri ötürürük və onlardan tələb olunan qaydada tələb olunan qeydləri çıxarmaq üçün verilənlər bazasına müvafiq sorğu yaratmaq üçün istifadə edirik.

Daha bir kiçik toxunuş əlavə edək. Nəzarətçiyə qayıdırıq. Əlavə etmə, redaktə etmə və silmə üsullarında əməliyyat başa çatdıqdan sonra əsas səhifəyə yönləndiririk "redirect:/" . Bu. əgər biz 50-ci səhifədə bir yerdəyiksə və girişi redaktə et düyməsini sıxırıqsa, icradan sonra " / " ünvanına gedəcəyik , yəni. 1-ci səhifəyə qayıdaq. Bu çox əlverişli deyil, mən gəldiyimiz yerə qayıtmaq istərdim. Bunu çox sadə həll edək. Sinifdə FilmControllernümunə dəyişəni yaradaqint page
private int page;
Metod daxilində allFilmsparametrin dəyərini bu dəyişənə təyin edəcəyik page:
this.page = page;
Bu. Bu üsul hər dəfə yerinə yetirildikdə (yəni, səhifələr arasında gəzəndə) cari səhifənin dəyəri dəyişənə yazılacaq. Və sonra biz bu dəyəri eyni səhifəyə yönləndirmək üçün metodlarımızda istifadə edirik.
modelAndView.setViewName("redirect:/?page=" + this.page);

Nəticə

Yəqin ki, burada bitirəcəyik. Nəticə tam hüquqlu CRUD tətbiqidir. Bu, əlbəttə ki, idealdan uzaqdır (çox uzaq), lakin onu optimallaşdırmaq və təkmilləşdirmək olar, səhvlər düzəldilə bilər və funksionallıq əlavə olunur. Xırda əməliyyatlar üçün daxili metodlardan istifadə edə bilərsiniz; filtrləmə, axtarış, çeşidləmə əlavə edin; digər əlaqəli cədvəllər əlavə edin; avtorizasiya və autentifikasiya ilə müxtəlif istifadəçilər üçün dəstəyi həyata keçirmək və s. və s. Təsəvvür sahəsi sonsuzdur, ona görə də gedin. Bu layihənin github-a keçidi . Diqqətinizə görə təşəkkürlər. P.S. Bu, həyatımda məqalə yazmaq üçün ilk cəhdimdir, odur ki, ciddi mühakimə etməyin :). Faydalı mənbələrə fərqli keçidlər əlavə etmədiyim üçün üzr istəyirəm; təəssüf ki, mən hələ də məlumat aldığım mənbələrə keçidləri saxlamaq vərdişini inkişaf etdirə bilmirəm. Və təbii ki, çoxlu hərflərə görə üzr istəyirəm, qısalıq mənim istedadım deyil, ümid edirəm kimsə bunun öhdəsindən gələ bilər. Bütün hissələrə keçidlər
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION