SSM_CRUD

ssm:Spring + SpringMVC + MyBatis CRUD:Create(创建),Retrieve(查询),Update(更新),Delete(删除)

功能点

  1. 分页
  2. 数据校验
    jquery前段校验 + JSR303后端校验
  3. ajax
  4. Rest风格的URI;使用Http协议请求方式的动词,来表示对资源的操作(GET(查询),POST(新增),PUT(更新),DELETE(删除))

技术点

  1. 基础框架-SSM(SpringMVC + Spring + MyBatis)
  2. 数据库-MySql
  3. 前段框架-bootstrap快速搭建
  4. 项目的依赖管理-Maven
  5. 分页-PageHelper
  6. 逆向工程-MyBatis Generator

基础环境搭建

  1. 创建一个maven工程
  2. 引入项目依赖的jar包
    1. spring
    2. springMVC
    3. mybatis
    4. 数据库连接池,驱动包(driver)
    5. 其他(jstl,servlet-api(这个servlet主要是为了单元测试),junit)
  3. 引入bootstrap前端框架(依赖jQuery必须放在前边)
  4. 编写ssm整合的关键配置文件
    1. web.xml
    2. spring
    3. springMVC
    4. mybatis
    5. 使用mybatis的逆向工程(MBG)生成对应的bean以及mapper
  5. 测试mapper

image-20201007202820091.png

maven项目

  1. <dependencies>
  2. <!--引入项目依赖jar包-->
  3. <!--
  4. 引入pageHelper分页插件
  5. pageHelper插件需要在mybatis的插件中注册
  6. -->
  7. <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
  8. <dependency>
  9. <groupId>com.github.pagehelper</groupId>
  10. <artifactId>pagehelper</artifactId>
  11. <version>5.2.0</version>
  12. </dependency>
  13. <!--
  14. JSR303数据校验
  15. tomcat7及以下的版本,el表达式,额外给服务器lib保重替换新的el
  16. 在bean中注解完要求后,必须在需要校验的地方使用注解@Valid进行声明,这样才会进行校验
  17. -->
  18. <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
  19. <dependency>
  20. <groupId>org.hibernate</groupId>
  21. <artifactId>hibernate-validator</artifactId>
  22. <version>6.1.0.Final</version>
  23. </dependency>
  24. <!--
  25. MBG,逆向工程:这个逆向工程的使用必须声明
  26. <property name="nullCatalogMeansCurrent" value="true"/>,这个配置如果不加,会造成生成的字段有误
  27. -->
  28. <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
  29. <dependency>
  30. <groupId>org.mybatis.generator</groupId>
  31. <artifactId>mybatis-generator-core</artifactId>
  32. <version>1.4.0</version>
  33. </dependency>
  34. <!--返回json字符串,这个包并不需要注册,好像springMVC会自动注入-->
  35. <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
  36. <dependency>
  37. <groupId>com.fasterxml.jackson.core</groupId>
  38. <artifactId>jackson-databind</artifactId>
  39. <version>2.11.0</version>
  40. </dependency>
  41. <!--SpringMVC、Spring spring webmvc-->
  42. <!--spring-webmvc 处理web请求-->
  43. <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
  44. <dependency>
  45. <groupId>org.springframework</groupId>
  46. <artifactId>spring-webmvc</artifactId>
  47. <version>5.2.8.RELEASE</version>
  48. </dependency>
  49. <!--spring jdbc 面向事务-->
  50. <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
  51. <dependency>
  52. <groupId>org.springframework</groupId>
  53. <artifactId>spring-jdbc</artifactId>
  54. <version>5.2.8.RELEASE</version>
  55. </dependency>
  56. <!--spring-test 单元测试-->
  57. <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
  58. <dependency>
  59. <groupId>org.springframework</groupId>
  60. <artifactId>spring-test</artifactId>
  61. <version>5.2.8.RELEASE</version>
  62. <scope>test</scope>
  63. </dependency>
  64. <!--Spring Aspects 面向切面AOP编程-->
  65. <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
  66. <dependency>
  67. <groupId>org.springframework</groupId>
  68. <artifactId>spring-aspects</artifactId>
  69. <version>5.2.8.RELEASE</version>
  70. </dependency>
  71. <!--MyBatis-->
  72. <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
  73. <dependency>
  74. <groupId>org.mybatis</groupId>
  75. <artifactId>mybatis</artifactId>
  76. <version>3.5.3</version>
  77. </dependency>
  78. <!--Mybatis整合spring的适配包-->
  79. <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
  80. <dependency>
  81. <groupId>org.mybatis</groupId>
  82. <artifactId>mybatis-spring</artifactId>
  83. <version>2.0.5</version>
  84. </dependency>
  85. <!--数据库连接池、驱动-->
  86. <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
  87. <dependency>
  88. <groupId>com.mchange</groupId>
  89. <artifactId>c3p0</artifactId>
  90. <version>0.9.5.2</version>
  91. </dependency>
  92. <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  93. <dependency>
  94. <groupId>mysql</groupId>
  95. <artifactId>mysql-connector-java</artifactId>
  96. <version>8.0.16</version>
  97. </dependency>
  98. <!--jstl,servlet-api, junit-->
  99. <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
  100. <dependency>
  101. <groupId>javax.servlet.jsp.jstl</groupId>
  102. <artifactId>jstl</artifactId>
  103. <version>1.2</version>
  104. </dependency>
  105. <!-- https://mvnrepository.com/artifact/org.mortbay.jetty/servlet-api -->
  106. <dependency>
  107. <groupId>org.mortbay.jetty</groupId>
  108. <artifactId>servlet-api</artifactId>
  109. <version>3.0.20100224</version>
  110. <scope>provided</scope>
  111. <!--已经提供的,这个是给Spring单元测试准备的-->
  112. </dependency>
  113. <!-- https://mvnrepository.com/artifact/junit/junit -->
  114. <dependency>
  115. <groupId>junit</groupId>
  116. <artifactId>junit</artifactId>
  117. <version>4.12</version>
  118. <scope>test</scope>
  119. </dependency>
  120. </dependencies>

