目录
4.5.2.1.2 事务管理器 — PlatformTransactionManager 接口
4.5.2.1.3 TransactionDefinition
4.5.4.2.1 SqlSessionFactoryBean
4.5.4.2.5 MapperScannerConfigurer
4.5.5.1 ApplicationContext应用上下文获取方式
4.5.1 JdbcTemplate
4.5.1.1 JdbcTemplate概述
4.5.1.1.1 什么是JdbcTemplate
Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作,持久层框架
4.5.1.1.2 导入坐标
由于spring-jdbc 依赖于spring-tx、spring-bean、spring-core,所以只需要导入spring-jdbc即可。
另外注意版本冲突问题,spring-jdbc版本要与spring版本一致。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
4.5.1.2 手动管理JdbcTemplate
4.5.1.2.1 C3P0
c3p0
{
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
comboPooledDataSource.setDriverClass("com.mysql.jdbc.Driver");
comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
comboPooledDataSource.setUser("root");
comboPooledDataSource.setPassword("123456");
JdbcTemplate jdbcTemplate = new JdbcTemplate(comboPooledDataSource);
}
增删改查操作
public void insert(){
String sql="insert into student (sid,sname,age,phone) values(?,?,?,?)";
jdbcTemplate.update(sql,1,"sd",27,"123456");
}
public void update(){
String sql="update student set sname=? where sid=? ";
jdbcTemplate.update(sql,"老大",2);
}
//注意JdbcTemplate的查询方法里面定义了类,可以返回指定泛型的list
public void select(){
String sql="select * from student";
List<Student> student = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Student>(Student.class));
System.out.println(student);
}
4.5.1.2.2 Druid
Druid
DruidDataSource dds = new DruidDataSource();
dds.setDriverClassName("com.mysql.jdbc.Driver");
dds.setUrl("jdbc:mysql://localhost:3306/mydb");
dds.setUsername("root");
dds.setPassword("123456");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dds);
增删改查操作一样。
4.5.1.3 Spring管理JdbcTemplate
手动配置有些麻烦,我们可以偷懒,将JdbcTemplate、数据源DataSource都交由Spring创建。
在Spring容器内部将数据源DataSource注入到JdbcTemplate模版对象中,然后通过Spring容器获得JdbcTemplate对象来执行操作。
以druid为例,首先我们先分析druid连接池的配置
DruidDataSource dds = new DruidDataSource(); dds.setDriverClassName("com.mysql.jdbc.Driver"); dds.setUrl("jdbc:mysql://localhost:3306/mydb"); dds.setUsername("root"); dds.setPassword("123456");
JdbcTemplate jdbcTemplate = new JdbcTemplate();
dbcTemplate.setDataSource(dds);
//也可以直接 JdbcTemplate jdbcTemplate = new JdbcTemplate(dds);
我们将本来由自己new的DruidDataSource、JdbcTemplate交由Spring创建。(IOC)
DruidDataSource有三个set属性,因此dds依赖注入基本类型,(DI)
JdbcTemplate只有一个set属性,而且传入的是引用类型,因此jdbcTemplate依赖注入引用类型。(DI)
applicationContext_JdbcTemplate.xml
<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/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:property-placeholder location="jdbc.properties"/>
<!--将druid交由Spring 并注入依赖-->
<bean id="druid" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--将JdbcTemplate交由Spring 并注入依赖,注意,这里的依赖是引用型,注入的是druid-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="druid"></property>
</bean>
</beans>
测试
@Test
public void test() {
ClassPathXmlApplicationContext cpxac= new ClassPathXmlApplicationContext("applicationContext_JdbcTemplate.xml");
JdbcTemplate jdbcTemplate = (JdbcTemplate) cpxac.getBean("jdbcTemplate");
//执行sql语句
String sql="select * from student";
List<Student> student = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Student>(Student.class));
System.out.println(student);
}
4.5.2 Spring事务
4.5.2.1 概述
4.5.2.1.1
详细事务知识点 【点击跳转 《2.1数据库-MySQL》】
Spring 支持两种事务方式,分别是编程式事务和声明式事务,常使用声明式事务(注解方式)
Spring通过事务管理器、事务管理类的实现类来管理事务
Spring的事务是一个统一的模型
(1)指定要使用的事务管理器实现类,使用<bean>
(2)指定哪些类,哪些方法需要加入事务的功能
(3)指定方法需要的事务的隔离级别、传播行为、超时时间。
4.5.2.1.2 事务管理器 — PlatformTransactionManager 接口
里面提供了常用的操作事务的方法。
方法 | 说明 |
TransactionStatus getTransaction(TransactionDefination defination) | 获取事务的状态信息 |
void commit(TransactionStatus status) | 提交事务 |
void rollback(TransactionStatus status) | 回滚事务 |
注意:
PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,例如: Dao 层技术是jdbc 或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager
Dao 层技术是hibernate时:org.springframework.orm.hibernate5.HibernateTransactionManager
4.5.2.1.3 TransactionDefinition
TransactionDefinition :事务的定义信息对象
事务的定义包括: 事务的隔离级别,事务的传播行为,超时时间,是否只读 。
一般不修改使用默认即可。
方法 | 说明 |
int getIsolationLevel ( ) | 获得事务的隔离级别 |
int getPropogationBehavior() | 获得事务的传播行为 |
int getTimeout() | 获得超时时间 |
booolean isReadOnly() | 是否只读 |
1、事务的隔离级别
隔离级别 | 说明 |
DEFAULT | 使用数据库默认的隔离级别 |
READ_UNCOMMITTED | 读未提交 |
READ_COMMITTED | 读已提交 |
REPEATABLE_READ | 可重复读 |
SERIALIZABLE | 串行化 |
通过以下设置事务隔离级别
ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITTED
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
2、事务的传播行为
行为 | 说明 |
REQUIRED | 默认值。 若当前没有事务,就新建一个事务,如果存在事务,就加入到这个事务中。 |
SUPPORTS | 支持当前事务,如果没有事务,就以非事务方式执行 |
MANDATORY | 使用当前事务,如果没有事务,就抛出异常 |
REQUIRES_NEW | 新建事务,如果当前已存在有事务,就把当前事务挂起 |
NOT_SUPPORTES | 以非事务的方式执行操作,如果当前存在事务,就把当前事务挂起 |
NEVER | 以非事务的方式运行,如果当前存在事务,抛出异常 |
NESTED | 如果当前存在事务,则嵌套在事务内执行。如果当前没有事务,则执行REQUIRED类似的操作 |
3、超时时间
默认值是-1,没有超时限制。如果有,以秒为单位进行设置
4、是否只读
建议查询时设置为只读
4.5.2.1.4 TransactionStatus
TransactionStatus 接口提供的是事务具体的运行状态,TransactionStatus继承SavepointManager接口,SavepointManager是对事务中上述保存点功能的封装。
SavepointManager
public interface SavepointManager {
Object createSavepoint() throws TransactionException;
void rollbackToSavepoint(Object savepoint) throws TransactionException;
void releaseSavepoint(Object savepoint) throws TransactionException;
}
TransactionStatus本身更多存储的是事务的一些状态信息
方法 | 说明 |
boolean hasSavepoint() | 是否存储回滚点 |
boolean isCompleted() | 事务是否完成 |
boolean isNewTransaction() | 是否是新事物 |
boolean isRollbackOnly() | 事务是否回滚 |
4.5.2.2 基于 XML 的声明式事务控制
4.5.2.2.1 声明式事务控制
在以前,我们每次都要提交事务、回滚,都要书写代码实现,太麻烦了。学习spring后,我们将事务也交由spring管理。
Spring 的声明式事务:采用声明的方式来处理事务。
声明:指在配置文件中声明,用在 Spring 配置文件中声明式的处理事务来代替编程式的处理事务。
事务管理不会影响到代码,事务服务的开启与关闭,只需在配置文件中修改,无需改变代码重新编译 。
明确三个关键点:
切点:service层实现类的所有方法,只有service层才可能同时调用多个Dao层一起执行。
通知:增强方法,前置通知:关闭自动提交开启事务;后置通知:关闭连接;异常通知:回滚;最终通知:提交。
切面:事务管理器,由于spring已经将通知的工作都做好了,但是不能按spring的配置方式配置,而是有自己的一套配置方式。
Spring 声明式事务控制底层就是AOP
4.5.2.2.2 引入tx命名空间
<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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
配置事务增强
<!--平台事务管理器-->
<!-- 将spring提供的事务管理器交由spring容器管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 进行事务管理 所以需要将允许使用的数据源注入
事务管理会对数据源进行监听 因为需要在连接处开启事务
-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--事务增强配置-->
<!-- 用于配置指定方法进行增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 对切点表达式匹配的方法 额外进行事务的配置 -->
<!-- 精确到方法 可以为每个方法配置不同的事务配置
name:用于指定配置的方法 * 代表所有方法
isolation:用于配置当前方法 使用的事务隔离级别 默认default根据数据库决定
propagation:用于配置当前方法 使用事务的传播方式 默认REQUIRED 没有事务创建事务 已有事务加入事务
timeout:用于配置当前方法 使用事务的超时时间 单位秒 默认-1 不超时
read-only:应用于配置当前方法 执行事务是否为只读 默认是false 建议查询功能使用
-->
<tx:method name="*" />
<tx:method name="updatePasswordByUid" isolation="DEFAULT" propagation="REQUIRED" timeout="-1" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- sprinng事务底层使用的是aop 所以配置事务 就是配置aop织入关系 -->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* com.bl.serviceimpl.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"></aop:advisor>
</aop:config>
@Override
public void transfer(String user_out, String user_in, double money) {
accountDao.transout(user_out,money);
//模拟报错
System.out.println(1/0);
accountDao.transin(user_in,money);
}
4.5.2.3 基于注解的声明式事务控制
<!-- spring事务使用注解开发很简单 只需要开启注解驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
①使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离级别、传播行为等。
②注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。
③使用在方法上,不同的方法可以采用不同的事务参数配置。
④Xml配置文件中要开启事务的注解驱动<tx:annotation-driven />
4.5.3 Spring整合MyBatis
4.5.3.1 概述
MyBatis是一个优秀的基于ORM的半自动轻量级持久层框架。Spring虽然有自己的持久化框架,但是仍然可以整合Mybatis框架。
Spring会管理MyBatis的配置,其中mybatis-spring.jar 是关键。
- mybatis-spring会用将 MyBatis 代码整合到 Spring 中
- Spring 将会加载必要的 MyBatis 工厂类和 Session 类
- 提供一个简单的方式来注入 MyBatis 数据映射器和 SqlSession 到业务层的 bean 中
- 方便集成 Spring 事务
- 翻译 MyBatis 的异常到 Spring 的 DataAccessException 异常(数据访问异常)中
另外我们需要考虑Mybatis-Spring 兼容性,我们在选择Spring、MyBatis以及mybatis-spring时,应注意版本之间的兼容性。
MyBatis-Spring | MyBatis | Spring框架 |
2.0 | 3.5+ | 5.0+ |
1.3 | 3.4+ | 3.2.2+ |
4.5.4 Spring与MyBatis整合
4.5.4.1 整合步骤
导入坐标
<?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>com.bl</groupId>
<artifactId>spring1128</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring1128 Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<!-- 版本配置抽离 通过${标签名获取} -->
<my.spring>5.3.18</my.spring>
<my.mybatis>3.5.6</my.mybatis>
<my.mybatis-spring>2.0.6</my.mybatis-spring>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- mybatis与spring整合 -->
<!-- spring相关jar包 -->
<!-- spring核心jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${my.spring}</version>
</dependency>
<!-- spring数据库操作jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${my.spring}</version>
</dependency>
<!-- srpingAOP动态织入jar包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<!-- mybatis相关jar包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${my.mybatis}</version>
</dependency>
<!-- mysql连接jar包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- mybatis与spring整合jar包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${my.mybatis-spring}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root
jdbc.password=123456
# 初始化大小,最小,最大
initialSize=10
minIdle=6
maxActive=50
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>
<!-- mybatis与spring整合后 大部分都交由spring进行配置
mybatis核心配置文件中只需要配置settings(几乎不配置)
-->
<settings>
<!-- 缓冲配置 -->
<setting name="cacheEnabled" value="true"/>
<!-- 懒加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 缓冲区配置 -->
<setting name="localCacheScope" value="SESSION"/>
<!-- 打印sql日志 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<typeAliases>
<package name="com.bl.javabean"/>
</typeAliases>
</configuration>
注意:
mybatis文件与之前不同,之前在mybatis-config.xml中配置数据库连接的,现在要把这些放在spring的配置文件中,所以mybatis配置文件中只写setting配置
spring.xml配置文件
<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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 引入外部properties配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 开启spring组件扫描 实现IOC注解开发-->
<context:component-scan base-package="com.bl"/>
<!-- 将druid连接池(数据源)交由spring容器管理 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="initialSize" value="${initialSize}"/>
<property name="minIdle" value="${minIdle}"/>
<property name="maxActive" value="${maxActive}"/>
</bean>
<!-- 将mybatis会话工厂对象交由spring容器管理 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 配置mapper映射文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!-- mybatis.spring自动映射,DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bl.mapper"/>
</bean>
<!--平台事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开启事务控制的注解支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 开启aop自动代理 -->
<aop:aspectj-autoproxy/>
</beans>
StudentMapper接口
public interface StudentMapper {
ArrayList<Student> selectAllStudent();
}
StudentMapper.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.bl.mapper.StudentMapper">
<select id="selectAllStudent" resultType="com.bl.javabean.Student">
select * from student
</select>
</mapper>
测试类
public class StudentTest {
static ClassPathXmlApplicationContext applicationContext;
static{
applicationContext= new ClassPathXmlApplicationContext("spring.xml");
}
@Test
public void test(){
StudentMapper student = applicationContext.getBean(StudentMapper.class);
ArrayList<Student> students = student.selectAllStudent();
}
}
4.5.4.2 说明
4.5.4.2.1 SqlSessionFactoryBean
在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的。 而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建。
<!-- 将mybatis会话工厂对象交由spring容器管理 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 配置mapper映射文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
4.5.4.2.2 DataSource
SqlSessionFactory 有一个唯一的必要属性:用于 JDBC 的 DataSource。这可以是任意的 DataSource 对象,它的配置方法和其它 Spring 数据库连接是一样的。
4.5.4.2.3 configLocation
一个常用的属性是 configLocation,它用来指定 MyBatis 的 XML 配置文件路径。它在需要修改 MyBatis 的基础配置非常有用。通常,基础配置指的是<settings> 或 <typeAliases> 元素。 需要注意的是,这个配置文件并不需要是一个完整的 MyBatis 配置。确切地说,任何环境配置(<environments>),数据源(<DataSource>)和 MyBatis 的事务管理器(<transactionManager>)都会被忽略。SqlSessionFactoryBean 会创建它自有的 MyBatis 环境配置(Environment),并按要求设置自定义环境的值。
如果 MyBatis 在映射器类对应的路径下找不到与之相对应的映射器 XML 文件,那么也需要配置文件。这时有两种解决办法:第一种是手动在 MyBatis 的 XML 配置文件中的 <mappers> 部分中指定 XML 文件的类路径;第二种是设置工厂 bean 的 mapperLocations 属性。
4.5.4.2.4 mapperLocations
mapperLocations 属性接受多个资源位置。这个属性可以用来指定 MyBatis 的映射器 XML 配置文件的位置。属性的值是一个 Ant 风格的字符串,可以指定加载一个目录中的所有文件,或者从一个目录开始递归搜索所有目录。
4.5.4.2.5 MapperScannerConfigurer
basePackage MapperScannerConfigurer:有一个重要的属性basePackage用于扫描映射指定包下所有的mapper映射接口,mybatis执行时会与已经加载的mapper对应的xml进行映射调用相应的方法执行sql语句返回结果
4.5.5 Spring与Web环境集成
spring总归是要在web项目上运行的。
4.5.5.1 ApplicationContext应用上下文获取方式
应用上下文对象是通过new ClasspathXmlApplicationContext(spring配置文件) 方式获取的,但是每次从容器中获得Bean时都要编写new ClasspathXmlApplicationContext(spring配置文件) ,这样的弊端是配置文件加载多次,应用上下文对象创建多次。
在Web项目中,可以使用ServletContextListener监听Web应用的启动,我们可以在Web应用启动时,就加载Spring的配置文件,创建应用上下文对象ApplicationContext,在将其存储到最大的域servletContext域中,这样就可以在任意位置从域中获得应用上下文ApplicationContext对象了。
4.5.5.2 Spring提供获取应用上下文的工具
Spring提供了一个监听器ContextLoaderListener就是对上述功能的封装,该监听器内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象。
所以我们需要做的只有两件事:
①在web.xml中配置ContextLoaderListener监听器(导入spring-web坐标)当服务启动时加载
②使用WebApplicationContextUtils获得应用上下文对象ApplicationContext
4.5.5.3 集成步骤
Spring集成web环境步骤:
- 配置ContextLoaderListener监听器
- 使用WebApplicationContextUtils获得应用上下文
- spring-web提供的监听器spring-webmvc也会提供(同时使用会冲突)
将项目配置成web项目:配置tomcat
导入Spring和SpringMVC的坐标、导入Servlet和Jsp的坐标
<!--Spring坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--SpringMVC坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
<!--Jsp坐标-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
<!-- Servlet坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
在web.xml配置全局参数和监听器
<!--全局参数-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--Spring的监听器-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
测试
@WebServlet(name = "TestServlet", value = "/my")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
WebApplicationContext spring = WebApplicationContextUtils.getWebApplicationContext(servletContext);
StudentMapper student = spring.getBean(StudentMapper.class);
student.selectAllStudent();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}