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-webappgit
4.輸入Group Id和 Artifact Id,package能夠不寫。github
Group Id:相似於包名
Artifact Id:項目的名稱
Version:初始的版本號,通常不須要改動
其餘選項設置爲空,點擊Next建立項目,以下圖:web
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,該插件的詳細參數以下所示:
官網 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');
測試運行結果:
二、新增用戶
在控制器中添加兩個方法,一個是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; } }