web.xml配置

web.xml配置,在这儿做的就是把spring,springMVC的功能域分发出去,(差不多就是分流吧!),然后在给配一些过滤器(我感觉过滤器在这儿才是最重要的),最主要的就是启动spring容器。

<?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">

    <!--1. 启动Spring的容器-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
        <!--这儿指定spring的配置文件的位置:contextConfigLocation-->
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--
    ContextLoaderListener的作用就是启动Web容器时,读取在contextConfigLocation中定义的xml文件,自动装配ApplicationContext的配置信息,并产生WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。
    -->


    <!--2. 配置springMVC 的前端控制器,拦截所有请求-->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--
        DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下:
        1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
        2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);
        3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);
        4、通过ViewResolver解析逻辑视图名到具体视图实现;
        5、本地化解析;
        6、渲染具体的视图等;
        7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。
        -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
            <!--
                springMVC的配置文件地址,如果不指定就需要在和web.xml同级的地方生成一个与<servlet-name>相同的xxx-servlet.xml文件;就比如:servlet-name是springDispatcherServlet,那么对应的springMVC 配置文件就是springDispatcherServlet-servlet.xml;所以一般情况下直接使用自定义的。
            -->
        </init-param>
        <load-on-startup>1</load-on-startup>
        <!--
        1. load-on-startup 元素标记容器是否应该在web应用程序启动的时候就加载这个servlet,(实例化并调用其init()方法)
        2. 它的值必须是一个整数,表示servlet被加载的先后顺序。
        3. 如果该元素的值为负数或者没有设置,则容器会当Servlet被请求时再加载。
        4. 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。
        -->
    </servlet>
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
        <!--拦截根路径下所有的访问,然后根据springMVC中地配置进行处理-->
    </servlet-mapping>


    <!--3. 字符编码过滤器,一定要放在所有过滤器之前-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <!--
            字符编码过滤器:CharacterEncodingFilter
            主要作用就是给请求和返回添加编码集,防止乱码;下面的这三个属性都是CharacterEncodingFilter中的属性,必须进行配置
            由于字符编码集必须在读取请求数据之前就进行设置,所以这个过滤器一定要放在第一个,不然就会不生效
        -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!--4. 使用Rest风格的URI,将页面普通的post转为delete或者put请求
    需要在发送POST请求时携带一个隐藏域name="_method"的隐藏域,值为DELETE/PUT,所以推荐使用下面的FormContentFilter
    -->
    <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>

    <!--FormContentFilter,可以同时过滤PUT和Delete请求还有Patch请求(好像啥都能解析)-->
    <filter>
        <filter-name>formContentFilter</filter-name>
        <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>formContentFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Spring MVC

