SSM框架超级详细整合记录:Spring+Spring MVC+MyBatis+Maven+MySQL

1.前言

本文主要对SSM框架整合的过程进行记录,作为之后参考的依据。

1.1.参考文章

Spring代码实例系列-绪论
Spring MVC代码实例系列-绪论
MyBatis代码实例系列-绪论

1.2.技术简介

在整合的SSM框架中,主要涉及的框架、插件或技术有:

  • Spring:一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
  • Spring MVC:一个用于构建 Web 应用程序的MVC框架(Spring的一个模块),可以替代Struts等等。
  • MyBatis:一个基于Java的持久层框架。
  • Maven:一款流行的项目管理与构建工具。
  • Git:一款流行的版本控制工具。
  • MySQL:一款常用的关系型数据库。
  • IDEA:一款流行的Java开发IDE。
  • .gitignore:Git忽略规则文件,控制不需要添加到版本库的文件。
  • README.md:项目说明。
  • Junit4:一款常用的Java单元测试技术。
  • JunitGenerator:一款IDEA提供的Junit插件。
  • log4j:一款流行的开源日志实现项目,可以控制日志信息输送的目的地是控制台、文件等等。
  • maven-compiler-plugin:可以集成到Maven的编译插件,用于解决IDEA项目刷新jdk回退的问题。
  • tomcat7-maven-plugin:可以集成到Maven的tomcat插件,省去tomcat的下载安装等工作。
  • mybatis-generator-maven-plugin:可以集成到Maven的MyBatis代码生成插件,用于生成MyBatis所需的三类文件。
  • com.haier.hairy.mybatis-generator-core:一个可用的mybatis-generator二次开发jar包。
  • org.github.pagehelper:一款可用的MyBatis分页插件。
  • hibernate-validator:一个表单字段校验jar包。
  • JsonResult:一个以泛型编写的通用的返回json对象的类。
  • ValidationUtils:一个简单的校验工具类。
  • CharacterEncodingFilter:编码过滤器,解决POST请求中文乱码问题。
  • IntrospectorCleanupListener:内存清理监听,放置Spring内存泄漏。

1.3.github

项目中只给出关键代码,如需项目的所有源代码,可以查看GitHub : https://github.com/hanchao5272/myssm。

2.SSM整合

2.1.项目初始化

2.1.1.创建项目

在IDEA中:
File–>New–>Project...
–>选择Maven项目
–>Project SDK设置为1.8
–>勾选Create from archetype
–>选中maven-archetype-webapp
–>点击Next
–>录入GroupIdArtifactId
–>点击Next
–>点击Finish
–>等待IDEA完成项目初始化
–>完成项目创建

2.1.2.目录初始化

  1. 添加{project}\src\main\java目录。
  2. 添加{project}\src\test\java目录。
  3. File–>Project structure–>Project Settings–>Modules中,将src\main\java设置为Source Folders,将src\test\java设置为Test Source Folders
  4. 添加{project}\.gitignore文件,并编辑不需要上传至版本库的文件类型。
  5. 添加{project}\README.md文件,并编写项目的基本说明。
  6. Git Bash通过git init完成git初始化。

注意:这里没有配置jdk,是因为后面会通过编译插件maven-compiler-plugin完成jdk配置

2.1.3.pom.xml

这里直接列出完整的pom.xml,主要包括:

  • commons基本jar
  • log4j相关jar
  • servlet相关jar
  • Spring相关jar
  • jackson相关jar
  • hibernate-validator表单验证相关jar
  • MyBatis相关jar
  • mybatis.generator相关jar
  • 分页插件pagehelper相关jar
  • MySql相关jar
  • 单元测试Junit4相关jar

如过不需要某个插件或jar包,请自行移除。

