SpringMVC+Spring+Mybatis框架集成

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。

2.選擇項目路徑,這裏選擇Use default Workspace location默認工作空間。

3.選擇項目類型,在Artifact Id中選擇maven-archetype-webapp

4.輸入Group Id和 Artifact Id,package可以不寫。

Group Id:類似於包名
Artifact Id:項目的名稱
Version:初始的版本號,一般不需要改動
其他選項設置爲空,點擊Next創建項目,如下圖:

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。

三、創建數據庫和表

打開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');

複製代碼

複製代碼

表結構如下所示:

四、添加依賴包

項目主要依賴的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>

複製代碼

複製代碼

如果是第一次依賴相關的包,則需要下載時間,請耐心等待,如果下載失敗則需要手動下載,下載完成後複製到本地的資源庫中。依賴後的項目結果如下:

五、完成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  -->
    <!-- 自動掃描該包,使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>

複製代碼

複製代碼

七、配置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,如下圖:

其中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,該插件的詳細參數如下所示:

 View Code

測試運行結果:

 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校驗,當保存對象是需要在參數前註解@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>

複製代碼

複製代碼

運行結果:

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>

複製代碼

複製代碼

運行結果:

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;
}

複製代碼

複製代碼

運行結果如下所示:

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

複製代碼

複製代碼


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章