通过查询书籍案例来演示

一:整合思路:

进行SSM框架整合时,3个框架的分工如下所示。

1.MyBatis负责与数据库进行交互。

2.Spring负责事务管理,Spring可以管理持久层的Mapper对象及业务层的Service对象。由Mapper对象和Service对象都在Spring容器中,所以可以在业务逻辑层通过Service对象调用持久层的Mapper对象。

3.Spring MVC负责管理表现层的Handler。Spring MVC容器是Spring容器的子容器,因此Spring MVC容器可以调用Spring容器中的Service对象。

二:搭建项目基础结构

1.首先需要在数据库中搭建项目对应的数据库环境;

CREATE TABLE book(
id INT,
name VARCHAR(32),
press VARCHAR(32),
author VARCHAR(32)
);
INSERT INTO book VALUES
(1,'Java EE企业级应用开发教程','人民邮电出版社','黑马程序员'),
(2,'第二本书名','第二本书作者','第二本书出版社'),
(3,'第三本书名','第三本书作者','第三本书出版社'); 

然后创建一个Maven Web项目略,并引入案例所需的依赖,依赖如下:

<?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>ssm-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- Spring 版本号 -->
        <spring.version>4.3.30.RELEASE</spring.version>
        <junit.version>4.12</junit.version>
        <spring-test.version>4.3.30.RELEASE</spring-test.version>
        <druid.version>1.1.8</druid.version>
    </properties>

    <dependencies>

        <!--spring-context : Spring上下文-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--spring-webmvc : Spring MVC核心-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring DAO 数据库相关依赖-->
        <!-- spring-jdbc包括了一些如jdbcTemplate的工具类 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!--mybatis依赖: MyBatis核心-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

        <!--mybatis-spring :MyBatis与Spring整合-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.4</version>
        </dependency>

        <!-- 数据源相关 druid : 阿里提供的数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>

        <!--mysql-connector-java : mysql的数据库驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

        <!--jsp-api : jsp页面使用request等对象-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>

        <!--servlet-api : java文件使用request等对象-->
        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5-20081211</version>
            <scope>provided</scope>
        </dependency>

        <!--测试依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-test.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>ssm-demo</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <path>/</path>
                        <port>888</port>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

最后创建项目的实体类:在项目的src\main\java目录下目录下创建一个con.itheima.pojo包下创建Book实体类

package com.itheima.pojo;

public class Book {
    
    private Integer id;
    
    private String name;
    
    private String press;
    
    private String author;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPress() {
        return press;
    }

    public void setPress(String press) {
        this.press = press;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", press='" + press + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

创建三层架构对应的模块、类和接口

(1)在项目的src\main\java目录下创建路径为com.itheima.mapper的类包,并在包下创建名称为BookMapper的持久层接口,在BookMapper接口中定义findBookById()方法,通过图书id获取对应的图书信息

package com.itheima.mapper;

import com.itheima.pojo.Book;

public interface BookMapper {
    /**
     * 根据id获取对应图书信息
     * @param id
     * @return
     */
    Book findBookById(Integer id);
}

(2)在项目的src\main\resources目录下创建路径为com\itheima\mapper的文件夹,并在文件夹下创建BookMapper接口对应的映射文件BookMapper.xml。 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.BookMapper">

    <select id="findBookById" resultType="com.itheima.pojo.Book">
        select * from book where id = #{id}
    </select>

</mapper>

(3)在项目的src\main\java目录下创建路径为com.itheima.service的类包,并在包下创建名称为BookService的业务层接口,在BookService接口中定义findBookById()方法,通过id获取对应的Book信息。

package com.itheima.service;

import com.itheima.pojo.Book;

public interface BookService {
    /**
     * 获取书籍详情
     * @param id
     * @return
     */
    Book findBookById(Integer id);
}

(4)在项目的src\main\java目录下创建路径为com.itheima.service.impl的类包,并在包下创建BookService接口的业务层实现类BookServiceImpl。BookServiceImpl类实现BookService接口的findBookById()方法,并在类中注入一个BookMapper对象。findBookById()方法通过注入的BookMapper对象调用findBookById()方法,根据id查询对应的图书信息。

package com.itheima.service.impl;
import com.itheima.mapper.BookMapper;
import com.itheima.pojo.Book;
import com.itheima.service.BookService;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author zxd
 * Description:@Service 指定一个业务逻辑组件Bean,用于将业务逻辑层的类标识为Spring中的Bean,功能上等同于@Component
 * @Autowired 指定要自动装配的对象
 * BookServiceImpl类实现BookService接口的findBookById()方法,并在类中注入一个BookMapper对象。
 * findBookById()方法通过注入的BookMapper对象调用findBookById()方法,根据id查询对应的图书信息。
 */
@Service
public class BookServiceImpl implements BookService {

    @Autowired
   private BookMapper bookMapper;

    /**
     * 获取书籍详情
     * @param id
     * @return
     */
    @Override
    public Book findBookById(Integer id) {
        // 处理业务逻辑
        Book book = bookMapper.findBookById(id);
        return book;
    }

}

(5)在项目的src\main\java目录下创建路径为com.itheima.controller的类包,并在包下创建名称为BookController的类。在BookController类中注入一个BookService对象,并且定义一个名称为findBookById()的方法。findBookById()方法获取传递过来的图书id,并将图书id作为参数传递给BookService对象调用的findBookById()方法。

package com.itheima.controller;

import com.itheima.pojo.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class BookController {

    @Autowired
    private BookService bookService;

    @GetMapping("book")
    public ModelAndView findBookById(Integer id) {
        Book book = bookService.findBookById(id);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("book.jsp");
        modelAndView.addObject("book", book);
        return modelAndView;
    }
}

至此,项目基础结构已经搭建完成,项目基础结构如图所示。

 

三:Spring和MyBatis的整合

  Spring和MyBatis的整合可以分为2步来完成,首先搭建Spring环境,然后整合MyBatis到Spring环境中。框架环境包含框架对应的依赖和配置文件,其中Spring的依赖、MyBatis的依赖、Spring和MyBatis整合的依赖,在项目基础结构搭建时候已经引入到项目中了,接下来,只需编写Spring的配置文件、Spring和MyBatis整合的配置文件即可。

1.Spring的配置文件: 

在项目的src\main\resources目录下创建配置文件application-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:context="http://www.springframework.org/schema/context"
       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">

    <!--开启注解扫描, 扫描包-->
    <context:component-scan base-package="com.itheima.service"/>

</beans>

2.Spring和MyBatis整合的配置:

Spring和MyBatis的整合包中提供了一个SqlSessionFactoryBean对象,该对象的Bean需要注入数据源,也可以根据需求在SqlSessionFactoryBean的Bean中配置MyBatis核心文件路径、别名映射和Mapper映射文件路径。在项目的src\main\resources目录下创建数据源属性文件jdbc.properties.

2.1:jdbc.properties配置的数据源信息如下所示。

# 这里是数据库的配置文件,根据你自己的来配置,我只是给了一个样板
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true
&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root

2.2:MyBatis自身的配置文件 mybatis-config.xml

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--这里是MyBatis自身的配置文件-->
<configuration>
    <settings>
        <!-- 开启日志 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <!-- 开启二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 将经典的SQL字段映射为Java驼峰命名变量-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!-- 别名 -->
    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>
    <!-- 映射注册 -->
    <mappers>
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>

2.3:spring和MyBatis的整合配置文件application-mapper.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--这里是用于整合MyBatis和Spring的配置文件-->
    <!--设置扫包-->
    <context:component-scan base-package="com.itheima.mapper"/>

    <!--1. 引入属性文件配置数据源和连接池-->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!-- 2. 将SqlSessionFactory交给Spring托管   -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="singleton">
        <!-- 加载数据环境   -->
        <property name="dataSource" ref="dataSource"/>
        <!--  绑定mybatis配置文件     -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--   几乎所有的东西都能在这里面配,完全不需要mybatis的核心配置-->
    </bean>

    <!--  3. 将SqlSession对象的加载交给Spring托管  -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 按照mybatis的习俗,通过工厂获得SqlSession会话对象       -->
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

    <!-- 4. Mapper 扫描器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.itheima.mapper"/>
    </bean>

</beans>

 四:Spring和MyBatis整合测试

在项目的src\main\test目录下的java文件夹中,创建名称为BookServiceTest的测试类,用于对Spring和MyBatis的整合进行测试。

import com.itheima.mapper.BookMapper;
import com.itheima.pojo.Book;
import com.itheima.service.BookService;

import com.itheima.utils.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:mybatis-config.xml", "classpath:application-service.xml",
        "classpath:application-mapper.xml"})
public class BookServiceTest {
    @Autowired
    private BookService bookService;

    @Test
    public void findBookById() {
        Book book = bookService.findBookById(1);
        System.out.println("图书id:" + book.getId());
        System.out.println("图书名称:" + book.getName());
        System.out.println("作者:" + book.getAuthor());
        System.out.println("出版社:" + book.getPress());
    }
}

控制台输出: 

五:Spring和SpringMVC整合

1.Spring的配置

之前Spring和MyBatis整合时,已经完成了Spring的配置文件,Spring和Spring MVC整合,只需在项目启动时加载Spring容器和Spring的配置文件即可。在项目的web.xml文件中配置Spring的监听器来加载Spring容器及Spring的配置文件,具体配置如下所示。

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
    <!--配置文件加载-->
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:application-*.xml</param-value>
    </context-param>
    <!--容器加载的监听器-->
    <listener>
      <listener-class>
        org.springframework.web.context.ContextLoaderListener
      </listener-class>
    </listener>
    
</web-app>

2.Spring MVC的配置

本案例主要测试SSM整合的情况,因此在Spring MVC的配置文件中只配置SSM整合案例必须的配置。必须配置的项有以下2个。    

配置包扫描,指定需要扫描到Spring MVC中的Controller层所在的包路径。    

配置注解驱动,让项目启动时启用注解驱动,并且自动注册HandlerMapping和HandlerAdapter。         在项目的src\main\resources目录下创建Spring MVC的配置文件spring-mvc.xml。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       	    http://www.springframework.org/schema/beans/spring-beans.xsd
       	    http://www.springframework.org/schema/mvc
       	    http://www.springframework.org/schema/mvc/spring-mvc.xsd
       	    http://www.springframework.org/schema/context
       	    http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置要扫描的包 -->
    <context:component-scan base-package="com.itheima.controller"/>
    <!-- 配置注解驱动 -->
    <mvc:annotation-driven/>

</beans>

spring-mvc.xml文件配置完成之后,在web.xml中配置Spring MVC的前端控制器,并在初始化前端控制器时加载Spring MVC的配置文件

<!--Spring MVC 前端控制器-->
    <servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <!--初始化参数 初始化前端控制器时加载Spring MVC的配置文件-->
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.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>

 六:SSM框架整合测试

接下来,通过在页面查询图书信息来测试SSM框架的整合情况。在项目的src\main\webapp目录下创建名称为book.jsp的文件,用于展示处理器返回的图书信息


<html>
<head>
    <title>图书信息查询</title>
</head>
<body>
<table border="1">
    <tr>
        <th>图书id</th>
        <th>图书名称</th>
        <th>出版社</th>
        <th>作者</th>
    </tr>
    <tr>
        <td>${ book.id }</td>
        <td>${book.name}</td>
        <td>${book.press}</td>
        <td>${book.author}</td>
    </tr>
</table>
</body>
</html>

八:结果测试

将项目部署到Tomcat中,启动项目,在浏览器中访问地址http://localhost:8080/book?id=1来进行图书查询,页面显示效果如图所示,

因为我自己设定的端口是888,所以我访问的是http://localhost:888/book?id=1

 遇到的问题:

1.java.lang.NullPointerException  at org.apache. jsp.index_jsp......空指针报错问题:

出现这种问题,可能有多方面的原因,最主要的就是自己工程里的jar包和tomca中的jar包冲突导致,我的处理方案是在

jsp页面使用request等对象加上范围<scope>provided</scope>
provided表明该包只在编译和测试的时候用
<!--jsp-api : jsp页面使用request等对象-->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2</version>
    <scope>provided</scope>
</dependency>

 2.jsp ${}获取不到对象

 jsp页面在浏览器中显示elb表达式为${xxx}形式,并没有显示为你后台设定的变量的值

解决方法:在<%page%>中添加 isELIgnored=“false” 即可

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>

所以应该修改pom.xml文件 和index.jsp文件这个整合才算成功

总结:

1.项目基础结构搭建

2.Spring和MyBatis整合

3.Spring和SpringMVC整合

4.测试完成

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