Spring MVC入门

来源:互联网 发布:windows正在下载更新0 编辑:程序博客网 时间:2024/05/25 05:35

目前为止,发现的最好的Spring MVC教材,来自http://my.oschina.net/gaussik/blog/385697,强烈推荐!

如果你能耐心地从头到尾跟着文章做一遍,然后反过来体会一遍,基本上该会的 就都会了。

推荐一本奥莱丽的书《Spring Data实战》,只看前两章就够用了。


感谢原文作者:

http://my.oschina.net/gaussik/blog/385697

http://my.oschina.net/gaussik/blog/513353

http://my.oschina.net/gaussik/blog/513444

http://my.oschina.net/gaussik/blog/513614

转载请注明出处:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生)

访问GitHub下载最新源码:https://github.com/gaussic/SpringMVCDemo



文章已针对IDEA 15做了一定的更新,部分更新较为重要,请重新阅读文章并下载最新源码。

前言

       由于近期一直在做学术方面的工作,项目开发相关工作并没有花太多的时间,导致这篇文章的更新停步了很长一段时间。现在应大家的要求,补上剩余部分,望能给大家带来一些帮助。由于时间的原因,在开发环境上面有了一定的更新,但是并不造成太大的影响。

       最近在做某在线教育平台网站的开发,按师兄的建议要用SpringMVC来搞。之前对SpringMVC的认知度为0,网上查阅各种资料,发现五花八门的配置都有,文章写的那叫一个乱啊,我觉得有些文章还是不要发出来的比较好,简直误人子弟耽误时间。最近借着师兄网上搜集的一些开发经验,找到了IntelliJ网站上的这篇文章《Getting Started with SpringMVC, Hibernate and JSON》(该链接已失效,内容会在文中体现),外加看了孔老师的《SpringMVC视频教程》,着实有一种醍醐灌顶的感觉,整个路子瞬间通了,开发速度指数型上涨。现在把开发过程中的一些相关经验贴出来。

一、相关环境

     - Intellij IDEA 15.0.4 Ultimate

     - Tomcat 7.0.68

     - JDK 1.7.0_80

     - Spring 3.2.0

     - MySql 5.7

     - Maven 3.3.9

     - Bootstrap 3.3.5

       以上是我要做的这个demo所需要的东西,当然有些是可选的,版本也是可控的。比如说如果你用不惯Maven的话可以自行去官网下载jar包然后导入自己的工程中,如果想要学习下Maven可以看看《Maven视频教程》(偶然找到,这个老师做的视频都挺好,推荐以下),不用完全的去学习Maven,懂大概意思后再去找找IntelliJ IDEA如何配置maven的相关文章就足够了。

      还有Bootstrap,纯粹是个人洁癖,不需要这可以去之。

      事先声明,请确保IntelliJ IDEA、Tomcat、MySql和JDK都已经安装好。Maven和Bootstrap的话能有则有。前者为了让导包更容易,后者为了让页面更美观。此外,由于jdk以及mysql的安装网上已经有了很多教程,在此为节省篇幅不做介绍。废话不多说,正式开始。

二、本地Maven与Tomcat的安装

注:如果使用IntelliJ IDEA集成的maven 3.0.5的话,可以忽略此步安装。

1、下载并安装本地maven    

    点击“Apache-Maven官方网站”进入官网,点击左侧Download选项:

     进入了下载页面,往下拉可发现当前版本是3.3.3,点击下面红框中的apache-maven-3.3.9-bin.zip就可下载,下载后解压缩到相应目录下:

    新增系统变量MAVEN_HOME:即MAVEN安装目录:

    在Path中加入:%MAVEN_HOME%\bin;    

   在cmd中输入mvn -v,若显示如下,则说明本地maven配置完成:

2、下载并安装本地Tomcat

进入Tomcat官网,点击左侧Download的Tomcat7.0,进入Tomcat的下载页面:

64位Windows版本下载64-bit Windows zip (pgp, md5, sha1),解压到所需目录下:

  解压后到\bin\目录下运行startup.bat,如图下所示,如果出现Server startup in xxxx ms说明Tomcat安装成功。

三、创建Maven Web项目

    前面说了这么多,差不多基本的东西都保障了(前提保证你已经安装了jdk)。现在进入正题,如何来创建一个Web项目。对于不使用Maven的开发者,可以直接建一个简单的Web项目。使用Maven的话,请按照图进行操作。

    菜单File->New Project可进入上图界面,首先选择左边栏Maven,再配置JDK(一般如果之前添加了JDK的话会自动填充,如未添加的话点击旁边的New将JDK目录导入即可)。勾选“Create from archetype“,然后选中4处蓝色位置webapp,点Next,进入如下界面:

    这里需要填写GroupId和ArtifactId还有Version,这三个属性目的是标识你的项目的唯一性,比如Tomcat的GroupId是org.apache,即它是apache组织的项目,ArtifactId是tomcat,项目名为tomcat,而我当前使用的Version是7.0.68。这些只在发布时有用,在此可以随便填写,填好后点Next,到如下界面。

    打开Maven home directory,可以发现IntelliJ IDEA已经集成了Maven 2和Maven 3两个版本,如果使用默认集成的maven的话,选择Buldled(Maven 3),直接点击Next。

   我们也可以导入本地新安装的较新的Maven版本,点击蓝色箭头右边的 ... 按钮将Maven路径导入即可,点击Next:

   填写项目名,选择项目保存路径,点击Finish:

   进入如下界面,maven会在后台生成web项目,这需要等待一定的时间,视网络环境而定,经验发现用较新版本的maven项目生成更快,使用IDEA集成的maven可能会等待很长一段实践。

    左边红框中展示了该项目的文件结构。可以发现,它在src/main下创建了一个recources文件夹,该文件夹一般用来存放一些资源文件,还有一个webapp文件夹,用来存放web配置文件以及jsp页面等,这已经组成了一个原始的web应用。选择右边红框的Enable-Auto-Import,可以在每次修改pom.xml后,自动的下载并导入jar包,这一点在后面详述。

