ssm整合

注意:

tomcat版本8.5.461

On frame deactivation IDE失去焦点的情况下 自动触发,而开发过程中 可能需要查询资料 或 与人聊天 或干其它事,IDE需要不停的失去焦点。每次失去焦点就自动触发 update ,CPU一下子 费很多,电脑瞬间变慢,所以没有必要这样,设置为Do nothing 最好,官方也默认的是 Do nothing。

On Update action ------- update classes and resources ----- 运行模式下(jsp 立即生效,java 需要redeploy才可生效)

On Update action ------- update classes and resources ----- 调试模式下(java、jsp 都立即生效)

其中resources代表静态资源jsp,html,js

ssm整合

新建项目

1.打开idea,顶部菜单->file->new->project,选择Empty project,填写一个项目路径;

2.在侧部菜单Modules,选择±>New Module,选择Maven,使用webapp骨架;

3.设置GroupID和ArtigactId

groupid和artifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找。

GroupId一般分为多个段,这里我只说两段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。举个apache公司的tomcat项目例子:这个项目的GroupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,artigactId是tomcat。

4.设置maven,完成创建。

pom文件

1.servlet和jsp的困惑?

在我们编写servlet时 HttpServletRequest和HttpServletResponse 等对象的是由servlet-api提供的,不导入servlet-api我们无法获取相应对象,但是在运行中,tomcat中也有这些对象,为了防止冲突,在配置pom文件时,在servlet-api 下设置作用范围provided,指该依赖不进行打包,该工程在运行tomcat时就会使用tomcat中的HttpServletRequest对象,在编译时使用servlet-api 的对象.

<?xml version="1.0" encoding="UTF-8"?>

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dxm</groupId>
    <artifactId>ssm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>com.dxm Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- 源代码使用的JDK版本 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <!-- 需要生成的目标class文件的编译版本 -->
        <maven.compiler.target>1.8</maven.compiler.target>

        <logback.version>1.1.7</logback.version>
        <slf4j.version>1.7.21</slf4j.version>
    </properties>

    <dependencies>
        <!--测试包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--mybatis 核心包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--mysql驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--mybatis 与spring的整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--spring-jdbc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--事务的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--aop依赖,可以理解为aop的注解实现, 你在类上直接一个@Aspect就搞定,不用费事在xml里配了。但是这需要额外的jar包( aspectjweaver.jar)-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <!--spring 测试包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--springMVC的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!--servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <!--jsp -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <!--jackson json解析 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.9</version>
        </dependency>
        <!--fastjson json解析 阿里巴巴-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.41</version>
        </dependency>
        <!-- JSTL,JSP标准标签库,jstl.jar文件包含JSTL规范中定义的接口和相关类,standard.jar文件包含用于 实现JSTL的.class文件以及JSTL中5个标签库描述符文件(TLD)-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <!--连接池HikariCP,springboot2.0默认使用,其余还有c3p0,dbcp,druid  -->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--需要安装lombok,可以省略get和set方法-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
        </dependency>
        <!--mybatis逆向工程-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--pagehelper分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>4.1.4</version>
        </dependency>
        <!--swagger文档,访问接口文档:localhost:8080/项目路径/swagger-ui.html-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

        <!--spring-mvc文件上传 ,引入fileUpload会自动依赖commons-io -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!--logback日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>org.logback-extensions</groupId>
            <artifactId>logback-ext-spring</artifactId>
            <version>0.1.1</version>
        </dependency>
        <!--mybatis逆向工程用的log4j日志,需要转换,并在pom中不写log4j依赖-->
        <!-- https://mvnrepository.com/artifact/org.slf4j/log4j-over-slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>

    </dependencies>

    <!--maven的profile用法有许多种,但基本原理就是根据激活环境的不同,自定义字段被赋予不同的值。-->
    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <!--自定义标签-->
                <active.profile>dev</active.profile>
            </properties>
            <!-- 把当前profile设置为默认profile,可以同时这是多个为默认-->
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <id>test</id>
            <properties>
                <active.profile>test</active.profile>
            </properties>
        </profile>
        <profile>
            <id>product</id>
            <properties>
                <active.profile>product</active.profile>
            </properties>
        </profile>

    </profiles>

    <build>
        <finalName>com.dxm</finalName>

        <filters>
            <filter>src/main/filters-${active.profile}.properties</filter>
        </filters>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>


        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>

            <!--配置tomcat7插件-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <!-- 配置项目的请求路径 -->
                    <path>/</path>
                    <!-- 配置服务器端口号 -->
                    <port>80</port>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>5.1.6</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <id>Generate MyBatis Artifacts</id>
                        <phase>package</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!--允许移动生成的文件 -->
                    <verbose>true</verbose>
                    <!-- 是否覆盖 -->
                    <overwrite>true</overwrite>
                    <!-- 自动生成的配置 -->
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                </configuration>
            </plugin>

        </plugins>

    </build>