回头来看,发现spring MVC 中的配置才是最少的(但是运行原理很复杂)。这儿配置了:

  1. 扫描器,但是禁用了默认的过滤器(use-default-filter),只是扫描Controller注解下面的内容(扫描就会创建对象,如果不处理,Spring也会扫描两个代理对象必然会出现问题),然后响应的内容在Controller中通过注解即可。
  2. 视图解析器,如果仅仅通过ajax来处理(前后端分离),可以不使用。
  3. 主要是用来处理静态文件的访问,因为DispatcherServlet映射配置了“/”,所有的请求都会被映射进去,配置了这个之后就会有DefaultServletHttpRequestHandler来检查每一个请求,如果是静态文件的请求,那么就会直接给返回静态资源,其他的才会交给DispatcherServlet继续处理
  4. 会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的,并且提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持读写XML的支持(JAXB)和读写JSON的支持(默认Jackson)等功能。我们处理响应ajax请求时,就使用到了对json的支持。
<?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 http://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/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--
    springMVC的配置文件,包含网站跳转逻辑的控制,配置
        user-default-filters禁用掉自动过滤
    -->
    <context:component-scan base-package="com.zh" use-default-filters="false">
        <!--只扫描控制器-->
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--配置视图解析器,方便页面返回-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--两个标准配置-->
    <!--将springMVC 不能处理的请求交给tomcat,这样就能实现静态文件的访问-->
    <mvc:default-servlet-handler/>
    <!--
如果将DispatcherServlet请求映射配置为"/",则Spring MVC将捕获Web容器所有的请求,包括静态资源的请求,Spring MVC会将它们当成一个普通请求处理,因此找不到对应处理器将导致错误。

在springMVC-servlet.xml中配置<mvc:default-servlet-handler />后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
    -->

    <!--能支持springMVC 更高级的一些功能:JSR303校验,快捷的ajax请求。。。映射动态请求-->
    <mvc:annotation-driven/>
    <!--
<mvc:annotation-driven>会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean,这是Spring MVC为@Controller分发请求所必需的,并且提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持读写XML的支持(JAXB)和读写JSON的支持(默认Jackson)等功能。
我们处理响应ajax请求时,就使用到了对json的支持。
    -->

</beans>

Spring配置

事务操作的详细内容,(看过去之后就忘了) 《事务操作》)

SqlSessionTemplate与SqlSessionFactory的关系与区别

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

    <!--扫描器-->
    <context:component-scan base-package="com.zh">
        <!--指定扫描的范围-->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--spring配置文件,这里主要配置和业务逻辑有关的-->
    <!--数据源,事务控制,。。。-->
    <context:property-placeholder location="classpath:dbconfig.properties"/>
    <!--引入今天资源,主要用来配置一些动态的数据:比如说数据源等-->

    <!--================================c3p0数据源-->
    <bean id="pooledDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--==============================================-->


    <!--=========================配置MyBatis的整合-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 指定mybatis全局配置文件的位置 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <!-- 指定数据源 -->
        <property name="dataSource" ref="pooledDataSource"></property>
        <!-- 指定mybatis.mapper文件的位置 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
    </bean>

    <!--扫描所有的dao接口的实现,加入到ioc容器中-->
    <!--<mybatis-spring:scan base-package="com.zh.mybatis.dao"/>-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--MapperScannerConfigurer 的作用是取代手动添加 Mapper ,自动扫描完成接口代理-->
        <property name="basePackage" value="com.zh.crud.dao"/>
    </bean>

    <!--配置一个可以执行批量的sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
        <!--批量操作-->
        <constructor-arg name="executorType" value="BATCH"></constructor-arg>
    </bean>
    <!--================================================-->




    <!--==================================事务控制的配置-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--控制住数据源-->
        <property name="dataSource" ref="pooledDataSource"/>
    </bean>

    <!--开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式)-->
    <aop:config>
        <!--切入点表达式,这个包下的所有操作事务都被控制-->
        <aop:pointcut id="txPoint" expression="execution(* com.zh.crud.service..*(..))"/>
        <!--配置-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>

    <!--配置事务增强:事务如何切入-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--*代表切入的所有方法都是事务方法-->
            <tx:method name="*"/>
            <!--以get开始的所有方法-->
            <tx:method name="get*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
    <!--================================================-->


    <!--Spring配置文件的核心点(数据源,于mybatis的整合,事务控制)-->

</beans>

MBG逆向工程

MyBatis Generator !!需要注意的是,逆向工程生成的并不能连表查询,需要我们进行一定的增强。 !!!特别需要注意的是jdbcConnection中nullCatalogMeansCurrent字段的配置,不然生成的mapper.xml文件会出问题的,别问我怎么知道的(整整2个小时啊!)

