http://publishblog.blogdriver.com/blog/tb.b?diaryID=1182919
JDBCTemplate
数据读取机制
JDBCTemplate
数据读取
一般的读取数据的步骤可以用下图表示:
l
确定需要读取的数据:这一步应该是我们程序员关心的重点。他是我们程序的原始需求。
l
通知数据库我们的需求:
在直接使用
JDBC
程序这一步主要是分成如下几步来完成的。
先注册一个驱动(驱动由不同的厂商或组织实现。对不同的数据库服务器有不同的实现)
典型的注册方法:
Class.forName("my.sql.Driver");
然后通过
DriverManager
来创建一个数据库连接。
接着我们的程序就通过这个数据库连接和数据库服务器交互。我们发送查询请求只是各种交互的一种。而我们的请求的内容是根据我们的需求而确定的(其实就是
Sql
语句需要查询的内容了)。
这部分的工作可分为三部分:
和数据库服务器建立连接。
根据需求组织请求内容(确定查询语句)。
通过连接向数据库服务器发送请求。
在以上的三步中其中第一步和第三步是约定好的。在
JDBC
程序中的典型实现方式为
//第一步
Class.forName("my.sql.Driver");
conn = DriverManager.getConnection(dbUrl);
//
第二步
sql = GenerateSql();
//
第三步
stmt = this.conn.createStatement();
rs = stmt.executeQuery(sql);
在这里我们应该把更多的注意点关注到第二步。
l
等待的过程我们就无能为力。这个牵涉到的东西很多包括网络,驱动的实现以及数据库服务器的性能。
l
组织数据。这应该是我们实现取数据目的的前骤。把关系型数据组织成我们方便使用的类型。如实体对象等。(其实这部分的工作可以用其他的
O/R mapping
框架来实现,但是这个不是今天想讨论的问题)这一部分复杂多样。只能由我们自己来实现。
l
通知数据库服务器请求结束。这一部分的工作应包括清理一些数据库资源,如数据库连接等。虽然很繁琐但是很重要,如果不做的话很有可能造成资源泄漏,在严重的情况下可能引发
OutofMenory
错误,导致系统瘫痪。很多时候我们会忘掉这个步骤。这个部分最好由工具完成。
l
使用是我们目标的一个实现。不多提了。
从上面的分析可以看出有两部分有很大的灵活性。
1.
向数据库服务器发送请求的请求组织部分。说白了也就
sql
语句的写法。
2.
组织数据部分。数据库读出来后把数据组织成我们所需要的格式。
做为一个
Template
,
JDBCTemplate
为我们做好了通用的动作,及除了上述两点外的说有动作。并为上述两点提供了灵活方便的接口。
核心的接口有两个
:
PreparedStatementCreator
和
RowCallBackHandler
l
PreparedStatementCreator
该接口只有一个方法需要实现。
PreparedStatement createPreparedStatement(Connection con) throws SQLException;
定制我们自己的查询条件。
下面的英文节选自
Expert One ? on ? One J2EE Design and Development
中的描述。
关于这本书和
Spring
框架的关系可以这么理解书是框架的最好说明。或者说框架是书的附带源码。
The
PreparedStatementCreator
interface must be implemented by application-specific classes to create a
java.sql.PreparedStatement
, given a
java.sql.Connection
.
This means specifying the SQL and setting bind parameters for an
application-specific query or update, which will be run by the
JdbcTemplate
class. Note that an implementation of this interface doesn't need to worry about obtaining a connection or catching any
SQLExceptions
that may result from its work. The
PreparedStatement
it creates will be executed by the
JdbcTemplate
class. The interface is as follows:
public
interface PreparedStatementCreator {
PreparedStatement createPreparedStatement (Connection conn)
throws
SQLException;
}
The following shows a typical implementation, which uses standard JDBC methods to construct a
PreparedStatement
with the desired SQL and set bind variable values. Like many
implementations of such simple interfaces, this is an anonymous inner
class:
PreparedStatementCreator psc = new
PreparedStatementCreator(
) {
public
PreparedStatement createPreparedStatement (Connection conn)
throws
SQLException {
PreparedStatement ps = conn.
prepareStatement
(
"SELECT seat_id AS id FROM available_seats WHERE " +
"performance_id
= ?
AND price_band_id
= ?
");
ps.setInt(
1, performanceId);
ps.setInt(
2, seatType);
return
ps;
}
};
The
PreparedStatementCreatorFactory
class is a generic helper that can be used repeatedly to create
PreparedStatementCreator
objects with different parameter values, based on the same SQL
statement and bind variable declarations. This class is largely used by
the higher-level, object-abstraction framework described below;
application code will normally define
PreparedStatementCreator
classes as shown above.
l
RowCallbackHandler
The
RowCallbackHandler
interface must be implemented by application-specific classes to extract column values from each row of the
ResultSet
returned by a query. The
JdbcTemplate
class handles iteration over the
ResultSet
. The implementation of this interface may also leave
SQLExceptions
uncaught: the
JdbcTemplate
will handle them. The interface is as follows:
public interface RowCallbackHandler {
void processRow(ResultSet rs) throws SQLException;
}
Implementations should know the number of columns and data types to expect in the
ResultSet
.
The following shows a typical implementation, which extracts an int
value from each row and adds it to a list defined in the enclosing
method:
RowCallbackHandler rch = new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
int seatId = rs.getInt(1) ;
list.add(new Integer (seatId) );
}
};
The
RowCountCallbackHandler
class is a convenient framework implementation of this interface that
stores metadata about column names and types and counts the rows in the
ResultSet
. Although it's a concrete class, its main use is as a superclass of application-specific classes.
The
ResultReader
interface extends
RowCallbackHandler
to save the retrieved results in a
java.util.List
:
public interface ResultReader extends RowCallbackHandler {
List getResults() ;
}
The conversion of each row of the
ResultSet
to an object is likely to vary widely between implementations, so there is no standard implementation of this interface.
到这儿
JDBCTemplate
其实已经建立起了个很完毕的数据库读取机制。下面我们将
JDBCTemplate
是如何实现数据库的读取。我们就来看看如何使用
JDBCTemplate
来实现数据库的查询。
RowCallBackHandler
的使用
public class BookDaoJdbc extends com.jet.springtest.dao.AbstractDaoJdbc
{
public List readAllBook() {
String sql = "SELECT id,name,publisher,isbn FROM spring.book ";
getJdbcTemplate().query(sql, new
RowCallbackHandler
(){
public void processRow(ResultSet rs) throws SQLException {
Book currentBook = new Book();
currentBook.setFBookName(rs.getString("name"));
currentBook.setFPublisher(rs.getString("publisher"));
currentBook.setFIsbn(rs.getString("isbn"));
currentBook.setFId(new Integer(rs.getInt("id")));
fBooks.add(currentBook);
}
});
}
return fBooks;
}
注意看一下
new RowCallbackHandler()
部分。这部分其实是我们实现了一个
RowCallbackHandler
接口的匿名类。我们必须实现一个
processRow(ResultSet rs)
的方法供
JDBCTemplate
回调。跟踪一下可以发现有如下的调用路径。
说明:这里有两个很有用的技巧。
1
、
使用接口实现回调的功能。
2
、
内部类的实用。
问题你一定想问一下我们如何得到数据库连接,打开并关闭呢?这所有的动作都是由
Template
在
execute
中帮我们完成的。通过下面的代码得到证实。
我们可以清晰地看到
Template
帮我们做的一切,不用再担心
Connection
没有关闭而导致系统垮掉的可能。
PreparedStatementCreator
的使用
在上面的例子中我们已经看到
RowCallBackHandler
的作用是在数据组织这一块。
PreparedStatementCreator
的作用就是为了“向数据库服务器发送请求的请求组织部分”而服务的了。
这里只是简单的演示和解释了一下
JDBCTemplate
中的数据读取的机制。他还提供很多其它的查询和更新的接口。简单的说
JDBCTemplate
可以让你只关注你需要关注的地方。
分享到:
相关推荐
java基于jdbctemplate数据持久层操作封装,实际开发项目使用,非常便捷。
本资源包含了两个子项目,分别进行了springboot+jpa+jdbcTemplate的多数据源独立事务配置和jta分布式事务配置,并针对不同的情况编写了事务配置测试接口,还演示了JPA的domain一对多自动生成数据库表且不生成数据库...
SpringBoot操作多数据源(JPA+JdbcTemplate)使用HikariCP数据源进行示例。
最近项目中的工作流需要查询多个数据源的数据,数据源可能是不同种类的:如sql server,oracl等等,一开始是用的配置实现,后来发现在项目运行中,可能需要动态的添加更多不同类型的数据源,所以最终的逻辑是将数据源...
spring 中对大数据的处理,包括clob,blob的数据。比之jdbc下简便很多。
使用Spring的JdbcTemplate实现分页功能
JdbcTemplate 调用存储过程
利用spring boot的jdbctemplate实现大批量数据导出数据库道文件,及文件中大批量数据导入mysql数据库
sprint boot JdbcTemplate MyBatis JPA多数据源配置xmind
JdbcTemplate是spring-jdbc提供的数据库核心操作类,那对JdbcTemplate进行事务控制呢?
spring boot + JdbcTemplate 使用druid数据源
spring-jdbcTemplate实例工程
jdbcTemplate分页彻底解决,使用游标滚动jdbcTemplate分页彻底解决,使用游标滚动
JdbcTemplate使用就是JdbcTemplate的使用 再说两遍JdbcTemplate使用就JdbcTemplate的使用 20字够了
JdbcTemplate CRUD示例
SpringJdbcTemplate封装工具包,包括规范model格式接口,封装SpringJdbcTemplate,实现分页,自适应多种数据库
提供了使用Spring的jdbcTemplate需要导入的五个jar包
jdbcTemplate