四、Maven自动导入jar包

    既然我们要用SpringMVC开发,那肯定少不了SpringMVC的相关jar包。如果不使用Maven的话,那就需要去官网下载相关的jar包,然后导入到项目中。现在使用maven的话,就不需要上网找jar包了。具体容我一一道来。

    Maven所做的工作其实很简单,就是自动把你需要的jar包下载到本地,然后关联到项目中来。maven的所有jar包都是保存在几个中央仓库里面的,其中一个最常用的是Maven Repository,即,你需要什么jar包,它就会从仓库中拿给你。那么如何告诉maven需要什么jar包呢?我们看看工程目录,能找到一个pom.xml文件(这个文件在刚创建好项目时就已经展现在了大家面前),maven就是靠它来定义需求的,代码如下:

<project xmlns="http://maven.apache.org/POM/4.0.0xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.gaussic</groupId>    <artifactId>springmvcdemo</artifactId>    <packaging>war</packaging>    <version>1.0-SNAPSHOT</version>    <name>springmvcdemo Maven Webapp</name>    <url>http://maven.apache.org</url>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>    </dependencies>    <build>        <finalName>springmvcdemo</finalName>    </build></project>

    我们可以看到这个文件包含了我们之前定义的本项目的gropId等信息,这些信息是该项目的标识,我们不要去改动它们。重点看<dependencies>标签,翻译过来是”依赖“的意思,也就是说把对每个包的需求都称为一个依赖<depedency>,定义在<dependencies>中。在每个<depedency>中,你需要提供的是所需jar包的groupId、artifactId、version这三个必要信息。比如上面我们看到引入可一个junit包,格式如下:

<dependency>    <groupId>junit</groupId>    <artifactId>junit</artifactId>    <version>3.8.1</version>    <scope>test</scope></dependency>

    这是单元测试包,提供了三个基本信息,第4个scope对其他包来说是非必需的。所有jar包的引入都要满足这个格式。那么如何查看这些jar包的3个信息呢,可能刚接触是开发者还不是很熟悉,这个时候就需要查阅仓库了。比如我们需要引入Spring核心jar包spring-core,打开Maven Repository,搜索spring-core,进入如下界面:

    点击进入红框选中的Spring Core,如下所示,可以看到各版本的使用情况:

   选择最新版本4.2.5.RELEASE,可以看到其dependency写法如下红框所示:

   我们将其复制到pom.xml中的<dependencies>中:

    这样,Maven就会开始自动下载jar包到本地仓库,然后关联到你的项目中,下载完成后,我们展开工程目录中External Libraries:

    可以发现,虽然我们只写了一个依赖,但是它导入了两个jar包,也就是说,导入某个jar包时,与它密切相关的jar包也会同时被导入进来。

    除了spring-core,我还要spring-context,复制spring-core的<dependency>,将spring-core改为spring-context,如下:

<dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-context</artifactId>    <version>4.2.5.RELEASE</version></dependency>

    下载完成后,查看External Libraries,会不会发现,瞬间导入了好多jar包(当然不是瞬间,这得看你的网速了)呢:

    这就是Maven的强大之处,如果你需要使用SpringMVC开发网站的话,只需记住几个重要的包的名字,就可以轻松将所有包导入项目中。

    长话短说,现在我们要进行SpringMVC的开发,请把你的pom.xml变成下面的样子,当然不要改你的grupId等信息(从modelVersion到url都不要动):

<properties>    <spring.version>3.2.0.RELEASE</spring.version>    <spring-data.version>1.2.0.RELEASE</spring-data.version></properties>

    请在<dependencies>中加入以下依赖:

    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-core</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-web</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>servlet-api</artifactId>        <version>2.5</version>    </dependency>    <dependency>        <groupId>javax.servlet.jsp</groupId>        <artifactId>jsp-api</artifactId>        <version>2.1</version>        <scope>provided</scope>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-test</artifactId>        <version>${spring.version}</version>        <scope>test</scope>    </dependency>    <dependency>        <groupId>jstl</groupId>        <artifactId>jstl</artifactId>        <version>1.2</version>    </dependency>    <dependency>        <groupId>org.springframework.data</groupId>        <artifactId>spring-data-jpa</artifactId>        <version>${spring-data.version}</version>    </dependency>    <dependency>        <groupId>org.hibernate.javax.persistence</groupId>        <artifactId>hibernate-jpa-2.0-api</artifactId>        <version>1.0.0.Final</version>    </dependency>    <dependency>        <groupId>org.hibernate</groupId>        <artifactId>hibernate-entitymanager</artifactId>        <version>3.6.10.Final</version>    </dependency>    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.34</version>    </dependency>    <dependency>        <groupId>org.json</groupId>        <artifactId>json</artifactId>        <version>20080701</version>    </dependency>

     我们可以发现,除了导入了spring相关jar包,还有一些其他的包,这些包都是有作用的,我们后面慢慢说。如果不使用Maven请自行下载spring、hibernate、mysql、jstl、javax-servlet、json等相关jar包然后导入到工程中。至此,jar包的导入就完成了,我们按 ctrl+alt+shift+s,或者File->Project Structure查看一下项目结构,看看有什么问题:

    由于之后我们要开始写代码了,先做一些配置,选择Modules,在SpringMVCDemo的src\main文件夹中新建一个文件夹,取名为java:

   选中java文件夹,点击上面的Make as:Sources,该文件夹就会变成蓝色,用以保存java代码,按OK,结束配置。

