shenang博客技术文档


理论不懂就实践,实践不会就学理论!

posts - 35,comments - 55,trackbacks - 0
 

SpringJDBC封装,很大一部分就是借助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方法的另一个版本,传入的参数有两个,第一个用于创建

PreparedStatementSQL。第二个参数是为PreparedStatement设定参数的

PreparedStatementSetter

第二个参数的使用方法比较独到,我们动态新建了一个PreparedStatementSetter类,

并实现了这个抽象类的setValues方法。之后将这个类的引用作为参数传递给update

update接受参数之后,即可调用第二个参数提供的方法完成PreparedStatement的初始

化。

上面演示了update方法的使用(同样的操作适用于updateinsertdelete。下面是

一个查询的示例。

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

 (摘自开发指南:夏昕)

1Application-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>

2UserDAO

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;

      }

    });

 }

}

3TestCase

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 重庆理工小子 阅读(275) 评论(0)  编辑  收藏 所属分类: Spring2

只有注册用户登录后才能发表评论。


网站导航: