Spring JDBC
一、 作用
方便我们操作数据库;
二、 基本使用
- 配置
首先配置数据源(加载数据库驱动类、数据库URL、用户名密码…..);
- 注册JDBC模板
即配置class=” org.springframework.jdbc.core.JdbcTemplate”的bean,我们需要使用该对象来对数据库进行操作;该bean需要配置dataSource属性,ref值为数据源bean;
- 通过继承JdbcDaoSupport类来使用jdbc模板
该类已经编写了JdbcTemplate字段,只要继承该类,并在配置中注入JdbcTemplate字段的JDBC模板bean引用,便可以在JdbcDaoSupport子类中使用jdbc模板了,使用方式为: this.getJdbcTemplate().增删改查方法...;
- 直接使用JdbcTemplate对象来操作数据库
即:JdbcTemplate 对象名 = Ioc容器对象名.getBean(“JDBC模板beanID”);
这样可以不继承JdbcDaoSupport类;
- 单行 增删改
this.getJdbcTemplate().update(sql语句, 参数1…,参数2,参数3,…..);
增删改都是使用.update方法,参数列表是可变的,可以有任意个;该方法有返回值,返回受影响的行数
- 批量 增删改
this.getJdbcTemplate().batchUpdate(sql语句, List<Objcet[]>参数);
其中List<Object[]>保存每行参数值(比如:list对象.add(new Object[]{id,”name”,”phone”}))
- 查询一列数据
一行:this.getJdbcTemplate().queryForObject(sql语句,数据类型.class,参数1,参数2,….);
多行:this.getJdbcTemplate().queryForList(sql语句,数据类型.class,参数1,参数2,….);
- 查询多列数据
this.getJdbcTemplate().queryForObject(sql, RowMapper对象, 参数1,参数2,….);
其中RowMapper对象是查询到的列与一个对象的映射;
创建RowMapper:
(1) RowMapper<对象> 实例名 =new BeanPropertyRowMapper<>(对象.class);
(2) 写一个类,实现RowMapper<T>接口,T为要映射的对象,该接口中有方法mapRow(ResultSet参数,int参数),其中ResultSet参数表示当前行,使用参数名.get基本数据类型(数据库列名/列号)获取到指定列,而第二个参数是当前行号;
(3) 无论是查询一行还是多行,Rowmapper会自动遍历,所有都用以上方法即可;
- 具名参数JDBC模板(NamedParameterJdbcTempate)
该JDBC模板与JdbcTemplate作用一致,但可以在SQL语句中需要写入的参数名与JDBC模板的增删改查方法中的参数名相对应
(0) 同样,需要先配置bean,该类的构造器是有参数的,配置时需要通过构造器注入方式把dataSource注入给它;
(1) 原本JdbcTemplate对象中的增删改查SQL语句需要参数时,就使用?号当作一个占位符,然后在方法中按sql语句参数顺序来写入参数;
例:sql=”select * from table where id=? and name=? ”
this.getJdbcTemplate().queryForObject(sql, RowMapper对象,id,name);
这里id和name参数的顺序要和sql语句中参数顺序一致
(2) 在具名参数JDBC模板中,用 :参数名 来占位,增删改差方法有一个map,该map键为sql语句中的参数名,值为需要操作的值;
例:sql=”select * from table where id=:id and name=:name ”
map.put(“id”,id值); map.put(“name”,name值);
具名参数JDBC模板对象.query(sql,map);
(3) 也可以使用.update(sql语句, SqlParameterSource对象)来操作;
其中:SqlParameterSource 对象名= new BeanPropertySqlParameterSource(对象实例);
这样可以将对象封装在一起,方便写入,需要注意的是,该方法sql语句占位符中名字需要和对象里的字段对应;
Spring 事务
〇、作用
- 事务具有ADID特性;
- 用来确保数据的完整性和一致性;
- 和数据库的事务是同一个意思;
- 其底层实现实质也是Java的动态代理
基于注解使用事务
- 使用事务时,需要引入spring-tx的jar包,配置文件里也要引入tx命名空间
1.在XML配置文件中配置事务管理器的bean,id随意,
class=” org.springframework.jdbc.datasource.DataSourceTransactionManager”
该bean还得配置dataSource属性;
2.启用事务注解
<tx:annotation-driven transaction-manager="transactionManager"/>
3.使用注解
在类的某一方法上写@Transactional,则该方法就使用了事务,里面的代码要么全部执行成功,要么就失败时回滚;
- 事务的传播行为
(0) 意义:指定一个事务方法被另一个事务方法调用时,应该如何传播;
(1) 例如:方法A是购买一张电影票;方法B里有个for循环调用方法A实现购买多张电影票;两个方法都实现了事务,当出现问题时(for到第二张时余额不足、电影票不足…),是应该全部失败回滚呢,还是余额不足那部分回滚?
(2) 默认地,出现问题时,是全部失败(即方法A(被调用方法)的事务挂起,在方法B(调用方法)的事务内运行);
(3) 也可以在被调用方法上的@Transactional内加上参数:
propagation=Propagation.REQUIRES_NEW
实现运行到被调用的方法A时,方法B就挂起(即余额不足那部分回回滚,余额与电影票充足的部分就购买成功);
(4) 需要注意,使用事务传播行为时,调用方法和被调用方法应在不同的类里;
- 事务的隔离级别
- 可在@Transactional内加上参数设置该事务方法的隔离级别 isolation=Isolation.级别
1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
另外四个与JDBC的隔离级别相对应
2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据
4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
- 指定回滚
- 事务默认回滚异常为运行时异常(即方法运行时异常时,事务就回滚)
- 可在@Transactional中加参数,指定哪些异常回滚,哪些异常不回滚
- noRollbackFor/ noRollbackForClassNama , rollbackFor/ rollbackForClassNama
前者不回滚,异常也会抛出,但修改了的数据不会回到执行前
后者指定哪些异常要回滚
- 指定超时时间
在@Transactional 内加入timeout参数(值为整数,单位秒),指定该事务方法执行的时间,当方法执行超时时,会抛出超时异常;
一、基于XML文件使用事务(AspectJ框架)
- bean的配置如常,事务管理器配置如上;
- 不需要写 启用事务注解 的标签了;
- 配置事务的属性(类似AspectJ AOP的切面)
<tx:advice id=”id随意” transaction-manager=”事务管理器的ID”>
<tx:attributes>
<tx:method name=”仅方法名(可用*号模糊匹配)” 各属性(比如传递、指定回滚、只读、超时….) propagation=”REQUIRES_NEW” />
….
若仅使用默认属性配置,则<tx:method name=”*” />
- 配置事务切入点(同AspectJ AOP),将方法、事务管理器和事务属性关联
<aop:config>
写切入点表达式<aop: expression……>
关联<aop:advisor advice-ref=”事务属性id” pointcut-ref=”切入点表达式id” />
二、基于XML文件使用事务(Spring 自带的Aop框架)
- bean的配置如常,事务管理器配置如上;
- 不需要写 启用事务注解 的标签了;
- 生成事务代理:
<bean id=”随意ID”
class=”org.springframework.transaction.interceptor.TransactionProxyFactoryBean”>
事务管理器<property name=”transactionManager” ref=”事务管理器beanID”>
目标对象<property name=” target” ref=”目标对象beanID” >
事务参数<property name=”transactionAttributes”>
<props>
<prop key=”目标对象里的方法(仅方法名,可用*模糊匹配)”>
各个参数值用逗号隔开(参数值比如PROPAGATION_RREQUIRED…)
</prop>
……
其它:一个props里可以有多个prop;
事务属性参数值请查阅API文档;
-异常类名 表示发生此异常时回滚,+异常类名 表示发生此异常时不回滚。
ps.请自行查阅开发过程中需要使用的jar包