</project>

web.xml配置(记得改约束)

<?xml version="1.0" encoding="UTF-8"?>
<!--默认的2.3版本不支持EL表达式,需要使用版本3.1-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">


    <!--配置全局参数 下面的监听器会加载此配置,如果没有指定的话,默认会去/WEB-INF/下加载applicationContext.xml。-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!--配置编码过滤器,只对post有效,或者post请求使用request.setCharacterEncoding("UTF-8");
      response.setCharacterEncoding("UTF-8");
      Tomcat 默认的编码为ISO-8859-1,所以Get 请求乱码问题可以通过修改Tomcat默认配置编码为UTF-8 来处理。
    get请求可以修改tomcat的配置文件conf/server.xml:
  <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="UTF-8"
       useBodyEncodingForURI="true"/>
只需增加 URIEncoding="UTF-8" 和useBodyEncodingForURI="true",然后重启tomcat即可,或者
String userName new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8");
注意:tomcat8解决了get请求乱码
-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--配置一个监听器  项目一启动 我们就将父容器spring容器 启动-->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
    <!--前端控制器: 创建了一个子容器对象-->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <!--共四种匹配方式,按优先级为精确匹配;扩展名匹配:*.action;路径匹配:/user/*,以“/”字符开头,并以“/*”结尾的;缺省匹配/
        此配置为/,挡住了tomcat中default servlet的路径匹配(见tomcat中的web.xml)-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
      <!--提高default servlet的路径匹配优先级,扩展名匹配,或者在spring-mvc中配置静态资源放行,或者在spring-mvc中配置默认servlet-->
  <!--  <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
        <url-pattern>*.htm</url-pattern>
        <url-pattern>*.css</url-pattern>
        <url-pattern>*.js</url-pattern>
        <url-pattern>*.png</url-pattern>
        <url-pattern>*.jpg</url-pattern>
        <url-pattern>*.jpeg</url-pattern>
        <url-pattern>*.gif</url-pattern>
    </servlet-mapping>-->
</web-app>

mysql数据库配置db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

applicationContext.xml

<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:property-placeholder location="classpath:db.properties"/>


    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--
          目的1 将sqlSessionFactory对象的创建交给spring容器
      -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 指定mybatis全局配置文件的位置 -->
        <property name="configLocation" value="classpath:SqlMapConfig.xml"/>
        <!--别名包-->
        <property name="typeAliasesPackage" value="com.dxm.domain"/>
        <!--sql语句的位置-->
        <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
        <!--数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--
      目的2 让spring容器 使用sqlSessionFactory帮助我们创建xxxDao实现类对象
  -->
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 它是告诉spring框架 接口在这个包下放着呢-->
        <property name="basePackage" value="com.dxm.dao"/>
        <!-- 注入sqlSessionFactory: 可以省略,注意是value-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>



    <!--扫包-->
    <context:component-scan base-package="com.dxm.service"/>

    <!-- 配置事务管理器 -->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置基于注解的声明式事务 -->
<!--    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>-->


    <!--事务增强:对方法的过滤-->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <!--<tx:method name="insert*"></tx:method>-->
            <!--<tx:method name="update*"></tx:method>-->
            <!--<tx:method name="del*"></tx:method>-->
            <!--<tx:method name="add*"></tx:method>-->
            <!--<tx:method name="transfer"></tx:method>-->
            <!--
                name="*" 其他方法
            -->
            <!--<tx:method name="*" propagation="SUPPORTS" read-only="true"></tx:method>-->
            <!--
                name: 方法名,可以使用通配符的方式配置
                propagation: 传播的行为,查询方法SUPPORTS, 增删改方法:REQUIRED
                isolation: 隔离级别:一般选择数据库默认的隔离级别(一般不用配置)
                read-only: 只读,查询使用只读操作,增删改使用非只读操作
                time-out: 超时的时间定义,默认-1 ,永不超时(一般不用配置)
            -->
            <!--非事务运行-->
            <tx:method name="get*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="select*" propagation="SUPPORTS" read-only="true"></tx:method>
            <tx:method name="query*" propagation="SUPPORTS" read-only="true"></tx:method>
            <!--其他的方法都是用在事务中运行-->
            <tx:method name="*"></tx:method>
        </tx:attributes>
    </tx:advice>

    <!--配置aop-->
    <aop:config>
        <!--切入点表达式-->
        <aop:pointcut id="pc" expression="execution(* com.dxm.service.impl.*.*(..))"></aop:pointcut>
        <!--织入-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pc" ></aop:advisor>
    </aop:config>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
     </bean>

</beans>

SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>

</configuration>

spring-mvc.xml

<?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:cotext="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">

    <!--扫包-->
    <cotext:component-scan base-package="com.dxm"/>

    <!--将静态资源交由默认的servlet处理,此配置会在 WEB 容器启动的时候会在上下文中定义一个 DefaultServletHttpRequestHandler,
    它会对DispatcherServlet的请求进行处理,如果该请求已经作了映射,那么会接着交给后台对应的处理程序,
    如果没有作映射,就交给WEB应用服务器默认的 Servlet处理,从而找到对应的静态资源,只有再找不到资源时才会报错。-->
    <mvc:default-servlet-handler />
    <!--重要!将你的SwaggerConfig配置类注入-->
    <bean class="com.dxm.config.SwaggerConfig"/>
    <!--重要!配置swagger资源不被拦截-->
    <mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/" />
    <mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/" />

    <!--关于拦截器的配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** 包括路径及其子路径-->
            <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
            <!--/admin/** 拦截的是/admin/下的所有-->
            <mvc:mapping path="/**"/>
            <!--bean配置的就是拦截器-->
            <bean class="com.dxm.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>


    <!--
    mapping:需要映射的虚拟路径,也就是放行的目录规则
        /js/* : 放行js请求路径下的任意请求,但是更深一级目录不会被放行
        /js/**:放行js请求路径下的任意请求,包括子包孙包
    location: 真实的项目路径
  -->
    <!--<mvc:resources mapping="/html/**" location="/html/" />-->
    <!--放行webapp下资源,自己写的-->
    <!--<mvc:resources mapping="/**" location=".//" />-->


    <!--配置内部资源视图解析器,前缀和后缀-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!--开启springmvc注解支持-->
    <mvc:annotation-driven>
        <!--@ResponseBody注解在转换日期类型时会默认把日期转换为时间戳(例如: date:2017-10-25  转换为 时间戳:15003323990)
        此配置为了将date类型转换为正确的类型,注意:如果想要单个bean的某个日期字段显示年月日时分秒的话,只需要在对应日期的get方法上添加@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")即可。-->
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="objectMapper">
            <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                <property name="dateFormat">
                    <bean class="java.text.SimpleDateFormat">
                        <constructor-arg value="yyyy-MM-dd HH:mm:ss">
                        </constructor-arg>
                    </bean>
                </property>
            </bean>
        </property>
        </bean>
    </mvc:message-converters>
    </mvc:annotation-driven>


    <!-- 配置文件上传解析器 -->
    <!-- id的值是固定的-->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置上传文件的最大尺寸为5MB -->
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>

</beans>

logback日志logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 不分级别同步文件日志输出配置 -->
<!-- 级别从高到低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
<!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 -->
<!-- 以下 每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志 -->
<!-- scan 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
<!-- scanPeriod 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false" >

    <!-- logback项目名称 -->
    <property name="appName" value="ssm"/>

    <!-- 日志级别 -->
    <property name="logLevel" value="DEBUG"/>

    <!-- 日志地址 -->
    <property name="logPath" value="./logs"/>

    <!-- 最大保存时间 10天 -->
    <property name="maxHistory" value="10"/>

    <!-- 异步缓冲队列的深度,该值会影响性能.默认值为256 -->
    <property name="queueSize" value="512" />

    <!-- lOGGER  PATTERN  配置化输出语句 根据自己的喜好选择 -->
    <property name="logPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger - %msg%n"/>
    <!-- %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger - %msg%n -->
    <!-- %d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %msg %n -->
    <!-- [ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n  -->


    <!-- 控制台打印日志的相关配置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志格式 -->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

    <!-- 文件保存日志的相关配置 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 保存日志文件的路径 -->
        <file>${logPath}/${appName}.log</file>

        <!-- 日志格式 -->
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>${logLevel}</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${logPath}/${appName}-%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 最大保存时间-->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
    </appender>

    <!--配置mybatis sql 日志-->
    <logger name="com.dxm.dao" level="DEBUG"/>
    <!-- 基于INFO处理日志:具体控制台或者文件对日志级别的处理还要看所在appender配置的filter,如果没有配置filter,则使用root配置 -->

    <root level="${logLevel}">
        <appender-ref ref="STDOUT" />
        <!-- 开发可以只要控制台就OK -->
         <appender-ref ref="FILE" />
    </root>
</configuration>

logback-online.xml(线上,未测试)

<?xml version="1.0" encoding="UTF-8"?>
<!-- 分级别异步文件日志输出配置 -->
<!-- 级别从高到低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
<!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 -->
<!-- 以下 每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志 -->
<!-- scan 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
<!-- scanPeriod 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">

    <!-- logback项目名称 -->
    <property name="appName" value="noSeatBeltProd"></property>

    <!-- 日志级别 DEBUGER INFO WARN ERROR -->
    <property name="logLevel" value="INFO"></property>

    <!-- 日志路径-->
    <property name="logPath" value="./logs"></property>

    <!-- 最大保存时间 30天-->
    <property name="maxHistory" value="3"/>

    <!-- 异步缓冲队列的深度,该值会影响性能.默认值为256 -->
    <property name="queueSize" value="256"></property>

    <!-- lOGGER  PATTERN 根据个人喜好选择匹配  -->
    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
   <property name="logPattern" value="[ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n"></property>
   <!-- %d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %logger - %msg%n -->
    <!-- %d{yyyy-MM-dd HH:mm:ss} %-4relative [%thread] %-5level %logger{35} - %msg %n -->
    <!-- [ %-5level] [%date{yyyy-MM-dd HH:mm:ss.SSS}] %logger{96} [%line] [%thread]- %msg%n  -->

    <!-- 动态日志级别 -->
    <jmxConfigurator/>

    <!-- 控制台的标准输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

    <!-- DEBUG 日志记录  -->
    <appender name="FILE_DEBUG"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录DEBUG级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}_debug.log</file>
        <!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责触发滚动 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志输出位置  可相对、和绝对路径 -->
            <fileNamePattern>${logPath}/debug/${appName}_debug.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6,
           则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除-->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

    <!-- INFO 级别的日志记录  -->
    <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}_info.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/info/${appName}_info.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

    <!--  WARN 级别的日志记录 -->
    <appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}_warn.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/warn/${appName}_warn.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

    <!-- Error 级别的日志记录 -->
    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <file>${logPath}/${appName}_error.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/error/${appName}_error.log.%d{yyyy-MM-dd}.zip
            </fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${logPattern}</pattern>
        </encoder>
    </appender>

    <!-- ASYNC_LOG_DEBUG  -->
    <appender name="ASYNC_LOG_DEBUG" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_DEBUG"/>
    </appender>

    <!-- ASYNC_LOG_INFO -->
    <appender name="ASYNC_LOG_INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_INFO"/>
    </appender>

    <!-- ASYNC_LOG_WARN -->
    <appender name="ASYNC_LOG_WARN" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_WARN"/>
    </appender>

    <!--ASYNC_LOG_ERROR  -->
    <appender name="ASYNC_LOG_ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>${queueSize}</queueSize>
        <appender-ref ref="FILE_ERROR"/>
    </appender>

    <!-- 日志的记录级别 -->
    <!-- 在定义后引用APPENDER -->
    <root level="${logLevel}">
        <!--  控制台  -->
        <appender-ref ref="STDOUT"/>

        <!-- 具体的日志级别和文件的配置 -->
        <appender-ref ref="ASYNC_LOG_DEBUG"/>
        <appender-ref ref="ASYNC_LOG_INFO"/>
        <appender-ref ref="ASYNC_LOG_WARN"/>
        <appender-ref ref="ASYNC_LOG_ERROR"/>
    </root>
</configuration>

Test测试

package com.dxm.controller;

import com.dxm.domain.User;
import com.dxm.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ServiceTest {
    @Autowired
    private UserService userService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    public void test(){
        List<User> users = userService.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
    @Test
    public void jdbcTemplate() {
        List<User> users = jdbcTemplate.query("select * from userInfo", new BeanPropertyRowMapper(User.class));
        for (User user : users) {
            System.out.println(user);
        }
    }
}

mybatis逆向生成

使用启动类或者插件,注意如果生成了一次,再生成的时候mapper.xml会追加

导入依赖

启动类MyBatisGenerate

package com.dxm.mgb;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
@Slf4j
public class MyBatisGenerate {


         public void generator() throws Exception {
                  List<String> warnings = new ArrayList<String>();
                  boolean overwrite = true;
                  // 指定配置文件
                  File configFile = new File(MyBatisGenerate.class.getClassLoader().getResource("generatorConfig.xml").getPath());
                  ConfigurationParser cp = new ConfigurationParser(warnings);
                  Configuration config = cp.parseConfiguration(configFile);
                  DefaultShellCallback callback = new DefaultShellCallback(overwrite);
                  MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
                  myBatisGenerator.generate(null);
         }

         // 执行main方法以生成代码
         public static void main(String[] args) {
                  try {
                           MyBatisGenerate generatorSqlmap = new MyBatisGenerate();
                           generatorSqlmap.generator();
                           log.info("finish...");
                  } catch (Exception e) {
                           e.printStackTrace();
                  }
         }

}

mybatisGeneratorInit.properties

# JDBC config
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/ssm
jdbc.userId=root
jdbc.password=123456

#JavaBean location
javaModelGenerator.targetProject=src/main/java
javaModelGenerator.targetPackage=com.dxm.domain

#interface location
javaClientGenerator.targetProject=src/main/java
javaClientGenerator.targetPackage=com.dxm.dao

#mapping location
sqlMapGenerator.targetProject=src/main/resources
sqlMapGenerator.targetPackage=mapper

generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- 引入外部配置文件-->
    <properties resource="generator/mybatisGeneratorInit.properties"/>

    <context id="testTables" targetRuntime="MyBatis3">


        <!-- 配置pojo的序列化 -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <commentGenerator>
            <!-- 是否去掉生成日期那行注释 true:是 : false:否,此配置只有在suppressAllComments为false才有意义-->
            <property name="suppressDate" value="true"/>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
        </jdbcConnection>

        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <!-- targetProject:生成PO类的位置 -->
        <javaModelGenerator targetPackage="${javaModelGenerator.targetPackage}"
                            targetProject="${javaModelGenerator.targetProject}">
            <!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
            <property name="enableSubPackages" value="true"/>
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- targetProject:mapper映射文件生成的位置 -->
        <sqlMapGenerator targetPackage="${sqlMapGenerator.targetPackage}"
                         targetProject="${sqlMapGenerator.targetProject}">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- targetPackage:mapper接口生成的位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="${javaClientGenerator.targetPackage}"
                             targetProject="${javaClientGenerator.targetProject}">
            <!-- enableSubPackages:是否让schema作为包的后缀 -->
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 指定数据库表 -->
        <!-- 修改 -->
        <table tableName="userinfo" domainObjectName="User">
            <!-- 使用驼峰命名方法,不使用数据库真实的列名-->
            <property name="useActualColumnNames" value="false"/>
            <!-- generatedKey用于生成生成主键的方法,
     如果设置了该元素,MBG会在生成的<insert>元素中生成一条正确的<selectKey>元素,该元素可选
     column:主键的列名;
     sqlStatement:要生成的selectKey语句,有以下可选项:
         Cloudscape:相当于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
         DB2       :相当于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
         DB2_MF    :相当于selectKey的SQL为:SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
         Derby      :相当于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
         HSQLDB      :相当于selectKey的SQL为:CALL IDENTITY()
         Informix  :相当于selectKey的SQL为:select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
         MySql      :相当于selectKey的SQL为:SELECT LAST_INSERT_ID()
         SqlServer :相当于selectKey的SQL为:SELECT SCOPE_IDENTITY()
         SYBASE      :相当于selectKey的SQL为:SELECT @@IDENTITY
         JDBC      :相当于在生成的insert元素上添加useGeneratedKeys="true"和keyProperty属性

         identity:当设置为true时,该列会被标记为identity列, 并且<selectKey>元素会被插入在insert后面。
         当设置为false时,<selectKey>会插入到insert之前(通常是序列)。
         **重要**: 即使您type属性指定为post,您仍然需要为identity列将该参数设置为true。
         这将标志MBG从插入列表中删除该列。默认值是false。
         type:type=post and identity=true的时候生成的<selectKey>中的order=AFTER,
         当type=pre的时候,identity只能为false,生成的<selectKey>中的order=BEFORE。
         可以这么理解,自动增长的列只有插入到数据库后才能得到ID,所以是AFTER,
         使用序列时,只有先获取序列之后,才能插入数据库,所以是BEFORE。
           -->
            <generatedKey column="id" sqlStatement="Mysql" identity="true" type="post"/>

        </table>
    </context>
</generatorConfiguration>

文件上传

导入依赖

在spring-mvc.xml配置文件上传的bean

上传页面index.jsp

<html>
<body>
<h2>Hello World!</h2>

<%--
        文件上传配置流程
            1. 引入commons-fileupload
            2. 表单必须post提交,设置表单的类型为多部件的表单, 表单中需要有一个file属性
            3. 在spring-mvc中配置文件上传解析器
    --%>
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="uploadFile">
    <input type="text" name="username">
    <input type="submit">
</form>
</body>
</html>

uploadController

package com.dxm.upload;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class UploadController {
    @RequestMapping("/upload")
    public String upload(@RequestParam("uploadFile") MultipartFile uploadFile, String username, HttpServletRequest request){
        // 唯一的文件名
        String uuid = UUID.randomUUID().toString().replace("-", "");
        //获取文件的扩展名
        //1. 获取真实的文件名称
        String originalFilename = uploadFile.getOriginalFilename();
        //2. 截取扩展名
        String extendName = originalFilename.substring(originalFilename.lastIndexOf("."));
        System.out.println(extendName);
        //3. 拼接文件名
        String fileName = uuid + extendName;

        //获取服务器的路径
        String realPath = request.getSession().getServletContext().getRealPath("/upload");
        System.out.println(realPath);
        //判断是否存在绝对路径
        File realFile = new File(realPath);
        if(!realFile.exists()){
            realFile.mkdirs();
        }

        try {
            uploadFile.transferTo(new File(realFile, fileName));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "success";
    }

}

swagger文档

导包

spring-mvc.xml配置bean以及配置swagger不被拦截

配置类swaggerConfig

package com.dxm.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
//@ComponentScan("com.dxm.controller")
public class SwaggerConfig {

    //ApiInfo:api文档的基本信息
    //Docket:配置框架的工作方式
    //apiInfo():配置基本说明信息
    //apis(): 配置api选择方式(包,类注解,方法注解)
    //paths():配置扫描路径(所有,正则匹配)

    /* 通过createRestApi函数创建Docket的Bean之后,
    apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)
    select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现,
    apis()函数扫描所有Controller中定义的API, 并产生文档内容(除了被@ApiIgnore指定的请求) */
    @Bean
    public Docket customDocket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        Contact contact = new Contact("团队名", "www.baidu.com", "my@my.com");
        return new ApiInfoBuilder()
                .title("文档标题")
                .description("文档描述")
                .contact(contact)   // 联系方式
                .version("1.1.0")  // 版本
                .build();
    }
}

