文章摘要
一、Spring JDBC
Spring JDBC 是Spring框架用于处理关系型数据库的模块。Spring JDBC 模块的核心类是:jdbcTemplate,该类提供了数据的CRUD方法。
1.1、Spring JDBC的使用步骤:
1、Maven工程引入依赖:spring-jdbc 、 mysql的驱动
2、applicationContext.xml配置DataSource数据源
<!-- 数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/spring_jdbc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"></property>
<property name="username" value="XXXX"></property>
<property name="password" value="XXXX"></property>
</bean>
<!-- jdbcTemplate对象与底层数据源绑定-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="employeeDao" class="com.test.spring.jdbc.dao.EmployeeDao">
<!-- 为Dao注入JdbcTemplate对象-->
<property name="jdbcTemplate" ref="jdbcTemplate"></property>
</bean>
3、在Dao注入jdbcTemplate对象,实现数据CURD
public class EmployeeDao {
private JdbcTemplate jdbcTemplate;
······
······
·····
}
二、jdbcTemplate对象
2.1、查询数据的核心方法
jdbcTemplate.
queryForObject()
==> 返回一条对象
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;
}
jdbcTemplate.
query()
==> 返回符合范围内的对象
public List<Employee> findByDname(String dname){
String sql = "select * from employee where dname = ?";
//new BeanPropertyRowMapper<>() 《========》 属性和字段子之间的转换
List<Employee> list = jdbcTemplate.query(sql, new Object[]{dname}, new BeanPropertyRowMapper<Employee>(Employee.class));
return list;
}
jdbcTemplate.
queryForList()
==> 将查询结果作为Map进行封装
public List<Map<String, Object>> findMapByDname(String dname){
String sql = "select eno as eeid , salary as money from employee where dname = ?";
List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql, new Object[]{dname});
return maps;
}
2.2、写入数据的核心方法
jdbcTemplate.
update()
==> 实现数据写入操作
public void insert(Employee employee){
String sql = "insert into employee(eno,ename,salary,dname,hiredate) values(?,?,?,?,?)";
jdbcTemplate.update(sql,new Object[]{
employee.getEno() , employee.getEname() , employee.getSalary() , employee.getDname() , employee.getHiredate()
});
}
jdbcTemplate.
update()
==> 实现数据更新操作
public int update(Employee employee){
String sql = "update employee set ename = ? , salary = ? , dname = ? , hiredate = ? where eno = ?";
int count = jdbcTemplate.update(sql, new Object[]{employee.getEname()
, employee.getSalary(), employee.getDname(), employee.getHiredate(), employee.getEno()});
return count;
}
jdbcTemplate.
update()
==> 实现数据删除操作
public int delete(Integer eno){
String sql = "delete from employee where eno = ?";
int count = jdbcTemplate.update(sql, new Object[]{eno});
return count;
}
三、Spring 编程式事务
编程式事务是指:通过 代码手动提交或者回滚的事务控制方法。就是SpringJDBC通过TransactionManager事务管理器实现事务控制
。事务控制器提供commit / rollback方法进行事务提交与回滚。
1、配置文件中添加,相应的Bean
<!-- 编程式事务 ===>>> 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
//dataSource数据源
<property name="dataSource" ref="dataSource"></property>
</bean>
2、添加相应的代码
//定义了事务默认的标准配置
TransactionDefinition definition = new DefaultTransactionDefinition();
//开始一个事务,返回事务状态,事务状态说明当前事务的执行阶段
TransactionStatus status = transactionManager.getTransaction(definition);
try {
````````
```````
```````
``````
`````
//提交事务
transactionManager.commit(status);
} catch (RuntimeException e) {
//事务回滚
transactionManager.rollback(status);
throw e;
}
四、声明事务配置方式
在不修改源代码的情况下通过配置自动实现是悟空,声明事物本质就是AOP环绕通知
。当目标方法执行成功时,自动提交事务。当目标方法抛出运行时异常时,自动事务回滚。
1、pom文件添加 AspectJ依赖
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
2、写 applicationContext.xml 配置文件
<!-- 事务管理器,用于创建事务提交或者回滚-->
<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>
<!-- 当执行目标方法batchImport时,启动声明事务,成功提交、异常就回滚-->
<tx:method name="batchImport" propagation="REQUIRED"/>
<!-- 如果遇到查询方法,不开启事务,而且是只读的-->
<tx:method name="find*" propagation="NOT_SUPPORTED" read-only="true"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 设置 => 通知的范围-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.test..*Service.*(..))"/>
<!-- 把上面的 通知+切点(pointCut) 绑定在一起-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
五、七种事务传播行为
事务传播行为是指多个拥有事务的方法在嵌套调用时的事务控制方法。
六、注解配置声明式事务
1、配置applicationContex.xml
<!-- 开启扫描器-->
<context:component-scan base-package="com.test"/>
<!-- 数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/spring_jdbc?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true"></property>
<property name="username" value="root"></property>
<property name="password" value="yhl05711"></property>
</bean>
<!-- 初始化jdbcTemlate-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 启用注解形式声明式事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
2、添加注解:
@Transactional
//(propagation = Propagation.xxxxxxxxx,readOnly = true)
如果添加在类上,那么该类所有方法都会添加事务,默认事务传播为 REQUIRED。
也可以写在方法上,只对该方法有效。
方法上的注解优先级高于类上的注解。