SpringMVC+Spring+Mybatis框架集成详解编程语言

一、基本概念

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)的容器框架。

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

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对象)映射成数据库中的记录。

二、使用Maven创建web项目

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

4.输入Group Id和 Artifact Id,package可以不写。

Group Id:类似于包名
Artifact Id:项目的名称
Version:初始的版本号,一般不需要改动
其他选项设置为空,点击Next创建项目,如下图:

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

6.修改项目编码方式

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

7.添加Source文件夹

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

Java -> Source Folder。

SpringMVC+Spring+Mybatis框架集成详解编程语言

如果出现了下面的情况,其实是文件夹已经存在了,只是我们看不到。

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

11.让项目使用jdk 1.7编译

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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。(如果没有选上的话)

SpringMVC+Spring+Mybatis框架集成详解编程语言

13.把项目变成Dynamic Web项目 

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

这个结构不符合maven的结构,我们还要做如下修改:

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

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

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

(1)我们删除跟test相关的项,因为test是测试使用,并不需要部署。

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

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

点击Next,选择Maven Dependencies

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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。

三、创建数据库和表

打开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', '[email protected]', '3', '13211335451', '北京市东城区XXXX', '2017-01-31 18:24:41'); 
INSERT INTO `tb_user` VALUES ('2', '张华', '2', '1988-11-15', '[email protected]', '3', '13811362254', '北京市西城区XXXX', '2017-01-31 18:29:08'); 
INSERT INTO `tb_user` VALUES ('3', '王媛媛', '2', '1990-04-06', '[email protected]', '3', '13511784568', '北京市西城区XXXX', '2017-01-18 10:30:48'); 
INSERT INTO `tb_user` VALUES ('4', '陈迪', '1', '1990-06-16', '[email protected]', '3', '13511697892', '北京市东城区XXXX', '2017-01-10 09:20:50'); 
INSERT INTO `tb_user` VALUES ('5', '王海东', '1', '1989-05-23', '[email protected]', '4', '13811981290', '北京市石景山区苹果园XXXXX', '2017-01-12 18:33:31'); 
INSERT INTO `tb_user` VALUES ('6', '李雪梅', '2', '1985-05-12', '[email protected]', '2', '13911378945', '北京市朝阳区XXX', '2017-01-27 18:34:42'); 
INSERT INTO `tb_user` VALUES ('7', '张扬', '1', '1988-04-12', '[email protected]', '3', '13611651245', '北京市石景山区XXXX', '2017-01-24 18:35:46'); 
INSERT INTO `tb_user` VALUES ('8', '赵庆', '1', '1986-05-06', '[email protected]', '2', '13599632147', '北京市朝阳区XXX', '2017-01-31 18:38:57');

表结构如下所示:

SpringMVC+Spring+Mybatis框架集成详解编程语言

SpringMVC+Spring+Mybatis框架集成详解编程语言

四、添加依赖包

项目主要依赖的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>

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

五、完成Spring与Mybatis的整合

1、在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

2、在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>

六、整合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  --> 
<!-- 自动扫描该包,[email protected] --> 
<context:component-scan base-package="com.demo.controller" />  
<!-- 2.配置注解的处理器映射器和处理器适配器 --> 
<!-- <mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学者 
快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与 
AnnotationMethodHandlerAdapter 两个bean,是spring [email protected] --> 
<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>

七、配置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>

 八、完善项目结构

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

九、创建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类的成员变量设置了一些注解信息。

十、创建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); 
}

十一、创建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>

十二、创建服务层
在包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); 
} 
}

十三、完成用户管理功能

1、用户列表与分页

在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,该插件的详细参数如下所示:

SpringMVC+Spring+Mybatis框架集成详解编程语言

官网 
https://github.com/gbirke/jquery_pagination 
 
jQuery Pagination插件 
参考资料:https://github.com/gbirke/jquery_pagination 
 
jquery paginate插件可以达到我们的要求,使用如下 
使用: 
1.首先定义一个页码容器 
<div id="Pagination"></div> 
2.设置属性 
$("#Pagination").pagination(122, { 
items_per_page:20, 
callback:handlePaginationClick 
}); 
3.定义一个相应的回调函数 
function handlePaginationClick(new_page_index, pagination_container) {        //new_page_index:页码,从0开始,  
 
pagination_container:容器对象    return false;}这样就定制了一个简单的分页控件,如需更多功能,请参照如下属性: 
callback:回调函数,就是点击页码除法的js事件,如上面定义的handlePaginationClick函数,可以通过ajax读取数据,或者控制数据的显隐 
current_page:当前页码 
items_per_page:每页的条数,用于计算总页数 
link_to:当callback回调函数return true时页码会转到此处定义的链接,其中我们可以用__id__传入页码值 
num_display_entries:展示页码的总数,默认为11,如果设置为0则简单的只显示“前一页,后一页” 
next_text:下一页文本 
next_show_always:是否总显示下一页 
prev_text:前一页 
prev_show_always:是否总显示前一页 
num_edge_entries:显示最前几条,最后几条 
load_first_page:初始化插件时是否调用回调函数 
#我们还可以通过代码调用分页功能: 
$("#News-Pagination").trigger('setPage', [4]); 
// Go to the next page 
$("#News-Pagination").trigger('nextPage'); 
// Go to the previous page 
$("#News-Pagination").trigger('prevPage');

View Code

测试运行结果:

SpringMVC+Spring+Mybatis框架集成详解编程语言

 2、新增用户

在控制器中添加两个方法,一个是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校验,[email protected](“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…”,搜索插件名称,显示内容如下:

SpringMVC+Spring+Mybatis框架集成详解编程语言

点击Installed,进入下一步:

SpringMVC+Spring+Mybatis框架集成详解编程语言

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

SpringMVC+Spring+Mybatis框架集成详解编程语言

在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>

运行结果:

SpringMVC+Spring+Mybatis框架集成详解编程语言

3、编辑用户

与新增用户类似,在控制器下新增两个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>

运行结果:

SpringMVC+Spring+Mybatis框架集成详解编程语言

4、删除与批量删除用户

     为了实现删除与批量删除功能,修改控制器,增加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; 
}

运行结果如下所示:

SpringMVC+Spring+Mybatis框架集成详解编程语言

最终的控制器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; 
} 
}

 

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/17287.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论