SpringMVC+Spring+Mybatis框架集成

1、基本概念javascript

1.Spring
     Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著做Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而建立的。Spring使用基本的JavaBean来完成之前只可能由EJB完成的事情。然而,Spring的用途不只限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用均可以从Spring中受益。 简单来讲,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。css

2.SpringMVC
     Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。html

3.MyBatis
     MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,而且更名为MyBatis 。MyBatis是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)MyBatis 消除了几乎全部的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。前端

2、使用Maven建立web项目java

1.打开Eclipse, 选择File -> New -> Other,在New窗口中选择 Maven -> Maven Project;点击Next。mysql

2.选择项目路径,这里选择Use default Workspace location默认工做空间。jquery

3.选择项目类型,在Artifact Id中选择maven-archetype-webappweb

4.输入Group Id和 Artifact Id,package能够不写。spring

Group Id:相似于包名
Artifact Id:项目的名称
Version:初始的版本号,通常不须要改动
其余选项设置为空,点击Next建立项目,以下图:sql

5.点击Finish,会生成一个这样目录的项目。

6.修改项目编码方式

在项目上右键 -> Properties -> Resource -> Text file encoding -> 改成“utf-8”。

7.添加Source文件夹

接下来须要添加src/main/java、src/test/java、src/test/resources三个文件夹。注意不是建普通的Folder,而是Source Folder。在项目上右键new -> Other,在New窗口中选择

Java -> Source Folder。

若是出现了下面的状况,实际上是文件夹已经存在了,只是咱们看不到。

8.在项目上右键,选择Properties,在弹出的属性窗口中依次选择Java Build Path -> Libraries -> JRE System Library -> Edit。

9.在Edit Library窗口中修改JRE为jdk1.7.0_25。

10.设置好以后的目录结构以下图所示:

这时看到src/main/java和src/test/java文件夹就已经显示出来了。

11.让项目使用jdk 1.7编译

在项目上右键 -> 选择Properties -> 选择Java Compiler -> 将Compiler Compliance Level 改成“1.7”。

12.更改class路径

右键项目,选择Java Build Path -> Source,下面应该有4个文件夹,src/main/java,src/main/resources,src/test/java,src/test/resources。双击每一个文件夹的Output folder,选择路径。src/main/java,src/main/resources,选择target/classes;src/test/java ,src/test/resources, 选择target/test-classes。选上Allow output folders for source folders。(若是没有选上的话)

13.把项目变成Dynamic Web项目 

右键项目,选择Properties,在属性窗口中选择Project Facets,修改Java版本号为1.7,默认为1.5或其余版本。注:先去掉“Dynamic Web Module”,而后再保存。

14.接下来继续右键项目 -> Properties ->选择Project Facets -> 勾选“Dynamic Web Module”,选择版本为3.0 -> 而后点击下方的“Further configuration available...”。

15.在弹出的窗口中修改Content directory为“src/main/webapp”。

设置好以后的项目结构以下图所示,能够看到在webapp下面多了一个META-INF文件夹。

或者还有一种作法,就是在“Modify Faceted Project”窗口中不用修改Content directory,即用他的默认值“WebContent”。

接下来观察咱们的项目结构,多了一个WebContent目录。

这个结构不符合maven的结构,咱们还要作以下修改:

把上图WebContent下面两个目录 META-INF ,WEB-INF 直接剪切到src/main/webapp目录下,并删掉WebContent目录便可。

16.设置部署程序集(Web Deployment Assembly)

在项目上右键,选择Properties -> Deployment Assembly,点击进去后,以下图:

此处列表是,部署项目时,文件发布的路径。

(1)咱们删除跟test相关的项,由于test是测试使用,并不须要部署。

(2)设置将Maven的jar包发布到lib下。

在右边点击“Add”按钮,在弹出的窗口中选择Java Build Path Entries。

点击Next,选择Maven Dependencies

点击Finish,而后能够看到已经把Maven Dependencies添加到Web应用结构中了,完成后以下图:

17.至此一个基于maven的webapp就创建好了,并能够直接从eclipse中发布到tomcat。发布完成后,进入到tomcat的部署路径,个人是D:\apache-tomcat-7.0.27\webapps\SSMProDemo,发现WEB-INF目录下自动生成了lib目录,而且全部依赖的jar包也都已经部署进来。若是没有lib目录,说明项目依赖的jar包没有部署进来,这时运行程序会报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener。

3、建立数据库和表

打开MySQL数据库,建立两张表,一张用于存放用户信息的表tb_user,另外一张为字典表tb_dict。SQL脚本以下:

