Spring之采用不继承JdbcDaoSupport的方式完成对数据库的操作、Spring事务
采用不继承JdbcDaoSupport的方式完成对数据库的操作
需要自己定义一个JdbcTemplate类型的对象(在applicationContext.xml文件中定义组件对象),然后注入给DAO的实现类.使用自定义的模板对象完成对应的数据库操作。当然自定义模板对象也需要注入dataSource。
-
查询银行账户表中的账户的数量
建立一张银行账户表,插入几条测试数据,提交
1
2
3
4
5
6
7
8
9
10
11create table xdl_bank_account_30(
id number constraint xdl_bank_account_30_id_pk
primary key,
acc_no varchar(30) constraint xdl_bank_account_30_acc_no_uk
unique,
acc_password varchar(30),
acc_money number
);
insert into xdl_bank_account_30 values(1,'liweijie','123',1234567);
insert into xdl_bank_account_30 values(2,'canglaoshi','123',123);
commit;建立一个项目导入jar包(ioc、aop、dao、连接池、数据库驱动),拷贝配置文件applicationContext.xml到src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.xdl"/>
<!-- 连接池对象的配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" >
<value>oracle.jdbc.OracleDriver</value>
</property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl">
</property>
<property name="username" value="raoweijia">
</property>
<property name="password" value="123">
</property>
</bean>
<!-- 创建一个JdbcTemplate 对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg index="0" ref="dataSource"></constructor-arg>
</bean>
</beans>编写DAO接口,查询银行账户表中的账户的数量
1
2
3public interface XdlBankAccountDAO {
int getAccountCount();
}编写DAO的实现类,实现DAO接口,使用自己定义一个JdbcTemplate类型的对象提供的模板结合sql语句完成查询
开启组件,在DAO实现类上打持久层标注,同时要给JdbcDaoSupport注入一个dataSource对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.xdl.dao.XdlBankAccountDAO;
public class XdlBankAccountDAOOracleImp implements XdlBankAccountDAO {
private JdbcTemplate jdbcTemplate;
public int getAccountCount() {
String sql = "select count(*) from xdl_bank_account_30";
return jdbcTemplate.queryForObject(sql, Integer.class);
}
}创建Spring容器,获取DAO并进行测试
1
2
3
4
5
6
7
8
9
10
11
12import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xdl.bean.XdlBankAccount;
import com.xdl.dao.XdlBankAccountDAO;
public class XdlBankAccountDAOTest {
public static void main(String[] args) {
ApplicationContext app =
new ClassPathXmlApplicationContext("applicationContext.xml");
XdlBankAccountDAO dao = app.getBean("accountDao",XdlBankAccountDAO.class);
System.out.println(dao.getAccountCount());
}
} -
根据账号查询银行账户
建立一张银行账户表,插入几条测试数据,提交 同上
建立一个项目,导入jar包(ioc、aop、dao、连接池、数据库驱动),拷贝配置文件到src 同上
编写一个名字XdlBankAccount的bean文件下的类
编写DAO接口,加入根据账号查询银行账户的方法
1
2
3public interface XdlBankAccountDAO {
XdlBankAccount getAccountByAccNo(String acc_no);
}编写XdlBankAccountMapper类实现RowMapper接口,把得到的结果集转换成对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14import com.xdl.bean.XdlBankAccount;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
// 把结果集转换成对象
public class XdlBankAccountMapper implements RowMapper<XdlBankAccount> {
public XdlBankAccount mapRow(ResultSet rs, int index) throws SQLException {
XdlBankAccount account = new XdlBankAccount(rs.getInt("id"),
rs.getString("acc_no"), rs.getString("acc_password"),
rs.getDouble("acc_money"));
return account;
}
}编写DAO的实现类继承JdbcDaoSupport实现DAO接口,使用父类提供的模板结合sql语句完成查询 同上
开启组件扫描在DAO实现类上打持久层标注,同时要给JdbcDaoSupport注入一个dataSource对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class XdlBankAccountDAOOracleImp extends JdbcDaoSupport implements XdlBankAccountDAO {
private JdbcTemplate jdbcTemplate;
public XdlBankAccount getAccountByAccNo(String acc_no) {
String sql = "select * from xdl_bank_account_30 where acc_no = ?";
try {
return jdbcTemplate.query(sql, new XdlBankAccountMapper(),
acc_no);
} catch (DataAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}创建Spring容器,获取DAO并进行测试
1
2
3
4
5
6
7
8
9
10
11
12import com.xdl.dao.XdlBankAccountDAO;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class XdlBankAccountDAOTest {
public static void main(String[] args) {
ApplicationContext app =
new ClassPathXmlApplicationContext("applicationContext.xml");
XdlBankAccountDAO dao = app.getBean("accountDao",XdlBankAccountDAO.class);
XdlBankAccount account = dao.getAccountByAccNo("liweijie");
System.out.println(account);
}
} -
根据账号给某个账户增加指定的钱数
建立一张银行账户表,插入几条测试数据,提交 同上
建立一个项目,导入jar包(ioc、aop、dao、连接池、数据库驱动),拷贝配置文件到src 同上
编写一个名字XdlBankAccount的bean文件下的类
编写DAO接口,加入根据账号查询银行账户的方法
1
2
3public interface XdlBankAccountDAO {
int updateAccountInMoney(XdlBankAccount to,double money);
}编写DAO的实现类继承JdbcDaoSupport实现DAO接口,使用父类提供的模板结合sql语句完成查询 同上
开启组件扫描在DAO实现类上打持久层标注,同时要给JdbcDaoSupport注入一个dataSource对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class XdlBankAccountDAOOracleImp extends JdbcDaoSupport implements XdlBankAccountDAO {
private JdbcTemplate jdbcTemplate;
public int updateAccountInMoney(XdlBankAccount to, double money) {
String sql = "update xdl_bank_account_30 set acc_money = acc_money + ? "
+ "where acc_no = ?";
try {
return jdbcTemplate.update(sql, money,to.getAcc_no());
} catch (DataAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 0;
}
}创建Spring容器,获取DAO并进行测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14import com.xdl.dao.XdlBankAccountDAO;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class XdlBankAccountDAOTest {
public static void main(String[] args) {
ApplicationContext app =
new ClassPathXmlApplicationContext("applicationContext.xml");
XdlBankAccountDAO dao = app.getBean("accountDao",XdlBankAccountDAO.class);
XdlBankAccount account = dao.getAccountByAccNo("liweijie");
int f1 = dao.updateAccountInMoney(account, 1);
account = dao.getAccountByAccNo("liweijie");
System.out.println(account);
}
}
Spring事务
提供了两种种事务管理方式:编程式事务管理和声明式事务管理
Spring编程式事务管理
1 | public class SimpleService implements Service { |
Spring的声明式事务
Spring声明式事务管理,是使用Spring的AOP方式实现的。
通过Spring配置将操作纳入到事务管理中,解除了事务管理和代码的耦合;不需要事务管理时,可直接从Spring配置文件中移除.
-
在Spring的配置文件中开启声明式事务
1
<tx:annotation-driven transaction-manager="事务管理器id" proxy-target-class="false" />
proxy-target-class默认使用SUN公司的代理机制,如果产生不了,则启用CGLIB;如果proxy-target-class="true"则直接使用CGLIB的代理机制
-
创建事务管理器组件 – 注意这个组件需要依赖于dataSource
1
2
3
4<!-- 创建事务管理器 -->
<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> -
在类上或者在业务方法加事务控制标注@Transactional
加在类上就是所有的方法都有事务控制
加在业务方法上,就要方法内的所有语句都要同时成立.
转账逻辑的实现
在src下的applicationContext.xml配置文件开启声明事务和创建事务管理器
1 | <!-- 开启声明式事务 --> |
在之前的DAO接口,加入根据账号查询银行账户的方法
1 | public interface XdlBankAccountDAO { |
编写DAO的实现类继承JdbcDaoSupport实现DAO接口,使用父类提供的模板结合sql语句完成查询 同上
开启组件扫描在DAO实现类上打持久层标注,同时要给JdbcDaoSupport注入一个dataSource对象
1 |
|
创建Service类,输入业务方法
1 | import org.springframework.beans.factory.annotation.Autowired; |
创建Spring容器,获取DAO并进行测试
1 | import org.springframework.context.ApplicationContext; |
@Transactional的属性
在使用时可以根据需要做特殊设定。声明式事务默认对检查异常不回滚,运行异常回滚
propagation: 设置事务传播
一个方法调用事务方法时,事务应该如何表现
1 | 如:@Transactional(propagation=Propagation.REQUIRED) |
isolation : 设置事务隔离级别,系统默认级别读提交
如:@Transactional(isolation=Isolation.SERIALIZABLE)
1 | 读未提交:读到未提交的数据、读提交:读取提交的数据、可重复读:读取事务保护数据不改变、序列化:此时在事务完成之前不允许其他事务对数据的读取和修改 |
readOnly : 设置为只读,还是可读写
当事务只有查询语句时,可以把readOnly=true,代表只读事务
rollbackFor : 设置遇到哪些检查异常必须回滚
如:@Transactional(rollbackFor={Exception.class})
noRollbackFor : 设置指定的运行异常不回滚
如:@Transactional(norollbackFor={异常.class})