五、SpringMVC框架配置

    进行完上面的配置,那就说明现在基本的开发环境已经搭建好了,现在要开始进行SpringMVC的网站开发。

1、web.xml配置

    打开src\main\webapp\WEB-INF\下的web.xml文件,稍微更新一下web.xml的版本,可以支持更高级的一些语法,如下:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"         version="3.1">    <display-name>SpringMVCDemo Web Application</display-name></web-app>

   在<web-app>中加入一个servlet:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"         version="3.1">    <display-name>SpringMVCDemo Web Application</display-name>    <servlet>        <servlet-name>mvc-dispatcher</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>mvc-dispatcher</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping></web-app>

   该servlet名为mvc-dispatcher(名称可修改),用于拦截请求(url-pattern为 / ,说明拦截所有请求),并交由Spring MVC的后台控制器来处理。这一项配置是必须的。

   为了能够处理中文的post请求,再配置一个encodingFilter,以避免post请求中文出现乱码情况:

<filter>    <filter-name>encodingFilter</filter-name>    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>    <init-param>        <param-name>encoding</param-name>        <param-value>UTF-8</param-value>    </init-param>    <init-param>        <param-name>forceEncoding</param-name>        <param-value>true</param-value>    </init-param></filter><filter-mapping>    <filter-name>encodingFilter</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>

  至此,web.xml配置完毕。

2、xxx-servlet.xml配置

    在配置完web.xml后,需在web.xml同级目录下新建 mvc-dispatcher-servlet.xml(-servlet前面是在servlet里面定义的servlet名):

    新建该xml文件后,点击右上角的configure,出现 Setup Frameworks界面,点击OK,这样,IntelliJ IDEA就识别了SpringMVC的配置文件:

    mvc-dispatcher-servlet.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></beans>

   MVC框架有model、view、controller三部分组成。model一般为一些基本的Java Bean,view用于进行相应的页面显示,controller用于处理网站的请求。

   在src\main\java中新建一个用于保存controller的package:

    在controller包中新建java类MainController(名称并不固定,可任意取),并修改如下:

package com.gaussic.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;/** * Created by dzkan on 2016/3/8. */@Controllerpublic class MainController {    @RequestMapping(value = "/"method = RequestMethod.GET)    public String index() {        return "index";    }}

    (1)@Controller注解:采用注解的方式,可以明确地定义该类为处理请求的Controller类;

    (2)@RequestMapping()注解:用于定义一个请求映射,value为请求的url,值为 / 说明,该请求首页请求,method用以指定该请求类型,一般为get和post;

    (3)return "index":处理完该请求后返回的页面,此请求返回 index.jsp页面。

    回到mvc-dispatcher-servlet.xml,进行相关配置。首先加入component-scan标签,指明controller所在的包,并扫描其中的注解(最好不要复制,输入时按IDEA会在beans xmlns中添加相关内容):

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <!--指明 controller 所在包,并扫描其中的注解-->    <context:component-scan base-package="com.gaussic.controller"/></beans>

    再进行js、image、css等静态资源访问的相关配置,这样,SpringMVC才能访问网站内的静态资源:

<!-- 静态资源(js、image等)的访问 --><mvc:default-servlet-handler/>

   再开启springmvc注解模式,由于我们利用注解方法来进行相关定义,可以省去很多的配置:

<!-- 开启注解 --><mvc:annotation-driven/>

再进行视图解析器的相关配置:

<!--ViewResolver 视图解析器--><!--用于支持Servlet、JSP视图解析--><bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>    <property name="prefix" value="/WEB-INF/pages/"/>    <property name="suffix" value=".jsp"/></bean>

    关于controller如何找到视图文件,这里需要详细的说明。在 controller 的一个方法中,返回的字符串定义了所需访问的jsp的名字(如上面的index)。在jspViewResolver中,有两个属性,一个是prefix,定义了所需访问的文件路径前缀,另一是suffix,表示要访问的文件的后缀,这里为 .jsp。那么,如果返回字符串是 xxx ,SpringMVC就会找到 /WEB-INF/pages/xxx.jsp 文件。

   完成以上配置后,mvc-dispatcher-servlet.xml文件如下图所示:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">    <!--指明 controller 所在包,并扫描其中的注解-->    <context:component-scan base-package="com.gaussic.controller"/>    <!-- 静态资源(js、image等)的访问 -->    <mvc:default-servlet-handler/>    <!-- 开启注解 -->    <mvc:annotation-driven/>    <!--ViewResolver 视图解析器-->    <!--用于支持Servlet、JSP视图解析-->    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>        <property name="prefix" value="/WEB-INF/pages/"/>        <property name="suffix" value=".jsp"/>    </bean></beans>

    我们删除 webapp 目录下的 index.jsp 文件,在WEB-INF目录下新建文件夹pages,再在pages目录下新建 index.jsp,并修改为如下所示:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>SpringMVC Demo 首页</title>    <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->    <!--[if lt IE 9]>    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>    <![endif]--></head><body><h1>这里是SpringMVC Demo首页</h1><h3>出现此页面,说明配置成功。</h3><!-- jQuery文件。务必在bootstrap.min.js 之前引入 --><script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script></body></html>

这里使用了Bootstrap的CDN加速服务,如果要使用本地的Bootstrap,请前往Bootstrap官网下载,并放在 webapp 目录下,然后引入到 index.jsp 中,这里不做详细介绍。

现在,需要配置 Tomcat 来运行该项目。点击界面右上角的向下箭头,选择 Edit Configurations:

点击左上角的”+“号,选择Tomcat Server,(如果没有请选择最下方的33 items more,找到Tomcat Server),再选择Local:

进入如下界面:

点击 Application server 右边的 Configure,导入Tomcat 目录:

在配置好tomcat的路径后,如下图所示,发现依然存在警告,且左方的Tomcat7图标上有一个错误标记,说明还没有配置完全:

我们还需要将项目部署到 Tomcat 服务器中。点击 Deployment,再点击右边的”+“号,添加一个Artifact:

选择第二个:war exploded,点击OK,这样,该项目就已经部署到了tomcat中:

再点击OK,整个Tomcat配置结束:

点击界面右上角的红框中的绿色箭头,就可以启动 Tomcat 了,其控制台输出将在 IDEA 下方显示

启动后,浏览器将自动弹出项目首页:

这样,说明配置完成。这里总结一下其相关机制:首先,浏览器访问 localhost:8080,后台controller拦截该请求,进行相应的处理(此处无),在跳转到视图 index.jsp进行显示。此后,将会进行详细的介绍。

六、数据库配置

      下面,就要通过一个简单的例子,来介绍SpringMVC如何集成Spring Data JPA(由 Hibernate JPA 提供),来进行强大的数据库访问,并通过本章节的讲解,更加深刻地认识Controller是如何进行请求处理的,相信看完这一章节,你就可以开始你的开发工作了。

准备工作:

    在src\main\java中新建两个包:com.gaussic.model、com.gaussic.repository,将在后面用上,如下图所示:

1、创建Mysql数据库

      本文的讲解使用Mysql数据库,如果使用其它数据库的读者,可以去网上参考其他的配置教程,在此不做太多的叙述。数据库是一个底层的东西,底层的细节对上层的抽象并没有太大的影响,因此,只要配置好数据库,本章的内容仍然是适用于所有数据库的(貌似如此)。

      假设我们现在要建立一个小小的博客系统,其数据库ER图如下所示(当然这只是一个小小的例子,真实的博客系统比这要复杂的多):

    新建一个数据库springdemo,在数据库中,有两张表:

    (1)用户表user:用户登录信息,主键id设为自增

    (2)博文表blog:储存用户发表的博文,主键id设为自增,其中有一个外键user_id链接到user表。

    详细表结构如下图所示:

使用MySQL Workbench添加外键流程:

注意:在添加外键时,应该根据需求设置,例如右边红框中的Foreign Key Options,默认在Delete时是NO ACTION,说明在删除一个用户时,如果数据库中存在该用户的文章,那么就无法删除该用户,也无法删除该用户的所有文章,而如果将该选项改为CASCADE,那么删除该用户,就会同时删除该用户所有的文章。通常后者是不太可取的,因为如果发生了删除用户的误操作,很有可能该用户的内容被连带删除,且不可逆,这也是实现真实系统时需要考虑的原因之一。

2、IntelliJ IDEA导入数据库

    对于此前所接触的一些常用的框架中,一张数据表往往对应一个Java Bean。在SpringMVC中,这个Java Bean相当于model。那么,这个类是否需要自己来写呢?不需要,利用IntelliJ IDEA可以帮我们自动的生成这些JavaBean。

    首先,右键项目,选择Add Framework Support:

下拉选择JavaEE Persistence,右边provider选择Hibernate:

    在这一步结束后,我们可以发现,在resources里面生成了persistence.xml配置文件,左边栏出现了一个Persistence标题(若没有请点击左下角那个灰框):

    persistemce.xml具体如下:

<?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">    <persistence-unit name="NewPersistenceUnit">        <provider>org.hibernate.ejb.HibernatePersistence</provider>        <properties>            <property name="hibernate.connection.url" value=""/>            <property name="hibernate.connection.driver_class" value=""/>            <property name="hibernate.connection.username" value=""/>            <property name="hibernate.connection.password" value=""/>            <property name="hibernate.archive.autodetection" value="class"/>            <property name="hibernate.show_sql" value="true"/>            <property name="hibernate.format_sql" value="true"/>            <property name="hbm2ddl.auto" value="update"/>        </properties>    </persistence-unit></persistence>

    我们先不着急填写这个配置文件。点开左边栏的Persistence,显示如下图所示:

右键项目名,选择Generate Persistence Mapping,再选择By Database Schema:

出现如下界面,其主要需要配置的地方如下图红框所示:

    点击Choose Data Source右边的三个点选择数据源,在弹出的界面左上角选择“+”,选择Mysql:

在如下界面填写主机、端口号、数据库名、用户名、密码,如果驱动丢失点击下面的Download可以下载驱动,点击 Test Connection可以测试数据库是否连接成功:

    在以上界面配置完成后,点OK,第一次使用需要Setup Master Password:

    

    回到如下页面,package填写model包(1),勾选Prefer primitive type使用原始数据类型(2),勾选Show default relationships以显示所有数据库关系(3),再点击刷新按钮(4),将会找到数据库中的两个表,勾选两个数据表(5),再勾选Generate Column Defination以生成每一列的描述信息(6)。选中blog表然后点击“+”号按钮,添加外键关系(7)。

    点击OK后,在Database Schema Mapping中可以发现多出了两个关系,如图所示:

   再点击OK,稍后,打开model包,可以看到生成了两个Java Bean,在SpringMVC中称为两个实体,它们对应了数据库的两张表:

BlogEntity如下所示(注意把java.sql.Date改为java.util.Date):

