Spring/Spring MVC/MyBatis整合详解
本文引用自:《Java EE企业级应用开发教程》
由于Spring MVC只是Spring框架中的一个模块,所以Spring MVC与Spring之间不存在整合的问题,只需要引入相应Jar包就可以直接使用。因此,Spring/Spring MVC/MyBatis的整合,只涉及Spring与MyBatis的整合,以及Spring MVC与MyBatis的整合。
首先,定义三大框架的版本:
- Spring 5.2.3(注意:Spring框架的所有Jar包版本必须保持一致,否则会发生不可预料的错误!)
- Spring MVC 5.2.3
- MyBatis 3.5.2
其它附件的版本:
- log4j 1.2.17
- mysql 5.1.49
- mybatis-spring 1.3.1
这些Jar包的引入地址,可以参考:https://mvnrepository.com/
一、准备所需要的Jar包
1.1 Spring核心包
commons-logging-1.2.jar Spring需要用它记录日志(第三方包) spring-beans-5.2.3.RELEASE.jar SpringIoC(依赖注入)的基础实现 spring-context-5.2.3.RELEASE.jar Spring提供在基础IoC功能上的扩展服务,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等 spring-core-5.2.3.RELEASE.jar Spring核心包 spring-expression-5.2.3.RELEASE.jar Spring表达式语言 spring-aop-5.2.3.RELEASE.jar Spring的面向切面编程,提供AOP(面向切面编程)实现
1.2 Spring的JDBC相关包
spring-jdbc-5.2.3.RELEASE.jar JDBC驱动包 spring-tx-5.2.3.RELEASE.jar 事务管理 commons-dbcp2-2.1.1.jar 数据源所需 commons-pool2-2.4.2.jar 数据源所需
1.3 Spring的aspectj相关包(可选 ,本节用不到)
aopalliance-1.0.jar AspectJ包(三个) aspectjrt-1.9.5.jar aspectjweaver-1.8.7.jar
1.4 Spring MVC相关包
spring-webmvc-5.2.3.RELEASE.jar spring-web-5.2.3.RELEASE.jar
1.5 MyBatis相关包
mybatis-3.5.2.jar ant-1.10.3.jar ant-launcher-1.10.3.jar asm-7.0.jar cglib-3.2.10.jar commons-logging-1.2.jar javassist-3.24.1-GA.jar log4j-1.2.17.jar log4j-api-2.11.2.jar log4j-core-2.11.2.jar ognl-3.2.10.jar slf4j-api-1.7.26.jar slf4j-log4j12-1.7.26.jar
1.6 其它包
mysql-connector-java-5.1.49-bin.jar MySQL数据库驱动 mybatis-spring-1.3.1.jar Spring与MyBatic整合包
1.7 pom.xml文件参考
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ssm</groupId> <artifactId>ssm</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>ssm</name> <description /> <properties> <webVersion>4.0</webVersion> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.servlet.jsp.jstl</artifactId> <version>1.2.4</version> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <!-- spring-context这个包囊括:spring-aop/spring-beans/spring-core/spring-expression --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.17.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency> <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance --> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.17.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.17.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <!-- spring-jdbc这个包囊括: spring-beans/spring-core/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.3.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <!-- mybatis这个包囊括: cglib (optional)/commons-logging (optional) /log4j (optional)/ognl (optional)/log4j-core (optional) /javassist (optional)/slf4j-api (optional)/slf4j-log4j12 (optional) --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <!-- junit这个包囊括: hamcrest-core --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.9.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.11.1</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.5</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.12.5</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.12.5</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>oraclejdbc</groupId> <artifactId>oraclejdbc</artifactId> <version>4.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/ojdbc6.jar</systemPath> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> <resources> <resource> <directory>lib</directory> <targetPath>/WEB-INF/lib/</targetPath> <includes> <include>**/*.jar</include> </includes> </resource> </resources> </build> </project>
注意:本配置文件额外引用lombok、junit、jackson、fileupload、oraclejdbc(本地引用)等相关包;不需要的,请自行删除。
二、创建配置文件
2.1 创建db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/xuejia?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 jdbc.username=root jdbc.password=admin jdbc.maxTotal=30 jdbc.maxIdle=10 jdbc.initialSize=5
2.2 创建log4j.properties
# Global logging configuration log4j.rootLogger=ERROR, stdout # MyBatis logging configuration... log4j.logger.com.itheima=DEBUG # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
2.3 创建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" 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 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!-- 读取db.properties --> <context:property-placeholder location="classpath:db.properties" /> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <!--数据库驱动 --> <property name="driverClassName" value="${jdbc.driver}" /> <!--连接数据库的url --> <property name="url" value="${jdbc.url}" /> <!--连接数据库的用户名 --> <property name="username" value="${jdbc.username}" /> <!--连接数据库的密码 --> <property name="password" value="${jdbc.password}" /> <!--最大连接数 --> <property name="maxTotal" value="${jdbc.maxTotal}" /> <!--最大空闲连接 --> <property name="maxIdle" value="${jdbc.maxIdle}" /> <!--初始化连接数 --> <property name="initialSize" value="${jdbc.initialSize}" /> </bean> <!-- 事务管理器,依赖于数据源 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 开启事务注解 --> <tx:annotation-driven transaction-manager="transactionManager" /> <!-- 配置MyBatis工厂SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--注入数据源 --> <property name="dataSource" ref="dataSource" /> <!--指定核MyBatis心配置文件位置 --> <property name="configLocation" value="classpath:mybatis-config.xml" /> </bean> <!-- 配置mapper扫描器 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.itheima.dao" /> </bean> <!-- 扫描Service --> <context:component-scan base-package="com.itheima.service" /> </beans>
该文件中,首先根据db.properties的信息配置数据源;然后配置事务管理器并开启事务注解;接下来配置整合MyBatis框架的MyBatis工厂信息,最后定义mapper扫描器来扫描DAO层以及扫描Service层的配置。
2.4 创建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> <!-- 别名定义 --> <typeAliases> <package name="com.itheima.po" /> </typeAliases> </configuration>
由于在Spring中已经配置数据源信息以及mapper接口文件扫描器,所以在MyBatis的配置文件中只需要根据POJO类路径进行别名配置即可。
2.5 创建springmvc-config.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 配置包扫描器,扫描@Controller注解的类 --> <context:component-scan base-package="com.itheima.controller" /> <!-- 加载注解驱动 --> <mvc:annotation-driven /> <!-- 配置视图解析器 --> <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
该文件中,主要配置用于扫描@Controller注解的包扫描器、注解驱动器以及视图解析器。
2.6 创建web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <!-- 配置加载Spring文件的监听器--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 编码过滤器 --> <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>*.action</url-pattern> </filter-mapping> <!-- 配置Spring MVC前端核心控制器 --> <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:springmvc-config.xml</param-value> </init-param> <!-- 配置服务器启动后立即加载Spring MVC配置文件 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!--/:拦截所有请求(除了jsp)--> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
该文件中,配置Spring的文件监听器、编码过滤器以及Spring MVC的前端控制器等信息。
三、创建各种程序
3.1 创建PO类
package com.itheima.po; /** * 客户持久化类 */ public class Customer { private Integer id; // 主键id private String username; // 客户名称 private String jobs; // 职业 private String phone; // 电话 public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getJobs() { return jobs; } public void setJobs(String jobs) { this.jobs = jobs; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
此实体类对应的数据库SQL语句为:
CREATE TABLE `t_customer` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `USERNAME` varchar(45) NOT NULL, `JOBS` varchar(45) DEFAULT NULL, `PHONE` varchar(45) DEFAULT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
3.2 创建Dao类,及其对应的映射文件(同一个package)
CustomerDao.java
package com.itheima.dao; import com.itheima.po.Customer; /** * Customer接口文件 */ public interface CustomerDao { /** * 根据id查询客户信息 */ public Customer findCustomerById(Integer id); }
CustomerDao.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.dao.CustomerDao"> <!--根据id查询客户信息 --> <select id="findCustomerById" parameterType="Integer" resultType="Customer"> select * from t_customer where id = #{id} </select> </mapper>
说明:配置文件applicationContext.xml,已经配置mapper扫描器扫描com.itheima.dao包下的所有接口及映射文件,所以此处完成DAO层接口及映射文件开发后,工作即告一段落。
3.3 创建service接口类,及其实现类
CustomerService.java
package com.itheima.service; import com.itheima.po.Customer; public interface CustomerService { public Customer findCustomerById(Integer id); }
CustomerServiceImpl.java
package com.itheima.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.itheima.dao.CustomerDao; import com.itheima.po.Customer; import com.itheima.service.CustomerService; @Service @Transactional public class CustomerServiceImpl implements CustomerService { //注解注入CustomerDao @Autowired private CustomerDao customerDao; //查询客户 public Customer findCustomerById(Integer id) { return this.customerDao.findCustomerById(id); } }
该文件中,使用@Service注解来标识业务层的实现类,使用@Transactional注解来标识类中所有方法都纳入Spring的事务管理,并使用@Autowired注解将CustomerDao对象注入到本类中,然后在本类的查询方法中调用CustomerDao对象的查询客户方法。
注:@Transactional注解主要针对数据的增加、修改、删除,此处仅为说明使用。
3.4 创建控制器类
package com.itheima.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import com.itheima.po.Customer; import com.itheima.service.CustomerService; @Controller public class CustomerController { @Autowired private CustomerService customerService; /** * 根据id查询客户详情 */ @RequestMapping("/findCustomerById") public String findCustomerById(Integer id,Model model) { Customer customer = customerService.findCustomerById(id); model.addAttribute("customer", customer); //返回客户信息展示页面 return "customer"; } }
该文件中,使用@Controller注解来标识控制器类,然后通过@Autowired注解将CustomerService接口对象注入到本类中,最后编写一个根据id查询客户的方法findCustomerById,并将结果返回到视图名为customer的JSP页面中。
3.5 创建JSP页面customer.jsp,位于:WEB-INF\jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>客户信息</title> </head> <body> <table border=1> <tr> <td>编号</td> <td>名称</td> <td>职业</td> <td>电话</td> </tr> <tr> <td>${customer.id}</td> <td>${customer.username}</td> <td>${customer.jobs}</td> <td>${customer.phone}</td> </tr> </table> </body> </html>
四、测试,打开页面:http://localhost:8080/ssm/findCustomerById?id=1
结果如上图所示。