MBG详细笔记链接 《MyBatis-逆向工程》)

<?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>

    <context id="simple" targetRuntime="MyBatis3">
        <commentGenerator>
            <!--生成的时候不产生烦人的注释-->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!--配置数据库连接信息-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssm_crud"
                        userId="root"
                        password="root">
            <!--这个配置在新版本中必须加,如果不加,逆向工程生成的文件会有问题-->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>

        <!--指定javaBean生成的位置-->
        <javaModelGenerator targetPackage="com.zh.crud.bean" targetProject="./src/main/java"></javaModelGenerator>

        <!--指定sql映射文件生成的位置-->
        <sqlMapGenerator targetPackage="mapper"  targetProject="./src/main/resources"></sqlMapGenerator>

        <!--指定dao接口生成的位置,mapper接口生成的位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.zh.crud.dao"  targetProject="./src/main/java"></javaClientGenerator>

        <!--指定每个表的生成策略-->
        <table tableName="tbl_dept" domainObjectName="Department"></table>
        <table tableName="tbl_emp" domainObjectName="Employee"></table>

    </context>
</generatorConfiguration>
// MBG生成的java代码
    @Test
    public void testMbg() throws Exception {

        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        File configFile = new File("mbg.xml");
        // 这儿的File必须是一个绝对路径,就是本项目文件夹下的路径,最好就放在项目文件夹下,(与pom.xml同级)
        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);

    }

MyBatis配置

在配置这儿就需要开启一个二级缓存,有利于减少数据的查询

MyBatis全局配置文件 《MyBatis-全局配置文件》)

<?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"/>
    </settings>

    <!--类型别名处理起-->
    <typeAliases>
        <package name="com.zh.crud.bean"/>
    </typeAliases>

    <plugins>
        <!--com.github.pagehelper.PageInterceptor,参数分页-->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--分页参数合理化-->
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>
</configuration>

spring单元测试

/**
 * @author cai-xiansheng
 * @Description 测试dao层的工作
 * @create 2020-10-05 22:00
 * 推荐Spring的项目就可以使用Spring的单元测试,可以自动注入我们需要的组件
 * 1. 导入SpringTest
 * 2. 使用@ContextConfiguration指定Spring配置文件的位置
 *      注解@RunWith标注测试单元
 * 3. 直接AutoWired要使用的组件即可
 */
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class MapperTest {

    @Autowired
    DepartmentMapper departmentMapper;

    @Autowired
    EmployeeMapper employeeMapper;

    @Autowired
    SqlSession sqlSession;
    // 执行批操作的SqlSessionTemplate

    /**
     * 测试DepartmentMapper
     */
    @Test
    public void testCRUD() {
        // 测试部门的mapper
        // 1. 创建SpringIOC容器
        //ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 2. 从容器中获取mapper
        //DepartmentMapper bean = ioc.getBean(DepartmentMapper.class);

        System.out.println(departmentMapper);
        //System.out.println(departmentMapper.selectByPrimaryKey(1));
        // 1. 插入几个部门
        //departmentMapper.insertSelective(new Department(null, "开发部"));
        //departmentMapper.insertSelective(new Department(null, "测试部"));

        // 2. 生成员工数据,测试员工插入
        //employeeMapper.insertSelective(new Employee(null, "Jerry", "M", "Jerry@zh.com", 1));

        // 3. 批量插入多个员工:批量:使用可以执行批量操作的sqlSession
        //for (int i = 0; i < 1000; i++) {
        //    employeeMapper.insertSelective(new Employee(null, "Jerry", "M", "Jerry@zh.com", 1));
        //}

        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
        for (int i = 0; i < 1000; i++) {
            String uuid = UUID.randomUUID().toString().substring(0, 5) + i;
            mapper.insertSelective(new Employee(null, uuid, "M",  uuid + "@zh.com", 1));
        }
        System.out.println("批量操作完成!");
    }
}

spring模块请求测试

这个主要是对于jsp的测试

/**
 * @author cai-xiansheng
 * @Description 使用spring模块提供的测试请求功能,测试crud请求的正确性
 * Spring4测试的时候,需要servlet3.0的支持
 * @create 2020-10-06 15:23
 */
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
// 注解@WebAppConfiguration是为了让WebApplicationContext完整自动注入
@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:springMVC.xml"})
public class MvcTest {
    // 传入Spring MVC 的ioc
    @Autowired
    WebApplicationContext context;
    // 虚拟mvc请求,获取到处理结果
    MockMvc mockMvc;

