Spring的JDBC封裝,很大一部分就是借助Template模式實現,它提供了一個優秀的
JDBC模板庫,借助這個工具,我們可以簡單有效的對傳統的JDBC編碼方式加以改進。
dbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("UPDATE user SET age = 10 WHERE id = 'erica'");
再對上面的例子進行一些改進,通過PrepareStatement執行update操作以避免SQL
njection 漏洞
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate
.update(
"UPDATE user SET age = ? WHERE id = ?",
new PreparedStatementSetter() {
public void setValues(PreparedStatementSetter ps)
throws SQLException {
ps.setInt(1, 18);
ps.setString(2, "erica");
}
}
)
可以看到,上面引用了update方法的另一個版本,傳入的參數有兩個,第一個用于創建
PreparedStatement的SQL。第二個參數是為PreparedStatement設定參數的
PreparedStatementSetter。
第二個參數的使用方法比較獨到,我們動態新建了一個PreparedStatementSetter類,
并實現了這個抽象類的setValues方法。之后將這個類的引用作為參數傳遞給update。
update接受參數之后,即可調用第二個參數提供的方法完成PreparedStatement的初始
化。
上面演示了update方法的使用(同樣的操作適用于update、insert、delete)。下面是
一個查詢的示例。
final List userList = new ArrayList();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate
.query(
"SELECT name, sex, address FROM user WHERE age > 18",
new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
User user = new User();
user.setId(rs.getString("name"));
user.setSex(rs.getString("sex"));
user.setAddress(rs.getString("address"));
userList.add(product);
}
}
)
下面我們通過已學習持的久性封裝知識,繼續討論事務管理
為了實現數據操作的原子性,我們需要在程序中引入事務邏輯,在JdbcTemplate中引入
事務機制,在Spring中有兩種方式:
1. 代碼控制的事務管理
2. 參數化配置的事務管理
下面就這兩種方式進行介紹。
代碼控制的事務管理
首先,進行以下配置,假設配置文件為(Application-Context.xml)
(摘自開發指南:夏昕)
1、Application-Context.xml
<beans>
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>net.sourceforge.jtds.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:jtds:sqlserver://127.0.0.1:1433/Sample</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>changeit</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransac
tionManager">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="userDAO" class="net.xiaxin.dao.UserDAO">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="transactionManager">
<ref local="transactionManager" />
</property>
</bean>
</beans>
2、UserDAO
public class UserDAO {
private DataSource dataSource;
private PlatformTransactionManager transactionManager;
public PlatformTransactionManager getTransactionManager() {
return transactionManager;
}
public void setTransactionManager(PlatformTransactionManager
transactionManager) {
this.transactionManager = transactionManager;
}
public DataSource executeTestSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void insertUser() {
TransactionTemplate tt =
new TransactionTemplate(getTransactionManager());
tt.execute(new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
JdbcTemplate jt = new JdbcTemplate(executeTestSource());
jt.update(
"insert into users (username) values ('xiaxin');");
jt.update(
"insert into users (id,username) values(2,
'erica');");
return null;
}
});
}
}
3、TestCase
InputStream is = new FileInputStream("Application-Context.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
UserDAO userDAO = (UserDAO) factory.getBean("userDAO");
userDAO.insertUser();
參數化配置的事務管理
在上面的Application-Context.xml增加一個事務代理(UserDAOProxy)配置,同時,由于事務由容器管理,UserDAO不再需要TransactionManager設定,將其移除:
<bean id="UserDAOProxy"
class="org.springframework.transaction.interceptor.Transac
tionProxyFactoryBean">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="target">
<ref local="userDAO" />
</property>
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="net.xiaxin.dao.UserDAO">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
與之對應,UserDAO.insertUser的代碼修改如下:
public void insertUser(RegisterInfo regInfo) {
JdbcTemplate jt = new JdbcTemplate(executeTestSource());
jt.update("insert into users (username) values ('xiaxin');");
jt.update("insert into users (id,username) values (2,'erica');");
}
比上面簡單了很多吧!
測試代碼修改如下:
InputStream is = new FileInputStream("Application-Context.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
//注意這里須通過代理Bean"userDAOProxy"獲得引用,而不是直接getBean(“userDA
//此外這里還存在一個有關強制轉型的潛在問題,請參見Hibernate in Spring一節后
//關于強制轉型的補充描述。
UserDAO userDAO = (UserDAO) factory.getBean("userDAOProxy");
userDAO.insertUser();
posted on 2009-03-24 13:25
重慶理工小子 閱讀(278)
評論(0) 編輯 收藏 所屬分類:
Spring2