北大青鸟

网站首页 > 常见IT技术问题 > Java开发 >

站内公告

JDBC进行数据访问的初步学习

责任编辑:宏鹏来源:武汉北大青鸟鲁广校区时间:2012-12-09 09:27:51
导读:JDBC进行数据访问的初步学习。

一、简介

Spring JDBC抽象框架所带来的价值将在以下几个方面得以体现:(注:使用了Spring JDBC抽象框架之后,应用开发人员只需要完成斜体字部分的编码工作。)

指定数据库连接参数

打开数据库连接

声明SQL语句

预编译并执行SQL语句

遍历查询结果(如果需要的话)

处理每一次遍历操作

处理抛出的任何异常

处理事务

关闭数据库连接

Spring将替我们完成所有单调乏味的JDBC底层细节处理工作。

二、Spring JDBC包结构

Spring JDBC抽象框架由四个包构成:coredataSourceobject以及support

org.springframework.jdbc.core包由JdbcTemplate类以及相关的回调接口(callback interface)和类组成。

org.springframework.jdbc.datasource包由一些用来简化DataSource访问的工具类,以及各种DataSource接口的简单实现(主要用于单元测试以及在J2EE容器之外使用JDBC)组成。工具类提供了一些静态方法,诸如通过JNDI获取数据连接以及在必要的情况下关闭这些连接。它支持绑定线程的连接,比如被用于DataSourceTransactionManager的连接。

接下来,org.springframework.jdbc.object包由封装了查询、更新以及存储过程的类组成,这些类的对象都是线程安并且可重复使用的。它们类似于JDO,与JDO的不同之处在于查询结果与数据库是“断开连接”的。它们是在org.springframework.jdbc.core包的基础上对JDBC更高层次的抽象。

后,org.springframework.jdbc.support包提供了一些SQLException的转换类以及相关的工具类。

在JDBC处理过程中抛出的异常将被转换成org.springframework.dao包中定义的异常。因此使用Spring JDBC进行开发将不需要处理JDBC或者特定的RDBMS才会抛出的异常。所有的异常都是unchecked exception,这样我们就可以对传递到调用者的异常进行有选择的捕获。

三、使用JDBC核心类控制基本的JDBC处理和错误处理

(1)JdbcTemplate:

这是在JDBC核心包中重要的类。它简化了JDBC的使用,因为它处理了资源的建立和释放。它帮助你避免一些常见的错误,比如忘了总要关闭连接。它运行核心的JDBC工作流,如Statement的建立和执行,而只需要应用程序代码提供SQL和提取结果。这个类执行SQL查询,更新或者调用存储过程,模拟结果集的迭代以及提取返回参数值。它还捕捉JDBC的异常并将它们转换成 org.springframework.dao包中定义的通用的,能够提供更多信息的异常体系。

使用这个类的代码只需要根据明确定义的一组契约来实现回调接口。 PreparedStatementCreator回调接口创建一个由该类提供的连接所建立的PreparedStatement,并提供SQL和任何必要的参数。CallableStatementCreateor实现同样的处理,只是它创建了CallableStatement。RowCallbackHandler接口从数据集的每一行中提取值。

这个类可以直接通过数据源的引用实例化,然后在服务中使用,也可以在ApplicationContext中产生并作为bean的引用给服务使用。注意:数据源应当总是作为一个bean在ApplicationContext中配置,种情况它被直接传递给服务,第二种情况给JdbcTemplate。因为这个类把回调接口和SQLExceptionTranslator接口作为参数表示,所以没有必要为它定义子类。这个类执行的所有SQL都会被记入日志。

(2)数据源:

为了从数据库获得数据,我们需要得到数据库的连接。 Spring采用的方法是通过一个数据源数据源是JDBC规范的一部分,它可以被认为是一个通用的连接工厂。它允许容器或者框架将在应用程序代码中隐藏连接池和事务的管理操作。开发者将不需要知道连接数据库的任何细节,那是设置数据源的管理员的责任。虽然你很可能在开发或者测试的时候需要兼任两种角色,但是你并不需要知道实际产品中的数据源是如何配置的。

