在实际开发过程中有很多持久化技术可供选择:Hibernate、iBATIS和JPA等。尽管如此,还是有很多应用使用古老的方法即JDBC技术,来访问数据库。

使用JDBC技术不需要开发人员学习新的框架,因为它就是基于SQL语言运行的。JDBC技术更加灵活,开发人员可以调整的余地很大,JDBC技术允许开发人员充分利用数据库的本地特性,而在其他ORM框架中可能做不到如此灵活和可定制。

除了上述提到的灵活性、可定制能力,JDBC技术也有一些缺点。

开发者使用JDBC技术提供的API可以非常底层得操作数据库,同时也意味着,开发者需要负责处理数据访问过程中的各个具体步骤:管理数据库资源和处理数据库访问异常。如果你使用JDBC插入数据库,在这个例子中,假设需要插入一条spitter数据,则可以使用如下代码:

  1. @Component
  2. public class SpitterDao {
  3. private static final String SQL_INSERT_SPITTER =
  4. "insert into spitter (username, password, firstName, lastName) values (?, ?, ?, ?)";
  5.  
  6. @Autowired
  7. private DataSource dataSource;
  8.  
  9. public void addSpitter(Spitter spitter) {
  10. Connection conn = null;
  11. PreparedStatement stmt = null;
  12.  
  13. try {
  14. conn = dataSource.getConnection();
  15. stmt = conn.prepareStatement(SQL_INSERT_SPITTER);
  16. stmt.setString(1, spitter.getUsername());
  17. stmt.setString(2, spitter.getPassword());
  18. stmt.setString(3, spitter.getFirstName());
  19. stmt.setString(4, spitter.getLastName());
  20. stmt.execute();
  21. } catch (SQLException e) {
  22. //do something...not sure what, though
  23. } finally {
  24. try {
  25. if (stmt != null) {
  26. stmt.close();
  27. }
  28. if (conn != null) {
  29. conn.close();
  30. }
  31. } catch (SQLException e) {
  32. //I'm even less sure about what to do here
  33. }
  34. }
  35. }
  36. }

  

addSpitter函数一共有28行,但是只有6行是真正的业务逻辑。为什么如此简单的操作也需要这么多代码?JDBC需要开发者自己管理数据库连接、自己管理SQL语句,以及自己处理可能抛出的异常。

对于SQLException,开发者并不清楚具体该如何处理该异常(该异常并未指明具体的错误原因),却被迫需要捕获该异常。如果在执行插入语句时发生错误,你需要捕获该异常;如果在关闭statement和connection资源时发生错误,你也需要捕获该异常,但是捕获后你并不能做实际的有意义的操作。

同样,如果你需要更新一条spitter记录,则可使用下列代码:

  1. private static final String SQL_UPDATE_SPITTER =
  2. "update spitter set username = ?, password = ?, firstName = ?, lastName=? where id = ?";
  3.  
  4. public void saveSpitter(Spitter spitter) {
  5. Connection conn = null;
  6. PreparedStatement stmt = null;
  7.  
  8. try {
  9. conn = dataSource.getConnection();
  10. stmt = conn.prepareStatement(SQL_UPDATE_SPITTER);
  11. stmt.setString(1, spitter.getUsername());
  12. stmt.setString(2, spitter.getPassword());
  13. stmt.setString(3, spitter.getFirstName());
  14. stmt.setString(4, spitter.getLastName());
  15. stmt.setLong(5, spitter.getId());
  16. stmt.execute();
  17. } catch (SQLException e) {
  18. // Still not sure what I'm supposed to do here
  19. } finally {
  20. try {
  21. if (stmt != null) {
  22. stmt.close();
  23. }
  24. if (conn != null) {
  25. conn.close();
  26. }
  27. } catch (SQLException e) {
  28. // or here
  29. }
  30. }
  31. }

  

这一次,saveSpitter函数用于更新数据库中的一行记录,可以看出,有很多重复代码。理想情况应该是:你只需要写特定功能相关的代码。

为了补足JDBC体验之旅,我们再看看如何使用JDBC从数据库中查询一条记录,例子代码如下:

  1. private static final String SQL_SELECT_SPITTER =
  2. "select id, username, firstName, lastName from spitter where id = ?";
  3.  
  4. public Spitter findOne(long id) {
  5. Connection conn = null;
  6. PreparedStatement stmt = null;
  7. ResultSet rs = null;
  8.  
  9. try {
  10. conn = dataSource.getConnection();
  11. stmt = conn.prepareStatement(SQL_SELECT_SPITTER);
  12. stmt.setLong(1, id);
  13. rs = stmt.executeQuery();
  14. Spitter spitter = null;
  15. if (rs.next()) {
  16. spitter = new Spitter();
  17. spitter.setId(rs.getLong("id"));
  18. spitter.setUsername(rs.getString("username"));
  19. spitter.setPassword(rs.getString("password"));
  20. spitter.setFirstName(rs.getString("firstName"));
  21. spitter.setLastName(rs.getString("lastName"));
  22. }
  23. return spitter;
  24. } catch (SQLException e) {
  25. } finally {
  26. if (rs != null) {
  27. try {
  28. rs.close();
  29. } catch (SQLException e) { }
  30. }
  31. if (stmt != null) {
  32. try {
  33. stmt.close();
  34. } catch (SQLException e) { }
  35. }
  36. if (conn != null) {
  37. try {
  38. conn.close();
  39. } catch (SQLException e) { }
  40. }
  41. }
  42. return null;
  43. }

  