使用UserController

package com.dxm.controller;


import com.dxm.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping("/user")
//@Api用在Controller类上
@Api(tags="接口所在的类")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/findAll")
    //@ApiOperation:用在请求的方法上,说明方法的用途、作用,value=“说明方法的用途、作用”
    //notes=“方法的备注说明”
    @ApiOperation(value = "接口名", notes = "接口描述", httpMethod = "POST")
    //@ApiImplicitParam :用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
    //name:参数名
    //value:参数的汉字说明、解释
    //required:参数是否必须传
    //paramType:参数放在哪个地方
    //· header --> 请求参数的获取:@RequestHeader
    //· query --> 请求参数的获取:@RequestParam
    //· path(用于restful接口)–> 请求参数的获取:@PathVariable
    //· body(不常用)
    //· form(不常用)
    //dataType:参数类型,默认String,其它值dataType=“Integer”
    //defaultValue:参数的默认值
    @ApiImplicitParams({
            @ApiImplicitParam(name = "length",value = "参数1", required = true, paramType = "path"),
            @ApiImplicitParam(name = "size",value = "参数2", required = true, paramType = "query"),
            @ApiImplicitParam(name = "page",value = "参数3", required = true, paramType = "header"),
            @ApiImplicitParam(name = "total",value = "参数4", required = true, paramType = "form"),
            @ApiImplicitParam(name = "start",value = "参数5",dataType = "string", paramType = "body")
    })
    public List findAll(HttpServletRequest request){
        String aa = request.getParameter("aa");
        String queryString = request.getQueryString();
        System.out.println("queryString:"+queryString);
        System.out.println(aa);
        String pathInfo = request.getPathInfo();
        System.out.println(pathInfo);
        return userService.findAll();
    }
    @GetMapping("/tx")
    public void tx(){
        userService.tx();
    }

 }

