SSM整合demo及个人思考

SSM整合

  • 项目整体架构说明
  • [1. 创建Maven项目](#1. 创建Maven项目)
  • [2. 配置web.xml](#2. 配置web.xml)
  • [4. 配置springmvc.xml](#4. 配置springmvc.xml)
  • [5. 配置spring.xml](#5. 配置spring.xml)
  • [6. 配置mybatis-config.xml以及创建mapper接口和mapper配置文件](#6. 配置mybatis-config.xml以及创建mapper接口和mapper配置文件)
  • [7. 配置log4j.xml](#7. 配置log4j.xml)
  • [8. 后端CURD测试](#8. 后端CURD测试)
    • [8.1 在数据库中插入数据](#8.1 在数据库中插入数据)
    • [8.2 pojo中的实体类Employee](#8.2 pojo中的实体类Employee)
    • [8.3 mapper层的EmployMapper接口](#8.3 mapper层的EmployMapper接口)
    • [8.4 mapper层的EmployeeMapper.xml配置文件(resources目录下)](#8.4 mapper层的EmployeeMapper.xml配置文件(resources目录下))
    • [8.5 service层的EmployeeService接口 和 service.impl层的EmployeeServiceImpl类](#8.5 service层的EmployeeService接口 和 service.impl层的EmployeeServiceImpl类)
    • [8.6 统一返回结果Result以及响应码Code](#8.6 统一返回结果Result以及响应码Code)
    • [8.7 controller层的EmployeeController](#8.7 controller层的EmployeeController)
    • [8.8 postman测试](#8.8 postman测试)

项目整体架构说明

1. 创建Maven项目

网上创建Maven的教程有很多,在这里就不再累赘了,有以下几个注意点:

  1. pom.xml中的打包方式一定要为war包,不配置默认是jar包,在后面配置tomcat的时候会找不到Artifacts情况;
  2. 创建新的Maven项目是没有web.xml的,需要进入Project Structure进行配置,如下图所示;

pom.xml依赖如下所示,如果有需要可以直接copy使用:

注意 : 如果在项目启动过程中出现:validateConnection false等错误,通常原因是因为druid数据源的版本与MySql 8.0版本不匹配导致的,可以参考文章:MySQL 8.0 驱动与阿里druid版本兼容操作

xml 复制代码
<?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>org.example</groupId>
    <artifactId>day25_ssm</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.version>5.3.1</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--springmvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- Mybatis核心 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!--mybatis和spring的整合包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <!-- log4j日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.2.0</version>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- ServletAPI -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- Spring5和Thymeleaf整合包 -->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.12.RELEASE</version>
        </dependency>
    </dependencies>

</project>

2. 配置web.xml

web.xml配置的文件内容

  1. 配置Spring的编码过滤器CharacterEncodingFilter;
  2. 配置处理请求方式PUTDELETE的过滤器HiddenHttpMethodFilter;
  3. 配置SpringMVC的前端控制器DispatcherServlet;
  4. 设置Spring的配置文件的位置和名称;
  5. 配置Spring监听器ContextLoaderListener;

1、2、3点都很容易理解,在SpringMVC配置中都需要,那么整合的时候也必须可少。那下面就分析一下为什么还需要4、5点。一个web项目启动起来至少有两个IOC容器:一个是SpringMVC管理的IOC容器,一个是Spring管理的IOC容器。这两个容器有什么关系吗?

答案是肯定的,根据MVC三层架构知,controller层依赖service层,service层依赖mapper层;而SpringMVC管理的IOC容器只管理controller层组件bean,Spring管理的组件IOC容器管理除controler层的所有组件bean。

所以这两个容器之间肯定是存在关系的,Spring管理的IOC容器必须要早于SpringMVC管理的IOC容器生成。并结合官方文档可知:SpringMVC管理的IOC容器是一个父容器,Spring管理的IOC容器是一个子容器,所以Spring管理的IOC容器必须早于SpringMVC管理的IOC容器生成,所以就设置了4、5条内容。

Spring提供了监听器ContextLoaderListener,实现ServletContextListener接口,可监听ServletContext的状态,在web服务器的启动,读取Spring的配置文件,创建Spring的IOC容器。web应用中必须在web.xml中配置

xml 复制代码
<!--自定义Spring配置文件的位置和名称-->
<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring.xml</param-value>
</context-param>

<listener>
	<!--
		配置Spring的监听器,在服务器启动时加载Spring的配置文件
		Spring配置文件默认位置和名称:/WEB-INF/applicationContext.xml
		可通过上下文参数自定义Spring配置文件的位置和名称
	-->
	<listenerclass>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

web.xml全部内容:

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的编码过滤器-->
    <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>
        <!--相应编码-->
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--PUT、DELETE请求-->
    <filter>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>HiddenHttpMethodFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--配置SpringMVC的前端控制器-->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--设置SpringMVC配置文件的位置和名称-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--设置Spring的配置文件的位置和名称-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring.xml</param-value>
    </context-param>

    <!--配置Spring监听器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>


</web-app>

4. 配置springmvc.xml

springmvc.xml可以配置的文件内容:

  1. 扫描controller层的包;
  2. 配置Thymeleaf视图解析器;
  3. 配置文件上传解析器multipartResolver;(multipartResolver是一个接口,实现类为CommonsMultipartResolver)
  4. 配置访问首页的试图控制;(需要再webapp/WEB-INF/templates目录下创建 一个index.html页面)
  5. 配置默认的servlet处理静态资源;
  6. 开启MVC的注解驱动;
  7. 拦截器和异常解析器也在该配置文件里面配置,这里就不展示了;

springmvc.xml全部内容,可以直接copy使用:

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

    <!--扫描controller层的包-->
    <context:component-scan base-package="qc.lsm.controller"></context:component-scan>

    <!-- 配置Thymeleaf视图解析器 -->
    <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
        <property name="order" value="1"/>
        <property name="characterEncoding" value="UTF-8"/>
        <property name="templateEngine">
            <bean class="org.thymeleaf.spring5.SpringTemplateEngine">
                <property name="templateResolver">
                    <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
                        <!--/WEB-INF/templates/xxx.html-->
                        <!-- 视图前缀 -->
                        <property name="prefix" value="/WEB-INF/templates/"/>
                        <!-- 视图后缀 -->
                        <property name="suffix" value=".html"/>
                        <property name="templateMode" value="HTML5"/>
                        <property name="characterEncoding" value="UTF-8" />
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

    <!--配置文件上传解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

    <!--配置访问首页的试图控制-->
    <mvc:view-controller path="/" view-name="index"></mvc:view-controller>

    <!--配置默认的servlet处理静态资源-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--开启MVC的注解驱动 -->
    <mvc:default-servlet-handler></mvc:default-servlet-handler>

</beans>

5. 配置spring.xml

Spring配置文件中的内容

  1. 扫描除了controller层的所有组件;
  2. 配置Druid数据源并引入外部文件jdbc.properties;
  3. 配置JdbcTemplate;
  4. 配置事务管理器组件DataSourceTransactionManager;
  5. 开启事务的注解驱动;
  6. 开启aop自动代理;
  7. 配置用于创建SqlSessionFactory的工程bean,这样就可以简化mybatis配置文件;
  8. 配置mapper接口的扫描配置:由mybatis-spring提供,可以将指定包下所有的mapper接口创建动态代理并将这些代理动态作为IOC容器的bean管理;

在SSM整合的时候添加了7-8的原因在于简化mybatis, 之前学习mybaits的时候很麻烦,要先加载mybaits-config.xml配置文件,然后创建SqlSessionFactory,获取Session以及对应的mapper等。

在SSM整合的时候进行了简化,第7项:可以直接在spring.xml配置文件里面进行创建SqlSessionFactory的工程bean,该组件里面的属性包括加载mybatis配置文件的路径,设置数据源,设置类型别名所对应的包以及映射文件的路径等,大大简化的mybatis-config.xml的配置。在spring.xml中进行配置后就不需要再mybatis-config.xml中进行配置了。

xml 复制代码
<!--配置用于创建SqlSessionFactory的工程bean,这样就可以简化mybatis配置文件-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--设置MyBatis配置文件的路径-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!--设置数据源-->
        <property name="dataSource" ref="dataSource"></property>
        <!--设置类型别名所对应的包-->
        <property name="typeAliasesPackage" value="qc.lsm.pojo"></property>
        <!--设置映射文件的路径,若映射文件所在路径和mapper接口所在路径一致,则不需要设置-->
<!--        <property name="mapperLocations" value="classpath:mapper/*.xml"></property>-->
    </bean>

第8项个人感觉非常牛皮,配置之后可以将指定包下所有的mapper接口创建动态代理并将这些代理动态作为IOC容器的bean管理。

xml 复制代码
<!--配置mapper接口的扫描配置:由mybatis-spring提供,可以将指定包下所有的mapper接口创建动态代理并将这些代理动态作为IOC容器的bean管理-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="qc.lsm.mapper"></property>
</bean>

spring.xml全部内容,可以直接copy使用:

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


    <!--扫描除了controller层的所有组件;-->
    <context:component-scan base-package="qc.lsm">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--引入外部文件jdbc.properties-->
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>

    <!--配置Druid数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

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

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

    <!--开启事务的注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

    <!--开启aop自动代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    <!--配置用于创建SqlSessionFactory的工程bean,这样就可以简化mybatis配置文件-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--设置MyBatis配置文件的路径-->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!--设置数据源-->
        <property name="dataSource" ref="dataSource"></property>
        <!--设置类型别名所对应的包-->
        <property name="typeAliasesPackage" value="qc.lsm.pojo"></property>
        <!--设置映射文件的路径,若映射文件所在路径和mapper接口所在路径一致,则不需要设置-->
<!--        <property name="mapperLocations" value="classpath:mapper/*.xml"></property>-->
    </bean>


    <!--配置mapper接口的扫描配置:由mybatis-spring提供,可以将指定包下所有的mapper接口创建动态代理并将这些代理动态作为IOC容器的bean管理-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="qc.lsm.mapper"></property>
    </bean>


</beans>

6. 配置mybatis-config.xml以及创建mapper接口和mapper配置文件

在学习mybatis的时候,mybatis-config.xml配置文件内容如下:

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>
    <!--引入properties文件,此时就可以${属性名}的方式访问属性值-->
    <properties resource="jdbc.properties"></properties>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/><!--将表中字段的下划线自动转换为驼峰-->
        <setting name="lazyLoadingEnabled" value="true"/><!--开启延迟加载-->
    </settings>

    <plugins>
        <!--设置分页插件-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>

    <typeAliases>
        <!--
        typeAlias:设置某个具体的类型的别名
        属性:type:需要设置别名的类型的全类名
        	 alias:设置此类型的别名,且别名不区分大小写。若不设置此属性,该类型拥有默认的别名,即类名
        -->
        <!--<typeAlias type="com.atguigu.mybatis.bean.User"></typeAlias>-->
        <!--<typeAlias type="com.atguigu.mybatis.bean.User" alias="user">        </typeAlias>-->
        <!--以包为单位,设置改包下所有的类型都拥有默认的别名,即类名且不区分大小写-->
        <package name="com.atguigu.bean"/>
    </typeAliases>
    <!--
    environments:设置多个连接数据库的环境
    属性:default:设置默认使用的环境的id
    -->
    <environments default="mysql_test">
        <!--
        environment:设置具体的连接数据库的环境信息
        属性:id:设置环境的唯一标识,可通过environments标签中的default设置某一个环境的id,表示默认使用的环境
        -->
        <environment id="mysql_test">
            <!--
            transactionManager:设置事务管理方式
            属性:
	            type:设置事务管理方式,type="JDBC|MANAGED"
	            type="JDBC":设置当前环境的事务管理都必须手动处理
	            type="MANAGED":设置事务被管理,例如spring中的AOP
            -->
            <transactionManager type="JDBC"/>
            <!--
            dataSource:设置数据源
            属性:
	            type:设置数据源的类型,type="POOLED|UNPOOLED|JNDI"
	            type="POOLED":使用数据库连接池,即会将创建的连接进行缓存,下次使用可以从缓存中直接获取,不需要重新创建
	            type="UNPOOLED":不使用数据库连接池,即每次使用连接都需要重新创建
	            type="JNDI":调用上下文中的数据源
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/><!--设置驱动类的全类名-->
                <property name="url" value="${jdbc.url}"/> <!--设置连接数据库的连接地址-->
                <property name="username" value="${jdbc.username}"/><!--设置连接数据库的用户名-->
                <property name="password" value="${jdbc.password}"/><!--设置连接数据库的密码-->
            </dataSource>
        </environment>
    </environments>
    <!--引入映射文件-->
    <mappers>
        <!-- <mapper resource="UserMapper.xml"/> 这样需要每一个文件都需要一个resource-->
        <!--
        以包为单位,将包下所有的映射文件引入核心配置文件
        注意:1. 此方式必须保证mapper接口和mapper映射文件必须在相同的包下
			 2. mapper接口要和mapper映射文件的名字一致
        -->
        <package name="com.atguigu.mapper"/>
    </mappers>
</configuration>

但是为了简化mybaits,咱们在spring.xml配置文件里面设置了SqlSessionFactory的工厂bean,并在里面配置了下面的内容:

  1. 设置mybatis配置文件的路径;
  2. 设立数据源;
  3. 设置类型别名所对应的包;
  4. 设置映射文件路径,若映射文件所在路径和mapper接口所在路径一致,则不需要设置;

所以mybatis-config.xml中的内容如下所示:

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>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/><!--将表中字段的下划线自动转换为驼峰-->
        <setting name="lazyLoadingEnabled" value="true"/><!--开启延迟加载-->
    </settings>

    <plugins>
        <!--设置分页插件-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>


</configuration>

7. 配置log4j.xml

log4j 8种日志级别:

  1. All: 最低等级的,用于打开所有日志记录.
  2. Trace: 是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,我们可以设置最低日志级别不让他输出.
  3. Debug: 指出细粒度信息事件对调试应用程序是非常有帮助的.
  4. Info: 消息在粗粒度级别上突出强调应用程序的运行过程.
  5. Warn: 输出警告及warn以下级别的日志.
  6. Error: 输出错误信息日志.
  7. Fatal: 输出每个严重的错误事件将会导致应用程序的退出的日志.
  8. OFF: 最高等级的,用于关闭所有日志记录.

日志级别等级按照从低到高为All < Trace < Debug < Info < Warn < Error < Fatal < OFF

Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS}%m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

8. 后端CURD测试

8.1 在数据库中插入数据

8.2 pojo中的实体类Employee

java 复制代码
public class Employee {
    private Integer empId;
    private String empName;
    private Integer age;
    private String sex;
    private String email;

   // 无参构造器,有参构造器,set/get方法,toString方法...
}

8.3 mapper层的EmployMapper接口

java 复制代码
package qc.lsm.mapper;
import qc.lsm.pojo.Employee;
import java.util.List;

public interface EmployeeMapper {

    /**
     * 根据id查询单个员工的信息
     * @param id
     * @return
     */
    Employee selectEmployeeById(Integer id);

    /**
     * 查询所有员工的信息
     * @return
     */
    List<Employee> selectAllEmployee();

    /**
     * 添加员工信息
     * @param employee
     * @return
     */
    int addEmployee(Employee employee);

    /**
     * 根据员工id删除员工信息
     * @param empId
     * @return
     */
    int deleteEmployee(Integer empId);

    /**
     * 根据员工id修改员工信息
     * @param employee
     * @return
     */
    int updateEmployee(Employee employee);
}

8.4 mapper层的EmployeeMapper.xml配置文件(resources目录下)

注意 :由于表t_emp的字段名与类Employee中的属性名不一致,所以在查询的时候使用了resultMap标签;

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="qc.lsm.mapper.EmployeeMapper">
    <!--
      1. 查询的标签select必须设置属性resultType或resultMap,用于设置实体类和数据库表的映射关系
	    - resultType:自动映射,用于 ====属性名和表中字段名一致===== 的情况
	    - resultMap:自定义映射,用于 ====一对多或多对一或字段名和属性名不一致===== 的情况
      2. 当查询的数据为多条时,不能使用实体类作为返回值,只能使用集合,否则会抛出异常TooManyResultsException;
         但是若查询的数据只有一条,可以使用实体类或集合作为返回值-->

    <resultMap id="employeeResultMap" type="Employee">
        <id property="empId" column="emp_id"></id>
        <result property="empName" column="emp_name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <result property="email" column="email"></result>
    </resultMap>

    <!--Employee selectEmployeeById(Integer id);-->
    <select id="selectEmployeeById" resultMap="employeeResultMap">
        select * from t_emp where emp_id = #{id};
    </select>

    <!-- List<Employee> selectAllEmployee();-->
    <select id="selectAllEmployee" resultMap="employeeResultMap">
        select * from t_emp;
    </select>

    <!--
       useGeneratedKeys:设置当前标签中的sql使用了自增的主键
       keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参数User对象的某个属性中
   -->
    <!--int addEmployee(Employee employee);-->
    <insert id="addEmployee" parameterType="qc.lsm.pojo.Employee">
        insert into t_emp values(null, #{empName}, #{age}, #{sex},#{email})
    </insert>

    <!--int deleteEmployee(Integer empId);-->
    <delete id="deleteEmployee" parameterType="Integer">
        delete from t_emp where emp_id = #{id}
    </delete>

    <!--int updateEmployee(Employee employee);-->
    <update id="updateEmployee" parameterType="Employee">
        update t_emp set emp_name = #{empName}, age = #{age}, sex = #{sex}, email = #{email} where emp_id = #{empId};
    </update>

</mapper>

8.5 service层的EmployeeService接口 和 service.impl层的EmployeeServiceImpl类

EmployeeService接口

java 复制代码
public interface EmployeeService {
    /**
     * 根据id查询单个员工的信息
     * @param id
     * @return
     */
    Employee selectEmployeeById(Integer id);

    /**
     * 查询所有员工的信息
     * @return
     */
    List<Employee> selectAllEmployee();

    /**
     * 添加员工信息
     * @param employee
     * @return
     */
    int addEmployee(Employee employee);

    /**
     * 根据员工id删除员工信息
     * @param empId
     * @return
     */
    int deleteEmployee(Integer empId);

    /**
     * 根据员工id修改员工信息
     * @param employee
     * @return
     */
    int updateEmployee( Employee employee);
}

EmployeeService接口的实现类EmployeeServiceImpl

java 复制代码
package qc.lsm.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.lsm.mapper.EmployeeMapper;
import qc.lsm.pojo.Employee;
import qc.lsm.service.EmployeeService;
import java.util.List;

@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    public Employee selectEmployeeById(Integer id) {
        System.out.println("employeeMapper: " + employeeMapper);
        return employeeMapper.selectEmployeeById(id);
    }

    @Override
    public List<Employee> selectAllEmployee() {
        System.out.println("employeeMapper: " + employeeMapper);
        return employeeMapper.selectAllEmployee();
    }

    @Override
    public int addEmployee(Employee employee) {
        return employeeMapper.addEmployee(employee);
    }

    @Override
    public int deleteEmployee(Integer empId) {
        return employeeMapper.deleteEmployee(empId);
    }

    @Override
    public int updateEmployee(Employee employee) {
        return employeeMapper.updateEmployee(employee);
    }
}

8.6 统一返回结果Result以及响应码Code

响应码Code类

java 复制代码
package qc.lsm.utils;

public class Code {
    public static final Integer ADD_OK = 10001;
    public static final Integer ADD_ERROR = 10000;

    public static final Integer SELETE_OK = 20001;
    public static final Integer SELETE_ERROR = 20000;

    public static final Integer UPDATE_OK = 30001;
    public static final Integer UPDATE_ERROR = 30000;

    public static final Integer DELETE_OK = 40001;
    public static final Integer DELETE_ERROR = 40000;
}

统一返回结果类Result

java 复制代码
package qc.lsm.controller;

/**
 * 定义统一返回格式类
 */
public class Result {
    // 描述统一格式中的数据
    private Object data;
    // 描述统计格式中的编码,用于区分操作,可以简化配置0/1表示成功失败
    private Integer code;
    // 描述统一格式中的消息,可选属性
    private String msg;

    public Result() {
    }

    public Result(Object data, Integer code) {
        this.data = data;
        this.code = code;
    }

    public Result(Object data, Integer code, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }


    // set/get方法

    @Override
    public String toString() {
        return "Result{" +
                "data=" + data +
                ", code=" + code +
                ", msg='" + msg + '\'' +
                '}';
    }
}

8.7 controller层的EmployeeController

java 复制代码
package qc.lsm.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import qc.lsm.pojo.Employee;
import qc.lsm.service.EmployeeService;
import qc.lsm.utils.Code;

import java.util.List;

/**
 * @author Mr.Lu
 * @version 1.0
 * @date 2023-09-08 20:13
 */

@RestController
@RequestMapping("/employee")
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    @RequestMapping("/selectEmployeeById/{id}")
    public Result selectEmployeeById(@PathVariable("id") Integer id){
        Employee employee = employeeService.selectEmployeeById(id);
        if(employee == null){
            return new Result(null, Code.SELETE_ERROR, "查询失败");
        }
        return new Result(employee,Code.SELETE_OK, "查询成功");
    }

    @RequestMapping("/selectAll")
    public Result selectAllEmployee(){
        List<Employee> employees = employeeService.selectAllEmployee();
        if(employees == null){
            return new Result(null, Code.SELETE_ERROR, "查询失败");
        }
        return new Result(employees, Code.SELETE_OK, "查询成功");
    }

    @RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
    public Result addEmployee(@RequestBody Employee employee){
        System.out.println("employee: " + employee);
        int count = employeeService.addEmployee(employee);
        if(count > 0) {
            List<Employee> employees = employeeService.selectAllEmployee();
            return new Result(employees, Code.ADD_OK, "添加成功");
        }
        return new Result(null, Code.ADD_ERROR, "添加失败");
    }

    @RequestMapping("/deleteEmployeeById/{id}")
    public Result deleteEmployeeById(@PathVariable("id") Integer id){
        int count = employeeService.deleteEmployee(id);
        if(count > 0){
            List<Employee> employees = employeeService.selectAllEmployee();
            return new Result(employees, Code.DELETE_OK, "删除成功");
        }
        return new Result(null, Code.DELETE_ERROR, "删除失败");
    }


    @RequestMapping("/updateEmployee")
    public Result updateEmployee(@RequestBody Employee employee){
        int count = employeeService.updateEmployee(employee);
        if(count > 0){
            return new Result(employeeService.selectEmployeeById(employee.getEmpId()), Code.UPDATE_OK, "更新成功");        }

        return new Result(null, Code.UPDATE_ERROR, "更新失败");
    }
}

8.8 postman测试

测试1:根据id查询员工信息http://localhost/ssm/employee/selectEmployeeById/2

java 复制代码
@RequestMapping("/selectEmployeeById/{id}")
public Result selectEmployeeById(@PathVariable("id") Integer id){
    Employee employee = employeeService.selectEmployeeById(id);
    if(employee == null){
        return new Result(null, Code.SELETE_ERROR, "查询失败");
    }
    return new Result(employee,Code.SELETE_OK, "查询成功");
}

测试2:查询所有员工信息http://localhost/ssm/employee/selectAll

java 复制代码
   @RequestMapping("/selectAll")
    public Result selectAllEmployee(){
        List<Employee> employees = employeeService.selectAllEmployee();
        if(employees == null){
            return new Result(null, Code.SELETE_ERROR, "查询失败");
        }
        return new Result(employees, Code.SELETE_OK, "查询成功");
    }

测试3:添加员工http://localhost/ssm/employee/addEmployee

java 复制代码
@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
public Result addEmployee(@RequestBody Employee employee){
    System.out.println("employee: " + employee);
    int count = employeeService.addEmployee(employee);
    if(count > 0) {
        List<Employee> employees = employeeService.selectAllEmployee();
        return new Result(employees, Code.ADD_OK, "添加成功");
    }
    return new Result(null, Code.ADD_ERROR, "添加失败");
}

测试4:根据id删除员工信息http://localhost/ssm/employee/deleteEmployeeById/2

java 复制代码
@RequestMapping("/deleteEmployeeById/{id}")
public Result deleteEmployeeById(@PathVariable("id") Integer id){
    int count = employeeService.deleteEmployee(id);
    if(count > 0){
        List<Employee> employees = employeeService.selectAllEmployee();
        return new Result(employees, Code.DELETE_OK, "删除成功");
    }
    return new Result(null, Code.DELETE_ERROR, "删除失败");
}

测试5:更新员工信息http://localhost/ssm/employee/updateEmployee

java 复制代码
@RequestMapping("/updateEmployee")
public Result updateEmployee(@RequestBody Employee employee){
    int count = employeeService.updateEmployee(employee);
    if(count > 0){
        return new Result(employeeService.selectEmployeeById(employee.getEmpId()), Code.UPDATE_OK, "更新成功");        }

    return new Result(null, Code.UPDATE_ERROR, "更新失败");
}
相关推荐
qq_12498707531 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
2301_818732061 小时前
前端调用控制层接口,进不去,报错415,类型不匹配
java·spring boot·spring·tomcat·intellij-idea
码字的字节2 小时前
Spring Cloud服务注册与发现(一):手把手搭建Eureka Server,详解高可用配置
spring·spring cloud·eureka
大厂资深架构师2 小时前
Spring Cloud Eureka在后端系统中的服务剔除策略
spring·spring cloud·ai·eureka
暮色妖娆丶5 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
·云扬·6 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
biyezuopinvip6 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现
7哥♡ۣۖᝰꫛꫀꪝۣℋ7 小时前
微服务负载均衡
spring·微服务
筵陌7 小时前
MySQL索引及其底层原理(上)
mysql