    @Before
    public void initMockMvc() {
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void testPage() throws Exception {

        // 模拟请求,拿到返回值
        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "202")).andReturn();

        // 请求成功后,请求域中会有pageInfo,我们可以取出pageInfo进行验证
        MockHttpServletRequest request = result.getRequest();
        PageInfo pageInfo = (PageInfo) request.getAttribute("pageInfo");
        System.out.println("当前页码: " + pageInfo.getPageNum());
        System.out.println("总页码: " + pageInfo.getPages());
        System.out.println("总记录数: " + pageInfo.getTotal());
        System.out.println("在页面需要连续显示的页码: " + Arrays.toString(pageInfo.getNavigatepageNums()));

        // 获取员工数据
        List<Employee> list = pageInfo.getList();
        for (Employee employee : list) {
            System.out.println(employee);
        }
    }


}

Maven打包jar或者war

  1. jar包的介绍

JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。JavaSE程序可以打包成Jar包(J其实可以理解为Java了)。

JAR 文件格式以流行的 ZIP 文件格式为基础。与 ZIP 文件不同的是,JAR 文件不仅用于压缩和发布,而且还用于部署和封装组件插件程序,并可被像编译器和 JVM 这样的工具直接使用。在 JAR 中包含特殊的文件,如 manifests 和部署描述符,用来指示工具如何处理特定的 JAR。

简单来说,jar包就是别人已经写好的一些类,然后对这些类进行打包。可以将这些jar包引入到你的项目中,可以直接使用这些jar包中的类和属性,这些jar包一般放在lib目录下。

  1. war包的介绍

war是一个可以直接运行的web模块,通常用于网站,打成包部署到容器中。以Tomcat来说,将war包放置在其\webapps\目录下,然后启动Tomcat,这个包就会自动解压,就相当于发布了。

war包是Sun提出的一种web应用程序格式,与jar类似,是很多文件的压缩包。war包中的文件按照一定目录结构来组织。根据其根目录下包含有html和jsp文件,或者包含有这两种文件的目录,另外还有WEB-INF目录。通常在WEB-INF目录下含有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的servlet类和jsp,或者servlet所依赖的其他类(如JavaBean)。通常这些所依赖的类也可以打包成jar包放在WEB-INF下的lib目录下。

简单来说,war包是JavaWeb程序打的包,war包里面包括写的代码编译成的class文件,依赖的包,配置文件,所有的网站页面,包括html,jsp等等。一个war包可以理解为是一个web项目,里面是项目的所有东西。

  1. 区别:(WAR文件代表了一个Web应用程序,JAR是类的归档文件。

如果一个Web应用程序的目录和文件非常多,那么将这个Web应用程序部署到另一台机器上,就不是很方便了,这时可以将Web应用程序打包成Web 归档(WAR)文件,这个过程和把Java类文件打包成JAR文件的过程类似。利用WAR文件,可以把Servlet类文件和相关的资源集中在一起进行发布。在这个过程中,Web应用程序就不是按照目录层次结构来进行部署了,而是把WAR文件作为部署单元来使用。

一个WAR文件就是一个Web应用程序,建立WAR文件,就是把整个Web应用程序(不包括Web应用程序层次结构的根目录)压缩起来,指定一个.war扩展名。

要注意的是,虽然WAR文件和JAR文件的文件格式是一样的,并且都是使用jar命令来创建,但就其应用来说,WAR文件和JAR文件是有根本区别的。JAR文件的目的是把类和相关的资源封装到压缩的归档文件中,而对于WAR文件来说,一个WAR文件代表了一个Web应用程序,它可以包含 Servlet、HTML页面、Java类、图像文件,以及组成Web应用程序的其他资源,而不仅仅是类的归档文件。

那么什么时候应该使用WAR文件呢?在开发阶段不适合使用WAR文件,因为在开发阶段,经常需要添加或删除Web应用程序的内容,更新 Servlet类文件,而每一次改动后,重新建立WAR文件将是一件浪费时间的事情。在产品发布阶段,使用WAR文件是比较合适的,因为在这个时候,几乎不需要再做什么改动了。

在开发阶段,我们通常将Servlet源文件放到Web应用程序目录的src子目录下,以便和Web资源文件区分。在建立WAR文件时,只需要将src目录从Web应用程序目录中移走,就可以打包了。

在Maven项目中打war包

<!--在pom.xml文件中添加这个即可-->
<packaging>war</packaging>
  1. 添加了上面配置后
  2. image-20201007230945120.png即可

注意:

这儿需要注意的是,一定要把test文件移走,不然他会执行。