ssm整合思路【java】(超详细)个人总结

目录

 

一、SSM简介

1.MVC介绍?

2.整合版本要求。

二、SSM整合实例

1.创建Maven Web项目。

step1:新建模块。

step2:点击下一个,构建坐标。

step3:点击完成,添加web框架的支持。

step4:检查项目结构,是否符合下图:

2.导入依赖。

3.创建数据库表和编写相关查询语句

4.根据这些语句编写实体类代码。

5.编写配置文件及资源文件

6.整合Mybatis与Spring。

7.JUnit测试。

8.整合SpringMVC。

1.配置Spring-mvc.xml

2.配置web.xml文件

3.编写视图层页面。

4.根据视图层编写控制层代码。

5.启动服务器进行测试是否整合成功。

三、SSM总结

如有不足,欢迎指正!


一、SSM简介

SSM(Spring+SpringMVC+MyBatis)框架集由Spring、SpringMVC、MyBatis三个开源框架整合而成,常作为数据源较简单的web项目的框架。

其中Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。

1.MVC介绍?

MVC:全名Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

通俗解释:一种文件的组织和管理形式!不要被缩写吓到了,这其实就是把不同类型的文件放到不同目录下的一种方法,然后取了个高大上的名字。当然,他带来的好处有很多,比如前后端分离,松耦合等等,就不详细说明了。

模型(model):数据持久层,即我们常用的Dao层,CRUD操作。同时需要配合Service层,处理详细的业务逻辑。

视图(View):前端展示数据,提供链发起Service请求,例如a,form,img...等。

控制器(Controller):接收用户的请求:req-请求参数、Session信息等,并把这些请求数据交给业务层进行处理相应代码,同时控制视图的跳转。

如图所示理解MVC:

2.整合版本要求。

导入的依赖一定要满足上图版本要求,不然运行项目时会出现各种报错!

二、SSM整合实例

1.创建Maven Web项目。

step1:新建模块。

step2:点击下一个,构建坐标。

step3:点击完成,添加web框架的支持。

  

step4:检查项目结构,是否符合下图:

如果存在,那就ok了,开始我们的项目配置工作。

2.导入依赖。

这里需要注意导入的依赖的版本要按照整合版本的要求来,这里我使用的是最新版本要求。

Spring  5.3.3

SpringMVC 5.3.3

Mybatis  3.5.2

<?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.luo</groupId>
    <artifactId>SSM-Demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>
        </plugins>
        <!--在build中配置resources,来防止我们资源导出失败的问题-->
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
    </build>
    <dependencies>

        <!--************************所使用的工具类依赖*********************-->
        <!--用于测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <!--用于快捷编写实体类-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!--文件上传-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!--JSON类型数据解析-->
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.1</version>
        </dependency>
        <!--**********************************************************************-->



        <!--********************** Spring框架 ************************************-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.3</version>
        </dependency>

        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--        使用SpringAop的时候需要导入-->
        <dependency>
            <groupId>org.apache.geronimo.bundles</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8_2</version>
        </dependency>
        <!--导入更高版本的servlet-api-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>
        <!--*********************************************************************-->


        <!--*************************Mybatis持久层框架**************************-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.22</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <!--*********************************************************************-->


        <!--************************ 日志管理 ***************************-->
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <!-- log4j.... -->
        <!-- /log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!--log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!-- log4j-web -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!-- end..... -->
        <dependency >
            <groupId >javax.mail</groupId >
            <artifactId >mail</artifactId >
            <version >1.4.5 </version >
        </dependency >
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    <!--********************************************************************-->


    </dependencies>

</project>

3.创建数据库表和编写相关查询语句

# 创建一个简单的用户表
CREATE TABLE `user_t` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  `age` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

-- 下面语句在Mybatis中使用即可
# 查询所有用户
 select * from user_t;
 
#根据id查询用户
  select * from ssm_test.user_t where id=#{userId};
 
#新增名字不重复的用户,前提表中至少有一条数据
  insert into ssm_test.user_t(user_name,password,age)
        (select #{user_name},#{password},#{age} from ssm_test.user_t
            where not exists(
                select * from ssm_test.user_t where user_name=#{user_name}
                )
        limit 1);