分页插件

导入依赖

在applicationContext.xml引入SqlMapConfig.xml

SqlMapConfig.xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置分页插件 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->
            <property name="dialect" value="mysql"/>
        </plugin>
    </plugins>

</configuration>

使用

UserService接口

package com.dxm.service;

import com.dxm.domain.User;

import java.util.List;

public interface UserService {
    List<User> findAll();

    void tx();

    void jdbcTemplate();


}

UserServiceImpl实现类

package com.dxm.service.impl;


import com.dxm.dao.UserMapper;
import com.dxm.domain.User;
import com.dxm.domain.UserExample;
import com.dxm.service.UserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;


@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JdbcTemplate jdbcTemplate;



    @Override
    public List findAll() {
        //pageNum:第几页;pageSize:每页个数
        PageHelper.startPage(1, 3);
        List<User> users = userMapper.selectByExample(new UserExample());
        PageInfo<User> userPageInfo = new PageInfo<>(users);
        System.out.println("total:" + userPageInfo.getTotal());
        return users;
    }

    @Override
    //@Transactional("dataSourceTransactionManager")
    public void tx() {
        User user = new User();
        user.setAge(11);
        user.setName("dd");
        userMapper.insert(user);
        System.out.println(1 / 0);
        userMapper.insert(user);

    }

    @Override
    public void jdbcTemplate() {
        List<User> users = jdbcTemplate.query("select * from userInfo", new BeanPropertyRowMapper(User.class));
        for (User user : users) {
            System.out.println(user);
        }
    }


    public static void main(String[] args) {
        System.out.println(ClassLoader.getSystemResource("SqlMapConfig.xml").getPath());
        System.out.println(UserServiceImpl.class.getClassLoader().getResource("SqlMapConfig.xml").getPath());
        System.out.println(System.getProperty("user.dir"));
        String configFilePath = System.getProperty("user.dir")
                .concat("/src/main/resources/generatorConfig.xml");
        System.out.println(configFilePath);


    }
}