使用Spring的JDBC层,你可以从JNDI得到一个数据源,也可以通过使用Spring发行版提供的实现自己配置它。后者对于脱离Web容器的单元测试是十分便利的。我们将在本节中使用DriverManagerDataSource实现,当然以后还会提到其他的一些的实现。 DriverManagerDataSource和传统的方式一样获取JDBC连接。为了让DriverManager可以装载驱动类,你必须指定JDBC驱动完整的类名。然后你必须提供相对于各种JDBC驱动的不同的URL。你必须参考你所用的驱动的文档,以获得需要使用的正确参数。后,你还必须提供用来连接数据库的用户名和密码下面这个例子说明如何配置DriverManagerDataSource:

DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName( "org.hsqldb.jdbcDriver"); dataSource.setUrl( "jdbc:hsqldb:hsql://localhost:"); dataSource.setUsername( "sa"); dataSource.setPassword( "");

(3)SQLExceptionTranslator:

SQLExceptionTranslator是一个需要实现的接口,它被用来处理SQLException和我们的数据访问异常org.springframework.dao.DataAccessException之间的转换。

实现可以是通用的(比如使用JDBC的SQLState值),也可以为了更高的度特殊化 (比如使用Oracle的ErrorCode)。

SQLErrorCodeSQLExceptionTranslator 是SQLExceptionTranslator的实现,它被默认使用。比供应商指定的SQLState更为。 ErrorCode的转换是基于被保存在SQLErrorCodes型的JavaBean中的值。这个类是由SQLErrorCodesFactory建立并填充的,就像它的名字说明的, SQLErrorCodesFactory是一个基于一个名为"sql-error-codes.xml"的配置文件的内容建立SQLErrorCodes的工厂。这个文件带有供应商的码一起发布,并且是基于DatabaseMetaData信息中的DatabaseProductName,适合当前数据库的码会被使用。

SQLErrorCodeSQLExceptionTranslator使用以下的匹配规则:

使用子类实现的自定义转换。要注意的是这个类本身就是一个具体类,并可以直接使用, 在这种情况下,将不使用这条规则。

使用ErrorCode的匹配。在默认情况下,ErrorCode是从SQLErrorCodesFactory得到的。它从classpath中寻找ErrorCode,并把从数据库metadata中得到的数据库名字嵌入它们。

如果以上规则都无法匹配,那么是用SQLStateSQLExceptionTranslator作为默认转换器。

SQLErrorCodeSQLExceptionTranslator可以使用以下的方式继承:

public class MySQLErrorCodesTransalator extends SQLErrorCodeSQLExceptionTranslator { protected DataAccessException customTranslate(String task, String sql, SQLException sqlex) { if (sqlex.getErrorCode() == -12345) return new DeadlockLoserDataAccessException(task, sqlex); return null; } }

在这个例子中,只有特定的ErrorCode'-12345'被转换了,其他的错误被简单的返回,由默认的转换实现来处理。要使用自定义转换器时,需要通过setExceptionTranslator 方法将它传递给JdbcTemplate,并且在所有需要使用自定义转换器的数据访问处理中使用这个JdbcTemplate 下面是一个如何使用自定义转换器的例子:

// create a JdbcTemplate and set data source JdbcTemplate jt = new JdbcTemplate(); jt.setDataSource(dataSource); // create a custom translator and set the datasource for the default translation lookup MySQLErrorCodesTransalator tr = new MySQLErrorCodesTransalator(); tr.setDataSource(dataSource); jt.setExceptionTranslator(tr); // use the JdbcTemplate for this SqlUpdate SqlUpdate su = new SqlUpdate(); su.setJdbcTemplate(jt); su.setSql("update orders set shipping_charge = shipping_charge * 1.05"); su.compile(); su.update();

这个自定义的转换器得到了一个数据源,因为我们仍然需要默认的转换器在sql-error-codes.xml中查找ErrorCode。

(4)执行Statement:

要执行一个SQL,几乎不需要代码。你所需要的部是一个数据源和一个JdbcTemplate。一旦你得到了它们,你将可以使用JdbcTemplate提供的大量方便的方法。下面是一个例子,它显示了建立一张表的小的但有完整功能的类。