4.根据这些语句编写实体类代码。

这里推荐一下 IDEA快速实现接口、查找接口的实现、getSet方法快速生成等等常用快捷键这篇文章,方便快速开发。

User.class

package com.luo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
    private String user_name;
    private String password;
    private int age;
}

这里我使用了lombok,它是相当于一个插件,与类里的注解配合使用,简便的省去写set,get啥的实体类的东西。

它的使用步骤如下:

  1. 在IDEA中安装Lombok插件

  2. 在项目中导入lombok的jar包

  3. 在实体类中可使用下面常用的注解:

 

使用这个插件的优缺点:

  • 优点: 1.能通过注解的形式自动生成构造器、getter/setter. equals、 hashcode. toString等方法, 提高了一定的开发效率 2.让代码变得简洁,不用过多的去关注相应的方法 3.属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等

  • 缺点: 1.不支持多种参数构造器的重载 2.虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度

5.编写配置文件及资源文件

首先创建db.properties,这设置了连接数据库的所需参数的资源信息。

username = 
password = 
url = jdbc:mysql://localhost:3306/ssm_test?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC
driver = com.mysql.cj.jdbc.Driver

#定义初始连接数
initialSize = 0
#定义最大连接数
maxActive = 20
#定义最大空间
maxIdle = 20
#定义最小空间
minIdle = 1
#定义最长等待时间
maxWait = 60000

然后在spring-mybatis.xml中引用,实现JDBC连接,同时此文件设置日志模式及spring与mybatis整合:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/util
        https://www.springframework.org/schema/util/spring-util.xsd"
>
<!--    自动扫描-->
    <context:component-scan base-package="com.luo"/>
<!--    开启注解支持-->
    <context:annotation-config/>
<!--扫描db.properties-->
    <context:property-placeholder location="classpath:db.properties" system-properties-mode="FALLBACK"/>
<!--    jdbc连接-->
    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
        <property name="url" value="${url}"/>
        <property name="driverClassName" value="${driver}"/>
    </bean>
<!--    配置sqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
       <property name="dataSource" ref="dataSource"/>
       <property name="configurationProperties">
           <props>
               <prop key="logImpl">LOG4J2</prop>
               <prop key="mapUnderscoreToCamelCase">true</prop>
           </props>
       </property>
        <property name="mapperLocations" value="classpath:com/luo/mapper/*.xml"/>
    </bean>
<!--    Dao接口所在的包,Spring自动向下找相关类-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.luo.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
<!--    配置声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource" />
    </bean>
<!--    sqlSessionFactoryTemplate-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!--        只能使用构造器注入sqlSession,因为它没有set方法-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
</beans>

由于在此设置了log4j2的日志模式,所以我们需要导入log4j2.xml文件,便于我们每次调试程序生成相关日志文件:

百度百科:为了方便调试,一般都会使用日志来输出信息,Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。为了方便调试,一般都会使用日志来输出信息,Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

