SSM:Spring + Spring MVC + MyBatis 的整合

发布时间:2024年01月24日

在这里插入图片描述

前言

在完成 Spring 、Spring MVC 与 MyBatis 基础知识的学习后,下面简单介绍 SSM 框架的整合使用。

整合

SSM,是 Java 开发中常用的一个 Web 框架组合,用于构建基于 Spring 和 MyBatis 的 Web 应用( Spring MVC 是 Spring 框架的扩展)。

简单示例:
首先,创建一个 Maven 工程( Web 项目)后,在 pom.xml 中添加依赖

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>compile</scope>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.3.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>5.3.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>5.3.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>

  <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.3</version>
    <scope>provided</scope>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.6</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-nop</artifactId>
    <version>2.0.6</version>
    <type>jar</type>
  </dependency>

  <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
  <dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-impl -->
  <dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-impl</artifactId>
    <version>1.2.5</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.apache.taglibs/taglibs-standard-spec -->
  <dependency>
    <groupId>org.apache.taglibs</groupId>
    <artifactId>taglibs-standard-spec</artifactId>
    <version>1.2.5</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.25</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
  <dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
  <dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
    <version>1.4.0</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.mybatis.caches/mybatis-ehcache -->
  <dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
  </dependency>

  <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.3.2</version>
  </dependency>
</dependencies>

<!--   UserMapper.xml 配置文件写在 src 找不到问题解决方案     -->
<build>
  <resources>
    <resource>
      <!-- directory:指定资源文件的位置 -->
      <directory>src/main/java</directory>
      <includes>
        <!-- “**”:表示任意级目录    “*”:表示任意任意文件 -->
        <!-- mvn resources:resources :对资源做出处理,先于 compile 阶段  -->
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <!--  filtering:开启过滤,用指定的参数替换 directory 下的文件中的参数(eg. ${name}) -->
      <filtering>false</filtering>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
    </resource>
  </resources>
</build>

项目结构如图:
在这里插入图片描述

接着,在 webapp/WEB-INF 目录下的 web.xml 配置文件中,对 spring 和 springmvc 进行初始化配置

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

  <!-- 配置整个 web 应用的初始化参数,指定 spring 的配置文件所在位置 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>
  <!-- spring 与 javaweb 应用的整合 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 配置前端控制器 dispatcherServlet -->
  <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>
    <!-- 配置初始化参数,启动时创建 servlet 对象 -->
    <load-on-startup>1</load-on-startup>
  </servlet>

  <!-- 配置url地址 -->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <!-- 根目录下所有地址,其他 servlet 除外 -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

同时,在 resources 目录下创建 spring.xml 和 springmvc.xml 配置文件,并且进行相关配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
       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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">

    <!-- spring.xml -->
    <!-- 指定排除扫描 Controller 和 ControllerAdvice 包,避免与 springmvc 扫描重复 -->
    <context:component-scan base-package="cn.edu.ssmdemo">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
    </context:component-scan>

    <!-- 在 Bean 的外部属性文件的使用中有所提及 -->
    <!-- 使用context命名空间,通过 location 属性指定 properties 文件位置 -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 连接MySQL数据库的基本信息的配置 -->
        <!-- 驱动程序类名:com.mysql.jdbc.Driver -->
        <property name="driverClass" value="${jdbc.driverClass}" />
        <!-- JDBC URL:jdbc:mysql://<host>:<port>/<database_name> -->
        <property name="jdbcUrl" value="${jdbc.url}" />
        <!-- 数据库用户名 -->
        <property name="user" value="${jdbc.user}" />
        <!-- 数据库用户密码 -->
        <property name="password" value="${jdbc.password}" />
        <!-- 若数据库中的连接数量不足时,向数据库申请的连接数量 -->
        <property name="acquireIncrement" value="${acquireIncrement}" />
        <!-- 初始化数据库连接池时连接的数量 -->
        <property name="initialPoolSize" value="${initialPoolSize}" />
        <!-- 数据库连接池最小的数据库连接数 -->
        <property name="minPoolSize" value="${minPoolSize}" />
        <!-- 数据库连接池最大的数据库连接数 -->
        <property name="maxPoolSize" value="${maxPoolSize}" />
        <!-- C3P0数据库连接池可以维护的Statement数量 -->
        <property name="maxStatements" value="${maxStatements}" />
        <!-- 每个连接同时可以使用Statement的数量 -->
        <property name="maxStatementsPerConnection" value="${maxStatementsPerConnection}" />
    </bean>

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

    <!-- 配置事务属性 -->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager" >
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="load*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="select*" read-only="true"/>
            <tx:method name="*" read-only="false"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置事务切入点 -->
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* cn.edu.ssmdemo.service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
    </aop:config>

    <!-- 配置 mybatis 整合 -->
    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" >
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis.xml" />
        <property name="mapperLocations" value="classpath:cn/edu/ssmdemo/mapper/*.xml" />
    </bean>

    <mybatis-spring:scan base-package="cn.edu.ssmdemo.mapper" />