复制代码
/*
Navicat MySQL Data Transfer

Source Server         : local
Source Server Version : 50617
Source Host           : localhost:3306
Source Database       : demodb

Target Server Type    : MYSQL
Target Server Version : 50617
File Encoding         : 65001

Date: 2017-01-31 18:39:18
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `tb_dict`
-- ----------------------------
DROP TABLE IF EXISTS `tb_dict`;
CREATE TABLE `tb_dict` (
  `dictid` int(11) NOT NULL AUTO_INCREMENT COMMENT '字典id',
  `field` varchar(15) DEFAULT NULL COMMENT '对照字段',
  `fieldname` varchar(20) DEFAULT NULL COMMENT '对照字段名称',
  `code` varchar(10) DEFAULT NULL COMMENT '代码',
  `codedesc` varchar(100) DEFAULT NULL COMMENT '代码描述',
  `enabled` varchar(2) DEFAULT '1' COMMENT '启用状态(0:禁用;1:启用)',
  `sortno` int(4) DEFAULT NULL COMMENT '排序号',
  PRIMARY KEY (`dictid`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_dict
-- ----------------------------
INSERT INTO `tb_dict` VALUES ('1', 'SEX', '性别', '1', '男', '1', '1');
INSERT INTO `tb_dict` VALUES ('2', 'SEX', '性别', '2', '女', '1', '2');
INSERT INTO `tb_dict` VALUES ('3', 'EDU', '学历', '1', '高中', '1', '1');
INSERT INTO `tb_dict` VALUES ('4', 'EDU', '学历', '3', '本科', '1', '3');
INSERT INTO `tb_dict` VALUES ('5', 'EDU', '学历', '4', '研究生', '1', '4');
INSERT INTO `tb_dict` VALUES ('6', 'EDU', '学历', '5', '博士', '1', '5');
INSERT INTO `tb_dict` VALUES ('7', 'EDU', '学历', '2', '专科', '1', '2');

-- ----------------------------
-- Table structure for `tb_user`
-- ----------------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(20) DEFAULT NULL COMMENT '姓名',
  `user_sex` varchar(2) DEFAULT NULL COMMENT '性别',
  `user_birthday` date DEFAULT NULL COMMENT '出生日期',
  `user_email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `user_edu` varchar(2) DEFAULT NULL COMMENT '学历',
  `user_telephone` varchar(30) DEFAULT NULL COMMENT '联系方式',
  `user_address` varchar(100) DEFAULT NULL COMMENT '住址',
  `create_time` datetime DEFAULT NULL COMMENT '建立时间',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', '李磊', '1', '1985-01-12', 'lilei123@sina.com', '3', '13211335451', '北京市东城区XXXX', '2017-01-31 18:24:41');
INSERT INTO `tb_user` VALUES ('2', '张华', '2', '1988-11-15', 'zhanghuajig@163.com', '3', '13811362254', '北京市西城区XXXX', '2017-01-31 18:29:08');
INSERT INTO `tb_user` VALUES ('3', '王媛媛', '2', '1990-04-06', 'yuanyuan112@sina.com', '3', '13511784568', '北京市西城区XXXX', '2017-01-18 10:30:48');
INSERT INTO `tb_user` VALUES ('4', '陈迪', '1', '1990-06-16', 'chendi0616@sina.com', '3', '13511697892', '北京市东城区XXXX', '2017-01-10 09:20:50');
INSERT INTO `tb_user` VALUES ('5', '王海东', '1', '1989-05-23', 'wanghaidong@163.com', '4', '13811981290', '北京市石景山区苹果园XXXXX', '2017-01-12 18:33:31');
INSERT INTO `tb_user` VALUES ('6', '李雪梅', '2', '1985-05-12', 'lixuemei@163.com', '2', '13911378945', '北京市朝阳区XXX', '2017-01-27 18:34:42');
INSERT INTO `tb_user` VALUES ('7', '张扬', '1', '1988-04-12', 'zhangyang11@sina.com', '3', '13611651245', '北京市石景山区XXXX', '2017-01-24 18:35:46');
INSERT INTO `tb_user` VALUES ('8', '赵庆', '1', '1986-05-06', 'zhaoqing56@163.com', '2', '13599632147', '北京市朝阳区XXX', '2017-01-31 18:38:57');
复制代码

表结构以下所示:

4、添加依赖包

项目主要依赖的jar包有Spring核心包、Spring AOP包、Spring MVC包、MyBatis ORM包、MyBatis-Spring适配包、JSTL、JUnit、Log4j2等,具体的pom.xml文件以下:

复制代码
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns: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.demo</groupId>
  <artifactId>SSMProDemo</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>SSMProDemo Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <spring.version>4.3.0.RELEASE</spring.version>
  </properties>
    
  <dependencies>
      <!--Spring框架核心库 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- Spring MVC -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context-support</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!-- aspectJ AOP 织入器 -->
      <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.8.9</version>
      </dependency>
      <!--mybatis-spring适配器 -->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis-spring</artifactId>
          <version>1.3.0</version>
      </dependency>
      <!--Spring java数据库访问包,在本例中主要用于提供数据源 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${spring.version}</version>
      </dependency>
      <!--mysql数据库驱动 -->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.38</version>
      </dependency>
      <!--log4j日志包 -->
      <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-core</artifactId>
          <version>2.6.1</version>
      </dependency>
      <!-- mybatis ORM框架 -->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.4.1</version>
      </dependency>
      <!-- JUnit单元测试工具 -->
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.10</version>
      </dependency>
      <!--c3p0 链接池 -->
      <dependency>
          <groupId>c3p0</groupId>
          <artifactId>c3p0</artifactId>
          <version>0.9.1.2</version>
      </dependency>
      <!-- JSTL -->
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
      </dependency>
      <!-- Servlet核心包 -->
      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.0.1</version>
          <scope>provided</scope>
      </dependency>
      <!--JSP -->
      <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.1</version>
          <scope>provided</scope>
      </dependency>
      <!-- jackson -->
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.5.2</version>
      </dependency>
      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.5.2</version>
      </dependency>
      <!--JSR303 -->
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-validator</artifactId>
          <version>5.2.2.Final</version>
      </dependency>
      <!--文件上传 -->
      <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.4</version>
      </dependency>
      <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.3.1</version>
      </dependency>
  </dependencies>
  <build>
    <finalName>SSMProDemo</finalName>
  </build>
</project>
复制代码

若是是第一次依赖相关的包,则须要下载时间,请耐心等待,若是下载失败则须要手动下载,下载完成后复制到本地的资源库中。依赖后的项目结果以下:

5、完成Spring与Mybatis的整合

一、在src/main/resources目录下新建config.properties文件,用于存放数据库链接信息,文件内容以下:

复制代码
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/ssmdb?useUnicode=true&characterEncoding=utf-8
mysql.user=root
mysql.password=root
mysql.acquireIncrement=5
mysql.initialPoolSize=10
mysql.minPoolSize=5
mysql.maxPoolSize=20
复制代码

二、在src/main/resources目录下新建spring-mybatis.xml文件,用于整合MyBatis与Spring,很是关键,具体的内容以下:

复制代码
<?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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    
    <!-- 1.引入属性文件 -->
    <context:property-placeholder location="classpath:config.properties" />
    
    <!-- 2.自动扫描service包(自动注入) -->
    <context:component-scan base-package="com.demo.service" />
    
    <!-- ========================================配置数据源========================================= -->
    <!-- 3.配置C3P0数据源 -->  
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
        destroy-method="close">
        <!--驱动类名 -->
        <property name="driverClass" value="${mysql.driver}" />
        <!-- url -->
        <property name="jdbcUrl" value="${mysql.url}" />
        <!-- 用户名 -->
        <property name="user" value="${mysql.user}" />
        <!-- 密码 -->
        <property name="password" value="${mysql.password}" />
        <!-- 当链接池中的链接耗尽的时候c3p0一次同时获取的链接数 -->
        <property name="acquireIncrement" value="${mysql.acquireIncrement}"></property>
        <!-- 初始链接池大小 -->
        <property name="initialPoolSize" value="${mysql.initialPoolSize}"></property>
        <!-- 链接池中链接最小个数 -->
        <property name="minPoolSize" value="${mysql.minPoolSize}"></property>
        <!-- 链接池中链接最大个数 -->
        <property name="maxPoolSize" value="${mysql.maxPoolSize}"></property>
       
    </bean>  
    
    <!-- ========================================针对myBatis的配置项============================== -->
    <!-- 4.配置sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 实例化sqlSessionFactory时须要使用上述配置好的数据源以及SQL映射文件 -->
        <!-- 数据源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- sql映射文件路径 -->
        <!-- 自动扫描com/demo/mapping/目录下的全部SQL映射的xml文件, 省掉Configuration.xml里的手工配置
        value="classpath:com/demo/mapping/*.xml"指的是classpath(类路径)下com.demo.mapping包中的全部xml文件 -->
        <property name="mapperLocations" value="classpath:com/demo/mapping/*.xml" />
    </bean>
    
    <!-- 5.配置扫描器  -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 扫描com.demo.dao这个包以及它的子包下的全部映射接口类 -->
        <property name="basePackage" value="com.demo.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    
    <!-- ========================================配置事务============================== -->
    <!-- 6.声明式事务管理 -->
    <!--定义事物管理器,由spring管理事务 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 配置数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 通知 -->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
        <tx:attributes>
             <!-- 传播行为 -->
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="append*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="modify*" propagation="REQUIRED" />
            <tx:method name="edit*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="remove*" propagation="REQUIRED" />
            <tx:method name="repair" propagation="REQUIRED" />

            <tx:method name="get*" propagation="REQUIRED"  />
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />
            <tx:method name="load*" propagation="REQUIRED" read-only="true" />
            <tx:method name="search*" propagation="REQUIRED" read-only="true" />
            <tx:method name="datagrid*" propagation="REQUIRED" read-only="true" />

            <tx:method name="*" propagation="REQUIRED"  />
        </tx:attributes>
    </tx:advice>
    
    <!-- 配置aop  -->
    <aop:config>
        <aop:pointcut id="transactionPointcut" expression="execution(* com.demo.service..*Impl.*(..))" />
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
    </aop:config>
    
</beans>
复制代码

6、整合SpringMVC

在src/main/java源代码目录下添加Spring MVC配置文件spring-mvc.xml,配置里面的注释也很详细,在此就不说了,主要是自动扫描控制器,视图模式,注解的启动这三个。

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/aop   
        http://www.springframework.org/schema/aop/spring-aop-4.3.xsd   
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd   
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-4.3.xsd   
        http://www.springframework.org/schema/mvc   
        http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd   
        http://www.springframework.org/schema/tx   
        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd" >
    
    <!-- 1.自动扫描包,实现支持注解的IOC  -->
    <!-- 自动扫描该包,使springmvc认为包下用了@Controller注解的类是控制器 -->
    <context:component-scan base-package="com.demo.controller" /> 
    
    <!-- 2.配置注解的处理器映射器和处理器适配器 -->
    <!-- <mvc:annotation-driven /> 是一种简写形式,彻底能够手动配置替代这种简写形式,简写形式可让初学者
        快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与
        AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。 -->
    <mvc:annotation-driven />
    
    <!-- 3.Spring MVC不处理静态资源  -->
    <mvc:default-servlet-handler/>
    
    <!-- 4.配置内部视图解析器 -->
      <!-- 对模型视图名称的解析,即在模型视图名称添加先后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!--5.配置文件上传解析器 -->
    <!--Spring MVC默认不能识别multipart格式的文件内容 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    </bean>
    
</beans>
复制代码

7、配置web.xml文件
      web.xml应该是整个项目最重要的配置文件了,不过servlet3.0中已经支持注解配置方式了。在servlet3.0之前每一个servlet必需要在web.xml中配置servlet及其映射关系。可是在spring框架中就不用了,由于Spring中是依赖注入(Dependency Injection)的也叫控制反转(Inversion of Control)。可是也要配置一个重要的servlet,就是前端控制器(DispatcherServlet)。配置方式与普通的servlet基本类似,具体内容以下:

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    
    <!--  加载spring和mybatis的配置文件 --> 
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mybatis.xml</param-value>
    </context-param>
      
    <!-- 使用ContextLoaderListener初始化Spring容器 -->
    <!--若没有指定其余参数,默认查找的配置文件位置是:/WEB-INF/applicationContext.xml  -->
    <listener>
        <description>Spring容器加载监听器</description>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- 配置springmvc核心控制器 -->
    <!-- spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <description>spring MVC 配置文件路径</description>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
         <!-- 启动动优先级,越小越早加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- Servlet访问的路径映射,全部的访问都必须通过调度用的前置控制器 -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!--编码过滤器 -->
    <filter>
        <description>字符集过滤器</description>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <description>字符集编码</description>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 路径映射 -->
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
</web-app>
复制代码

 8、完善项目结构

在src/main/java目录下建几个Package,以下图:

其中controller对应控制层,dao对应持久层,mapping对应SQL映射文件,model对应实体层,service对应业务层。

9、建立POJO实体类

在model下面新建三个实体类,分别为用户类(User.java)、字典类(Dict.java)、用户扩展类(UserExtend.java),具体代码以下。

用户类:

复制代码
package com.demo.model;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;

public class User {
    
    //用户id
    private int user_id;
    //姓名
    @NotEmpty(message="{user_name.notEmpty}")
    private String user_name;
    //性别
    @NotEmpty(message="{user_sex.notEmpty}")
    private String user_sex;
    //出生日期
    @NotEmpty(message="{user_birthday.notEmpty}")
    private String user_birthday;
    //邮箱
    @NotEmpty(message="{user_email.notEmpty}")
    @Email(message="{user_email.wrong}")
    private String user_email;
    //学历
    @NotEmpty(message="{user_edu.notEmpty}")
    private String user_edu;
    //联系方式
    @NotEmpty(message="{user_telephone.notEmpty}")
    private String user_telephone;
    //住址
    private String user_address;
    
    public int getUser_id() {
        return user_id;
    }
    public void setUser_id(int user_id) {
        this.user_id = user_id;
    }
    public String getUser_name() {
        return user_name;
    }
    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }
    public String getUser_sex() {
        return user_sex;
    }
    public void setUser_sex(String user_sex) {
        this.user_sex = user_sex;
    }
    public String getUser_birthday() {
        return user_birthday;
    }
    public void setUser_birthday(String user_birthday) {
        this.user_birthday = user_birthday;
    }
    public String getUser_email() {
        return user_email;
    }
    public void setUser_email(String user_email) {
        this.user_email = user_email;
    }
    public String getUser_edu() {
        return user_edu;
    }
    public void setUser_edu(String user_edu) {
        this.user_edu = user_edu;
    }
    public String getUser_telephone() {
        return user_telephone;
    }
    public void setUser_telephone(String user_telephone) {
        this.user_telephone = user_telephone;
    }
    public String getUser_address() {
        return user_address;
    }
    public void setUser_address(String user_address) {
        this.user_address = user_address;
    }
    
}
复制代码

字典类:

复制代码
package com.demo.model;

public class Dict {
    
    //字典id
    private int dictid;
    //对照字段
    private String field;
    //对照字段名称
    private String fieldname;
    //代码
    private String code;
    //代码描述
    private String codedesc;
    
    public int getDictid() {
        return dictid;
    }
    public void setDictid(int dictid) {
        this.dictid = dictid;
    }
    public String getField() {
        return field;
    }
    public void setField(String field) {
        this.field = field;
    }
    public String getFieldname() {
        return fieldname;
    }
    public void setFieldname(String fieldname) {
        this.fieldname = fieldname;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getCodedesc() {
        return codedesc;
    }
    public void setCodedesc(String codedesc) {
        this.codedesc = codedesc;
    }
}
复制代码

用户扩展类:

复制代码
package com.demo.model;

/**
 * 用户的扩展类
 * @author lixiaoxi
 *
 */