package com.gaussic.model;import javax.persistence.*;import java.util.Date;/** * Created by dzkan on 2016/3/8. */@Entity@Table(name = "blog", schema = "springdemo", catalog = "")public class BlogEntity {    private int id;    private String title;    private String content;    private Date pubDate;    private UserEntity userByUserId;    @Id    @Column(name = "id", nullable = false)    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @Basic    @Column(name = "title", nullable = false, length = 100)    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    @Basic    @Column(name = "content", nullable = true, length = 255)    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }    @Basic    @Column(name = "pub_date", nullable = false)    public Date getPubDate() {        return pubDate;    }    public void setPubDate(Date pubDate) {        this.pubDate = pubDate;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        BlogEntity that = (BlogEntity) o;        if (id != that.id) return false;        if (title != null ? !title.equals(that.title) : that.title != null) return false;        if (content != null ? !content.equals(that.content) : that.content != null) return false;        if (pubDate != null ? !pubDate.equals(that.pubDate) : that.pubDate != null) return false;        return true;    }    @Override    public int hashCode() {        int result = id;        result = 31 * result + (title != null ? title.hashCode() : 0);        result = 31 * result + (content != null ? content.hashCode() : 0);        result = 31 * result + (pubDate != null ? pubDate.hashCode() : 0);        return result;    }    @ManyToOne    @JoinColumn(name = "user_id", referencedColumnName = "id", nullable = false)    public UserEntity getUserByUserId() {        return userByUserId;    }    public void setUserByUserId(UserEntity userByUserId) {        this.userByUserId = userByUserId;    }}

    再看UserEntity:

package com.gaussic.model;import javax.persistence.*;import java.util.Collection;/** * Created by dzkan on 2016/3/8. */@Entity@Table(name = "user", schema = "springdemo", catalog = "")public class UserEntity {    private int id;    private String nickname;    private String password;    private String firstName;    private String lastName;    private Collection<BlogEntity> blogsById;    @Id    @Column(name = "id", nullable = false)    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    @Basic    @Column(name = "nickname", nullable = false, length = 45)    public String getNickname() {        return nickname;    }    public void setNickname(String nickname) {        this.nickname = nickname;    }    @Basic    @Column(name = "password", nullable = false, length = 45)    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    @Basic    @Column(name = "first_name", nullable = true, length = 45)    public String getFirstName() {        return firstName;    }    public void setFirstName(String firstName) {        this.firstName = firstName;    }    @Basic    @Column(name = "last_name", nullable = true, length = 45)    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        UserEntity that = (UserEntity) o;        if (id != that.id) return false;        if (nickname != null ? !nickname.equals(that.nickname) : that.nickname != null) return false;        if (password != null ? !password.equals(that.password) : that.password != null) return false;        if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;        if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false;        return true;    }    @Override    public int hashCode() {        int result = id;        result = 31 * result + (nickname != null ? nickname.hashCode() : 0);        result = 31 * result + (password != null ? password.hashCode() : 0);        result = 31 * result + (firstName != null ? firstName.hashCode() : 0);        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);        return result;    }    @OneToMany(mappedBy = "userByUserId")    public Collection<BlogEntity> getBlogsById() {        return blogsById;    }    public void setBlogsById(Collection<BlogEntity> blogsById) {        this.blogsById = blogsById;    }}

3、配置数据库

    既然数据库已经导入了,那么前期准备工作基本完成,还需要进行最终的配置。

    首先,打开mvc-dispatcher-servlet.xml,添加下列配置(如果某些地方报错,请选中并按Alt + Insert补全配置):

<!-- 表示JPA Repository所在的包 --><jpa:repositories base-package="com.gaussic.repository"/><!-- 链接到persistence.xml --><bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">    <property name="persistenceUnitName" value="defaultPersistenceUnit"/></bean><!-- 事务管理 --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">    <property name="entityManagerFactory" ref="entityManagerFactory"/></bean><!-- 开启事务管理注解 --><tx:annotation-driven transaction-manager="transactionManager"/>

    讲解:

    (1) jpa:repositories:这一部分涉及到数据库的接口,将在后面详解;

    (2)entityManagerFactory:实体管理器工厂,读取persistence.xml配置;

    (3)transactionManager:事务管理器,利用entityManager进行事务管理;

    (4)tx:annotation-driven:打开事务管理器的注解驱动,可以使用注解的方法操纵数据库。

整体如下所示:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:mvc="http://www.springframework.org/schema/mvc"       xmlns:jpa="http://www.springframework.org/schema/data/jpa"       xmlns:tx="http://www.springframework.org/schema/tx"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd       http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">    <!--指明 controller 所在包,并扫描其中的注解-->    <context:component-scan base-package="com.gaussic.controller"/>    <!-- 静态资源(js、image等)的访问 -->    <mvc:default-servlet-handler/>    <!-- 开启注解 -->    <mvc:annotation-driven/>    <!--ViewResolver 视图解析器-->    <!--用于支持Servlet、JSP视图解析-->    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>        <property name="prefix" value="/WEB-INF/pages/"/>        <property name="suffix" value=".jsp"/>    </bean>    <!-- 表示JPA Repository所在的包 -->    <jpa:repositories base-package="com.gaussic.repository"/>    <!-- 链接到persistence.xml -->    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">        <property name="persistenceUnitName" value="defaultPersistenceUnit"/>    </bean>    <!-- 事务管理 -->    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">        <property name="entityManagerFactory" ref="entityManagerFactory"/>    </bean>    <!-- 开启事务管理注解 -->    <tx:annotation-driven transaction-manager="transactionManager"/></beans>

    下面,填充persistence.xml,将persistence-unit的name改为 defaultPersistenceUnit。在下面的文件中,我添加了一些更为详细的配置:

<?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://java.sun.com/xml/ns/persistenceversion="2.0">    <persistence-unit name="defaultPersistenceUnit"  transaction-type="RESOURCE_LOCAL">        <provider>org.hibernate.ejb.HibernatePersistence</provider>        <properties>            <!-- 使用MySQL方言 -->            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>            <!-- 数据库连接的URL地址 -->            <property name="hibernate.connection.url"                      value="jdbc:mysql://localhost:3306/springdemo"/>            <!-- 数据库连接的驱动 -->            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>            <!-- 数据库连接的用户名 -->            <property name="hibernate.connection.username" value="root"/>            <!-- 数据库连接的密码 -->            <property name="hibernate.connection.password" value="111111"/>            <!-- 显示SQL语句 -->            <property name="hibernate.show_sql" value="true"/>            <property name="hibernate.connection.useUnicode" value="true"/>            <property name="hibernate.connection.characterEncoding" value="UTF-8"/>            <!-- 在显示SQL语句时格式化语句 -->            <property name="hibernate.format_sql" value="true"/>            <property name="hibernate.use_sql_comments" value="false"/>            <!-- 自动输出schema创建DDL语句 -->            <property name="hibernate.hbm2ddl.auto" value="update"/>            <!-- 数据库连接超时后自动重连 -->            <property name="hibernate.connection.autoReconnect" value="true"/>            <property name="connection.autoReconnectForPools" value="true"/>            <property name="connection.is-connection-validation-required" value="true"/>        </properties>    </persistence-unit></persistence>

    现在,重新启动tomcat,如果没有报错,说明数据库已经配置完成了,接下来就要讲解数据库的相关开发工作。


更新:

      阅读评论发现许多同学的persistence.xml出现了问题,因为出现问题的原因可能有很多,如果没有完全的报错以及代码的话,我这边很难解决问题,一个办法就是在GitHub Issues上面提问并贴出代码,我这边尽量解答。另一个办法就是下载最新的代码运行看有没有什么问题。

       最后一个办法,尝试另外一种配置方法,无需persistence.xml,直接在mvc-dispatcher-servlet.xml中配置数据库,如下所示:

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">    <property name="persistenceUnitName" value="defaultPersistenceUnit"/>    <property name="packagesToScan" value="com.gaussic.model" />    <property name="jpaVendorAdapter">        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>    </property>    <property name="jpaProperties">        <props>            <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>            <prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/springdemo</prop>            <prop key="hibernate.connection.username">root</prop>            <prop key="hibernate.connection.password">111111</prop>            <prop key="hibernate.show_sql">false</prop>            <prop key="hibernate.connection.useUnicode">true</prop>            <prop key="hibernate.connection.characterEncoding">UTF-8</prop>            <prop key="hibernate.format_sql">true</prop>            <prop key="hibernate.use_sql_comments">true</prop>            <prop key="hibernate.hbm2ddl.auto">validate</prop>            <prop key="hibernate.connection.autoReconnect">true</prop>            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>            <prop key="connection.autoReconnectForPools">true</prop>            <prop key="connection.is-connection-validation-required">true</prop>        </props>    </property></bean>

          删除persistence.xml,直接修改entityManagerFactory bean为如上图所示。这个方法可以拜托persistence.xml的困扰,但是有一个小小的问题,如果之前没有添加Java EE Persistence这个框架的,文中的Persistence工具栏将不会显示。一个解决办法就是,先修改mvc-dispatcher-servlet,然后再添加Java EE Persistence框架,等能够看到Persistence工具栏后,删除persistence.xml,余下的步骤可以继续操作。

七、用户管理

    既然我们要做一个博客管理系统,当然要首先实现我们的用户管理。在上一文中,我们已经配置好了数据库。接下来,就要实现网站的一些业务逻辑。

1、JPA操作定义

    在实现用户管理操作之前,需要讲解一下JPA的开发工作。

    首先,在com.gaussic.repository包内新建一个UserRepository接口:

    让该接口继承 JpaRepository:

package com.gaussic.repository;import com.gaussic.model.UserEntity;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;/** * Created by dzkan on 2016/3/8. */@Repositorypublic interface UserRepository extends JpaRepository<UserEntityInteger> {}

    在JpaRepository中,定义了几个简化的操作数据库的方法:

    (1) findAll():查找表中所有记录;

    (2)findOne(Integer id):按id来查找某一条记录;

    (3)findByXXX(Object xxx):在这里XXX是一个字段名,根据该字段的值开查找所有记录;

    (4)save()和delete():添加一条记录以及删除一条记录。

    除此之外,我们还可以在该repository中自定义新的方法,这将在稍后实际开发中提及。

2、后台管理

    为了尽可能的在省去篇幅的情况下,在此省去管理员操作的开发。默认在访问 /admin 时,进入后台管理。

(1)查看所有用户

    将MainController补充为如下形式:

package com.gaussic.controller;import com.gaussic.model.UserEntity;import com.gaussic.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import java.util.List;/** * Created by dzkan on 2016/3/8. */@Controllerpublic class MainController {    // 自动装配数据库接口,不需要再写原始的Connection来操作数据库    @Autowired    UserRepository userRepository;    @RequestMapping(value = "/"method = RequestMethod.GET)    public String index() {        return "index";    }    @RequestMapping(value = "/admin/users"method = RequestMethod.GET)    public String getUsers(ModelMap modelMap) {        // 查询user表中所有记录        List<UserEntity> userList = userRepository.findAll();        // 将所有记录传递给要返回的jsp页面,放在userList当中        modelMap.addAttribute("userList", userList);        // 返回pages目录下的admin/users.jsp页面        return "admin/users";    }}

    讲解:

    1. 自动装配:相当于数据库操作的极简化,只要定义了就可以直接进行数据库操作,不用再去管开启连接、关闭连接等问题

    2. 找到所有记录:使用JpaRepository的默认方法findAll()。

    3. modelMap:用于将controller方法里面的参数传递给所需的jsp页面,以进行相关显示。

    现在,需要在pages下新建目录admin,并新建users.jsp页面,以进行用户的管理:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>SpringMVC 用户管理</title>    <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->    <!--[if lt IE 9]>    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>    <![endif]--></head><body><div class="container">    <h1>SpringMVC 博客系统-用户管理</h1>    <hr/>    <h3>所有用户 <a href="/admin/users/addtype="button" class="btn btn-primary btn-sm">添加</a></h3>    <!-- 如果用户列表为空 --> <c:if test="${empty userList}">        <div class="alert alert-warning" role="alert">            <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>User表为空,请<a href="/admin/users/addtype="button" class="btn btn-primary btn-sm">添加</a>        </div>    </c:if>    <!-- 如果用户列表非空 --> <c:if test="${!empty userList}">        <table class="table table-bordered table-striped">            <tr>                <th>ID</th>                <th>昵称</th>                <th>姓名</th>                <th>密码</th>                <th>操作</th>            </tr>            <c:forEach items="${userList}" var="user">                <tr>                    <td>${user.id}</td>                    <td>${user.nickname}</td>                    <td>${user.firstName} ${user.lastName}</td>                    <td>${user.password}</td>                    <td>                        <a href="/admin/users/show/${user.id}" type="button" class="btn btn-sm btn-success">详情</a>                        <a href="/admin/users/update/${user.id}" type="button" class="btn btn-sm btn-warning">修改</a>                        <a href="/admin/users/delete/${user.id}" type="button" class="btn btn-sm btn-danger">删除</a>                    </td>                </tr>            </c:forEach>        </table>    </c:if></div><!-- jQuery文件。务必在bootstrap.min.js 之前引入 --><script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script></body></html>

    讲解:

  1. <c>标签:在jsp中使用了jstl语法,可以方便地进行一些判断<c:if>与遍历操作<c:forEach>;

  2. 页面使用了Bootstrap,部分功能将在之后实现。

    运行Tomcat,在浏览器中输入 http://localhost:8080/admin/users,进入用户管理界面,显示如下:

    由于目前数据库中没有数据,因而显示为空,现在需要向数据库中添加用户。

(2)添加用户

    在MainController中增加两个方法:

// get请求,访问添加用户 页面@RequestMapping(value = "/admin/users/add"method = RequestMethod.GET)public String addUser() {    // 转到 admin/addUser.jsp页面    return "admin/addUser";}// post请求,处理添加用户请求,并重定向到用户管理页面@RequestMapping(value = "/admin/users/addP"method = RequestMethod.POST)public String addUserPost(@ModelAttribute("user"UserEntity userEntity) {    // 注意此处,post请求传递过来的是一个UserEntity对象,里面包含了该用户的信息    // 通过@ModelAttribute()注解可以获取传递过来的'user',并创建这个对象    // 数据库中添加一个用户,该步暂时不会刷新缓存    //userRepository.save(userEntity);    // 数据库中添加一个用户,并立即刷新缓存    userRepository.saveAndFlush(userEntity);    // 重定向到用户管理页面,方法为 redirect:url    return "redirect:/admin/users";}

    讲解:

  1. /admin/users/add请求:get请求转到添加用户页面

  2. /admin/users/addP请求:post请求收集数据并存库

  3. @ModelAttribute注解:收集post过来的数据(在此,相当于post过来了一整个userEntity,不用一个一个地取)

  4. save()和saveAndFlush():save()方法处理完毕后,数据依然在缓冲区未写入数据库,使用saveAndFlush()可以立即刷新缓冲区,写入数据库

  5. redirect:/admin/users:这里使用重定向,可以让该方法重定向访问一个请求,ruturn之后,将跳转到 :/admin/users 所访问的页面。

现在,在pages目录下新建一个addUser.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>SpringMVC 添加用户</title>    <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->    <!--[if lt IE 9]>    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>    <![endif]--></head><body><div class="container">    <h1>SpringMVC 添加用户</h1>    <hr/>    <form:form action="/admin/users/addPmethod="post" commandName="user" role="form">        <div class="form-group">            <label for="firstName">Nickname:</label>            <input type="text" class="form-control" id="nickname" name="nickname" placeholder="Enter Nickname:"/>        </div>        <div class="form-group">            <label for="firstName">First Name:</label>            <input type="text" class="form-control" id="firstName" name="firstName" placeholder="Enter FirstName:"/>        </div>        <div class="form-group">            <label for="lastName">Last Name:</label>            <input type="text" class="form-control" id="lastName" name="lastName" placeholder="Enter LastName:"/>        </div>        <div class="form-group">            <label for="password">Password:</label>            <input type="text" class="form-control" id="password" name="password" placeholder="Enter Password:"/>        </div>        <div class="form-group">            <button type="submit" class="btn btn-sm btn-success">提交</button>        </div>    </form:form></div><!-- jQuery文件。务必在bootstrap.min.js 之前引入 --><script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script></body></html>

    讲解:

  1. <form:form>标签:使用Spring的form标签,可以方便的收集整块数据,commondName=“user”说明form内的内容都保存在这个user实例中,然后将整个user实例传递给controller处理。在所有的input标签中,name一定要与UserEntity中的成员相同,不然无法找到

  2. 在提交之后,后台将会处理 /admin/users/addP 请求。

    现在,重新启动服务器,访问 http://localhost:8080/admin/users/add 页面,如下图所示:

    输入数据,点击提交,数据库中将会写入新的用户,重新跳转到用户管理页面:

(3)查看用户详情

    在MainController中加入查看详情操作:

// 查看用户详情// @PathVariable可以收集url中的变量,需匹配的变量用{}括起来// 例如:访问 localhost:8080/admin/users/show/1 ,将匹配 id = 1@RequestMapping(value = "/admin/users/show/{id}"method = RequestMethod.GET)public String showUser(@PathVariable("id"Integer userId, ModelMap modelMap) {    // 找到userId所表示的用户    UserEntity userEntity = userRepository.findOne(userId);    // 传递给请求页面    modelMap.addAttribute("user", userEntity);    return "admin/userDetail";}

    在pages目录下新建 userDetail.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>SpringMVC 用户详情</title>    <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->    <!--[if lt IE 9]>    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>    <![endif]--></head><body><div class="container">    <h1>SpringMVC 用户详情</h1>    <hr/>    <table class="table table-bordered table-striped">        <tr>            <th>ID</th>            <td>${user.id}</td>        </tr>        <tr>            <th>Nickname</th>            <td>${user.nickname}</td>        </tr>        <tr>            <th>First Name</th>            <td>${user.firstName}</td>        </tr>        <tr>            <th>Last Name</th>            <td>${user.lastName}</td>        </tr>        <tr>            <th>Password</th>            <td>${user.password}</td>        </tr>    </table></div><!-- jQuery文件。务必在bootstrap.min.js 之前引入 --><script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script></body></html>

    讲解:如何访问一个实例内的数据?

        使用${}语法,在{}内可以使用类似Java的方法方便地访问数据。

    重启服务器,进入 http://localhost:8080/admin/users ,点击ID = 1的用户的 详情 按钮,可以查看用户详情:

    从url可以看出,访问的是ID=1的用户的详细情况,这样的URL采用了REST风格设计,看起来更加简便。

(4)修改用户信息

    现在我们要对用户信息做一定的修改,那该如何做呢。假设我们要能够修改全部的数据(除了id),JpaRepository未定义update方法,需要我们自己定义。

    打开UserRepository,添加updateUser()接口方法:

package com.gaussic.repository;import com.gaussic.model.UserEntity;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.Modifying;import org.springframework.data.jpa.repository.Query;import org.springframework.data.repository.query.Param;import org.springframework.stereotype.Repository;import org.springframework.transaction.annotation.Transactional;/** * Created by dzkan on 2016/3/8. */@Repositorypublic interface UserRepository extends JpaRepository<UserEntityInteger{    @Modifying      // 说明该方法是修改操作    @Transactional  // 说明该方法是事务性操作    // 定义查询    // @Param注解用于提取参数    @Query("update UserEntity us set us.nickname=:qNickname, us.firstName=:qFirstName, us.lastName=:qLastName, us.password=:qPassword where us.id=:qId")    public void updateUser(@Param("qNickname"String nickname, @Param("qFirstName"String firstName,                           @Param("qLastName"String qLastName, @Param("qPassword"String password, @Param("qId") Integer id);}

    在MainController中定义update操作方法:

// 更新用户信息 页面@RequestMapping(value = "/admin/users/update/{id}"method = RequestMethod.GET)public String updateUser(@PathVariable("id"Integer userId, ModelMap modelMap) {    // 找到userId所表示的用户    UserEntity userEntity = userRepository.findOne(userId);    // 传递给请求页面    modelMap.addAttribute("user", userEntity);    return "admin/updateUser";}// 更新用户信息 操作@RequestMapping(value = "/admin/users/updateP"method = RequestMethod.POST)public String updateUserPost(@ModelAttribute("userP"UserEntity user) {    // 更新用户信息    userRepository.updateUser(user.getNickname(), user.getFirstName(),            user.getLastName(), user.getPassword(), user.getId());    userRepository.flush(); // 刷新缓冲区    return "redirect:/admin/users";}

    然后,在pages目录下,新建updateUser.jsp文件:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="utf-8">    <meta http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1">    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <title>SpringMVC Demo 更新用户</title>    <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->    <!--[if lt IE 9]>    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>    <![endif]--></head><body><div class="container">    <h1>SpringMVC 更新用户信息</h1>    <hr/>    <form:form action="/admin/users/updatePmethod="post" commandName="userP" role="form">        <div class="form-group">            <label for="firstName">Nickname:</label>            <input type="text" class="form-control" id="nickname" name="nickname" placeholder="Enter Nickname:" value="${user.nickname}"/>        </div>        <div class="form-group">            <label for="firstName">First Name:</label>            <input type="text" class="form-control" id="firstName" name="firstName" placeholder="Enter FirstName:" value="${user.firstName}"/>        </div>        <div class="form-group">            <label for="lastName">Last Name:</label>            <input type="text" class="form-control" id="lastName" name="lastName" placeholder="Enter LastName:" value="${user.lastName}"/>        </div>        <div class="form-group">            <label for="password">Password:</label>            <input type="text" class="form-control" id="password" name="password" placeholder="Enter Password:" value="${user.password}"/>        </div>        <!-- 把 id 一并写入 userP 中 --> <input type="hidden" id="id" name="id" value="${user.id}"/>        <div class="form-group">            <button type="submit" class="btn btn-sm btn-success">提交</button>        </div>    </form:form></div><!-- jQuery文件。务必在bootstrap.min.js 之前引入 --><script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script></body></html>

    重启服务器,进入 http://localhost:8080/admin/users ,点击第一个用户的 修改 按钮,做如下修改:

    提交后,重新跳转回用户管理页面,可发现修改完成:

(5)删除用户

    现在,新添加一个用户:

    现在我们需要删掉新加入的用户,打开MainController,加入以下方法:

// 删除用户@RequestMapping(value = "/admin/users/delete/{id}"method = RequestMethod.GET)public String deleteUser(@PathVariable("id"Integer userId) {    // 删除id为userId的用户    userRepository.delete(userId);    // 立即刷新    userRepository.flush();    return "redirect:/admin/users";}

    重启服务器,进入 http://localhost:8080/admin/users ,点击ID=2的用户的删除按钮,在controller中处理完之后,将跳转回用户管理界面:


    这样,增删该查基本完成了。

    其实,更到这里,基本就可以开始开发工作了,还有一些其他的功能,都需要通过平时的积累以及多查资料来完成。例如JSON数据的处理,异步请求的处理,以及相关外键等操作。

    要知道的是,读者所阅读的三十分钟,需要写这篇文章的人数个小时的努力,整理确实不易。读文章要有举一反三地态度,才能真正的把东西学精学全。


0 0
原创粉丝点击