关于如果设置了log4j的日志模式,那么我们可以使用这篇文章的配置:http://www.blogjava.net/zJun/archive/2006/06/28/55511.html

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="1800">

    <Properties>
        <!-- ==============================================公共配置============================================== -->
        <!-- 设置日志文件的目录名称 -->
        <property name="logFileName">log</property>

        <!-- 日志默认存放的位置,可以设置为项目根路径下,也可指定绝对路径 -->
        <!-- 存放路径一:通用路径,window平台 -->
        <property name="basePath">${logFileName}</property>
        <!-- 存放路径二:web工程专用,java项目没有这个变量,需要删掉,否则会报异常,这里把日志放在web项目的根目录下 -->
        <!-- <property name="basePath">${web:rootDir}/${logFileName}</property> -->
        <!-- 存放路径三:web工程专用,java项目没有这个变量,需要删掉,否则会报异常,这里把日志放在tocmat的logs目录下 -->
        <!--<property name="basePath">${sys:catalina.home}/logs/${logFileName}</property>-->

        <!-- 控制台默认输出格式,"%-5level":日志级别,"%l":输出完整的错误位置,是小写的L,因为有行号显示,所以影响日志输出的性能 -->
        <property name="console_log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %l - %m%n</property>
        <!-- 日志文件默认输出格式,不带行号输出(行号显示会影响日志输出性能);%C:大写,类名;%M:方法名;%m:错误信息;%n:换行 -->
        <!-- <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %C.%M - %m%n</property> -->
        <!-- 日志文件默认输出格式,另类带行号输出(对日志输出性能未知);%C:大写,类名;%M:方法名;%L:行号;%m:错误信息;%n:换行 -->
        <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %C.%M[%L line] - %m%n</property>

        <!-- 日志默认切割的最小单位 -->
        <property name="every_file_size">20MB</property>
        <!-- 日志默认输出级别 -->
        <property name="output_log_level">DEBUG</property>

        <!-- ===========================================所有级别日志配置=========================================== -->
        <!-- 日志默认存放路径(所有级别日志) -->
        <property name="rolling_fileName">${basePath}/all.log</property>
        <!-- 日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="rolling_filePattern">${basePath}/%d{yyyy-MM}/all-%d{yyyy-MM-dd-HH}-%i.log.gz</property>
        <!-- 日志默认同类型日志,同一文件夹下可以存放的数量,不设置此属性则默认为7个,filePattern最后要带%i才会生效 -->
        <property name="rolling_max">500</property>
        <!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
                如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
                如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
        <property name="rolling_timeInterval">12</property>
        <!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
                如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
        <property name="rolling_timeModulate">true</property>

        <!-- ============================================Info级别日志============================================ -->
        <!-- Info日志默认存放路径(Info级别日志) -->
        <property name="info_fileName">${basePath}/info.log</property>
        <!-- Info日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="info_filePattern">${basePath}/%d{yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log.gz</property>
        <!-- Info日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
        <property name="info_max">100</property>
        <!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
                如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
                如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
        <property name="info_timeInterval">12</property>
        <!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
                如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
        <property name="info_timeModulate">true</property>

        <!-- ============================================Warn级别日志============================================ -->
        <!-- Warn日志默认存放路径(Warn级别日志) -->
        <property name="warn_fileName">${basePath}/warn.log</property>
        <!-- Warn日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="warn_filePattern">${basePath}/%d{yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log.gz</property>
        <!-- Warn日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
        <property name="warn_max">100</property>
        <!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
                如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
                如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
        <property name="warn_timeInterval">12</property>
        <!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
                如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
        <property name="warn_timeModulate">true</property>

        <!-- ============================================Error级别日志============================================ -->
        <!-- Error日志默认存放路径(Error级别日志) -->
        <property name="error_fileName">${basePath}/error.log</property>
        <!-- Error日志默认压缩路径,将超过指定文件大小的日志,自动存入按"年月"建立的文件夹下面并进行压缩,作为存档 -->
        <property name="error_filePattern">${basePath}/%d{yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log.gz</property>
        <!-- Error日志默认同一文件夹下可以存放的数量,不设置此属性则默认为7个 -->
        <property name="error_max">100</property>
        <!-- 日志默认同类型日志,多久生成一个新的日志文件,这个配置需要和filePattern结合使用;
                如果设置为1,filePattern是%d{yyyy-MM-dd}到天的格式,则间隔一天生成一个文件
                如果设置为12,filePattern是%d{yyyy-MM-dd-HH}到小时的格式,则间隔12小时生成一个文件 -->
        <property name="error_timeInterval">12</property>
        <!-- 日志默认同类型日志,是否对封存时间进行调制,若为true,则封存时间将以0点为边界进行调整,
                如:现在是早上3am,interval是4,那么第一次滚动是在4am,接着是8am,12am...而不是7am -->
        <property name="error_timeModulate">true</property>

        <!-- ============================================控制台显示控制============================================ -->
        <!-- 控制台显示的日志最低级别 -->
        <property name="console_print_level">DEBUG</property>

    </Properties>

    <!--定义appender -->
    <appenders>
        <!-- =======================================用来定义输出到控制台的配置======================================= -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 设置控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="${console_print_level}" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 设置输出格式,不设置默认为:%m%n -->
            <PatternLayout pattern="${console_log_pattern}"/>
        </Console>

        <!-- ================================打印root中指定的level级别以上的日志到文件================================ -->
        <RollingFile name="RollingFile" fileName="${rolling_fileName}" filePattern="${rolling_filePattern}">
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${rolling_timeInterval}" modulate="${warn_timeModulate}"/>
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>
            <!-- 设置同类型日志,同一文件夹下可以存放的数量,如果不设置此属性则默认存放7个文件 -->
            <DefaultRolloverStrategy max="${rolling_max}" />
        </RollingFile>

        <!-- =======================================打印INFO级别的日志到文件======================================= -->
        <RollingFile name="InfoFile" fileName="${info_fileName}" filePattern="${info_filePattern}">
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${info_timeInterval}" modulate="${info_timeModulate}"/>
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy max="${info_max}" />
            <Filters>
                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- =======================================打印WARN级别的日志到文件======================================= -->
        <RollingFile name="WarnFile" fileName="${warn_fileName}" filePattern="${warn_filePattern}">
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${warn_timeInterval}" modulate="${warn_timeModulate}"/>
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy max="${warn_max}" />
            <Filters>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>

        <!-- =======================================打印ERROR级别的日志到文件======================================= -->
        <RollingFile name="ErrorFile" fileName="${error_fileName}" filePattern="${error_filePattern}">
            <PatternLayout pattern="${log_pattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${error_timeInterval}" modulate="${error_timeModulate}"/>
                <SizeBasedTriggeringPolicy size="${every_file_size}"/>
            </Policies>
            <DefaultRolloverStrategy max="${error_max}" />
            <Filters>
                <ThresholdFilter level="FATAL" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </RollingFile>
    </appenders>

    <!--定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!-- 设置打印sql语句配置开始,以下两者配合使用,可以优化日志的输出信息,减少一些不必要信息的输出 -->
        <!-- 设置java.sql包下的日志只打印DEBUG及以上级别的日志,此设置可以支持sql语句的日志打印 -->
        <logger name="java.sql" level="DEBUG" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <!-- 设置org.mybatis.spring包下的日志只打印WARN及以上级别的日志 -->
        <logger name="org.mybatis.spring" level="WARN" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <!-- 设置org.mybatis.spring包下的日志只打印WARN及以上级别的日志 -->
        <logger name="org.springframework" level="WARN" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <!-- 设置org.mybatis.spring包下的日志只打印WARN及以上级别的日志 -->
        <logger name="com.luo.service" level="WARN" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <!-- 设置打印sql语句配置结束 -->

        <!--建立一个默认的root的logger-->
        <root level="${output_log_level}">
            <appender-ref ref="RollingFile"/>
            <appender-ref ref="Console"/>
            <appender-ref ref="InfoFile"/>
            <appender-ref ref="WarnFile"/>
            <appender-ref ref="ErrorFile"/>
        </root>
    </loggers>

</configuration>

applicationContext.xml中导入spring-mybatis.xml文件,创建这个文件的作用目的是为了方便以后的多人开发,同时便于AOP编程:

<?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:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd             
        http://www.springframework.org/schema/aop 
        https://www.springframework.org/schema/aop/spring-aop.xsd 
        http://www.springframework.org/schema/util 
        https://www.springframework.org/schema/util/spring-util.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="spring-mybatis.xml"/>

    <!--配置Spring框架声明式事务管理-->
    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>

    <!--配置AOP增强-->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.luo.service.*.*(..))"/>
    </aop:config>


</beans>

 

6.整合Mybatis与Spring。

由于spring-mybatis.xml配置文件中,我们已经设置支持了注解驱动,那么我们可以现在编写如下目录下的几个类了:

由于之前我们已经完成了User.class文件的编写,那么我们现在只需要创建UserDao接口及mappper映射文件了:

UserDao.class:

package com.luo.dao;

import com.luo.pojo.User;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserDao {

    //根据主键查找用户
    User selectByPrimaryKey(int userId);

    //查找所有用户
    List<User> selectAllUser();

    //增加用户
    void addUser(User user);

}

UserMapper.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.luo.dao.UserDao">
    <select id="selectByPrimaryKey" resultType="com.luo.pojo.User">
        select * from ssm_test.user_t where id=#{userId};
    </select>
    <select id="selectAllUser" resultType="com.luo.pojo.User">
        select * from ssm_test.user_t;
    </select>
    <insert id="addUser" parameterType="com.luo.pojo.User">
        insert into ssm_test.user_t(user_name,password,age)
        (select #{user_name},#{password},#{age} from ssm_test.user_t
            where not exists(
                select * from ssm_test.user_t where user_name=#{user_name}
                )
        limit 1);
    </insert>
</mapper>

由于更好的去实现业务,我们需要建立Service接口和实现类,对单元测试的支持,通过单独的一层service实现业务逻辑,那么对于业务逻辑的单元测试会更容易编写,只需要对service来编写就可以了;而web层的单元测试就不需要关注业务本身,只需要关注反馈格式就行了;不然web层就既要考虑业务逻辑的计算,还要考虑web反馈的格式验证,太过复杂。

UserService.class:

package com.luo.service;

import com.luo.pojo.User;

import java.util.List;

public interface UserService {
    //根据主键查找用户
    User selectByPrimaryKey(int userId);

    //查找所有用户
    List<User> selectAllUser();

    //增加用户
    void addUser(User user);
}

UserServiceImp.class:

package com.luo.service;

import com.luo.dao.UserDao;
import com.luo.pojo.User;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service("UserService")
public class UserServiceImp  implements UserService{
    @Resource
    private UserDao userDao;

    @Override
    public User selectByPrimaryKey(int userId) {
        return this.userDao.selectByPrimaryKey(userId);
    }

    @Override
    public List<User> selectAllUser() {
        return this.userDao.selectAllUser();
    }

    @Override
    public void addUser(User user) {
        this.userDao.addUser(user);
    }
}

7.JUnit测试。

测试类在src/test/java中建立使用注解的方式来引入配置文件和类,然后再将service接口对象注入,就可以进行测试了。如果测试成功,表示Spring和Mybatis已经整合成功了。输出信息使用的是Log4j打印到控制台。

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.luo.pojo.User;
import com.luo.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class TestMyBatis {

   @Resource
   private UserService userService;
   @Test
    public void test1() throws JsonProcessingException {
      ObjectMapper mapper = new ObjectMapper();
       User user = userService.selectByPrimaryKey(1);
       System.out.println(mapper.writeValueAsString(user));
   }
}

控制台输出如下:

这是生成的日志文件:

至此,完成Spring和Mybatis这两大框架的整合,下面再继续进行SpringMVC的整合。

8.整合SpringMVC。

1.配置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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">

    <!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
    <context:component-scan base-package="com.luo.controller"/>

    <!--让SpringMVC不处理静态资源 .css .js .mp3  .html-->
    <mvc:default-servlet-handler/>

    <!--设置支持mvc注解驱动:
                在Spring中一般采用@RequestMapping注解来完成映射关系,
                要想使@RequestMapping注解生效,
                必须向上文中注册DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例,
                这两个实例分别在类级别和方法级别处理。
                而annotation-driver配置帮助我们自动完成上述两个实例的注入
     -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <!--使用Jackson解决json乱码问题配置-->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
            <!--避免IE执行AJAX时,返回JSON出现下载文件 -->
            <bean id="mappingJacksonHttpMessageConverter"
                  class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!--    添加视图解析器-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >

        <!--        前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--        后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--    文件上传的配置-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <!--    请求的编码格式,必须和jsp的pageEncoding属性一致,以便我们正确读取表单的内容,默认为ISO-8859-1-->
        <property name="defaultEncoding" value="utf-8"/>
        <!--    上传文件大小限制,单位为字节(10485760=10M)-->
        <property name="maxInMemorySize" value="40960"/>
        <property name="maxUploadSize" value="10485760"/>
    </bean>
</beans>

2.配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<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_4_0.xsd"
         version="4.0">

    <!--Spring-servlet配置-->
    <servlet>
        <servlet-name>springmvc</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>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <!--Spring与Mybatis的配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!--Spring提供的过滤器,可以解决乱码,要配置在所有过滤器前面-->
    <filter>
        <filter-name>encoding</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>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--日志监听-->
    <listener>
        <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
    </listener>
    <filter>
        <filter-name>log4jServletFilter</filter-name>
        <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log4jServletFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <!-- Spring监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--防止Spring内存溢出监听-->
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>

</web-app>

3.编写视图层页面。

在jsp文件夹下:showUser.jsp

<%@ page import="com.luo.pojo.User" %>
<%@ page import="java.util.List" %><%--
  Created by IntelliJ IDEA.
  User: Luo
  Date: 2021/2/23
  Time: 16:42
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>查看用户</title>
    <style type="text/css">
        *{
            font-family: "楷体";
        }
        #title{
            color: red;
        }
        table,th,td{
            border: black solid 1px;
        }
    </style>
    <script>
        window.onload=function () {
            var colors = ["red","black","orange","green","yellow","white"];
            var ti = document.getElementById("title");
            var i = 0;
            setInterval(function () {
                i++;
                ti.style.color = colors[i];
                if(i===(colors.length-1)){
                    i=0;
                }
            },1000);
        }
    </script>
</head>
<body>
<h3 style="background-color: aquamarine" id="title">Hello World!</h3>
<h1>用户输入</h1>
<form id="test" action="${pageContext.request.contextPath}/user/add" method="post">
    用户名:<input type="text" name="username"><br/>
    年&nbsp; 龄:<input type="text" name="age"><br/>
    密&nbsp; 码:<input type="password" name="password"><br/>
    <br>
    <input type="submit" value="提交" style="margin-left: 165px">
</form>
<table>
    <thead>
    <tr>
        <th>用户名</th>
        <th>年龄</th>
        <th>密码</th>
    </tr>
    </thead>
    <tbody style="border: black 1px solid">
        <%
            List<User> list = (List<User>)request.getAttribute("users");
            for (User user : list) {
        %>
            <tr>
                <td><%=user.getUser_name()%></td>
                <td><%=user.getAge()%></td>
                <td><%=user.getPassword()%></td>
            </tr>
        <%
            }
        %>
    </tbody>
</table>
</body>
</html>

4.根据视图层编写控制层代码。

package com.luo.controller;

import com.luo.pojo.User;
import com.luo.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;

@Controller
public class UserShow {
    @Resource
    private UserService userService;

    //根据Restful风格通过地址栏查询用户
    @RequestMapping("/user/{id}")
    public String test(Model model, @PathVariable int id){
        return "showUser";
    }

    //进入页面查询所有用户
    @RequestMapping("/user/login")
    public String test1(Model model){
        model.addAttribute("users",this.userService.selectAllUser());
        System.out.println(model.getAttribute("users"));
        return "showUser";
    }

    //新增用户数据刷新页面
    @RequestMapping("/user/add")
    public String test2(String username, int age, String password, ModelAndView mv,Model model){
        User user = new User(username,password,age);
        this.userService.addUser(user);
        return test1(model);
    }

}

5.启动服务器进行测试是否整合成功。

启动成功!!!如果没有启动成功,可能是你Build的时候没有添加所需库。按照如下操作即可:

打开浏览器进入首页,点击跳转:


点击提交,页面刷新,表中数据增加,同时数据库中数据增加,不会出现重复用户:

至此,三大框架的整合就完成了,在此基础上也可以很容易的添加其他功能。

三、SSM总结

ssm 是 Spring 、SpringMVC 、Mybatis 的结合, Spring 相当于在 SpringMVC 与 Mybatis 之间的桥梁。其中 SpringMVC 相当于传统的 service+model+servlet 。结合注解进行开发,使整个开发高效代码量大大的减少。Mybatis 负责数据库的数据交换,不用自己写 SQL 语句防止了 SQL 注入问题发生,而且相比于 python中的Django框架, 他非常的轻,dao 与 model 直接自动生成大大减少了多表开发的时间,因此 ssm 是非常优秀的后台框架。

如有不足,欢迎指正!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值