public class UserExtend extends User{
    
    // 性别描述(对应字典表里的代码描述)
    private String user_sex_desc;
    
    // 学历描述(对应字典表里的代码描述)
    private String user_edu_desc;
    
    public String getUser_sex_desc() {
        return user_sex_desc;
    }

    public void setUser_sex_desc(String user_sex_desc) {
        this.user_sex_desc = user_sex_desc;
    }

    public String getUser_edu_desc() {
        return user_edu_desc;
    }

    public void setUser_edu_desc(String user_edu_desc) {
        this.user_edu_desc = user_edu_desc;
    }
}
复制代码

为了实现校验,在User类的成员变量设置了一些注解信息。

10、建立Dao层接口(mapper接口)

在dao层下面新建两个接口文件IUserDao.java和IDictDao.java,具体代码以下:

复制代码
package com.demo.dao;

import java.util.List;
import org.apache.ibatis.annotations.Param;

import com.demo.model.User;
import com.demo.model.UserExtend;

public interface IUserDao {
    
    /**
     * 查询用户信息并分页
     * @param skip
     * @param size
     * @return
     */
    public List<UserExtend> queryUserPager(@Param("skip") int skip,@Param("size") int size);
    
    /**
     * 查询用户总数
     * @return
     */
    public int queryUserCount();
    