<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.0modelVersion>
    <groupId>pers.hanchaogroupId>
    <artifactId>myssmartifactId>
    <packaging>warpackaging>
    <version>1.0-SNAPSHOTversion>
    <name>Spring + Spring MVC + MyBaits + Maven Examplename>
    <url>http://maven.apache.orgurl>
    <properties>
        
        
        <compiler-plugin.version>3.7.0compiler-plugin.version>
        
        <tomcat-plugin.version>2.2tomcat-plugin.version>

        
        <commons-logging.version>1.2commons-logging.version>
        <commons-lang3.version>3.3.2commons-lang3.version>
        <commons-io.version>2.4commons-io.version>
        <commons-fileupload.version>1.3.1commons-fileupload.version>
        
        <log4j.version>1.2.17log4j.version>

        
        
        <servlet-api.version>3.1.0servlet-api.version>
        <jsp-api.version>2.0jsp-api.version>
        <jstl.version>1.2jstl.version>


        
        <springframework.version>5.0.0.RELEASEspringframework.version>
        
        <jackson.version>2.9.0jackson.version>
        
        <hibernate-validator.version>5.4.1.Finalhibernate-validator.version>

        
        <mybatis.version>3.4.5mybatis.version>
        <mybatis-spring.version>1.3.1mybatis-spring.version>
        
        <mybatis-generator.version>1.3.2mybatis-generator.version>
        <hairy.mybatis-generator.version>1.0.1hairy.mybatis-generator.version>
        
        <pagehelper.version>5.1.2pagehelper.version>
        
        <mysql.version>5.1.40mysql.version>

        
        <junit.version>4.12junit.version>
    properties>
    <dependencies>
        
        <dependency>
            <groupId>org.apache.commonsgroupId>
            <artifactId>commons-lang3artifactId>
            <version>${commons-lang3.version}version>
        dependency>
        <dependency>
            <groupId>commons-iogroupId>
            <artifactId>commons-ioartifactId>
            <version>${commons-io.version}version>
        dependency>
        <dependency>
            <groupId>commons-logginggroupId>
            <artifactId>commons-loggingartifactId>
            <version>${commons-logging.version}version>
        dependency>
        <dependency>
            <groupId>commons-fileuploadgroupId>
            <artifactId>commons-fileuploadartifactId>
            <version>${commons-fileupload.version}version>
        dependency>

        
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>${log4j.version}version>
        dependency>

        
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>javax.servlet-apiartifactId>
            <version>${servlet-api.version}version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>javax.servlet.jspgroupId>
            <artifactId>jsp-apiartifactId>
            <version>${jsp-api.version}version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>jstlartifactId>
            <version>${jstl.version}version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-context-supportartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aopartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-coreartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-beansartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
            <version>${springframework.version}version>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-ormartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-txartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webartifactId>
            <version>${springframework.version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-expressionartifactId>
            <version>${springframework.version}version>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-oxmartifactId>
            <version>${springframework.version}version>
        dependency>
        
        
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-databindartifactId>
            <version>${jackson.version}version>
        dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-coreartifactId>
            <version>${jackson.version}version>
        dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.coregroupId>
            <artifactId>jackson-annotationsartifactId>
            <version>${jackson.version}version>
        dependency>
        
        <dependency>
            <groupId>org.hibernategroupId>
            <artifactId>hibernate-validatorartifactId>
            <version>${hibernate-validator.version}version>
        dependency>
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>${mybatis.version}version>
        dependency>
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>${mybatis-spring.version}version>
        dependency>
        
        
        <dependency>
            <groupId>org.mybatis.generatorgroupId>
            <artifactId>mybatis-generator-coreartifactId>
            <version>${mybatis-generator.version}version>
        dependency>
        
        
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelperartifactId>
            <version>${pagehelper.version}version>
        dependency>
        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>${mysql.version}version>
        dependency>

        
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>${junit.version}version>
            <scope>testscope>
        dependency>
    dependencies>
    <build>
        <finalName>myssmfinalName>
        
        <plugins>
            
        plugins>
    build>
project>

2.1.4.配置编译插件

在pom.xml中配置编译插件maven-compiler-plugin,如下:

<plugins>
  
  <plugin>
    <groupId>org.apache.maven.pluginsgroupId>
    <artifactId>maven-compiler-pluginartifactId>
    <version>${compiler-plugin.version}version>
    <configuration>
      
      <source>1.8source>
      
      <target>1.8target>
      
      <encoding>UTF-8encoding>
    configuration>
  plugin>
plugins>

2.1.5.配置tomcat插件

在pom.xml中配置tomcat插件tomcat7-maven-plugin,如下:

<plugins>

      <plugin>
        <groupId>org.apache.tomcat.mavengroupId>
        <artifactId>tomcat7-maven-pluginartifactId>
        <version>${tomcat-plugin.version}version>
        <configuration>
          <path>/path>
          <port>8080port>
          
          <uriEncoding>utf-8uriEncoding>
        configuration>
      plugin>
plugins>

2.1.6.配置欢迎页

修改web.xml,进行web项目最初始配置:display-name和welcome-file-list,如下:

<web-app 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"
         version="3.0">
  <display-name>Spring + Spring MVC + MyBatis + Maven Web Applicationdisplay-name>

  <welcome-file-list>
    <welcome-file>index.jspwelcome-file>
  welcome-file-list>
web-app>

2.1.7.运行配置

在IDEA中Edit Run/Debug configurations界面,添加一个Maven配置,修改Name,并将Command line设置为clean tomcat7:run -e,然后保存退出。
SSM框架超级详细整合记录:Spring+Spring MVC+MyBatis+Maven+MySQL_第1张图片

2.1.8.运行项目

通过点击或快捷键启动项目,在浏览器录入http://localhost:8080/,显示如下页面,证明项目初始化成功。
这里写图片描述

2.2.配置log4j并进行验证

2.2.1.jar包依赖


<log4j.version>1.2.17log4j.version>

2.2.2.配置log4j

编写main\resources\log4j.properties,如下:

# 日志级别为DEBUG级别,设置两类日志信息存储媒介:控制台和文件
log4j.rootLogger = DEBUG,console,file
# 控制台日志配置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# 日志文件配置
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File = himybatis.log
log4j.appender.file.datePattern = '.'yyyy-MM-dd
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.console.file.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

有关log4j的更详细配置,可以参考:Spring MVC代码实例系列-05:配置Log4j以及 log4j.properties 属性详解

2.2.3.验证log4j

创建pers.hanchao.myssm.test.log4j.Log4jDemo.java,如下

/**
 * 

测试log4j

* @author hanchao 2018/2/10 21:11 **/
public class Log4jDemo { private static final Logger LOGGER = Logger.getLogger(Log4jDemo.class); public static void main(String[] args) { LOGGER.info("Hello World!"); } }

运行,控制信息如下:

2018-02-10 21:14:01 INFO  Log4jDemo:12 - Hello World!

这表明log4j配置正确。

2.3.安装JUnitGenerator插件验证junit

2.3.1.jar包依赖


<junit.version>4.12junit.version>

2.3.2.插件安装与配置

JUnitGenerator插件的安装可以参考: IDEA中使用Junit4进行测试的入门配置。

2.3.3.验证Junit

编写测试类JunitDemo.java

/**
 * 

测试junit

* @author hanchao 2018/2/5 22:03 **/
public class JunitDemo { private static final Logger LOGGER = Logger.getLogger(JunitDemo.class); /** *

加法

* @author hanchao 2018/2/5 22:02 **/
public static int add(int a,int b){ LOGGER.info(a + b); return a + b;

通过Alt+Insert的快捷菜单生成junit4单元测试类:JunitDemoTest.java,进行测试方法修改:

@Test
public void testAdd() throws Exception {
    Assert.assertEquals(2,JunitDemo.add(1,1));
} 

运行测试用例,显示1 test passed,表名Junit4可用。

2.4.初步整合Spring+Spring MVC

本节记录如何配置Spring+Spring MVC。可供参考的文章如下:
Spring MVC代码实例系列-01:Spring MVC项目简单搭建与Hello Wolrd:较为详细的说明了Spring+SpringMVC整合及Spring MVC的工作原理。

2.4.1.jar包依赖


<commons-logging.version>1.2commons-logging.version>
<commons-lang3.version>3.3.2commons-lang3.version>
<commons-io.version>2.4commons-io.version>



<servlet-api.version>3.1.0servlet-api.version>
<jsp-api.version>2.0jsp-api.version>
<jstl.version>1.2jstl.version>


<springframework.version>5.0.0.RELEASEspringframework.version>

<jackson.version>2.9.0jackson.version>

2.4.2.配置web.xml

web.xml中关于Spring和Spring MVC的主要配置项:

  • DispatcherServlet:Spring MVC前端分发器,负责控制分发web请求。
  • contextConfigLocation:Spring配置文件配置,读取applicationContext.xml。
  • ContextLoaderListener:Spring 上下文环境监听器。

此外,还有两个不必须但很重要的配置:

  • characterEncodingFilter:编码过滤器,解决post请求中文参数乱码问题。
  • IntrospectorCleanupListener:防止Spring内存溢出监听器。

全部的web.xml配置如下:

<web-app 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"
         version="3.0">
  <display-name>Spring + Spring MVC + MyBatis + Maven Web Applicationdisplay-name>
  
  <filter>
    <filter-name>characterEncodingFilterfilter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
    <init-param>
      <param-name>encodingparam-name>
      <param-value>UTF-8param-value>
    init-param>
  filter>

  <filter-mapping>
    <filter-name>characterEncodingFilterfilter-name>
    <url-pattern>/*url-pattern>
  filter-mapping>

  
  <servlet>
    <servlet-name>spring-mvcservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:spring-mvc-servlet.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>

  
  <context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:applicationContext.xmlparam-value>
  context-param>

  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
  listener>

  
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListenerlistener-class>
  listener>

  <servlet-mapping>
    <servlet-name>spring-mvcservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>


  <welcome-file-list>
    <welcome-file>index.jspwelcome-file>
  welcome-file-list>
web-app>

2.4.3.配置spring-mvc-servlet.xml

spring-mvc-servlet.xml是Spring MVC的主要配置文件,在这里主要配置一下内容:

  • 通过context:annotation-config开启Spring注解
  • 通过mvc:annotation-driven开启Spring MVC注解
  • 通过context:component-scan开启自动扫描装配(@Component等)。相关参考文章:
    Spring代码实例系列-06:通过注解@Component、@Controller、@Service和@Repository定义bean
  • 通过mvc:resources定义静态资源,即不需要DispatcherServlet分发的请求。
  • 通过InternalResourceViewResolver配置默认的视图解析器。相关参考文章:
    Spring MVC代码实例系列-04:通过自定义视图(继承InternalResourceView),解析Jsp页面、Html页面

spring-mvc-servlet.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    
    <context:annotation-config/>
    
    <mvc:annotation-driven/>
    
    <context:component-scan base-package="pers.hanchao.myssm.*"/>

    
    <mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/>

    
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="contentType" value="charset=utf-8"/>
        <property name="order" value="10"/>
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    bean>
beans>

2.4.4.创建applicationContext.xml

创建Spring的主配置文件applicationContext.xml,到这个阶段还是空配置,后续会增加配置:


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

beans>

2.4.5.测试Spring+Spring MVC的整合

编写一个测试Controller,如下:

package pers.hanchao.myssm.test.spring;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * 

测试Spring 和 Spring MVC的整合

* @author hanchao 2018/2/5 23:01 **/
@Controller public class SpringMVCDemoController { @GetMapping("/mvc/test") public String mvcTest(Model model){ model.addAttribute("mvc","Spring + Spring MVC is OK!"); return "/mvc"; } }

编写一个测试jsp,如下:

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/2/5
  Time: 23:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring + Spring MVC testtitle>
head>
<body>
Hi, ${mvc}
<br>
<a href="/index.jsp">返回首页a>
body>
html>

测试结果:
SSM框架超级详细整合记录:Spring+Spring MVC+MyBatis+Maven+MySQL_第2张图片
测试结果表明Spring和Spring MVC初步整合成功。

2.5.添加表单校验:hibernate-validator

参考文章:
Spring MVC代码实例系列-12:使用自带的validation实现自定义message表单校验
Spring MVC代码实例系列-06:Spring MVC配置Hibernate-Validator以及自定义校验注解
这里使用的是Spring MVC代码实例系列-12所描述的配置方式,能够通过properties文件自定义message信息。
而且,可以通过EL表达式动态加载最大值、最小值之类的信息。

2.5.1.jar包依赖


<hibernate-validator.version>5.4.1.Finalhibernate-validator.version>

2.5.2.创建Resources Bundle(message资源包)

在src/main/resources/目录下依次创建:
ValidationMessages.properties、ValidationMessages_zh_CN.properties
在IDEA中,能够自动将这两个文件转换成一个Resources Bundle(国际化资源包),如下图所示:
这里写图片描述
ValidationMessages.properties:

# 全局配置/默认配置
user.username.length = 用户名 [${validatedValue}] 的长度必须在{min}至{max}之间!
user.password.length = 密码 [${validatedValue}] 的长度必须在{min}至{max}之间!

ValidationMessages_zh_CN.properties

# 中文(大陆)配置
user.username.length = 用户名 [${validatedValue}] 的长度必须在{min}至{max}之间!
user.password.length = 密码 [${validatedValue}] 的长度必须在{min}至{max}之间!

2.5.3.编写校验示例

编写校验实体类User.java:

public class User {
    /** 用户名 */
    @NotNull
    @Length(min = 5,max = 10, message = "{user.username.length}")
    private String username;

    /** 密码 */
    @NotNull
    @Length(min = 5,max = 10, message= "{user.password.length}")
    private String password;

    //setter getter toString equals&hashCode
}

编写JsonResult.java,以泛型方式装载返回对象

public class JsonResult<E> {
    /** 响应状态 */
    private Integer code = 1;
    /** 响应消息 */
    private String message = "success!";
    /** 响应内容 */
    private List list;

    //setter getter toString equals&hashCode
}

编写ValidationUtils,统一处理校验失败信息:

public class ValidationUtils {

    /**
     * 

进行校验,如果有错误,将结果赋给jsonResult,并返回false;如果无错误,则返回true

* @author hanchao 2018/2/7 23:33 **/
public static boolean validateAndSetJsonResult(BindingResult bindingResult, JsonResult jsonResult){ if (bindingResult.hasErrors()){ StringBuffer errors = new StringBuffer(); List allErrors = bindingResult.getAllErrors(); for (ObjectError objectError : allErrors){ errors.append(objectError.getDefaultMessage() + "\n"); } jsonResult.setCode(-1); jsonResult.setMessage(errors.toString()); return false; }else { return true; } } }

修改SpringMVCDemoController,编写表单校验测试方法:

    /**
     * 

简单测试注解、校验和JsonResult

* @author hanchao 2018/2/7 23:27 **/
@PostMapping("/mvc/login") @ResponseBody public JsonResult loginTest(@Valid @RequestBody User user, BindingResult bindingResult){ LOGGER.info(user.toString()); //定义返回值 JsonResult jsonResult = new JsonResult(); //表单校验 if (ValidationUtils.validateAndSetJsonResult(bindingResult,jsonResult)){//如果没错误 List list = new ArrayList(); list.add(user); jsonResult.setList(list); } //返回结果 return jsonResult; }

在这里用到了@PostMapping、@ResponseBody、@RequestBody等注解,参考文件:
Spring MVC代码实例系列-03:@PathVariable、@RequestHeader、@RequestParam、@RequestBody等

编写校验测试页面login.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录测试:注解、校验title>
head>
<script type="text/javascript" src="../static/js/jquery-3.2.1.min.js">script>
<body>
<div>
    <input type="text" value="David" name="username" id="username"/>
    <input type="password" value="123456" name="password" id="password"/>
    <input type="button" value="校验测试" onclick="login()"/>
div>
body>
<script type="text/javascript">
    function login() {
        $.ajax({
            type:'POST',
            url:'/mvc/login',
            data:JSON.stringify({username:$('#username').val(),password:$('#password').val()}),
            contentType:'application/json;charset=utf-8',
            success:function (data) {
                alert(data.message);
            },
            error:function (data) {
                alert(data.message);
            }
        });
    }
script>
html>

2.5.4.校验结果

SSM框架超级详细整合记录:Spring+Spring MVC+MyBatis+Maven+MySQL_第3张图片
表明,hibernate-validator配置成功。

2.6.配置Spring MVC拦截器

拦截器是Spring AOP(Aspected-Oriented Programming,面向切面的编程)的一种实现。
拦截器的应用场景有很多,如:日志记录、权限检查、性能监控、通用行为等等。
这里只给出一个简单的方法执行时间拦截器作为测试。如果想了解更多内容,可以参考:
Spring MVC代码实例系列-11:Spring MVC实现简单的权限控制拦截器和请求信息统计拦截器

2.6.1.编写简单的测试拦截器

编写MethodTimeInterceptor,计算每个方法的执行时间:

package pers.hanchao.myssm.test.interceptor;

import org.apache.log4j.Logger;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Clock;

/**
 * 简单的方法执行时间拦截器,用来验证mvc拦截器可用
 * Created by 韩超 on 2018/2/8.
 */
public class MethodTimeInterceptor extends HandlerInterceptorAdapter{
    private final static Logger LOGGER = Logger.getLogger(MethodTimeInterceptor.class);
    private ThreadLocal startTime = new ThreadLocal();
    /**
     * 

Title: 方法执行前记录时间

* @author 韩超@bksx 2018/2/8 10:20 */
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //如果是方法处理 if (handler instanceof HandlerMethod){ //Java 8 Clock startTime.set(Clock.systemDefaultZone().millis()); } return true; } /** *

Title: 方法执行完成计算时间

* @author 韩超@bksx 2018/2/8 10:20 */
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { //如果是方法处理 if (handler instanceof HandlerMethod){ //获取方法处理时间 Long useTime = Clock.systemDefaultZone().millis() - startTime.get(); StringBuffer sb = new StringBuffer(); //设置访问URI sb.append("[URI = ").append(request.getRequestURI()); //设置请求类型 sb.append(", type = ").append(request.getMethod()); //设置用时 sb.append(", useTime = ").append(useTime).append("ms]"); LOGGER.info(sb.toString()); } } }

2.6.2.修改spring-mvc-serlvet.xml

修改spring-mvc-serlvet.xml,通过mvc:interceptor标签配置MehtodTimeInterceptor拦截器,如下:

    
    <mvc:interceptors>
        
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="pers.hanchao.myssm.test.interceptor.MethodTimeInterceptor"/>
        mvc:interceptor>
    mvc:interceptors>

2.6.3.测试拦截器

任意运行一个请求,如登录,查看控制台日志如下:

2018-02-10 22:16:04 INFO  MethodTimeInterceptor:49 - [URI = /mvc/login, type = POST, useTime = 297ms]

表明拦截器配置成功。其他更高级的拦截器都按照这个模式进行配置即可。

2.7.配置Spring MVC文件上传

这里只给出简单的文件上传配置,参考文章:
Spring MVC代码实例系列-10:Spring MVC实现简单的文件上传和下载

2.7.1.jar包依赖

<commons-fileupload.version>1.3.1commons-fileupload.version>

2.7.2.配置spring-mvc-servlet.xml

修改spring-mvc-servlet.xml添加CommonsMultpartResolver,尤其注意:
- maxUploadSize:一次上传文件的最大byte值.
- maxUploadSizePerFile:一个上传文件的最大byte值
.

配置如下:

    
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        
        <property name="maxUploadSize" value="10485760"/>
        
        <property name="maxUploadSizePerFile" value="1048576"/>
        
        <property name="defaultEncoding" value="UTF-8"/>
    bean>

2.7.2.测试文件上传

编写上传文件控制器

/**
 * 简单的文件上传:用于展示MultiPartFile
 * Created by 韩超 on 2018/2/8.
 */
@Component
@RequestMapping("file")
public class FileUtilsDemo {
    private final static Logger LOGGER = Logger.getLogger(FileUtilsDemo.class);

    /**
     * 

Title: 文件上传

* @author 韩超@bksx 2018/2/8 11:12 */
@PostMapping("/upload") public String upload(HttpServletRequest request, @RequestBody MultipartFile[] multiFiles,Model model){ //获取上传根目录 String uploadRootPath = request.getServletContext().getRealPath("upload"); LOGGER.info("当前上传文件根路径:" + uploadRootPath); File rootFile = new File(uploadRootPath); //判断目录是否存在,不存在层级目录 if (!rootFile.exists()){ rootFile.mkdirs(); } //设置返回值,默认为成功 JsonResult jsonResult = new JsonResult(); //上传目录 try { for (MultipartFile file : multiFiles){ //如果文件不为空,则可以上传 if (null != file){ File serverFile = new File(rootFile.getAbsolutePath() + File.separator + file.getOriginalFilename()); LOGGER.info("当前上传文件路径:" + serverFile.getAbsolutePath()); if (serverFile.exists()){ serverFile.delete(); } file.transferTo(serverFile); } } } catch (IOException e) { e.printStackTrace(); LOGGER.info("文件上传失败!"); //设置返回消息为失败 jsonResult.setCode(-1); jsonResult.setMessage("文件上传失败!"); } model.addAttribute("result",jsonResult); return "test/file"; } }

编写测试jsp页面,尤其注意:

  • enctype=”multipart/form-data”.
  • 文件上传input框的name应该与Controller的传参名一致。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>简单文件上传示例title>
head>
<body>
<form method="post" action="/file/upload" enctype="multipart/form-data">
    <input type="file" name="multiFiles"/><br/>
    <input type="file" name="multiFiles"/><br/>
    <input type="file" name="multiFiles"/><br/>
    <input type="submit" value="上传"/>
form>
<div>
    <h3>code:${code},message:${message}h3>
div>
body>
html>

测试结果:
SSM框架超级详细整合记录:Spring+Spring MVC+MyBatis+Maven+MySQL_第4张图片
表明,上传文件可用。

2.8.初步整合MyBatis

参考文章:
MyBatis代码实例系列-05:Mybatis初步整合Spring + Spring MVC框架,实现Web请求实例

2.8.1.通过Spring引入Spring-Mybatis配置

通过修改applicationContext.xml,引入(import)Spring-Mybatis的配置文件:


<import resource="spring-mybatis.xml"/>

2.8.2.spring-mybatis.xml

spring-mybatis.xml依赖于mybatis-spring-x.y.z.jar,能够帮助我们将MyBatis大部分配置无缝地整合到 Spring 中。spring-mybatis.xml的主要配置:

  • 通过属性文件定位器(property-placeholder)读取数据库连接资源文件
  • 配置数据源(dataSource)进行数据库连接
  • 通过会话工厂bean(sqlSessionFactoryBean)配置XML映射文件路径
  • 通过映射扫描配置(MapperScannerConfigurer)配置数据访问层(Dao)路径
  • 通过事务控制(DataSourceTransactionManager)配置Spring事务控制。
  • 通过tx:annotation-driven开启声明式的事务注解

详细配置如下:


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

    
    <context:property-placeholder file-encoding="UTF-8" location="classpath:jdbc.properties"/>

    
    
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    bean>
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        
        
        
        <property name="dataSource" ref="dataSource"/>
        
        <property name="mapperLocations" value="classpath:mybatis-mapper/*.xml"/>
    bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        
        <property name="basePackage" value="pers.hanchao.myssm.**.dao"/>
    bean>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>
beans>

关于context:property-placeholder的作用,可以参考:
Spring代码实例系列-09:通过Spring PropertyPlaceholderConfigurer将properties配置的属性注入到xml配置文件中

2.8.3.创建jdbc.properties

创建jdbc.properties,用于配置数据库连接信息:

# 数据库连接信息
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/exam?useSSL=false
jdbc.username=root
jdbc.password=******

2.8.4.创建mybatis-config.xml

创建MyBatis的主配置文件mybatis-config.xml,用于配置一些Mybatis的专有配置(目前为空配置):




<configuration>

configuration>

2.8.5.测试MyBatis

SQL语句:

drop table topic;
create table `topic`(
    `id` int(5) unsigned not null auto_increment comment '话题',
    `title` varchar(20) not null comment '题目',
    `score` int(3) not null comment '分数',
    `answer` varchar(100) comment '答案',
    primary key(id)
)engine=InnoDB comment='话题' auto_increment=1 default charset=utf8;
insert into topic values(99999,'题目1',100,'你好吗?');

目录结构:

src\main\java\
|   pers.hanchao.myssm.test.curd
|       \---controller
|           \---TopicController.java
|       \---dao
|           \---TopicDao.java
|       \---entity
|           \---TopicEntity.java
|       \---service
|           \---TopicService.java
|           |---impl
|               \---TopicServiceImpl
src\main\resources\
    mybatis-mapper
        \---TopicDao.xml

TopicController.java
控制层,通过@Autowired自动装配接口TopicService,符合设计模式中的面向接口编程

/**
 * 

简单实例测试Mybatis的事务控制和增删改查

* @author hanchao 2018/2/8 23:55 **/
@Controller public class TopicController { @Autowired private TopicService topicService; /** *

简单测试增删改查

* @author hanchao 2018/2/8 23:41 **/
@GetMapping("mybatis/curd") public String curdTest(){ this.topicService.curdTest(); return "test/curd"; } }

TopicService.java
服务接口层,注意:在接口中通过注解@Transactional进行声明式事务控制

public interface TopicService {
    @Transactional
    void curdTest();
}

TopicServiceImpl.java
服务实现层,注意:通过@Autowired自动装配的接口TopicDao并没有显示实现。
因为在TopicService.java已经进行了事务控制,这里不需要再进行注解。

@Service
public class TopicServiceImpl implements TopicService {
    private static final Logger LOGGER = Logger.getLogger(TopicServiceImpl.class);

    @Autowired
    private TopicDao topicDao;

    /**
     * 

简单测试事务注解和增删改查

* @author hanchao 2018/2/8 23:45 **/
@Override public void curdTest() { //查询所有 LOGGER.info("查询所有"); LOGGER.info(this.topicDao.selectAll()); //插入一个,查询所有 System.out.println(); LOGGER.info("插入一个"); TopicEntity newTopic = new TopicEntity(); newTopic.setId(100); newTopic.setTitle("新增的标题"); newTopic.setScore(200); newTopic.setAnswer("新增的答案"); this.topicDao.insert(newTopic); LOGGER.info(this.topicDao.selectAll()); //查询一个 System.out.println(); LOGGER.info("查询一个"); LOGGER.info(this.topicDao.selectByPrimaryKey(99999)); //修改一个,然后查询 System.out.println(); LOGGER.info("修改一个"); newTopic = new TopicEntity(); newTopic.setId(1); newTopic.setTitle("修改的标题"); newTopic.setScore(1000); newTopic.setAnswer("修改的答案"); this.topicDao.updateByPrimaryKey(newTopic); LOGGER.info(this.topicDao.selectByPrimaryKey(99999)); //删除一个,然后查询 System.out.println(); LOGGER.info("删除一个,然后查询"); this.topicDao.deleteByPrimaryKey(99999); LOGGER.info(this.topicDao.selectByPrimaryKey(99999)); } }

TopicDao.java

/**
 * 

话题Dao

* @author hanchao 2018/2/8 23:39 **/
@Repository public interface TopicDao { /** * 根据主键删除数据库的记录 * * @param id */ int deleteByPrimaryKey(Integer id); /** * 插入数据库记录 * * @param record */ int insert(TopicEntity record); /** * 根据主键获取一条数据库记录 * * @param id */ TopicEntity selectByPrimaryKey(Integer id); /** * 获取全部数据库记录 * */ List selectAll(); /** * 根据主键来更新数据库记录 * * @param record */ int updateByPrimaryKey(TopicEntity record); }

TopicEntity.java:

/**
 * 

话题

* @author hanchao 2018/2/8 23:33 **/
public class TopicEntity { /** *
     * 话题
     * 表字段 : topic.id
     * 
*/
private Integer id; //other fields // setter getter toString equals&hashCode }

TopicDao.xml
好吧,我承认这里偷懒了,这里是用MBG(后面会讲)生成的代码。



<mapper namespace="pers.hanchao.myssm.test.curd.dao.TopicDao">
  <resultMap id="BaseResultMap" type="pers.hanchao.myssm.test.curd.entity.TopicEntity">
    
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="title" jdbcType="VARCHAR" property="title" />
    <result column="score" jdbcType="INTEGER" property="score" />
    <result column="answer" jdbcType="VARCHAR" property="answer" />
  resultMap>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    
    delete from topic
    where id = #{id,jdbcType=INTEGER}
  delete>
  
mapper>

测试结果

2018-02-10 22:54:01 INFO  TopicServiceImpl:32 - 查询所有
2018-02-10 22:54:01 INFO  TopicServiceImpl:33 - [TopicEntity [Hash = 1936880702, id=99999, title=题目1, score=100, answer=你好吗?], TopicEntity [Hash = -1744284694, id=100000, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744254903, id=100001, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744225112, id=100002, title=新增的标题, score=200, answer=新增的答案]]

2018-02-10 22:54:01 INFO  TopicServiceImpl:45 - 插入一个
2018-02-10 22:54:01 INFO  TopicServiceImpl:52 - [TopicEntity [Hash = 1936880702, id=99999, title=题目1, score=100, answer=你好吗?], TopicEntity [Hash = -1744284694, id=100000, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744254903, id=100001, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744225112, id=100002, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744195321, id=100003, title=新增的标题, score=200, answer=新增的答案]]

2018-02-10 22:54:01 INFO  TopicServiceImpl:55 - 查询一个
2018-02-10 22:54:01 INFO  TopicServiceImpl:56 - TopicEntity [Hash = 1936880702, id=99999, title=题目1, score=100, answer=你好吗?]

2018-02-10 22:54:01 INFO  TopicServiceImpl:59 - 修改一个
2018-02-10 22:54:01 INFO  TopicServiceImpl:66 - TopicEntity [Hash = 1936880702, id=99999, title=题目1, score=100, answer=你好吗?]

2018-02-10 22:54:01 INFO  TopicServiceImpl:69 - 删除一个,然后查询
2018-02-10 22:54:01 INFO  TopicServiceImpl:71 - 
2018-02-10 22:54:02 INFO  MethodTimeInterceptor:49 - [URI = /mybatis/curd, type = GET, useTime = 1100ms]

测试结果,证明MyBatis整合成功。

2.9.实现MyBatis对SQL的打印

参考文章:
MyBatis代码实例系列-02:MyBatis用log4j打印SQL以及MyBatis的事务控制
MyBatis代码实例系列-09:初步整合Spring + Spring MVC框架之后,如何打印MyBatis的SQL语句
实现对MyBatis对SQL的打印在我们开发调试中十分有用,下面对其配置方法进行说明:

2.9.1.修改log4j.propertis

将log4j的日志级别设置为debug或更低级别

log4j.rootLogger = debug,console,file

2.9.2.修改mybatis-config.xml

在MyBatis配置文件中添加setting配置:name="logImpl" value="LOG4J",指定使用log4j作为日志实现:

<configuration>
    <settings>
        
        <setting name="logImpl" value="LOG4J"/>
    settings>
configuration>

2.9.3.测试结果

2018-02-10 23:14:44 INFO  TopicServiceImpl:55 - 查询一个
2018-02-10 23:14:44 DEBUG SqlSessionUtils:97 - Creating a new SqlSession
2018-02-10 23:14:44 DEBUG SqlSessionUtils:148 - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@10e54129] was not registered for synchronization because synchronization is not active
2018-02-10 23:14:44 DEBUG DataSourceUtils:114 - Fetching JDBC Connection from DataSource
2018-02-10 23:14:44 DEBUG DriverManagerDataSource:143 - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/exam?useSSL=false]
2018-02-10 23:14:44 DEBUG SpringManagedTransaction:87 - JDBC Connection [com.mysql.jdbc.JDBC4Connection@294e531c] will not be managed by Spring
2018-02-10 23:14:44 DEBUG selectByPrimaryKey:159 - ==>  Preparing: select id, title, score, answer from topic where id = ? 
2018-02-10 23:14:44 DEBUG selectByPrimaryKey:159 - ==> Parameters: 99999(Integer)
2018-02-10 23:14:44 DEBUG selectByPrimaryKey:159 - <==      Total: 0
2018-02-10 23:14:44 DEBUG SqlSessionUtils:191 - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@10e54129]
2018-02-10 23:14:44 DEBUG DataSourceUtils:340 - Returning JDBC Connection to DataSource
2018-02-10 23:14:44 INFO  TopicServiceImpl:56 - 

测试结果证明配置成功。

2.10.配置分页插件PageHelper

参考文章:
MyBatis代码实例系列-10:MyBatis通过PageHelper插件实现分页查询

这里使用的一款开源的MyBatis分页插件:com.github.pagehelper。
GItHub地址:https://github.com/pagehelper/Mybatis-PageHelper

2.10.1.jar包依赖


<pagehelper.version>5.1.2pagehelper.version>

2.10.2.mybatis-config.xml

MyBatis配置文件,添加pagehelper拦截器:

<configuration>
    <plugins>
        
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            
            <property name="pageSizeZero" value="true"/>
            
            <property name="reasonable" value="true"/>
        plugin>
    plugins>
configuration>

2.10.3.修改业务代码

在业务代码中:

  • 在需要分页的查询前,插入PageHelper.startPage(pageNumb,pageSize)
  • 分页查询返回类型为Page,需要手动进行转换

在之前的TopicServiceImpl.java中,进行修改:

 //查询所有
 LOGGER.info("查询所有");
 LOGGER.info(this.topicDao.selectAll());
 //查询所有(分页)
 System.out.println();
 PageHelper.startPage(0,10);
 LOGGER.info("查询所有(分页)");
 //将Page类型转换成List
 List topicEntityList = topicDao.selectAll();
 LOGGER.info(topicEntityList);
 //通过lambda表达式输出集合信息
 topicEntityList.forEach(LOGGER::info);

2.10.4.验证

再次运行,控制台信息:

2018-02-10 22:54:01 INFO  TopicServiceImpl:32 - 查询所有
2018-02-10 22:54:01 INFO  TopicServiceImpl:33 - [TopicEntity [Hash = 1936880702, id=99999, title=题目1, score=100, answer=你好吗?], TopicEntity [Hash = -1744284694, id=100000, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744254903, id=100001, title=新增的标题, score=200, answer=新增的答案], TopicEntity [Hash = -1744225112, id=100002, title=新增的标题, score=200, answer=新增的答案]]

2018-02-10 22:54:01 INFO  TopicServiceImpl:37 - 查询所有(分页)
2018-02-10 22:54:01 INFO  TopicServiceImpl:40 - Page{count=true, pageNum=1, pageSize=10, startRow=0, endRow=10, total=4, pages=1, reasonable=true, pageSizeZero=true}
2018-02-10 22:54:01 INFO  TopicServiceImpl:1249 - TopicEntity [Hash = 1936880702, id=99999, title=题目1, score=100, answer=你好吗?]
2018-02-10 22:54:01 INFO  TopicServiceImpl:1249 - TopicEntity [Hash = -1744284694, id=100000, title=新增的标题, score=200, answer=新增的答案]
2018-02-10 22:54:01 INFO  TopicServiceImpl:1249 - TopicEntity [Hash = -1744254903, id=100001, title=新增的标题, score=200, answer=新增的答案]
2018-02-10 22:54:01 INFO  TopicServiceImpl:1249 - TopicEntity [Hash = -1744225112, id=100002, title=新增的标题, score=200, answer=新增的答案]

经验证,分页插件可用。

2.11.配置MyBatis Generator

参考文章:
MyBatis代码实例系列-08:MyBatisGenerator插件及扩展(中文注释和Mapper重命名为Dao)

在使用MyBatis框架进行开发时,每用到一张表就要手动创建实体类、XML映射文件和映射接口,这些都是重复性工作,耗费了我们大量精力。
MyBatis Generator (简称MBG) 是一个Mybatis的代码生成器。它可以根据数据库中的表,生成对应的实体类、XML映射文件和映射接口,节约了大量的时间去开发和业务逻辑有关的功能。
当然,如果是多表联合查询和存储过程,仍然需要手动处理。

2.11.1.将开源jar包添加到本地仓库

git clone

git clone git@github.com:li24361/mybatis-generator-core.git

mvn install

mvn install -Dmaven.test.skip=true

2.11.2.jar包依赖


<mybatis-generator.version>1.3.2mybatis-generator.version>
<hairy.mybatis-generator.version>1.0.1hairy.mybatis-generator.version>

2.11.3.pom.xml插件

说明:

  • mybatis-generator-maven-plugin是原生的MBG插件。
  • com.haier.hairy.mybatis-generator-core是对MBG一个开源扩展,实现了中文注释等。
 
 <plugin>
     <groupId>org.mybatis.generatorgroupId>
     <artifactId>mybatis-generator-maven-pluginartifactId>
     <version>${mybatis-generator.version}version>
     <dependencies>
         
         <dependency>
             <groupId>mysqlgroupId>
             <artifactId>mysql-connector-javaartifactId>
             <version>${mysql.version}version>
         dependency>
         
         <dependency>
             <groupId>com.haier.hairygroupId>
             <artifactId>mybatis-generator-coreartifactId>
             <version>${hairy.mybatis-generator.version}version>
         dependency>
     dependencies>
     <configuration>
         
         <configurationFile>src/main/resources/generatorConfig.xmlconfigurationFile>
         
         <overwrite>trueoverwrite>
         
         <verbose>trueverbose>
     configuration>
 plugin>

2.11.4.配置generatorConfig.xml

修改MBG的配置文件:generatorConfig.xml。主要配置项:

  • 通过properties配置jdbc的属性文件
  • 将生成目标定为MyBatis3Simple,不需要example方法
  • 通过Delimiter配置表名区分分隔符
  • 通过plugin生成实体类的toString、equals和hashCode方法
  • 通过commentGenerator配置自定义类,生成中文注释
  • 通过jdbcConnection配置数据库连接信息
  • 通过javaModelGenerator配置实体类的生成配置
  • 通过sqlMapGenerator配置XML映射文件的生成配置
  • 通过javaClientGenerator配置Dao层类的生成配置
  • 通过table配置需要生成的schema、table和pk

详细配置:




<generatorConfiguration>
    
    <properties resource="jdbc.properties"/>
    
    
    <context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        
        <property name="beginningDelimiter" value="${mgb.table.delimiter}"/>
        <property name="endingDelimiter" value="${mgb.table.delimiter}"/>

        
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>

        
        <commentGenerator type="org.mybatis.generator.internal.HairyCommentGenerator">
            
            <property name="javaFileEncoding" value="UTF-8"/>
            
            <property name="suppressAllComments" value="${mgb.comment.suppress.all}"/>
            
            <property name="suppressDate" value="${mgb.comment.suppress.date}"/>
        commentGenerator>

        
        <jdbcConnection driverClass="${jdbc.driverClassName}"
                        connectionURL="${jdbc.url}"
                        userId="${jdbc.username}"
                        password="${jdbc.password}">
        jdbcConnection>

        
        <javaModelGenerator targetPackage="${mgb.entity.package}" targetProject="${mgb.entity.project}">
            
            <property name="enableSubPackages" value="${mgb.enableSubPackages}"/>
            
            <property name="trimStrings" value="true"/>
        javaModelGenerator>

        
        <sqlMapGenerator targetPackage="${mgb.xml.package}" targetProject="${mgb.xml.project}">
            
            <property name="enableSubPackages" value="${mgb.enableSubPackages}"/>
        sqlMapGenerator>

        
        <javaClientGenerator targetPackage="${mgb.dao.package}" targetProject="${mgb.dao.project}" type="XMLMAPPER">
            
            <property name="enableSubPackages" value="${mgb.enableSubPackages}"/>
        javaClientGenerator>

        
        <table schema="exam" tableName="apple">
            
            <generatedKey column="id" sqlStatement="MySql"/>
        table>
    context>
generatorConfiguration>

2.11.5.修改jdbc.properties

修改jdbc.properties,添加MBG相关配置:

# MyBatis Generator配置信息
## 表名分隔符
mgb.table.delimiter=`
## 注释抑制配置
mgb.comment.suppress.all=false
mgb.comment.suppress.date=true
## 是否运行根据schema创建子包
mgb.enableSubPackages=true
## entity配置
mgb.entity.project=src\\main\\java
mgb.entity.package=pers.hanchao.myssm.generator.entity
## Dao配置
mgb.dao.project=src\\main\\java
mgb.dao.package=pers.hanchao.myssm.generator.dao
## XML配置
mgb.xml.project=src\\main\\resources
mgb.xml.package=generator

2.11.6.构建测试

构建命令:

mybatis-generator:generate

构建结果:

src\main\java\
|   pers.hanchao.myssm.test.curd
|       \---dao
|           \---AppleDao.java
|       \---entity
|           \---AppleEntity.java
src\main\resources\
    generator
        \---AppleDao.xml

测试成功!

3.总结

全部整合过程:

  1. 目录初始化
  2. 配置log4j并进行验证
  3. 安装JUnitGenerator插件验证junit
  4. 初步整合Spring+Spring MVC
  5. 添加表单校验:hibernate-validator
  6. 配置Spring MVC拦截器
  7. 配置Spring MVC文件上传
  8. 初步整合MyBatis
  9. 实现MyBatis对SQL的打印
  10. 配置分页插件PageHelper
  11. 配置MyBatis Generator

其中,

  • 只有第1、4、8步骤是整合SSM的必须步骤。
  • 第2、3、5、6、7、9、10、11都不是必须的,但是确是常用的。
  • 可以根据项目情况选择取舍。

你可能感兴趣的:(Spring合集,Spring-MVC合集,MyBatis合集,Spring学习实例,Spring,MVC学习实例,MyBatis学习实例)