目录
前言
上一节我们学习了Spring AOP相关知识,接下来我们继续学习Spring JDBC技术。
学习内容
什么是Spring JDBC?
- Spring JDBC是Spring框架用于处理关系型数据库的模块;
- Spring JDBC对JDBC API进行封装,极大简化开发工作量;
- JdbcTemplate是Spring JDBC的核心类,提供数据的CRUD方法;
Spring JDBC使用步骤
- Maven工程中引入依赖spring-jdbc;
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
- applicationContext.xml配置DataSource数据源;
<!-- 数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/imooc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<!--JdbcTemplate提供数据CRUD的API-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
- 在Dao注入JdbcTemplate对象,实现数据CRUD;
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
public Employee findById(Integer eno){
String sql = "select * from employee where eno = ?";
//查询单条数据
Employee employee = jdbcTemplate.queryForObject(sql, new Object[]{eno}, new BeanPropertyRowMapper<Employee>(Employee.class));
return employee;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
<bean id="employeeDao" class="com.imooc.spring.jdbc.dao.EmployeeDao">
<!--为Dao注入JdbcTemplate对象-->
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
运行结果:
JdbcTemplate数据查询
查询单条数据
查询多条数据
- 直接使用query
- 使用Map封装
JdbcTemplate数据写入
- 新增数据
- 修改数据
- 删除数据
编程式事务管理
- 编程式事务是指通过代码手动提交回滚事务的事务控制方法
- SpringJDBC通过TranscationManager事务管理器实现事务控制
- 事务管理器提供commit/rollback方法进行事务提交与回滚
<bean id="employeeService" class="com.imooc.spring.jdbc.service.EmployeeService">
<property name="employeeDao" ref="employeeDao"/>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
public class EmployeeService {
private EmployeeDao employeeDao;
private DataSourceTransactionManager transactionManager;
public void batchImport(){
//定义了事务默认的标准配置
TransactionDefinition definition = new DefaultTransactionDefinition();
//开始一个事务,返回事务状态,事务状态说明当前事务的执行阶段
TransactionStatus status = transactionManager.getTransaction(definition);
try {
for (int i = 1; i <= 10; i++) {
/*if (i == 3) {
throw new RuntimeException("意料之外的异常");
}*/
Employee employee = new Employee();
employee.setEno(8000 + i);
employee.setEname("员工" + i);
employee.setSalary(4000f);
employee.setDname("市场部");
employee.setHiredate(new Date());
employeeDao.insert(employee);
}
//提交事务
transactionManager.commit(status);
}catch (RuntimeException e){
//回滚事务
transactionManager.rollback(status);
throw e;
}
}
public EmployeeDao getEmployeeDao() {
return employeeDao;
}
public void setEmployeeDao(EmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
public DataSourceTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(DataSourceTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
}
分析:
这时候我们执行操作的时候要么全部插入,要么一条都不插入,因为数据是以事务的方式进行提交的。
声明式事务管理
- 声明式事务是指在不修改源代码的情况下通过配置形式自动实现事务控制,声明式事务的本质是AOP环绕通知
- 当目标方法执行成功时,自动提交事务
- 当目标方法抛出异常时,自动回滚事务
-
配置TranscationManager事务管理器
-
配置事务通知与事务属性
<!-- 1.事务管理器,用于创建事务/提交/回滚 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--2.事务通知配置,决定哪些方法使用事务,哪些方法不使用事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 目标方法名为batchImport时,启用声明式事务,成功提交,运行时异常回滚 -->
<tx:method name="batchImport" propagation="REQUIRED"/>
<tx:method name="batch*" propagation="REQUIRED"/>
<!-- 设置所有findXXX方法不需要使用事务 -->
<tx:method name="find*" propagation="NOT_SUPPORTED" read-only="true"/>
<tx:method name="get*" propagation="NOT_SUPPORTED" read-only="true"/>
<tx:method name="importJob1" propagation="REQUIRES_NEW"/>
<tx:method name="importJob2" propagation="REQUIRES_NEW"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
- 为事务绑定PointCut切点
<!--3. 定义声明式事务的作用范围-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
事务传播行为
- 事务传播行为是指多个拥有事务的方法在嵌套调用时的事务控制方式
- XML:<tx:method name="…" propagation=“REQUIRES_NEW”/>
- 注解:@Transactional(propagation=Propagation.REQUIRED)
注解形式声明事务
- 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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
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/tx
https://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.imooc"/>
<!--数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/imooc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<!--JdbcTemplate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 启用注解形式声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
总结
本节我们学习了Spring JDBC与JdbcTemplate对象的使用以及编程式事务和声明式事务相关知识,欢迎评论区交流~