</beans>
<?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.xml -->
    <!-- 指定只扫描 Controller 和 ControllerAdvice 包 -->
    <context:component-scan base-package="cn.edu.ssmdemo" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
    </context:component-scan>

    <mvc:annotation-driven />

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

    <!-- 配置自动识别静态资源 -->
    <mvc:default-servlet-handler />
</beans>

另外,在 spring.xml 配置文件中,还要相应文件的创建与配置。在 resources 目录下再创建 jdbc.properties 资源文件和 mybatis.xml 配置文件,并且进行相关配置

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmdemo?useSSL=false&serverTimezone=UTC
jdbc.user=root
jdbc.password=0123
acquireIncrement=5
initialPoolSize=10
minPoolSize=5
maxPoolSize=100
maxStatements=2
maxStatementsPerConnection=5
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC
        "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">

<!-- mybatis.xml 配置文件 -->
<configuration>

    <settings>
        <!-- 懒加载配置 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>

        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <!-- typeAliases:设置别名,简化类型名称的书写。用一个别名代替一个类全名 -->
    <typeAliases>
        <package name="cn.edu.ssmdemo.model" />
    </typeAliases>

    <!-- plugins 标签需要在 environments 标签前 -->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
    </plugins>
</configuration>

然后,在 resources 目录下创建一个 Generator 的配置文件 mybatis_generator.xml ,并且进行相关配置

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

<generatorConfiguration>

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

        <commentGenerator>
            <!-- 是否去除自动生成的注释 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!-- MySQL数据库连接的信息:驱动类、连接地址、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/ssmdemo?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;serverTimezone=UTC"
                        userId="root"
                        password="0123" >
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>

        <!-- Java 类型解析器,一般默认为 false -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- Domain 生成器:生成实体类。属性 targetProject :生成 POJO 类的位置;其余默认 -->
        <javaModelGenerator targetPackage="cn.edu.ssmdemo.model" targetProject=".\src\main\java" />

        <!-- Mapping 生成器:生成映射文件。属性 targetProject :mapper 映射文件生成的位置;其余默认 -->
        <sqlMapGenerator targetPackage="cn.edu.ssmdemo.mapper" targetProject=".\src\main\java">
            <!-- enableSubPackages :是否让 schema 作为包的后缀 -->
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- Mapper 生成器:生成接口。targetProject 属性:mapper 接口生成的的位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="cn.edu.ssmdemo.mapper" targetProject=".\src\main\java">
            <!-- enableSubPackages :是否让 schema 作为包的后缀 -->
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!-- 指定数据表。tableName 属性:指定数据库的表名;domainObjectName 属性:生成对应实体类的名字;...Example 属性:设置关闭即可 -->
        <table tableName="user"
               domainObjectName="User"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false" />
    </context>

</generatorConfiguration>

再在 MySQL 数据库 ssmdemo 中,创建数据表 user
表结构信息如图:
在这里插入图片描述

随之,在 test 目录下创建 RunSSMGenerator 类,通过数据库表结构自动生成对应的实体类、DAO 接口和 SQL 映射文件

package cn.edu.ssmdemo.test;

import org.junit.Test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class RunSSMGenerator {
    @Test
    public void mbgTest() throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;

        // 只需修改 Generator 的配置文件名称即可
        String path = this.getClass().getClassLoader().getResource("mybatis_generator.xml").getPath();
        File configFile = new File(path);

        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);
    }
}

运行生成实体类、DAO 接口和 SQL 映射文件后,接下来只实现 selectByPrimaryKey(Integer id) 方法作为简单的演示:
1.在 service 层创建接口 UserService

package cn.edu.ssmdemo.service;

import cn.edu.ssmdemo.model.User;

//简单示例
public interface UserService {
    User selectByPrimaryKey(Integer id);
}

2.在 service 层创建接口实现类 UserServiceImpl

package cn.edu.ssmdemo.service;

import cn.edu.ssmdemo.mapper.UserMapper;
import cn.edu.ssmdemo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public User selectByPrimaryKey(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }
}

3.在 controller 层创建 UserController 类获取指定用户信息并放在视图上

package cn.edu.ssmdemo.controller;

import cn.edu.ssmdemo.model.User;
import cn.edu.ssmdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/user")
    public String user(Model model){
        User user = userService.selectByPrimaryKey(20230903);
        model.addAttribute("user",user);
        System.out.println("用户信息:" + user);
        return "user";
    }
}

4.在 webapp/WEB-INF/views 目录下创建对应的视图 user.jsp

<%--
  Created by IntelliJ IDEA.
  User: dell
  Date: 2023/9/3
  Time: 18:18
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
    用户信息:${user}
</body>
</html>

最后,启动 JRebel ,测试结果
在这里插入图片描述

结果如图:
在这里插入图片描述

文章来源:https://blog.csdn.net/qq_56886142/article/details/132631148
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。