异常处理

spring-mvc.xml配置扫包

ExceptionResolver

package com.dxm.exception;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Component
public class ExceptionResolver implements HandlerExceptionResolver{
    /**
     *
     * @param request 请求对象
     * @param response  相应
     * @param handler 处理器
     * @param e  异常对象
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
        e.printStackTrace();
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("forward:/index.jsp");
        return modelAndView;
    }
}

拦截器

在spring-mvc.xml配置拦截器

MyInterceptor

package com.dxm.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class MyInterceptor implements HandlerInterceptor {
    /**
     * 什么时候执行
     *      在执行控制器方法之前执行--》 控制器方法
     * 拦截器链的执行顺序
     *      按照配置顺序执行
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器1:preHandle");
        return true;
    }

    /**
     * 必须所有的preHandle方法都返回true,才会执行
     * 什么时候执行
     *      控制器方法执行之后执行
     * 拦截器链的执行顺序
     *      按照配置顺序倒序执行
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截器1:postHandle");
    }

    /**
     * 什么时候执行
     *      控制器方法执行之后,视图页面渲染完成之后执行
     *  必须所有的preHandle方法都返回true,才会执行
     * 拦截器链的执行顺序
     *      按照配置顺序倒序执行
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("拦截器1:afterCompletion");
    }
}

maven多环境配置

注意:务必勾选profiles的baidu和dev

pom.xml

<!--maven的profile用法有许多种,但基本原理就是根据激活环境的不同,自定义字段被赋予不同的值。-->
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <!--自定义标签-->
            <active.profile>dev</active.profile>
        </properties>
        <!-- 把当前profile设置为默认profile,可以同时这是多个为默认-->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <active.profile>test</active.profile>
        </properties>
    </profile>
    <profile>
        <id>product</id>
        <properties>
            <active.profile>product</active.profile>
        </properties>
    </profile>

</profiles>

<build>
    <finalName>com.dxm</finalName>

    <filters>
        <filter>src/main/filters-${active.profile}.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
  
  ...
</build>

db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8
jdbc.username=root
jdbc.password=${jdbc.ppp}

在src/main新建filters-dev.properties,filters-product.properties,filters-test.properties

内容类似如下

filters-dev.properties

jdbc.ppp=1

打包

命令

mvn clean package -P test -P为指定profiles,有可能报错,记得关闭tomcat或者使用下面的命令

mvn clean package -Dmaven.test.skip=true -P test

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值