import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; public class ExecuteAStatement { private JdbcTemplate jt; private DataSource dataSource; public void doExecute() { jt = new JdbcTemplate(dataSource); jt.execute("create table mytable (id integer, name varchar(100))"); } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } }

(5)执行查询:

除了execute方法,还有大量的查询方法。其中的一些被用来执行那些只返回单个值的查询。也许你需要得到合计或者某一行中的一个特定的值。如果是这种情况,你可以使用queryForIntqueryForLong或者queryForObject。后者将会把返回的JDBC类型转换成参数中指定的Java类。如果类型转换无效,那么将会抛出一个InvalidDataAccessApiUsageException。下面的例子有两个查询方法,一个查询得到int,另一个查询得到String

import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; public class RunAQuery { private JdbcTemplate jt; private DataSource dataSource; public int getCount() { jt = new JdbcTemplate(dataSource); int count = jt.queryForInt("select count(*) from mytable"); return count; } public String getName() { jt = new JdbcTemplate(dataSource); String name = (String) jt.queryForObject("select name from mytable", java.lang.String.class); return name; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } }

除了得到单一结果的查询方法之外,还有一些方法,可以得到一个包含查询返回的数据的List。其中通用的一个方法是queryForList,它返回一个List,其中每一项都是一个表示字段值的Map。你用下面的代码在上面的例子中增加一个方法来得到一个所有记录行的List:

public List getList() { jt = new JdbcTemplate(dataSource); List rows = jt.queryForList("select * from mytable"); return rows; }

返回的List会以下面的形式: [{name=Bob, id=1}, {name=Mary, id=2}].

(6)更新数据库:

还有很多更新的方法可以供你使用。我将展示一个例子,说明通过某一个主键更新一个字段。 在这个例子里,我用了一个使用榜定参数的SQL Statement。大多数查询和更新的方法都有这个功能。 参数值通过对象数组传递。

import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; public class ExecuteAnUpdate { private JdbcTemplate jt; private DataSource dataSource; public void setName(int id, String name) { jt = new JdbcTemplate(dataSource); jt.update("update mytable set name = ? where id = ?", new Object[] {name, new Integer(id)}); } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } }

本文标题:JDBC进行数据访问的初步学习,责任编辑:宏鹏,来源:武汉北大青鸟鲁广校区栏目,于2012-12-09 09:27:51发布于北大青鸟鲁广校区。JDBC进行数据访问的初步学习。

专业老师指导

赵老师

赵老师

从事IT教育培训十年有余,致力于帮助广大学子找到适合自己的专业

立即在线咨询

培训咨询客服

陈老师

陈老师

IT培训专业客服,用自己的真诚解决了无数学子的困惑

立即在线咨询

本文地址:https://m.027hpedu.com/wenda/java/2007.html

文章标题:JDBC进行数据访问的初步学习

上一篇:学Java软件开发 做专业合格人才

下一篇:JavaScript实现图片在线编辑以及上传预览

热点关注

推荐Java开发

热门Java开发

预约你的精彩未来

预约将免费领取7天课程体验卡

-------请选择试预约课程-------

JAVA
WEB前端
PHP
UI设计
Python
电子商务
视频剪辑
大数据工程师
平面设计

83345人已领取

全国百余家校区

只为您方便就学

北大青鸟鲁广校区

北大青鸟鲁广校区

武汉市洪山区珞喻路724号(地铁二号线光谷广场站F口出)

预约到校
领取学习大礼包

首页

热门课程

视频网课

新闻资讯

关于学校

联系学校

预约选课申请

  • 预约时间

    请选择预约时间

  • 预约课程

    请选择预约课程

  • 姓   名
  • 手机号
  • QQ 号
  • 微信号

添加老师微信号

专业老师24小时1对1学习指导

定制专属于你的专属学习方案

微信号:17740513250

复制老师的微信号

复制成功啦

快去微信添加老师为好友吧~

北大青鸟小青

微信号:17740513250

北大青鸟小青

微信号:17740513250

设置备注
小主知道啦