我们的目标是希望在任何使用JDBC的场合都能够利用SpringFramework的JDBC Support Module,同时尽可能少地引入不必要的元素。因此,我们假定不使用J2EE环境提供的任何服务,也不使用SpringFramework的IoC容器和AOP两大特性。
首先,我们需要的自然是一个DataSource。在非J2EE环境下,可以使用Jakarta的commons-dbcp来得到一个DataSource的实例。我们选择使用SharedPoolDataSource,它提供了一个close()方法,在程序结束前调用它可以关闭所有的Connection,释放相关的资源。
接着,将spring-core.jar和spring-dao.jar置入CLASSPATH。事实上,我们将要用到的class几乎全部都在spring-dao.jar中,之所以需要spring-core.jar是因为NestedRuntimeException,所有JDBC Support Module中的异常都直接或间接继承自这个Runtime Exception。由此也可以看出,我们只是在受控制的情况下引入了SpringFramework的一小部分而已。
下面,我们就可以开始逐步设置和组装我们的基础设施。
org.springframework.jdbc.core.JdbcTemplate
JdbcTemplate是整个package的核心,所有的JDBC调用流程都通过它来完成,开发者只需要实现对应的callback接口即可。JdbcTemplate是无状态且线程安全的,也就是说在整个系统中只需要创建一个实例就够了。创建它的时候需要提供DataSource作为参数。
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.afterPropertiesSet();
afterPropertiesSet()方法是对InitializingBean接口的实现,如果实例是由IoC容器管理的,则容器会自动调用。由于我们并没有使用IoC容器,所以需要在创建实例后主动调用该方法。
org.springframework.transaction.support.TransactionTemplate
TransactionTemplate帮助我们以编程的方式实现事务控制。同样的,开发者也是通过实现callback接口来使用它。TransactionTemplate也是无状态且线程安全的。创建TransactionTemplate的实例需要提供一个PlatformTransactionManager的实例,在SpringFramework中有多种PlatformTransactionManager的实现类,提供多种事务控制的途径。基于前面设定的限制,我们选择DataSourceTransactionManager。
PlatformTransactionManager platformTransactionManager =
new DataSourceTransactionManager(dataSource);
TransactionTemplate transactionTemplate =
new TransactionTemplate(platformTransactionManager);
transactionTemplate.afterPropertiesSet();
org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer
在数据库中插入数据的时候,需要获得唯一的Long或Integer类型的值做为主键。DataFieldMaxValueIncrementer提供了这样一个途径,而具体的实现方法则因各种数据库系统而异。简单地说,如果数据库系统本身提供了Sequences(例如Oracle),则直接从sequences取得所需的序列值,如果数据库系统不支持Sequences(例如MySQL),则通过一个单独的Table来保存和产生新的序列值。每个DataFieldMaxValueIncrementer的实例都需要有一个对应的Sequences或者Table,换句话说,开发者要选择是整个系统共用同一个Incrementer实例,还是对应每个Table使用各自专有的Incrementer实例。目前SpringFramework已经提供了针对Oracle、DB2、PostgreSQL、MySQL,HSQL五种数据库的实现,支持从超重量级直到超轻量级的常见数据库系统,而且,要自己编写针对其它数据库系统的实现也并非难事。在例子中我们选择使用HSQL数据库,创建一个HsqlMaxValueIncrementer的实例需要提供DataSource、table name、column name。
HsqlMaxValueIncrementer incrementer = new HsqlMaxValueIncrementer(dataSource,
"id_sequence", "value");
incrementer.afterPropertiesSet();
基础设施准备好了之后,就可以在上面进行DAO的实现了,前面已经提到了开发者是通过实现callback接口来使用JdbcTemplate的,现在让我们来逐个尝试。
Insert、Update、Delete三种情况都不需要返回结果给调用者,因此可以使用JdbcTemplate的update()方法,该方法有多个重载的版本,可以根据实际情况选择一个合适的。由于数据库系统的原因,我无法测试对BLOB和CLOB的操作,但是从文档来看,相关的支持应该是满足需要的。
long id = incrementer.nextLongValue();
user.setId(id);
String sql = "INSERT INTO users VALUES (?,?,?,?);";
Object[] params = new Object[] { new Long(id), user.getUsername(),
user.getPassword(), new Boolean(user.isEnabled()) };
jdbcTemplate.update(sql, params);
对于Query,则是使用JdbcTemplate的query()方法,同样提供了多个重载的版本。通常要先实现一个RowMapper,能够将ResultSet中的一条记录取出来,填充到一个对象中。我们可以将它设计为一个内部类,同时它的实例也是线程安全的。
private class UserRowMapper implements RowMapper
{
public Object mapRow(ResultSet resultSet, int row) throws SQLException
{
User user = new User();
user.setId(resultSet.getLong("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
user.setEnabled(resultSet.getBoolean("enabled"));
return user;
}
}
String sql = "SELECT * FROM users;";
RowMapper mapper = new UserRowMapper();
RowMapperResultReader reader = new RowMapperResultReader(mapper);
List users = jdbcTemplate.query(sql, reader);
return users;
数据库操作自然离不开事务控制,使用TransactionTemplate很简单,只需要调用execute()方法即可。当然前提是你实现了TransactionCallback接口,并且在doInTransaction()方法里进行各种数据库操作。于是这一组操作就会作为一个事务提交,一旦出现任何异常,则相应地进行事务回滚。
transactionTemplate.execute(createUser);
public Object doInTransaction(TransactionStatus status)
{
try
{
userDao.insertUser(user);
authorityDao.updateAuthority(user, auths);
}
catch (Exception exception)
{
status.setRollbackOnly();
log.debug(exception.getCause(), exception);
}
return null;
}
以上,就是借助SpringFramework JDBC Support的DAO实现方式。我们可以将最初设定的限制条件放宽一些,假定我们处于J2EE环境下,那么DataSource的实例可以通过JNDI直接从J2EE容器获得,同时也可以选择通过JTA进行事务控制。假定我们使用SpringFramework的IoC容器,那么所有前面提到的对象都可以交给IoC容器中进行设置和组装,以获得更简洁、更灵活的代码实现。
我还漏了一点——在前面的代码中看不出来——SpringFramework对SQLException的重新包装。SQLException所携带的信息几乎都是通过其中的error code来传递的,而本身类的层次结构扁平,我们只好不分青红皂白全都catch住,然后再根据error code决定是否应该进行一些异常处理。而SpringFramework的异常类层次结构很丰富,我们可以充分利用try catch机制仅catch那些我们想要处理的异常,这又使我们的代码倾向于简洁。
结论:在一个典型的项目中,如果我们由于这样或那样的原因决定不使用EJB、Hibernate、iBatis等等等等,而打算亲自操刀烹调JDBC时,同样有充分的理由使用SpringFramework。我们只需要付出很少的学习成本,就能让我们的DAOs更可靠、更灵活、更一针见血。
分享到:
相关推荐
【低代码平台】商城可视化搭建平台 - Mall-Cook 是一种创新的电商解决方案,它允许开发者和非技术人员通过图形用户界面快速构建和定制电子商务网站。这个平台的核心特点在于其可视化构建功能,大大降低了商城开发的...
约翰逊-库克(Johnson-Cook)模型是一种广泛应用于金属材料塑性变形模拟的本构关系模型,尤其在焊接、冲击、热成形等领域的数值模拟中占据重要地位。该模型考虑了应变、应变速率、温度以及加载历史等因素对材料应力-...
Johnson Cook model,abaqus VUMAT
标题 "johnson cook-vumat-temp.rar_cook_johnson cook vumat_johnson-cook" 暗示了我们正在讨论一个与Johnson-Cook模型相关的VUMAT(Von Mises Updated Material Algorithm)文件。VUMAT是ABAQUS等有限元软件中的一...
标题中的"COOK"可能指的是一个特定的字体或者与烹饪相关的软件或应用。在IT行业中,"COOK"如果是字体,通常是指一种设计独特的字符集,用于文本编辑、排版或者图形设计。这类字体可能包含多种风格,如粗体、斜体、...
With H2O software, you can perform machine learning and data analysis using a simple open source framework that’s easy to use, has a wide range of OS and language support, and scales for big data....
《Combinatorial Optimization》Cook, Cunningham, Pulleyblank, Schrijver
《KMplayer cook.dll:解决解码冲突的策略与技术解析》 在数字媒体播放领域,KMplayer是一款备受用户喜爱的多媒体播放器,以其强大的自定义功能和广泛的格式支持而著称。然而,当KMplayer与RealPlayer同时存在于...
本文内容主要涉及了R编程cook book这本书的介绍,包括其出版背景、编辑团队以及出版的相关书籍系列。下面将详细解读这些知识点。 首先,R programming cook book这本书主要是用于引导R编程初学者。R语言是一种广泛...
在"cook-with-me-server-main"这个压缩包中,我们可以期待找到项目的主要源代码和配置文件。JavaScript通常与Node.js框架一起使用来开发服务器端应用,因此这个项目很可能基于Node.js的Express框架,这是一个轻量级...
标题"Abaqus-VUMAT-Johnson-Cook-master_jc_jcvumat_abaqusJC_johnsoncook"指的是一个关于Abaqus软件中使用的VUMAT(User-Defined Material)子程序,具体是Johnson-Cook模型的应用。这个模型是材料力学领域的一个...
`@RunWith`允许你指定自定义的测试运行器,比如`Parameterized`运行器支持参数化的测试。 此外,JUnit 5引入了更多改进,如`@Nested`测试类嵌套,`@Tag`用于标记和过滤测试,以及`@DisplayName`为测试组或测试方法...
《Johnson-Cook模型在Abaqus中的实现及应用》 Johnson-Cook模型是材料力学领域广泛应用的一种塑性损伤和硬化模型,尤其在模拟金属材料在动态加载条件下的行为时,其表现尤为出色。该模型由Johnson和Cook在1983年...
《Python Cookbook》是一本经典的Python编程手册,它不仅适合初学者学习,也适合有一定经验的开发者参考。本书详细讲解了多种Python技巧,覆盖数据结构与算法、字符串和文本、数字、日期和时间、迭代器与生成器、...
ASP.NET 2.0 .Cook 是一份专门针对ASP.NET 2.0开发的学习资源,它提供了丰富的实践示例和技巧,旨在帮助开发者更好地理解和应用这一技术。这份文档可能包括了从基础概念到高级特性的全面讲解,对于初学者和有经验的...
同时,项目可能依赖于一些流行的框架,如Spring Boot、Django、React等,这些框架的选择会显著影响代码结构和实现方式。 4. **设计模式应用** 源码中会体现出各种设计模式,如工厂模式用于对象创建,单例模式用于...
《Unreal Engine 4 Scripting with C++ Cookbook》是一本面向游戏开发者的专业书籍,专门介绍了如何使用C++语言结合Unreal Engine 4(UE4)进行游戏脚本编写。本书在2016年10月发布了新版,并且包含彩色插图,使得...
MySQL 8 Cookbook 是一本专注于 MySQL 数据库最新版本 8 的技术指南书籍。书中通过超过150个实用的食谱形式介绍了高性能数据库查询和管理的方法。本书的作者是Karthik Appigatla,他通过本书分享了自己在数据库管理...