全网疯传的Spring学习笔记【整合Mybatis和SpringMVC】,看完我也想写一个了!
十、Spring整合Mybatis
10.1、整合概述
JavaEE开发需要持久层来进行访问数据库的操作,但是现有的持久层开发过程中存在大量的代码冗余,不方便我们开发和后期维护,而Spring基于模板设计模似对于上述的持久层技术进行了封装,方便了我们的开发和减少了代码冗余。
10.2、传统Mybatis编码存在的问题
MyBatis开发步骤回顾:
- 编写实体类。
- 配置实体别名。
- 创建表。
- 创建DAO接口。
- 实现Mapper文件。
- 注册Mapper文件。
- MyBatis的API的调用。
我们在开发MyBatis的时候可以发现,传统的MyBatis的开发有一个很致命的弊端:配置繁琐且代码冗余。于是我们需要Spring这个超级工厂来进行整合。
10.3、整合思路
10.4、代码实现
MyBatis整合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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///javaweb?characterEncoding=utf-8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1101121833"/>
</bean>
<!-- 创建SqlSessionFactory、创建SqlSessionFactoryBean-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 别名-->
<property name="typeAliasesPackage" value="com.lin.domain"/>
<!-- mapper配置文件路径-->
<property name="mapperLocations">
<list>
<value>classpath:com/lin/mapper/*Mapper.xml</value>
</list>
</property>
</bean>
<!-- Dao对象的创建-->
<bean id="scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- sqlSessionFactoryBean对象-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
<!-- Dao接口的位置-->
<property name="basePackage" value="com.lin.mapper"/>
</bean>
</beans>
/**
* 用于测试Spring与Mybatis整合
*/
@Test
public void testSpringMybatis(){
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext(
"/applicationContext.xml");
UserMapper userMapper = (UserMapper) app.getBean("userMapper");
List<User> users = userMapper.queryAll();
System.out.println(users);
}
10.5、注意
- Spring与Mybatis整合的时候,为什么不提交事物,但是我们插入数据的时候依然可以插入到数据可呢?
分析:本质上谁控制了链接对象,谁就可以提交事物。连接对象是由连接池来获取的:
1. MyBatis提供的连接池对象:他将Connection.setAutoCommit的值从默认值true设置成为了false,所以导致无法自动提交,手动控制事物,需要在操作完成后,手工提交事务。
2. Druid(C3P0、DBCP)提供的连接池对象:Connection.setAutoCommit的值为默认值true,保持自动控制事物,自动提交。
- 在未来实际开发中,一般都是多条sql一起成功或者一起失败,我们还是需要手动提交。但是后续我们会把事物交给Spring通过事物控制来解决。
10.6、Spring的事物处理
10.6.1、事物概述
保证业务操作完整性的一种数据库机制。具有四个特性:A(原子性)、C(一致性)、I(隔离性)、D(持久性)。
常见的两种持久化技术的事物控制:
-
JDBC (依赖于Connection对象来进行事物控制)
Connection.setAutoCommit(false);
Connection.commit();
Connection.rollback();
-
MyBatis(自动提交事务)
sqlSession.commit();
sqlSession.rollback();
-
结论:控制事物的底层都是Connection对象来控制的(sqlSession的底层也是Connection)。
10.6.2、编码实现
<!-- 配置原始对象-->
<bean id="userService" class="com.lin.service.impl.UserServiceImpl">
<property name="userMapper" ref="userMapper"/>
</bean>
<!-- 额外功能,Spring帮我们封装好了一个对象DataSourceTransactionManager,简化我们的开发-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 先注入数据源,获取链接对象,进而才可以控制事物-->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 组装切面-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
@Transactional // 切入点,给谁加入事物
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
@Override
public List<User> queryAll() {
return userMapper.queryAll();
}
}
十二、Spring整合MVC
12.1、依赖准备
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.13</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.8</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<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/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</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.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
12.2、为什么要整合MVC框架
因为有很多的需求和功能是原生的Spring框架无法解决的,需要MVC框架来简化我们的开发。常用的MVC框架有:SpringMVC、Struts2、Struts1、jsf、webwork(除了第一个其他的都被淘汰了)。
- MVC框架提供了控制器(Controller),用来调用Service层。
- 请求响应的处理。
- 接受请求参数。
- 控制程序的运行流程。
- 视图解析(JSP、JSON、Freemarker、Thyemeleaf)
12.3、Spring整合MVC框架的核心思路
准备工厂
1. Web开发过程中如何创建工厂
ApplicationContext ctx = new WebXmlApplication("/applicationContext.xml");
2. 如何保证工厂被共用同时保证唯一性
被共用:在Web中有四个作用于:request、session、ServletContext(application),我们可以把工厂存储到ServletContext这个作用域中。
唯一性:我们可以利用ServletContextListener这个监听器,因为在ServletContext对象创建的同时,ServletContextListener会被调用且只被调用一次。所以我们可以把工厂创建的代码写在ServletContextListener中,这样就保证了唯一性。
3. 总结
我们首先在ServletContextListener这个监听器中书写创建工厂的代码,其次将这个工厂放在ServletContext对象中。
4. Spring的封装
既然这些代码如此繁琐,那么Spring肯定会帮我们封装好了。
5. ContextLoaderListener类
Spring封装了一个ContextLoaderListener类,他的作用是创建工厂和将工厂放进ServletContext对象中。
配置文件
既然Spring帮我们封装好了一个ContextLoaderListener类,那么我们直接按照监听器在web.xml中进行配置即可。
<!---我们只需要在web.xml中进行配置即可-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--告诉Spring我们的配置文件在哪里-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
代码整合
代码整合的核心是依赖注入,将控制器需要的Service对象注入到控制器对象中。
- 点赞
- 收藏
- 关注作者
评论(0)