    /**
     * 根据用户id查询用户
     * @param userid
     * @return
     */
    public User queryUserById(int userid);
    
    /**
     * 新增用户
     * @param user
     * @return
     */
    public int insertUser(User user);
    
    /**
     * 修改用户
     * @param user
     * @return
     */
    public int updateUser(User user);
    
    /**
     * 根据用户id删除用户
     * @param user_id
     * @return
     */
    public int deleteUserById(int user_id);
    
    /**
     * 删除多个用户
     * @param userIds
     * @return
     */
    public int deleteUsers(int[] userIds);
}
复制代码
复制代码
package com.demo.dao;

import java.util.List;

import com.demo.model.Dict;

public interface IDictDao {
    
    /**
     * 根据字段获取字典
     * @param field
     * @return
     */
    public List<Dict> getDictByField(String field);
}
复制代码

11、建立Mybatis SQL映射文件
在mapping下面建立sql映射文件:

UserMapper.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper 
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间应该是对应接口的包名+接口名 -->
<mapper namespace="com.demo.dao.IUserDao">
    <!--查询用户信息并分页 -->
    <select id="queryUserPager" resultType="com.demo.model.UserExtend">
        select t.user_id,t.user_name,t.user_sex,date_format(t.user_birthday,'%Y-%m-%d')user_birthday,
        t.user_email,t.user_edu,t.user_telephone,t.user_address,p.codedesc as user_sex_desc,
        p1.codedesc as user_edu_desc
        from tb_user t inner join tb_dict p on t.user_sex=p.code and p.field='SEX' 
        inner join tb_dict p1 on t.user_edu = p1.code and p1.field = 'EDU'
        order by t.create_time desc
        limit #{skip},#{size}
    </select>
      
      <!--查询用户总数 -->
    <select id="queryUserCount" resultType="int">
        select count(*) from tb_user
    </select>
    
    <!--根据用户id查询用户 -->
    <select id="queryUserById" parameterType="int" resultType="com.demo.model.User">
        select user_id,user_name,user_sex,date_format(user_birthday,'%Y-%m-%d')user_birthday,
        user_email,user_edu,user_telephone,user_address from tb_user where user_id=#{user_id}
    </select>
    
    <!--新增用户 -->
    <insert id="insertUser" parameterType="com.demo.model.User">
        insert into tb_user(user_name,user_sex,user_birthday,user_email,user_edu,user_telephone,user_address,
            create_time) 
        values(#{user_name},#{user_sex},str_to_date(#{user_birthday},'%Y-%m-%d'),#{user_email},#{user_edu},
            #{user_telephone},#{user_address},now());
    </insert>
    
    <!--编辑用户 -->
    <update id="updateUser" parameterType="com.demo.model.User">
        update tb_user 
        set user_name=#{user_name},user_sex=#{user_sex},user_birthday=str_to_date(#{user_birthday},'%Y-%m-%d'),
        user_email=#{user_email},user_edu=#{user_edu},user_telephone=#{user_telephone},user_address=#{user_address} 
        where user_id=#{user_id}
    </update>
    
    <!--根据用户id删除用户 -->
    <delete id="deleteUserById" parameterType="int">
       delete from tb_user where user_id=#{user_id}
    </delete>
    
    <!--删除多个用户 -->
    <delete id="deleteUsers" parameterType="java.util.List">
       delete from tb_user where user_id in
       <!-- <foreach>标签有循环的功能,能够用来生成有规律的SQL语句,主要属性有:
        item:表示集合每个元素进行迭代时的别名
        index:表示在迭代过程当中,每次迭代到的位置
        open:表示该语句以什么开始
        separator:表示每次迭代之间以什么符号做为分隔
        close:表示该语句以什么结束
        collection:要循环的集合 -->
       <foreach item="item" index="index" collection="array" open="(" separator="," close=")">
           #{item}
         </foreach>
    </delete>
</mapper>
复制代码

DictMapper.xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper 
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间应该是对应接口的包名+接口名 -->
<mapper namespace="com.demo.dao.IDictDao">
    <!--根据字段获取字典 -->
    <select id="getDictByField" parameterType="java.lang.String" resultType="com.demo.model.Dict">
       select code,codedesc from tb_dict 
       where field=#{value} and enabled='1' 
       order by sortno
    </select>

</mapper>
复制代码

12、建立服务层
在包com.demo.service下建立两个接口文件,以下:

IUserService.java

复制代码
package com.demo.service;

import java.util.List;

import com.demo.model.User;
import com.demo.model.UserExtend;

/**
 * 用户业务接口
 * @author lixiaoxi
 *
 */
public interface IUserService {
    
    /**
     * 分页
     * @param pageNO
     * @param size
     * @return
     */
    public List<UserExtend> queryUserPager(int pageNO, int size);
    
    /**
     * 查询用户总数
     * @return
     */
    public int queryUserCount();
    
    /**
     * 根据用户id查询用户
     * @param userid
     * @return
     */
    public User queryUserById(int userid);
    
    /**
     * 新增用户
     * @param user
     * @return
     */
    public int insertUser(User user);
    
    /**
     * 修改用户
     * @param user
     * @return
     */
    public int updateUser(User user);
    
    /**
     * 根据用户id删除用户
     * @param user_id
     * @return
     */
    public int deleteUserById(int user_id);
    
    /**
     * 删除多个用户
     * @param userIds
     * @return
     */
    public int deleteUsers(int[] userIds);
}
复制代码

IDictService.java

复制代码
package com.demo.service;

import java.util.List;

import com.demo.model.Dict;

/**
 * 字典业务接口
 * @author lixiaoxi
 *
 */
public interface IDictService {
    
    /**
     * 根据字段获取字典
     * @param field
     * @return
     */
    public List<Dict> getDictByField(String field);
}
复制代码

实现类:

UserServiceImpl.java

复制代码
package com.demo.service.impl;

import java.util.List;

import javax.annotation.Resource;
import org.springframework.stereotype.Service;

import com.demo.dao.IUserDao;
import com.demo.model.User;
import com.demo.model.UserExtend;
import com.demo.service.IUserService;

@Service
public class UserServiceImpl implements IUserService{
    
    //自动装配
    @Resource
    private IUserDao userDao;
    
    /**
     * 分页
     */
    public List<UserExtend> queryUserPager(int pageNO, int size) {
        int skip=(pageNO-1)*size;
        return userDao.queryUserPager(skip, size);
    }
    
    /**
     * 查询用户总数
     */
    public int queryUserCount() {
        return userDao.queryUserCount();
    }
    
    /**
     * 根据用户id查询用户
     */
    public User queryUserById(int userid){
        return userDao.queryUserById(userid);
    }
    
    /**
     * 新增用户
     */
    public int insertUser(User user){
        return userDao.insertUser(user);
    }
    
    /**
     * 修改用户
     */
    public int updateUser(User user){
        return userDao.updateUser(user);
    }
    
    /**
     * 根据用户id删除用户
     */
    public int deleteUserById(int user_id){
        return userDao.deleteUserById(user_id);
    }
    
    /**
     * 删除多个用户
     */
    public int deleteUsers(int[] userIds){
        return userDao.deleteUsers(userIds);
    }
}
复制代码

DictServiceImpl.java

复制代码
package com.demo.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo.dao.IDictDao;
import com.demo.model.Dict;
import com.demo.service.IDictService;

@Service
public class DictServiceImpl implements IDictService{
    
    /**
     * 自动装配
     */
    @Autowired
    private IDictDao dictDao;
    /**
     * 根据字段获取字典
     * @param field
     * @return
     */
    public List<Dict> getDictByField(String field){
        return dictDao.getDictByField(field);
    }

}
复制代码

十3、完成用户管理功能

一、用户列表与分页

在com.demo.controller包下定义UserController控制器,代码以下:

复制代码
package com.demo.controller;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.demo.model.User;
import com.demo.service.IDictService;
import com.demo.service.IUserService;

@Controller
@RequestMapping("/user")
public class UserController {
     
    @Resource
    private IUserService userService;
    @Autowired
    private IDictService dictService;
     
    /*
     * 用户列表与分页Action
     */
    @RequestMapping("/list")
    public String list(Model model,@RequestParam(required=false,defaultValue="1") int pageNO){
        int size=5;
        model.addAttribute("size",size);
        model.addAttribute("pageNO",pageNO);
        model.addAttribute("count",userService.queryUserCount());
        model.addAttribute("userList", userService.queryUserPager(pageNO, size));
        return "user/list";
    }
}
复制代码

参数size表示每页记录数,pageNO表示当前页号,处于第几页,count表示总记录数。

在views/user 目录下添加视图list.jsp页面,页面的内容以下:

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="<c:url value="/styles/main.css"/>"  type="text/css" rel="stylesheet" />
<title>用户管理</title>
</head>
<body>
    <div class="main">
        <h2 class="title"><span>用户管理</span></h2>
        <form action="deleteUsers" method="post">
        <table border="1" width="100%" class="tab">
            <tr>
                <th><input type="checkbox" id="chkAll"></th>
                <th>姓名</th>
                <th>性别</th>
                <th>出生日期</th>
                <th>邮箱</th>
                <th>学历</th>
                <th>联系方式</th>
                <th>家庭住址</th>
                <th>操做</th>
            </tr>
            <c:forEach var="entity" items="${userList}">
                <tr>
                    <th><input type="checkbox" name="user_id" value="${entity.user_id}"></th>
                    <td>${entity.user_name}</td>
                    <td>${entity.user_sex_desc}</td>
                    <td>${entity.user_birthday}</td>
                    <td>${entity.user_email}</td>
                    <td>${entity.user_edu_desc}</td>
                    <td>${entity.user_telephone}</td>
                    <td>${entity.user_address}</td>
                    <td>
                    <a href="edit/${entity.user_id}" class="abtn">编辑</a>
                    <a href="deleteUserById/${entity.user_id}" class="abtn">删除</a>
                    </td>
                </tr>
            </c:forEach>
        </table>
        <div id="pager"></div>
        <p>
            <a href="add" class="abtn out">添加</a>
            <input type="submit"  value="批量删除" class="btn out" onclick="return submitForm();"/>
        </p>
        <p style="color: red">${message}</p>
        <!--分页 -->
        <script type="text/javascript" src="<c:url value="/scripts/jQuery1.11.3/jquery-1.11.3.min.js"/>" ></script>
        <link href="<c:url value="/scripts/pagination22/pagination.css"/>"  type="text/css" rel="stylesheet" />
        <script type="text/javascript" src="<c:url value="/scripts/pagination22/jquery.pagination2.2.js"/>" ></script>
        <script type="text/javascript">
            
            $(document).ready(function(){
                //全选/取消全选
                $("#chkAll").click(function(){
                    var checked=$("#chkAll").prop("checked");
                    $("input[name='user_id']").prop("checked",checked);
                })
            })
        
           //初始化分页组件
           var count=${count};
           var size=${size};
           var pageNO=${pageNO};
           $("#pager").pagination(count, {
              items_per_page:size,
               current_page:pageNO-1,
               next_text:"下一页",
               prev_text:"上一页",
               num_edge_entries:2,
               load_first_page:false,
              callback:handlePaginationClick
            });
           
           //回调方法
           function handlePaginationClick(new_page_index, pagination_container){
               location.href="list?pageNO="+(new_page_index+1);
           }
           
           function submitForm(){
               if($("input[name='user_id']:checked").length==0){
                   alert("请选择要删除的记录!");
                   return false;
               }
               return true;
           }
        </script>
    </form>
    </div>
</body>
</html>
复制代码

为了实现分页,添加了一个jQuery插件pagination,该插件的详细参数以下所示:

  View Code

测试运行结果:

 二、新增用户

在控制器中添加两个方法,一个是add用于完成添加页面展现,一个是addSave用于完成添加保存处理,代码以下:

复制代码
/**
 * 添加用户
 * @param model
 * @return
 */
@RequestMapping("/add")
public String add(Model model){
    // 与form绑定的模型
    model.addAttribute("user",new User());
    // 用于生成“性别”下拉列表
    model.addAttribute("sexList",dictService.getDictByField("SEX"));
    // 用于生成“学历”下拉列表
    model.addAttribute("eduList",dictService.getDictByField("EDU"));
    
    return "user/add";
}

 /**
  * 添加用户保存
  * @param model
  * @param entity
  * @param bindingResult
  * @return
  */
 @RequestMapping("/addSave")
 public String addSave(Model model,@ModelAttribute("user") @Valid User user,BindingResult bindingResult){
    //若是模型中存在错误
    if(!bindingResult.hasErrors()){
        if(userService.insertUser(user)>0){
            return "redirect:/user/list";
        }
    }
    model.addAttribute("user", user);
    // 用于生成“性别”下拉列表
    model.addAttribute("sexList",dictService.getDictByField("SEX"));
    // 用于生成“学历”下拉列表
    model.addAttribute("eduList",dictService.getDictByField("EDU"));
    return "user/add";
 }
复制代码

这里有一个问题是由于使用了JSR303校验,当保存对象是须要在参数前注解@ModelAttribute("entity") @Valid,用于激活校验,不然页面将不会有错误展现。

为了配合Bean Validation,定义的User Bean须要注解,内容以下:

复制代码
//姓名
@NotEmpty(message="{user_name.notEmpty}")
private String user_name;
//性别
@NotEmpty(message="{user_sex.notEmpty}")
private String user_sex;
//出生日期
@NotEmpty(message="{user_birthday.notEmpty}")
private String user_birthday;
//邮箱
@NotEmpty(message="{user_email.notEmpty}")
@Email(message="{user_email.wrong}")
private String user_email;
//学历
@NotEmpty(message="{user_edu.notEmpty}")
private String user_edu;
//联系方式
@NotEmpty(message="{user_telephone.notEmpty}")
private String user_telephone;
复制代码

这里的错误消息来源一个是直接写在注解中,另外一个来自消息文件;{user_name.notEmpty}来自消息文件ValidationMessages.properties,在src/main/resources目录下新建该文件,文件内容以下:

复制代码
user_name.notEmpty=姓名不容许为空
user_sex.notEmpty=性别不容许为空
user_birthday.notEmpty=出生日期不容许为空
user_email.notEmpty=邮箱不容许为空
user_email.wrong=邮箱格式不正确
user_edu.notEmpty=学历不容许为空
user_telephone.notEmpty=联系方式不容许为空
复制代码

这里需注意的是,默认状况下中文会显示成utf-8编码格式如:

复制代码
user_name.notEmpty=\u59D3\u540D\u4E0D\u5141\u8BB8\u4E3A\u7A7A
user_sex.notEmpty=\u6027\u522B\u4E0D\u5141\u8BB8\u4E3A\u7A7A
user_birthday.notEmpty=\u51FA\u751F\u65E5\u671F\u4E0D\u5141\u8BB8\u4E3A\u7A7A
user_email.notEmpty=\u90AE\u7BB1\u4E0D\u5141\u8BB8\u4E3A\u7A7A
user_email.wrong=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E
user_edu.notEmpty=\u5B66\u5386\u4E0D\u5141\u8BB8\u4E3A\u7A7A
user_telephone.notEmpty=\u8054\u7CFB\u65B9\u5F0F\u4E0D\u5141\u8BB8\u4E3A\u7A7A
复制代码

为了正常显示,能够安装一个插件,让属性文件支持正常显示中文,插件名称是properties-editor,点击“Help”->“Eclipse Marketplace...”,搜索插件名称,显示内容以下:

点击Installed,进入下一步:

完成后在properties文件上右键选择“Open With”,具体步骤以下:

在views/user 目录下添加视图add.jsp页面,页面的内容以下:

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<link href="<c:url value="/styles/main.css" />" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" 
    src="<c:url value="/scripts/My97DatePicker/WdatePicker.js" />"></script>
<title>新增用户</title>
</head>
<body>
    <div class="main">
        <h2 class="title"><span>新增用户</span></h2>
        <form:form action="addSave" method="post" modelAttribute="user">
        <fieldset>
            <legend>用户</legend>
            <table cellpadding="5" cellspacing="8"> 
                <tr>
                    <td><label for="user_name">姓名:</label></td>
                    <td><form:input path="user_name" size="40"/></td>
                    <td><form:errors path="user_name" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_sex">性别:</label></td>
                    <td>
                        <form:select path="user_sex" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${sexList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="user_sex" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_birthday">出生日期:</label></td>
                    <td><form:input path="user_birthday" size="40" class="Wdate" onClick="WdatePicker()"/></td>
                    <td><form:errors path="user_birthday" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_email">邮箱:</label></td>
                    <td><form:input path="user_email" size="40"/></td>
                    <td><form:errors path="user_email" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_edu">学历:</label></td>
                    <td>
                         <form:select path="user_edu" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${eduList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="user_edu" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_telephone">联系方式:</label></td>
                    <td><form:input path="user_telephone" size="40"/></td>
                    <td><form:errors path="user_telephone" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_address">家庭住址:</label></td>
                    <td><form:input path="user_address" size="40"/></td>
                    <td><form:errors path="user_address" cssClass="error"></form:errors></td>
                </tr>
            </table>
            <p>
              <input type="submit" value="保存" class="btn out">
            </p>
        </fieldset>
        <!--<form:errors path="*"></form:errors> -->
        </form:form>
        <p style="color: red">${message}</p>
        <p>
            <a href="<c:url value="/user/list" />"  class="abtn out">返回列表</a>
        </p>
    </div>
</body>
</html>
复制代码

运行结果:

三、编辑用户

与新增用户相似,在控制器下新增两个action,一个用于展现编辑,另外一个用于执行编辑后保存,代码以下所示:

复制代码
 /**
  * 编辑用户
  * @param model
  * @param user_id
  * @return
  */
 @RequestMapping("/edit/{user_id}")
 public String edit(Model model,@PathVariable int user_id){
 
    model.addAttribute("user", userService.queryUserById(user_id));
    // 用于生成“性别”下拉列表
    model.addAttribute("sexList",dictService.getDictByField("SEX"));
    // 用于生成“学历”下拉列表
    model.addAttribute("eduList",dictService.getDictByField("EDU"));
    return "user/edit";
}

/**
 * 修改用户并保存
 * @param model
 * @param user
 * @param bindingResult
 * @return
 */
@RequestMapping("/editSave")
public String editSave(Model model,@ModelAttribute("user") @Valid User user,BindingResult bindingResult){
    //若是模型中存在错误
    if(!bindingResult.hasErrors()){
        if(userService.updateUser(user)>0)
        {
            return "redirect:list";    
        }
    }
    model.addAttribute("user", user);
    model.addAttribute("sexList",dictService.getDictByField("SEX"));
    model.addAttribute("eduList",dictService.getDictByField("EDU"));
    return "/user/edit";
}
复制代码

在views/user 目录下新增长edit.jsp页面,页面的内容以下:

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<link href="<c:url value="/styles/main.css" />" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" 
    src="<c:url value="/scripts/My97DatePicker/WdatePicker.js" />"></script>
<title>编辑用户</title>
<base href="<%=basePath %>" />
</head>
<body>
    <div class="main">
        <h2 class="title"><span>编辑用户</span></h2>
        <form:form action="user/editSave" method="post" modelAttribute="user">
        <fieldset>
            <legend>用户</legend>
            <table cellpadding="5" cellspacing="8"> 
                <tr>
                    <td><label for="user_name">姓名:</label></td>
                    <td><form:input path="user_name" size="40"/></td>
                    <td><form:errors path="user_name" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_sex">性别:</label></td>
                    <td>
                        <form:select path="user_sex" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${sexList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="user_sex" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_birthday">出生日期:</label></td>
                    <td><form:input path="user_birthday" size="40" class="Wdate" onClick="WdatePicker()"/></td>
                    <td><form:errors path="user_birthday" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_email">邮箱:</label></td>
                    <td><form:input path="user_email" size="40"/></td>
                    <td><form:errors path="user_email" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_edu">学历:</label></td>
                    <td>
                         <form:select path="user_edu" style="width:100%">
                             <form:option value="">--请选择--</form:option>
                             <form:options items="${eduList}"  itemLabel="codedesc" itemValue="code"/>
                        </form:select>
                    </td>
                    <td><form:errors path="user_edu" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_telephone">联系方式:</label></td>
                    <td><form:input path="user_telephone" size="40"/></td>
                    <td><form:errors path="user_telephone" cssClass="error"></form:errors></td>
                </tr>
                <tr>
                    <td><label for="user_address">家庭住址:</label></td>
                    <td><form:input path="user_address" size="40"/></td>
                    <td><form:errors path="user_address" cssClass="error"></form:errors></td>
                </tr>
            </table>
            <p>
                <form:hidden path="user_id" />
                <input type="submit" value="保存" class="btn out">
            </p>
        </fieldset>
        <!--<form:errors path="*"></form:errors> -->
        </form:form>
        <p style="color: red">${message}</p>
        <p>
            <a href="<c:url value="/user/list" />"  class="abtn out">返回列表</a>
        </p>
    </div>
</body>
</html>
复制代码

运行结果:

四、删除与批量删除用户

     为了实现删除与批量删除功能,修改控制器,增长2个action,deleteUserById请求处理方法用于删除单个记录,deleteUsers用于批量删除记录。rediredtAttributes是为了保持重定向后的message值。

复制代码
/**
 * 根据用户id删除用户
 * @param model
 * @param user_id
 * @param pageNO
 * @param redirectAttributes
 * @return
 */
@RequestMapping("/deleteUserById/{user_id}")
public String deleteUserById(Model model,@PathVariable int user_id,@RequestParam(required=false,defaultValue="1") int pageNO,
        RedirectAttributes redirectAttributes){

    if(userService.deleteUserById(user_id)>0){
        redirectAttributes.addFlashAttribute("message", "删除成功!");
    }else{
        redirectAttributes.addFlashAttribute("message", "删除失败!");
    }
    return "redirect:/user/list?pageNO="+pageNO;
}

/**
 * 删除多个用户
 * @param model
 * @param userIds
 * @param pageNO
 * @param redirectAttributes
 * @return
 */
@RequestMapping("/deleteUsers")
public String deleteUsers(Model model,@RequestParam int[] user_id,@RequestParam(required=false,defaultValue="1") int pageNO,
        RedirectAttributes redirectAttributes){

    if(userService.deleteUsers(user_id)>0){
        redirectAttributes.addFlashAttribute("message", "删除成功!");
    }else{
        redirectAttributes.addFlashAttribute("message", "删除失败!");
    }
    return "redirect:/user/list?pageNO="+pageNO;
}
复制代码

运行结果以下所示:

最终的控制器UserController.java文件内容以下:

复制代码
package com.demo.controller;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.demo.model.User;
import com.demo.service.IDictService;
import com.demo.service.IUserService;

@Controller
@RequestMapping("/user")
public class UserController {
     
    @Resource
    private IUserService userService;
    @Autowired
    private IDictService dictService;
     
    /*
     * 用户列表与分页Action
     */
    @RequestMapping("/list")
    public String list(Model model,@RequestParam(required=false,defaultValue="1") int pageNO){
        int size=5;
        model.addAttribute("size",size);
        model.addAttribute("pageNO",pageNO);
        model.addAttribute("count",userService.queryUserCount());
        model.addAttribute("userList", userService.queryUserPager(pageNO, size));
        return "user/list";
    }
    
    /**
     * 添加用户
     * @param model
     * @return
     */
    @RequestMapping("/add")
    public String add(Model model){
        // 与form绑定的模型
        model.addAttribute("user",new User());
        // 用于生成“性别”下拉列表
        model.addAttribute("sexList",dictService.getDictByField("SEX"));
        // 用于生成“学历”下拉列表
        model.addAttribute("eduList",dictService.getDictByField("EDU"));
        
        return "user/add";
    }
    
     /**
      * 添加用户保存
      * @param model
      * @param entity
      * @param bindingResult
      * @return
      */
     @RequestMapping("/addSave")
     public String addSave(Model model,@ModelAttribute("user") @Valid User user,BindingResult bindingResult){
        //若是模型中存在错误
        if(!bindingResult.hasErrors()){
            if(userService.insertUser(user)>0){
                return "redirect:/user/list";
            }
        }
        model.addAttribute("user", user);
        // 用于生成“性别”下拉列表
        model.addAttribute("sexList",dictService.getDictByField("SEX"));
        // 用于生成“学历”下拉列表
        model.addAttribute("eduList",dictService.getDictByField("EDU"));
        return "user/add";
     }
     
     /**
      * 编辑用户
      * @param model
      * @param user_id
      * @return
      */
     @RequestMapping("/edit/{user_id}")
     public String edit(Model model,@PathVariable int user_id){
     
        model.addAttribute("user", userService.queryUserById(user_id));
        // 用于生成“性别”下拉列表
        model.addAttribute("sexList",dictService.getDictByField("SEX"));
        // 用于生成“学历”下拉列表
        model.addAttribute("eduList",dictService.getDictByField("EDU"));
        return "user/edit";
    }
    
    /**
     * 修改用户并保存
     * @param model
     * @param user
     * @param bindingResult
     * @return
     */
    @RequestMapping("/editSave")
    public String editSave(Model model,@ModelAttribute("user") @Valid User user,BindingResult bindingResult){
        //若是模型中存在错误
        if(!bindingResult.hasErrors()){
            if(userService.updateUser(user)>0)
            {
                return "redirect:list";    
            }
        }
        model.addAttribute("user", user);
        model.addAttribute("sexList",dictService.getDictByField("SEX"));
        model.addAttribute("eduList",dictService.getDictByField("EDU"));
        return "/user/edit";
    }
    
    /**
     * 根据用户id删除用户
     * @param model
     * @param user_id
     * @param pageNO
     * @param redirectAttributes
     * @return
     */
    @RequestMapping("/deleteUserById/{user_id}")
    public String deleteUserById(Model model,@PathVariable int user_id,@RequestParam(required=false,defaultValue="1") int pageNO,
            RedirectAttributes redirectAttributes){

        if(userService.deleteUserById(user_id)>0){
            redirectAttributes.addFlashAttribute("message", "删除成功!");
        }else{
            redirectAttributes.addFlashAttribute("message", "删除失败!");
        }
        return "redirect:/user/list?pageNO="+pageNO;
    }
    
    /**
     * 删除多个用户
     * @param model
     * @param userIds
     * @param pageNO
     * @param redirectAttributes
     * @return
     */
    @RequestMapping("/deleteUsers")
    public String deleteUsers(Model model,@RequestParam int[] user_id,@RequestParam(required=false,defaultValue="1") int pageNO,
            RedirectAttributes redirectAttributes){

        if(userService.deleteUsers(user_id)>0){
            redirectAttributes.addFlashAttribute("message", "删除成功!");
        }else{
            redirectAttributes.addFlashAttribute("message", "删除失败!");
        }
        return "redirect:/user/list?pageNO="+pageNO;
    }
}
复制代码
相关文章
相关标签/搜索