SSM框架分为Spring、Spring MVC、Mybatis,去前面我们分别学习了这三个部分,现在我们来整理一下如何成功的整合这三部分以达到完整的SSM框架。
0.环境
首先来配一下环境,IDEA2020,Maven项目,这些就不说了,主要看一下依赖:
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0-M1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
</dependencies>
1.前期配置
配置applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
这里我们先什么都不配,来看下一步,在src下建立controller、mapper、pojo、service四个包,分别对应Servlet、Dao、DoMain、Service这四个部分。
简单的Demo
因为处理事务的原因,所以简单的写一个Demo用来说明,我们需要一个数据库,Demo用来实现图书数据的增删改查。
数据库准备
首先建立一个数据库,以及数据:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for books
-- ----------------------------
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
`bookID` int(10) NOT NULL AUTO_INCREMENT,
`bookName` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`bookCounts` int(11) NOT NULL,
`detail` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`bookID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of books
-- ----------------------------
INSERT INTO `books` VALUES (1, 'Java', 1, '从入门到放弃');
INSERT INTO `books` VALUES (2, 'Mysql', 10, '从入门到放弃');
INSERT INTO `books` VALUES (3, 'Linux', 5, '从入门到放弃');
SET FOREIGN_KEY_CHECKS = 1;
pojo准备
接下来在pojo包中建立Books类:
package com.test.pojo;
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
public Books() {
}
public Books(int bookID, String bookName, int bookCounts, String detail) {
this.bookID = bookID;
this.bookName = bookName;
this.bookCounts = bookCounts;
this.detail = detail;
}
public int getBookID() {
return bookID;
}
public void setBookID(int bookID) {
this.bookID = bookID;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public int getBookCounts() {
return bookCounts;
}
public void setBookCounts(int bookCounts) {
this.bookCounts = bookCounts;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
@Override
public String toString() {
return "Books{" +
"bookID=" + bookID +
", bookName='" + bookName + '\'' +
", bookCounts=" + bookCounts +
", detail='" + detail + '\'' +
'}';
}
}
前期准备就绪,现在我们可以开始整合了。
2.整合Mybatis
Mapper接口
有了pojo实体类后就应该编写接口来定义方法:
package com.test.mapper;
import com.test.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookMapper {
public int addBook(Books books);
public int deleteBookById(@Param("bookID") int id);
public int updateBook(Books books);
public List<Books> queryBooks();
public Books queryBooksById(@Param("bookID")int id);
}
我们简简单单的编写五个方法,实现增删改查的功能。
mybatis-config.xml
有了接口接下来我们需要建立mybatis-config.xml注册接口,因为使用Spring,所以mybatis-config的大部分工作交给Spring去做,mybatis-config中只需要注册mapper接口和实现别名就可以:
<?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>
<typeAliases>
<package name="com.test.pojo"/>
</typeAliases>
<mappers>
<mapper class="com.test.mapper.BookMapper"/>
</mappers>
</configuration>
数据库配置文件
编写database.properties文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&charsetEncoding=utf8
jdbc.username=#你的账号#
jdbc.password=#你的密码#
Spring接管mybatis
使用Spring接管Mybatis的大部分工作,建立spring-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"
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:property-placeholder location="classpath:database.properties"/>
<!--<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"></bean>-->
<!--数据库连接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--c3p0私有属性-->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!--关闭连接后不自动commit-->
<property name="autoCommitOnClose" value="false"/>
<!--获取连接超时时间-->
<property name="checkoutTimeout" value="10000"/>
<!--连接失败重试次数-->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!--SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定Mybatis的配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--配置dao接口扫描包,动态实现dao接口注入到Spring中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--要扫描的dao包-->
<property name="basePackage" value="com.test.mapper"/>
</bean>
</beans>
我们并没有使用Spring自带的DriverManagerDataSource来做连接池,而是使用了c3p0,这是因为c3p0比较方便。
BookMapper.xml文件
接下来就可以编写sql语句了:
<?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.test.mapper.BookMapper">
<insert id="addBook" parameterType="Books">
insert into ssmbuild.books (bookID, bookName, bookCounts, detail)
values (#{bookID}, #{bookName}, #{bookCounts}, #{detail});
</insert>
<delete id="deleteBookById" parameterType="int">
delete from ssmbuild.books where bookID = #{id};
</delete>
<update id="updateBook" parameterType="Books">
update ssmbuild.books
set bookName = #{bookName}, bookCounts = #{bookCounts}, detail = #{detail}
where bookID = #{bookID};
</update>
<select id="queryBooks" resultType="Books">
select * from ssmbuild.books;
</select>
<select id="queryBookById" parameterType="int" resultType="Books">
select * from ssmbuild.books where bookID = #{bookID};
</select>
</mapper>
3.整合service
service接口
有了DAO层,接下来就是Service层,同样的,建立接口:
package com.test.service;
import com.test.pojo.Books;
import java.util.List;
public interface BookService {
public int addBook(Books books);
public int deleteBookById(int id);
public int updateBook(Books books);
public List<Books> queryBooks();
public Books queryBooksById(int id);
}
接口实现类
有了接口就要建立实现类:
package com.test.service;
import com.test.mapper.BookMapper;
import com.test.pojo.Books;
import java.util.List;
public class BookServiceImpl implements BookService {
//service层调DAO层
private BookMapper mapper;
public BookServiceImpl() {
}
public BookServiceImpl(BookMapper mapper) {
this.mapper = mapper;
}
public BookMapper getMapper() {
return mapper;
}
public void setMapper(BookMapper mapper) {
this.mapper = mapper;
}
@Override
public String toString() {
return "BookServiceImpl{" +
"mapper=" + mapper +
'}';
}
public int addBook(Books books) {
return mapper.addBook(books);
}
public int deleteBookById(int id) {
return mapper.deleteBookById(id);
}
public int updateBook(Books books) {
return mapper.updateBook(books);
}
public List<Books> queryBooks() {
return mapper.queryBooks();
}
public Books queryBooksById(int id) {
return mapper.queryBooksById(id);
}
}
Spring注入Service
有了Service就可以使用Spring来做注入:
<?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">
<!--扫描Service下的包-->
<context:component-scan base-package="com.test.service"/>
<!--将业务类注入到Spring,通过注解或者配置-->
<bean id="BookServiceImpl" class="com.test.service.BookServiceImpl">
<property name="mapper" ref="bookMapper"/>
</bean>
<!--声明式事务配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
配置applicationContext.xml
不要忘记applicationContext.xml需要修改,不然dataSource注入不了:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<import resource="classpath:spring-mapper.xml"/>
<import resource="classpath:spring-service.xml"/>
</beans>
4.整合SpringMVC
配置web.xml
首先将普通的Maven项目变成一个Web项目,添加Web Framework support,变为web项目后来配置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">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
配置spring-mvc.xml
在web.xml中配置DispatcherServlet,filter,session,接下来配置mvc:
<?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
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--扫描包-->
<context:component-scan base-package="com.test.controller"/>
<!--注解驱动-->
<mvc:annotation-driven/>
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
配置applicationContext.xml
当然配置后就要修改applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:spring-mapper.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
BookController
最后就到了Controller层:
package com.test.controller;
import com.test.pojo.Books;
import com.test.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
//controller层调service层
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
@RequestMapping("/allBook")
public String list(Model model){
List<Books> books = bookService.queryBooks();
model.addAttribute("list", books);
return "allBook";
}
}
直接使用@Qualifier注入Service,接下来该写页面了。
jsp页面
因为Demo主要是为了整合SSM框架,所以页面功能就不做细节,简单实现就可,首先是allBook.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示</title>
</head>
<body>
<h1>书籍展示</h1>
${list}
</body>
</html>
接下来是index.jsp入口页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allBook">进入书籍页面</a>
</h3>
</body>
</html>
5.细节
这里有几个小细节,我们要注意一下:
Not used ‘webapp’
我们使用的是普通Maven项目+web framework support,这样做的好处是基本不会出错,一切都可以根据我们自己来选,但是这样也会有问题,就是artifacts目录下的WEB-INF目录中没有lib目录,所以我们要手动添加:
然后将所有的jar全部添加,apply,ok,就可以了。
配置Tomcat
最后就是配置Tomcat:
6.总结
结构
这是最后的文件结构,大家可以核对一下自己的:
效果
以及最终的效果:
SSM整合就这么多东西,其余的如拦截器,功能实现,前端页面等,都可以直接把这个框架拿过去修改,完全没有问题,接下来就该找时间将上次给我爸做的那个商品管理系统使用SSM重构一下,我们下次见👋