这个函数跟之前的insert和update例子一样啰嗦冗长:几乎只有20%的代码是真正有用的业务逻辑,而80%的代码则是模板样式代码。

可以看出,使用JDBC持久化技术,就需要编写大量的模板样式代码,用于创建连接、创建statements和处理异常。另外,上述提到的模板样式代码在数据库访问过程中又非常重要:释放资源和处理异常等,这都能提高数据访问的稳定性。如果没有这些操作,应用就无法及时处理错误、资源始终被占用,会导致内存泄露。因此,开发者需要一个数据库访问框架,用于处理这些模板样式代码。

spring: 在Spring应用中使用JDBC(使用profiles选择数据源/使用基于JDBC驱动的数据源)的更多相关文章

  1. spring: 使用Spring提供的JDBC模板(使用profiles选择数据源/使用基于JDBC驱动的数据源)

    Spring提供的JDBC框架负责管理资源和异常处理,从而可以简化开发者的JDBC代码.开发者只需要编写写入和读取数据库相关的代码即可. 正如在之前的小节中论述过的,Spring将数据库访问过程中的模 ...

  2. 数据源管理 | 基于JDBC模式,适配和管理动态数据源

    本文源码:GitHub·点这里 || GitEE·点这里 一.关系型数据源 1.动态数据源 动态管理数据源的基本功能:数据源加载,容器维护,持久化管理. 2.关系型数据库 不同厂商的关系型数据库,提供 ...

  3. Spring AOP: Spring之面向方面编程

    Spring AOP: Spring之面向方面编程 面向方面编程 (AOP) 提供从另一个角度来考虑程序结构以完善面向对象编程(OOP). 面向对象将应用程序分解成 各个层次的对象,而AOP将程序分解 ...

  4. [原创]java WEB学习笔记109:Spring学习---spring对JDBC的支持:使用 JdbcTemplate 查询数据库,简化 JDBC 模板查询,在 JDBC 模板中使用具名参数两种实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. 【转】在Spring中基于JDBC进行数据访问时怎么控制超时

    http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...

  6. [原创]java WEB学习笔记109:Spring学习---spring中事物管理

    博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好 ...

  7. Spring Cloud Data Flow 中的 ETL

    Spring Cloud Data Flow 中的 ETL 影宸风洛 程序猿DD 今天 来源:SpringForAll社区 1 概述 Spring Cloud Data Flow是一个用于构建实时数据 ...

  8. 在web项目中搭建一个spring mvc + spring + mybatis的环境

    介绍:本文中示范搭建一个ssm环境的框架:使用流程就是客户端通过http请求访问指定的接口,然后由服务器接受到请求处理完成后将结果返回. 本项目请求流程细节介绍:由客户端请求到指定的接口,这个接口是个 ...

  9. Spring Cloud 微服务中搭建 OAuth2.0 认证授权服务

    在使用 Spring Cloud 体系来构建微服务的过程中,用户请求是通过网关(ZUUL 或 Spring APIGateway)以 HTTP 协议来传输信息,API 网关将自己注册为 Eureka ...

随机推荐

  1. 解决IE,z-index失效

    在影响显示顺序的模块加上: style="position:relative;z-index:-1;" 解决IE,z-index失效

  2. Python3.6全栈开发实例[021]

    21.给出一个纯数字列表. 请对列表进行排序(升级题). 思路: (1)完成a和b的数据交换. 例如, a = 10, b = 24 交换之后, a = 24, b = 10(2)循环列表. 判断a[ ...

  3. shutil 模块 高级的文件、文件夹、压缩包 处理模块

    高级的文件.文件夹.压缩包 处理模块 # 将文件内容拷贝到另一个文件中 shutil.copyfileobj(fsrc, fdst[, length]) import shutil shutil.co ...

  4. Js前台页面搜索

    $("#filter").on("keyup",function(){$(".aimed_list").hide().filter(&quo ...

  5. JavaWeb—拦截器Interceptor

    1.概念 java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取A ...

  6. 剑指offer 面试3题

    面试3题: 题:数组中重复的数字 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复 ...

  7. 顽石系列:Linux基础笔试

    顽石系列:Linux基础笔试 系统操作 压缩文件 扩展名 压缩程序 *.Z compress *.zip zip *.gz gzip *.bz2 bzip2 *.xz xz *.tar tar 程序打 ...

  8. SpringBoot2.1.0 application.properties配置

    # =================================================================== # COMMON SPRING BOOT PROPERTIE ...

  9. 支持鼠标拖拽滑动的jQuery焦点图

    在线演示 本地下载

  10. js 职责链模式简要介绍

    定义: 使多个对象都有机会处理请求,避免发送者与接受者之间的耦合关系,将对象连成一条链,沿着这条链传递请求,直到有一个对象处理它. 如何把对象串联起来?解决方法通常是将另一个对象作为新创建对象的参数, ...