问题描述:
对于给定的SQL语句(SELECT),以及数据库信息(url,用户名,密码),如何快速获取SQL语句执行后返回的结果集的结构?比如包含的字段个数,包含的字段名称以及Java类型
小试牛刀:
第一眼看上去,问题确实很简单。任何对JDBC有一定了解的人,都会很容易给出下面的方案:
1、根据数据库信息,创建数据库Connection;
2、利用Connection和SQL语句,创建一个PreparedStatement;
3、执行PreparedStatement,获取结果集ResultSet;
4、通过ResultSet获取ResultSetMetaData,所有的信息都在ResultSetMetaData中。
代码很快写好了,测试一下吧,select * from table,ok没问题。
问题出现了:
代码顺利提交,正寻思休息一下,测试姐姐满头大汗的过来了:
帮我看看,我的页面怎么死住了?
怎么可能?我测试可是没问题的啊。是不是你的SQL写的不对啊。
没有啊,我写的也是select * from table。
经过一番查找,终于发现问题了:
我的table里,只有100条数据,测试姐姐的表,居然有5,000,000条数据,select *一次,居然一分钟,IE长时间等不到返回,直接就死住了。
问题的症结:
其实上面的方案还是正确的,问题主要是查询出来的数据太多,导致数据库长时间不返回,页面就死掉了。
如果有一种方案,能保证查询出来的数据很少,最好是一条记录都没有,就好了。反正我要的是结果集的结构,不关心有没有数据。
将SQL修改成:select * from table where 1=2,用测试姐姐的数据表试试,页面马上就出来了,看来这招可行。
再次尝试:
经过上面的尝试,初步确定了第二个方案:对于用户给定的SQL,拼接上一个永假式,再执行拼接后的SQL。因为拼接了永假式,所以不会有满足条件的数据,这样就可以快速的获取到ResultSet了。
对于用户给定的SQL语句,可以采用以下方式处理:
1、直接拼接永假式,如:select * from table,拼接后:select * from table where 1=2
2、如果上面的方式不成立,再次尝试,如: select * from table t where t.id > 100,可以拼结成:select * from table t where t.id > 100 AND 1 = 2
3、如果第2种方式依然不行,直接执行SQL。
可惜,这种方案能依然存在问题:
1、最坏的情况下,需要查询三次数据库;
2、如果第3步查询的结果集中,包含数据过大,页面依然会假死。
最终解决:
吃午饭的时候,和DBA简单的聊了一会儿,到底是DBA,一句话点醒梦中人:用子查询。
最终得到了方案,很简洁:
对于用户输入的SQL,转化为以下形式:
SELECT * FROM ( SQL ) TEST_SQL_TEMP WHERE 1 = 2
让我们进一步看一下:
1、我们将SQL作为一个子查询,起了一个别名 TEST_SQL_TEMP ;
2、然后我们基于TEST_SQL_TEMP进行查询,用SELECT * 可以保证结果集与直接执行SQL得到的结果集结构相同;
3、最后别忘了的永假式 WHERE 1=2
声明:
文章来自于ITeye,欢迎访问我的博客:xiaoyu1985ban.iteye.com
ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者。
相关推荐
**jdbc数据集生成器**是一种实用工具,它能够根据通过JDBC(Java Database Connectivity)接口获取的数据集(ResultSet)自动生成HTML文档,通常以表格的形式展示。这种工具模仿了数据库的导出数据功能,使得开发者...
JDBC提供了一组接口和类,允许开发者在Java程序中执行SQL语句,处理结果集,以及管理数据库连接。通常,数据库操作包括以下几个步骤:加载驱动、建立连接、创建Statement或PreparedStatement对象、执行SQL、处理结果...
4. **结果集处理**:`ResultSet`类代表SQL查询的结果,提供遍历查询结果、获取单个列值或行数据的方法。 5. **异常处理**:类库应包含适当的异常处理机制,当发生错误时抛出异常,以便于程序捕获并处理。 6. **...
- **Statement**: 用于执行静态SQL语句,获取结果集。 - **PreparedStatement**: 预编译的SQL语句,支持参数化查询,提高性能和安全性。 - **CallableStatement**: 用于调用存储过程的接口。 - **ResultSet**: 存储...
1. **结果集处理**: `ResultSet`对象表示查询的结果,可以通过`next()`方法遍历行,通过列索引或列名获取数据。 2. **事务管理**: 使用`conn.setAutoCommit(false)`关闭自动提交,通过`conn.commit()`和`conn....
当我们通过JDBC执行SQL查询并获取结果集(ResultSet)时,通常我们需要将这些数据转换为更易于处理的数据结构,如List。本篇文章将详细讲解如何将ResultSet转换为对应的List集合。 首先,我们了解ResultSet对象。...
通过JDBC,我们可以执行SQL语句,获取结果集,以及进行事务处理等操作。在数据库迁移中,我们需要利用JDBC连接源数据库和目标数据库,读取源数据库的数据,然后写入到目标数据库中。 MySQL是一款广泛使用的开源关系...
可以遍历这个结果集,获取每一行的数据。 6. **事务管理**:在JDBC中,可以使用`Connection`对象的`setAutoCommit()`方法控制事务。如果禁用自动提交,需要手动调用`commit()`或`rollback()`来提交或回滚事务。 7....
5. **处理结果集**:对于查询操作,会返回一个`ResultSet`对象,可以通过迭代来获取查询结果。 6. **关闭资源**:最后,别忘了关闭`ResultSet`, `Statement`和`Connection`,以释放系统资源。 在实际应用中,JDBC ...
总之,`jdbc连接mysql工具类`主要涉及JDBC API的使用,包括数据库连接、预编译的SQL语句(PreparedStatement)、结果集处理以及资源管理。这个工具类可以极大地简化数据库操作,提高代码的可维护性和复用性。通过...
- **结果集管理**:学习如何使用ResultSet对象获取查询结果,包括数据类型转换、结果集滚动和元数据访问等高级技巧。 - **批处理操作**:介绍如何使用BatchUpdate操作提高数据插入、更新或删除的效率,减少网络往返...
描述:此文章将详细介绍一个用于简化Java中JDBC操作的封装类,该类通过提供一系列方法来加速数据库编程任务,包括建立数据库连接、执行查询、处理结果集以及执行更新操作。 ### 一、JDBC封装类概述 在Java开发中,...
在JDBC中,查询的结果通常会返回一个ResultSet对象,我们需要遍历这个结果集来获取数据。ResultMaker可能提供了便利的方法,如将ResultSet转换成List、Map或者其他自定义的数据结构,方便业务层进行数据处理。这可以...
- **ResultSet类**:表示SQL查询的结果集,提供遍历查询结果的方法。 - **ResultSetMetaData类**:提供关于ResultSet列的信息,如列数量、名称、类型等。 - **DatabaseMetaData类**:提供了获取数据库元数据的方法,...
通过JDBC,我们可以执行SQL语句、处理结果集、事务管理等。JDBC的核心组件包括DriverManager、Connection、Statement、PreparedStatement和ResultSet等。 ### 2. JDBC驱动程序 JDBC驱动程序是Java程序与数据库之间...
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 **整合...
此外,它还包含了官方的sample,这些示例代码可以帮助开发者更好地理解和使用SQL Server JDBC驱动,快速上手数据库操作。 SQL Server JDBC驱动的核心功能包括: 1. 数据源连接:驱动提供了DataSource接口,允许...
MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。它使开发者能够专注于SQL本身,而无需关注那些臃肿和容易出错的JDBC代码。 在本示例项目中,我们看到"resources/sql"目录下包含了针对不同数据库的...
- 执行查询并获取结果集。 ##### 4.3 Statement中的方法: - `executeQuery(String sql)`:执行SQL查询语句,并返回结果集。 - `executeUpdate(String sql)`:执行SQL更新语句(如INSERT、UPDATE、DELETE)。 - `...