通过查询书籍案例来演示
一:整合思路:
进行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.测试完成