JavaRush /Java 博客 /Random-ZH /Maven、Spring、MySQL、Hibernate 和第一个 CRUD 应用程序简介(第 4 部分)
Макс
第 41 级

Maven、Spring、MySQL、Hibernate 和第一个 CRUD 应用程序简介(第 4 部分)

已在 Random-ZH 群组中发布
下午好。在这篇文章中,我想分享我在创建一个简单的 CRUD 应用程序的过程中第一次接触到 Maven、Spring、Hibernate、MySQL 和 Tomcat 等东西。这是最后一部分。本文主要面向那些已经完成 30-40 个级别,但尚未超越纯 Java 并刚刚开始(或即将开始)进入拥有所有这些技术、框架和其他陌生词汇的开放世界的人。 这是文章“Maven、Spring、MySQL、Hibernate 简介和第一个 CRUD 应用程序”的最后第四部分。前面的部分可以通过以下链接查看:

内容:

设计和网络资源

我们的应用程序可以工作,但你看它时会流泪、无聊的铭文、丑陋的链接、空荡荡的白色背景。我们需要解决这个问题并添加不同的美感。我们如何做到这一点?好吧,首先,您可以使用HTML的功能来玩弄页面并执行各种操作。但如果您尝试单独使用 HTML 来更改背景、颜色、大小、元素的排列等。等等。那么最终你会把页面弄得一团糟,以至于以后你什么也看不清。此外,HTML 的设计选项非常有限。最好使用CSS(层叠样式表)来实现此目的。然后,与设计相关的所有内容都可以收集到一个地方,然后应用于页面的所需元素。CSS代码可以直接写在JSP页面上的特殊标签中,但是将其放在单独的文件中,然后简单地将其应用到必要的页面中要方便得多。为了放置带有样式和其他静态 Web 资源的文件,我们将在webapp中创建一个单独的目录。为了不将 Web 资源与常规资源(其中有db.properties)混淆,我们将此目录命名为res并将所有 CSS 文件、图像等放置在其中:
Maven、Spring、MySQL、Hibernate 和第一个 CRUD 应用程序简介(第 4 部分)- 1
要使用这些文件,我们需要在配置中指定它们的位置。我们去我们班吧WebConfig。之前我们使用注解的时候@EnableWebMvc没有配置任何东西,只是简单的使用默认的配置。但现在需要配置一些东西。为此,我们使用接口WebMvcConfigurer,它允许您覆盖配置方法。那。我们可以使用默认配置,但同时可以为自己定制一些方面。在这种情况下addResourceHandlers,我们需要一种方法来指示静态 Web 资源的位置。以防万一,整个类最终看起来像这样:
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;
    }
}
现在要在页面上使用我们的 CSS,您需要在标签内链接到它head
<head>
    <link href="<c:url value="/res/style.css"/>" rel="stylesheet" type="text/css"/>
