【SpringMVC & Spring & Mybatis】SSM整合方案 | SpringMVC 、 Spring 、Mybatis的完美整合方案

一、基本环境

配置

IntelliJ IDEA 2019.2.4

apache-maven-3.6.3

jdk1.8.0

Tomcat8.5.38

mysql8.0.19.0


1. 数据库环境搭建

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for books
-- ----------------------------
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
  `bookID` int NOT NULL AUTO_INCREMENT,
  `bookName` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
  `bookPrice` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`bookID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of books
-- ----------------------------
INSERT INTO `books` VALUES ('1', 'java的世界', '58.9');
INSERT INTO `books` VALUES ('2', 'php你懂得', '48');
INSERT INTO `books` VALUES ('3', 'python', '45.9');

2. 构建Maven
maven依赖
<dependencies>
        <!--junit单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

        <!--c3p0依赖-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>mchange-commons-java</artifactId>
            <version>0.2.20</version>
        </dependency>
        
        <!--servlet的依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <!--JSP的依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!--JSTL的依赖-->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <!--standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <!--Mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <!--第三方缓存-Ehcache依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!--log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!--spring操作数据库的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.8</version>
        </dependency>

        <!--spring整合mybatis的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>

        <!--spring依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.5</version>
        </dependency>

        <!--使用AOP织入,需要导入一个依赖包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>

        <!-- lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>

        <!--Jackson的依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>

        <!--FirstJson的maven依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>
    </dependencies>

必须:当我们将所需的maven依赖都添加上之后,需要做下面的操作
在这里插入图片描述

静态资源导出

因为我们的XxxMapper.xml是要和XxxMapper一起写在dao目录下的,这样可能导致加载静态资源的时候,dao目录下的xml文件不能被加载到target目录中。
在这里插入图片描述
解决方案如下:

    <!--在java目录下的资源时导不出的,所以我们需要手动配xml文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

编码问题

maven 项目运行时出控制台报错:
com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1字节的 UTF-8 序列的字节 1 无效。
该错误是由一些配置文件引起的:如mybatis-config.xml的编码问题;

解决方法如下:

<!--资源文件编码的问题-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

pom.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>com.sdpei</groupId>
    <artifactId>SSMCombinate</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--junit单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

        <!--c3p0依赖-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>mchange-commons-java</artifactId>
            <version>0.2.20</version>
        </dependency>



        <!--servlet的依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <!--JSP的依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!--JSTL的依赖-->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>

        <!--standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <!--Mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <!--第三方缓存-Ehcache依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!--log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!--spring操作数据库的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.8</version>
        </dependency>

        <!--spring整合mybatis的依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>

        <!--spring依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.5</version>
        </dependency>

        <!--使用AOP织入,需要导入一个依赖包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>

        <!-- lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
        </dependency>

        <!--Jackson的依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>

        <!--FirstJson的maven依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.76</version>
        </dependency>

    </dependencies>

    <!--在java目录下的资源时导不出的,所以我们需要手动配xml文件-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

    <!--资源文件编码的问题-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

3. 创建目录

在这里插入图片描述


二、连接数据库(Mybatis层)

1.核心配置文件

mybatis-config.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>
        <!--设置log4j为日志(固定)-->
        <setting name="logImpl" value="LOG4J"/>
        <!--设置以及缓存(若要使用二级缓存,请在相应的xxxMapper.xml中添加<cache/>)-->
        <setting name="cacheEnabled" value="true" />
    </settings>

    <!--别名(动态)-->
    <typeAliases>
        <!--定位到包-->
        <package name="sdpei.pojo"/>
    </typeAliases>


    <!--注册mapper(动态)-->
    <mappers>
        <mapper class="com.sdpei.dao.BooksMapper"/>
    </mappers>

</configuration>

2.配置文件

log4j.properties
这个文件完全就是固定写法

#将等级为DEBUG的日志信息输出到console和fiLe这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
#log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
log4j.appender.console.layout.ConversionPattern=%5p [%t] - %m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/jh.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd HH:mm:ss}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG



三、整合dao、service和controller(MVC)

1.核心配置文件

配置文件
database.properties
database.properties在spring-dao.xml会用的到。
注意:这个尽量按照下面的写,避免不必要的麻烦,如:${username}可能获取的是本地名。

driverClass=com.mysql.cj.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/ssmcombinate?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
user=root
password=root123123

spring-dao.xml
spring整合dao层

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

    <!--1.关联数据库配置文件database.properties(动态)-->
    <context:property-placeholder location="classpath:database.properties"/>


    <!--2.数据库连接池c3p0(固定)-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${driverClass}"/>
        <property name="jdbcUrl" value="${jdbcUrl}"/>
        <property name="user" value="${user}"/>
        <property name="password" value="${password}"/>

        <!--连接池的最大容量(动态)-->
        <property name="maxPoolSize" value="30"/>
        <!--连接池的基本容量(动态)-->
        <property name="minPoolSize" value="10"/>
        <!--连接超时时间(动态)-->
        <property name="checkoutTimeout" value="10000"/>
        <!--连接失败后,再允许连接的次数(动态)-->
        <property name="acquireRetryAttempts" value="2"/>

    </bean>

    <!--3.配置spring的SqlSessionFactory(SqlSessionFactoryBean源于mybatis-spring)(固定)-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--绑定mybatis的核心配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--实现mybatis中的mapper的注册-->
        <!--<property name="mapperLocations" value="classpath:com/sdpei/dao/*.xml"/>-->
    </bean>

    <!--4.配置dao接口扫描包,动态实现dao接口注入到spring容器中(部分固定)-->
    <!--是用于给XxxMapperImpl的sqlSessionFactory属性注入使用的-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描dao的包(动态)-->
        <property name="basePackage" value="com.sdpei.dao"/>
    </bean>


    <!--使用SqlSessionTemplate取代原本mybatis中的SqlSession-->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        &lt;!&ndash;因为没有set方法,所以注入的时候只能使用构造器注入&ndash;&gt;
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

</beans>

spring-service.xml
spring整合service层

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

    <!--1.扫描service层下的包(固定)-->
    <context:component-scan base-package="com.sdpei.service"/>

    <!--2.将我们的所有业务类注入到Spring,可以通过配置文件实现,也可以通过注解实现(动态)-->
     <!--当然我们也可以使用注解进行自动注入@Service @Autowired-->
    <bean id="BooksServiceImpl" class="com.sdpei.service.BooksServiceImpl">
        <property name="booksMapper" ref="booksMapper"/>
    </bean>

    <!--3.声明式事务管理(固定)-->
    <!--给dao层添加事务,避免脏数据-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--4.aop事务支持-->
    <!--结合AOP实现事务的织入-->
    <!--配置事务通知-->
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>-->
                <!--给那些方法配置事务(固定)-->
                <tx:method name="*"/>
            </tx:attributes>
        </tx:advice>

    <!--事务的切入点(动态)-->
        <aop:config>-->
            <aop:pointcut id="txPointCut" expression="execution(* com.sdpei.dao.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
        </aop:config>

</beans>

spring-mvc.xml
spring整合controller层

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

    <!--1.使注解驱动生效(固定)-->
    <mvc:annotation-driven />

    <!--2.过滤(不处理)静态资源,如:.css .js .mp3....(固定)-->
    <mvc:default-servlet-handler />

    <!--3.自动扫描包,让指定包下的注解生效,有IOC统一管理(动态)-->
    <context:component-scan base-package="com.sdpei.controller"/>

    <!--4.视图解析器(局部可变)-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!--前缀:/WEB-INF/jsp/是动态的-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--解决json乱码配置(固定)-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <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>
        </mvc:message-converters>
    </mvc:annotation-driven>

</beans>

因为这个写的视图解析器的前缀是/WEB-INF/jsp/,如下:
在这里插入图片描述
所以,我们需要将所有的xxx.jsp写在/WEB-INF/jsp/下面,如下:
在这里插入图片描述


applicationContext.xml
applicationContext.xml的目的是将spring-dao.xml、spring-service.xml、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/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">

    <import resource="spring-dao.xml"/>
    <import resource="spring-service.xml"/>
    <import resource="spring-mvc.xml"/>

</beans>



三、配置Web

1.增加web支持

我们是建立的一个空的maven项目,并没有使用什么模版,所以是不支持web的,我们要向手动添加web支持,如下:
在这里插入图片描述
在这里插入图片描述

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

    <!--配置DispatchServlet: 这个是springMVC的核心(请求分发器/前端控制器)(固定)-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet需要绑定spring的配置文件(固定)-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <!--设置启动级别为1,和服务器一起启动(固定)-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--在spring中,/只会去匹配所有的请求,不会匹配jsp页面;/*会去匹配所有的请求,包括匹配jsp页面-->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


    <!--乱码过滤处理,基本够用(固定)-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!--乱码过滤处理,终极解决方案-->
<!--    <filter>-->
<!--        <filter-name>genericEncodingFilter</filter-name>-->
<!--        <filter-class>com.sdpei.filter.GenericEncodingFilter</filter-class>-->
<!--    </filter>-->
<!--    <filter-mapping>-->
<!--        <filter-name>genericEncodingFilter</filter-name>-->
<!--        <url-pattern>/*</url-pattern>-->
<!--    </filter-mapping>-->


    <!--设置Session过期时间(动态)-->
    <session-config>
        <!--30分钟过期-->
        <session-timeout>30</-timeout>
    </session-config>

</web-app>

四、编写对应的类和接口

1.pojo层

Books实体类

为了避免必要的麻烦,pojo下的类都要实现Serializable 接口
Serializable接口就是Java提供用来进行高效率的异地共享实例对象的机制,实现这个接口即可

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books implements Serializable {
    private int bookID;
    private String bookName;
    private String bookPrice;
}


2.dao层

BooksMapper接口

public interface BooksMapper {
    int addBook(Books book);
    int deleteBookByID(int booksID);
    int updateBook(Map map);
    List<Books> queryBooks(Map map);
    List<Books> queryAllBooks();
}

BooksMapper.xml
开启二级缓存(固定)的操作添加< cache/>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sdpei.dao.BooksMapper">
    <!--开启二级缓存(固定)-->
    <cache/>
    <!--第三方缓存ehcache,暂时不能使用,因为ehcache.xml中noNamespaceSchemaLocation抓取不到-->
<!--    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>-->

    <select id="queryBooks" parameterType="map" resultType="com.sdpei.pojo.Books">
        select * from `books` where booksName = #{booksName}
    </select>

    <select id="queryAllBooks" resultType="com.sdpei.pojo.Books">
        select * from `books`
    </select>

    <insert id="addBook" parameterType="com.sdpei.pojo.Books">
        insert into `books`(`bookName`,`bookPrice`) values (#{bookName},#{bookPrice})
    </insert>

    <delete id="deleteBookByID" parameterType="int">
        delete from `books` where `bookID` = #{bookID}
    </delete>

    <update id="updateBook" parameterType="map">
        update  books
        set bookName = #{bookName}, bookPrice = #{bookPrice}
        where bookID = #{bookID}
    </update>

</mapper>


3.service层

BooksService接口

public interface BooksService {
    int addBook(Books book);
    int deleteBookByID(int id);
    int updateBook(Map map);
    List<Books> queryBooks(Map map);
    List<Books> queryAllBooks();
}

BooksServiceImpl实现类

public class BooksServiceImpl implements BooksService {

    private BooksMapper booksMapper;

    public void setBooksMapper(BooksMapper booksMapper) {
        this.booksMapper = booksMapper;
    }

    public int addBook(Books book) {
        return booksMapper.addBook(book);
    }

    public int deleteBookByID(int booksID) {
        return booksMapper.deleteBookByID(booksID);
    }

    public int updateBook(Map map) {
        return booksMapper.updateBook(map);
    }

    public List<Books> queryBooks(Map map) {
        return booksMapper.queryBooks(map);
    }

    public List<Books> queryAllBooks() {
        return booksMapper.queryAllBooks();
    }
}
4.controller层

BooksController类

@Controller
@RequestMapping("/books")
public class BooksController {
//controller层调用service层

    @Autowired
    @Qualifier("BooksServiceImpl")
    private BooksService booksService;


    @RequestMapping("allbooks")
    public String allbooks(Model model){
        List<Books> books = booksService.queryAllBooks();

        model.addAttribute("listbooks",books);
        return "allbooks";
    }
}

5.filter层

GenericEncodingFilter类
这个类是网上的大佬写的,是解决乱码问题的

public class GenericEncodingFilter implements Filter {

    public void destroy() {
    }


    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 转型为与协议相关对象
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        // 对request包装增强
        HttpServletRequest myrequest = new MyRequest(httpServletRequest);
        response.setContentType("text/html;charset=utf-8");
        chain.doFilter(myrequest, response);
    }


    public void init(FilterConfig filterConfig) throws ServletException {
    }

}

// 自定义request对象
class MyRequest extends HttpServletRequestWrapper {

    private HttpServletRequest request;

    private boolean hasEncode;

    public MyRequest(HttpServletRequest request) {
        super(request);// super必须写
        this.request = request;
    }

    // 对需要增强方法 进行覆盖
    @Override
    public Map getParameterMap() {
        // 先获得请求方式
        String method = request.getMethod();
        if (method.equalsIgnoreCase("post")) {
            // post请求
            try {
                // 处理post乱码
                request.setCharacterEncoding("utf-8");
                return request.getParameterMap();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else if (method.equalsIgnoreCase("get")) {
            // get请求
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (!hasEncode) { // 确保get手动编码逻辑只运行一次
                for (String parameterName : parameterMap.keySet()) {
                    String[] values = parameterMap.get(parameterName);
                    if (values != null) {
                        for (int i = 0; i < values.length; i++) {
                            try {
                                // 处理get乱码
                                values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                hasEncode = true;
            }
            return parameterMap;
        }

        return super.getParameterMap();
    }

    @Override
    public String getParameter(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        if (values == null) {
            return null;
        }
        return values[0]; // 取回参数的第一个值
    }

    @Override
    public String[] getParameterValues(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        return values;
    }

}

需要在web.xml中注册filter,当然在web.xml中已经配置了Spring提供的乱码过滤处理,基本够用。所以大佬写的可以先注释掉。

    <!--乱码过滤处理,终极解决方案-->
<!--    <filter>-->
<!--        <filter-name>genericEncodingFilter</filter-name>-->
<!--        <filter-class>com.sdpei.filter.GenericEncodingFilter</filter-class>-->
<!--    </filter>-->
<!--    <filter-mapping>-->
<!--        <filter-name>genericEncodingFilter</filter-name>-->
<!--        <url-pattern>/*</url-pattern>-->
<!--    </filter-mapping>-->

6.utils层

这一层主要是我写的一些工具类,可能会用到所以就加上了

UUIDUtil工具类
其作用是获取随机的不会重复的ID,用法:UUIDUtil.getID()

public class UUIDUtil {
    public static  String getID(){
        return UUID.randomUUID().toString().replace("-", "");
    }
}

JacksonUtil工具类
对Jackson工具类的再封装,其作用是将Java对象转化成JDSON字符串

public class JacksonUtil {

    private static final String DEFAULT_DATE_FORM = "yyyy-MM-dd HH:mm:ss";

    //将基本的对象转成JSON字符串
    public static String toJSONString(Object o){
        return toJSONString(o,DEFAULT_DATE_FORM);
    }

    //将
    public static String toJSONString(Object o,String dateForm){
        ObjectMapper jaskson = new ObjectMapper();

        //将设置"打印时间为时间戳"的默认置为false
        jaskson.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);

        //设置打印日期的格式
        jaskson.setDateFormat(new SimpleDateFormat(dateForm));

        try {
            return jaskson.writeValueAsString(o);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

用法:

  1. JacksonUtil.toJSONString(Object o)
    将Java对象转化成JDSON字符串
  2. JacksonUtil.toJSONString(Date date)
    将Date对象转化成JDSON字符串,默认格式为yyyy-MM-dd HH:mm:ss
  3. JacksonUtil.toJSONString(Date date, “yyyy-MM-ddHH”)
    将Date对象转化成JDSON字符串,自定义格式为yyyy-MM-dd HH

MybatisUtil工具类
这个类用到的可能性不大,在学习spring整合mybatis时,spring中的对象SqlSessionFactory完全取代mybatis中的SqlSession对象。
这个类的作用是获取SqlSessionFactory对象

public class MybatisUtil {
    private static SqlSessionFactory sqlSessionFactory = null;

    static {
        try {
            // 从 XML 文件中构建 SqlSessionFactory 的实例
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
    // 可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }
}



五、结语

    我整合的这个SSM可以说已经是非常完善了,希望你可以保存下来,因为有很多的东西都是死的,所以当你在构建一个新的项目的时候,完全可以将这个整合好的SSM项目拿过来直接使用。

    我在学习的过程中,有一个非常大的体会。
    对于新的知识,我们学习过后很容易就忘了,尤其是对于框架而言,更是忘得极快。你应该养成一个坚持写博客的好习惯(尽量写的美观,当然这需要一个过程),当我们忘记什么知识之后,可以直接上自己的博客上拿来用。

    最后,恭喜你发现宝藏男孩一枚,希望你能关注,我并且是因为喜欢我。

在这里插入图片描述

百度网盘:https://pan.baidu.com/s/1C_D9fWJNLiCs3KyjRnfiTg
提取码:5u4q                                        
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值