</head>
只需添加这一行并创建一个简单的 CSS 文件,例如:
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;
}
这将彻底改变我们的表格(当然,它看起来很愚蠢,但它是这样的,例如): Maven、Spring、MySQL、Hibernate 和第一个 CRUD 应用程序简介(第 4 部分)- 2嗯,我认为没有必要详细谈论CSS,一切都很简单。在互联网上,您可以找到许多用于设计表格和表单的现成选项。但当然,最好自己做设计,你不需要成为设计师,毕竟这不是什么复杂的网站。即使在第一次熟悉后的几个小时也足以为这样一个简单的页面创建一个相当漂亮和整洁的设计。此外,互联网上充满了各种各样的课程、示例,还有一些特殊的网站,您可以在一个屏幕上同时编辑 HTML、CSS,并立即看到它们的样子。只要稍加练习,您就可以创造出真正的艺术。确实,你也不应该在这里太得意忘形(当然,除非你计划成为一名设计师),否则设计就是这样的事情,你可能会被困在这里很长一段时间。当我第一次开始理解 CSS 时,我陷入了困境。我想尝试一切,每一个属性,扭曲一些东西,修补它,进行实验,抓取一些网站的页面并将它们重新制作得面目全非。我可能用这个玩具玩了一个星期,什么也不做,直到它让我离开:) 好吧,一般来说,当然,你不应该做得太过分,创造一个难以理解的多彩奇迹,你需要简单地做,并且有品味。唯一值得注意的是。您需要了解CSS 是设计的描述,而HTML 是标记。你不应该尝试通过 CSS 完成所有事情;有些方面会很难做到,有些方面根本不可能,而在 HTML 中,这是通过几行额外的行,甚至只是标签中的一个属性来完成的。您需要将它们组合起来,在 CSS 中制作各种颜色、背景、字体,例如,如果您需要组合几个表格单元格,那么使用 HTML 工具会更容易。好吧,例如,这就是我在几个小时摆弄 CSS 和 HTML 的情况下对页面所做的事情(我不会在这里详细介绍我为实现这一目标而造成的混乱,最后将会有该项目的 GitHub 链接(您可以在其中查看): Знакомство с Maven, Spring, MySQL, Hibernate и первое CRUD приложение (часть 4) - 3当然,我不知道我在那里做的所有事情有多熟练,但考虑到我一周前第一次看到 CSS,我认为结果相当不错。

分页

现在一切正常,看起来不错,但到目前为止表中只有几条记录。如果里面有一百部电影,或者一千部电影怎么办?这么长的列表滚动起来不太方便。例如,当列表以 10 个条目的页面形式显示时,会更加方便。因此,现在我们将尝试实现将列表拆分为页面(有时这也称为“分页”或“分页”(英文pagination))。这可以通过不同的方式来完成。例如,您可以将完整列表传输到 jsp 页面,并在其中创建一个包含所需记录数的表。或者,例如,您可以从服务中的常规列表中提取所需的记录,然后将这个迷你列表发送到jsp页面进行显示。但当然最好是在数据库级别执行此操作。这个想法不是从数据库中获取完整的列表,然后将其分成几部分,而是首先从数据库中获取所需的部分,而不触及其他所有内容。毕竟,为什么我们需要一次性从数据库中取出数百或数千条记录,如果我们需要的是前十条记录,那么最好只取出这十条记录。让我们转到DAO并在方法中添加allFilms一个参数int page,该参数将负责页码(当然,在服务中我们也这样做)。让我们稍微改变一下这个方法的实现;如果之前我们提取了整个列表,那么现在我们将只提取一部分。setFirstResult方法(从表的哪一行开始)和setMaxResults(显示多少条记录) 将帮助我们:
@SuppressWarnings("unchecked")
public List<Film> allFilms(int page) {
    Session session = sessionFactory.getCurrentSession();
    return session.createQuery("from Film").setFirstResult(10 * (page - 1)).setMaxResults(10).list();
}
那些。如果这是第 1 页,则最多显示 10 条记录,从第 0 条开始;如果这是第 5 页,则从第 40 条开始显示 10 条记录(不要忘记数据库中的编号是从 0 开始的)。我们还将另外创建一个方法来返回表中的记录数。我们需要这个来了解所有页面的数量并在我们的 jsp 页面上为它们创建链接:
public int filmsCount() {
     Session session = sessionFactory.getCurrentSession();
     return session.createQuery("select count(*) from Film", Number.class).getSingleResult().intValue();
 }
使用这样的查询,我们将获得表中所有记录的数量(作为int值),而无需提取记录本身。现在让我们转到控制器并处理返回带有电影列表的主页的方法:
@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;
}
这里出现了一个新的注释@RequestParam,它表明我们正在从请求参数中获取该值。现在,如果我们访问带有参数的地址,例如http://localhost:8080/ ?page=4,我们将相应地获得第四页。我们将默认值设置为“ 1 ”,这样当应用程序启动时,当我们访问不带http://localhost:8080/参数的地址时,我们会得到第一页。在该方法中,我们获取所有记录的数量,然后通过这种简单的方式我们计算页数。那些。如果我们有 10 条记录,则这是 1 页,如果有 11 条记录,则这已经是 2 页。好吧,我们将整个事情转移到模型中。您需要知道页面数,以便在一个循环中为所有页面创建链接,并让电影数存在以防万一,例如,如果您想在页面上的某个位置显示此信息。现在剩下的就是转到movie.jsp并使用以下构造添加到每个页面的链接:
<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>
我们通过计数器 1、2、3、... 创建链接,并通过索引值设置参数。

顺便说一下,与分页一样,您可以添加其他功能,例如排序、过滤和搜索。我们只需将各种参数传递给 DAO 方法,并使用它们形成对数据库的适当查询,以便按所需顺序提取所需记录。

让我们再添加一点小改动。我们回到控制器。在添加、编辑和删除方法中,操作完成后,我们重定向到主页面“redirect:/”。那。如果我们在第 50 页上的某个位置并单击编辑条目,那么执行后我们将转到地址“ / ”,即 让我们回到第 1 页。这不太方便;我想回到我们来的地方。让我们非常简单地解决这个问题。让我们在类中创建FilmController一个实例变量int page
private int page;
在方法内部,allFilms我们将参数的值分配给该变量page
this.page = page;
那。每次执行此方法时(即当我们浏览页面时),当前页面的值将被写入变量。然后我们在方法中使用这个值来重定向回同一页面。
modelAndView.setViewName("redirect:/?page=" + this.page);

结论

我们可能会在这里结束。结果是一个成熟的 CRUD 应用程序。它当然离理想还很远(非常远),但它可以优化和改进,修复错误并添加功能。可以使用内置方法进行增删改查操作;添加过滤、搜索、排序;添加其他相关表;通过授权和认证等实现对不同用户的支持。等等。想象的空间是无限的,所以尽情发挥吧。 链接到该项目的 github。感谢您的关注。 PS这是我人生第一次尝试写文章,所以不要严格评判:)。我很抱歉没有添加任何不同的有用资源链接;不幸的是,我仍然无法养成保存获取信息来源链接的习惯。当然,我对这么多信表示歉意,简洁不是我的天赋,我希望有人能处理它。 所有部分的链接
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION