JDBC用法小结

本文总结了JDBC的用法,介绍了DriverManger、Connection、Statement、ResultSet等类和接口的作用及使用方法,还给出了JDBC语句对象Statement和PrepareStatement的区别,并提供了建立数据库连接的实例代码,对Java程序设计有一定帮助。

JDBC用法小结

本文实例总结了JDBC的用法。分享给大家供大家参考。具体分析如下:

DriverManger:驱动管理器类

要操作数据库,必须先与数据库创建连接,得到连接对象

public static Connection getConnection(String url, String username,String password){}

Connection:连接接口:

通过DriverManger类的getConnection方法,将获得连接对象,执行sql语句必须借助语句对象(Statement)

Statement creajkomSNPteStatement();

Statement:语句接口

通过连接对象的createStatement方法获得语句对象后,语句对象即可执行sql语句,Statement中提供了executeUpdate、executeQuery语句,分别执行不同的sql语句

int executeUpdate(String sql):执行增删改操作的语句,返回值为操作的总行数

ResultSet executeQuery(String sql):执行查询语句,返回值为查询结果集合

ResultSet:结果集接口

boolean next():该方法可以使结果集游标向下移动,如果仍有记录返回true,如果已经遍历结束,返回false

getXXX(String columnName):该系列方法用来根据字段名返回字段的值结果集接口里面有大量的getXXX(String columnName)方法,如getString,getInt等

getXXX(int index):该系列方法用来根据字段在结果集中的索引值返回字段的值,结果集中有大量的getXXX方法,与 上面的类似,用来根据索引值,获取该字段的值,XXX是该字段的数据类型。

JDBC语句对象:

Statement:如上 stmt = conn.createStatement();

PrepareStatement:称为预编译的语句对象,是Statement的子接口 stmt = conn.prepareStatement(String sql),和Statement的不同之处

复制代码 代码如下:

public class ConnectTest {

  public static void main(String[] args) {

    String driverName = "oracle.jdbc.driver.OracleDriver";

    String url = "jdbc:oracle:thin:@localhost:1521:ZFY";

    String username = "briup";

    String password = "briup";

    Connection conn = null;

    //建立数据库连接的第一种方法,也是最常用的方法

    try {

      //1、实例化驱动类

      //  Class.forName(driverName) ;

      //  OracleDriver driver = new OracleDriver();

      //2、注册驱动,获取连接

      //  Drivehttp://rManager.registerDriver(driver);

      conn = DriverManager.getConnection(url, username, password);

      System.out.println(conn);

     } catch (Exception e) {

        e.printStackTrace();

      }finally{

    //4、关闭连接

    try {

      if (conn!=null)

      conn.close();

      } catch (SQLException e) {

        e.printStackTrace();

       } 

     }

   }

}

希望本文所述对大家的java程序设计有所帮助。

<think>我们正在讨论Java JDBC中的fetchSize参数。这个参数用于控制从数据库服务器每次获取的行数,对于优化内存使用和减少网络往返次数非常重要。根据引用[1],Oracle JDBC驱动默认fetchSize为10,增大这个值可以减少客户端与数据库的通信次数,但设置过大可能增加中间件内存消耗(一般建议不超过100)。引用[2]提到MySQL JDBC驱动对fetchSize的支持可能不一致,有些情况下会被忽略,需要查看源码确认。引用[4]指出,fetchSize生效的条件是事务非自动提交(autocommit=false),Oracle默认满足此条件,而LightDB需要手动设置。引用[5]则说明即使设置了fetchSize,也可能因为配置不当导致不生效,从而引发OOM问题。 现在,我将详细解释fetchSize的用法和设置方法: ### 一、fetchSize的作用 1. **减少网络往返**:默认情况下,JDBC驱动每次从数据库获取少量数据(如Oracle默认10行)。设置`fetchSize`可指定每次从数据库获取的行数,减少网络通信次数[^1]。 2. **控制内存占用**:避免一次性加载全部结果集到内存,尤其处理大数据量时[^5]。 ### 二、基本用法 ```java // 创建Statement时指定游标类型 Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY ); // 设置fetchSize(关键步骤) stmt.setFetchSize(100); // 每次从数据库获取100行 ResultSet rs = stmt.executeQuery("SELECT * FROM large_table"); while (rs.next()) { // 处理每行数据(避免整体加载到集合) } ``` ### 三、不同数据库的注意事项 | 数据库 | fetchSize生效条件 | 说明 | |----------|---------------------------------------|----------------------------------------------------------------------| | Oracle | 默认生效 | 增大fetchSize可提升性能,但建议不超过100[^1] | | MySQL | 需结合`useCursorFetch=true`参数 | 部分驱动版本需在连接字符串添加参数才能生效[^2] | | PostgreSQL | 自动生效 | 无需额外配置 | | SQL Server | 需指定游标类型 | 必须使用`TYPE_FORWARD_ONLY` | #### MySQL 示例连接字符串 ```java String url = "jdbc:mysql://localhost:3306/testdb?useCursorFetch=true"; Connection conn = DriverManager.getConnection(url, user, password); ``` ### 四、事务提交模式要求 - **必须关闭自动提交**:`conn.setAutoCommit(false);` 引用[4]指出,Oracle默认满足此条件,但LightDB、MySQL等需手动设置: ```java Connection conn = ...; conn.setAutoCommit(false); // 关键:使fetchSize生效 ``` ### 五、常见问题解决 1. **fetchSize不生效**: - 检查是否设置游标类型:`ResultSet.TYPE_FORWARD_ONLY` - MySQL添加`?useCursorFetch=true`连接参数 - 关闭自动提交:`conn.setAutoCommit(false)` 2. **深分页性能问题**: - 避免大偏移量`OFFSET`,改用`WHERE id > last_id`分页 - 结合`fetchSize`实现流式分页 ### 六、完整示例(MySQL) ```java public void readLargeData() throws SQLException { // 连接字符串添加useCursorFetch参数 String url = "jdbc:mysql://localhost:3306/testdb?useCursorFetch=true"; try (Connection conn = DriverManager.getConnection(url, "user", "password")) { // 关闭自动提交 conn.setAutoCommit(false); Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY ); stmt.setFetchSize(100); // 设置每次获取100行 ResultSet rs = stmt.executeQuery("SELECT * FROM billion_row_table"); while (rs.next()) { // 流式处理数据(示例:仅打印ID) System.out.println(rs.getLong("id")); } } } ``` ### 七、性能优化建议 1. **fetchSize取值**: - 初始值建议100,根据网络延迟和内存调整 - 监控GC频率,避免内存压力过大[^1] 2. **结果集处理原则**: - 遍历时直接处理数据,**禁止**存入`ArrayList`等集合 - 复杂业务可分批写入文件/外部存储 > **关键结论**:`fetchSize`是JDBC优化大数据查询的核心参数,但必须结合游标类型、事务提交模式及数据库特性正确使用[^1][^4][^5]。 §§相关问题§§ 1. 为什么MySQL的fetchSize需要设置`useCursorFetch=true`参数? 2. 如何验证fetchSize是否生效? 3. 使用fetchSize时,数据库游标资源何时释放? 4. 哪些场景不适合使用fetchSize? 5. fetchSize与JDBC批量更新(`executeBatch`)有何区别?</think>### Java JDBC `fetchSize` 用法详解 `fetchSize` 是 JDBC API 中的关键参数,用于**控制数据库驱动每次从服务器获取的数据行数**,能显著优化大数据查询的性能和内存占用。以下是详细用法和注意事项: --- #### 一、核心作用 1. **减少网络往返次数** 默认情况下(如 Oracle 默认 fetchSize=10),JDBC 驱动会多次访问数据库获取数据。增大 `fetchSize` 可减少网络通信次数[^1]。 ```java stmt.setFetchSize(100); // 每次从数据库获取100行 ``` 2. **控制内存占用** 避免一次性加载全部结果集到内存,防止 OOM(尤其处理百万级数据时)[^5]。 3. **流式处理支持** 结合 `TYPE_FORWARD_ONLY` 游标实现低内存消耗的流式处理: ```java Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY ); ``` --- #### 二、正确设置方法 ##### 1. 基础设置 ```java try (Connection conn = DriverManager.getConnection(url, user, pwd)) { Statement stmt = conn.createStatement(); stmt.setFetchSize(50); // 设置每次获取50行 ResultSet rs = stmt.executeQuery("SELECT * FROM large_table"); while (rs.next()) { // 处理数据(避免存入集合) } } ``` ##### 2. 不同数据库的适配 | 数据库 | 关键配置 | 注意事项 | |-----------|--------------------------------------------------------------------------|--------------------------------------------------------------------------| | **Oracle** | 默认生效 | 建议值 ≤ 100[^1] | | **MySQL** | 需添加连接参数:`jdbc:mysql://host/db?useCursorFetch=true` | 部分驱动版本可能忽略该设置[^2] | | **PostgreSQL** | 自动生效 | 无需额外配置 | | **SQL Server** | 需使用 `TYPE_FORWARD_ONLY` 游标 | 必须配合流式游标使用 | --- #### 三、必须满足的条件 1. **关闭自动提交** `fetchSize` 仅在非自动提交模式下生效[^4]: ```java conn.setAutoCommit(false); // 关键步骤! ``` 2. **使用正确游标类型** 必须配合 `TYPE_FORWARD_ONLY` 游标: ```java // 正确示例 PreparedStatement pstmt = conn.prepareStatement( sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY ); ``` 3. **避免全量加载** 遍历时禁止将结果集存入集合: ```java // 错误做法(导致内存溢出) List<Data> list = new ArrayList<>(); while (rs.next()) { list.add(extractData(rs)); // 逐行存入集合 } // 正确做法(流式处理) while (rs.next()) { processImmediately(rs); // 直接处理每行数据 } ``` --- #### 四、典型问题解决 ##### 场景:MySQL 的 `fetchSize` 不生效 **解决方案**: 1. 在连接字符串添加参数: ```java jdbc:mysql://localhost/db?useCursorFetch=true ``` 2. 验证游标类型是否为 `TYPE_FORWARD_ONLY` ##### 场景:LightDB/Oracle 事务差异 - Oracle 默认 `autocommit=false`,LightDB 需手动关闭[^4]: ```java // LightDB 必须显式设置 conn.setAutoCommit(false); conn.commit(); // 处理完一批数据后提交 ``` --- #### 五、性能优化建议 1. **取值建议** - 测试环境基准值:100 - 高网络延迟环境:200-500 - 内存敏感场景:50-100 2. **监控指标** ```java ResultSet rs = ...; int actualFetchSize = rs.getFetchSize(); // 验证实际生效值 ``` 3. **深分页优化** 结合 `WHERE id > last_id` 替代 `OFFSET` 避免全表扫描: ```sql SELECT * FROM orders WHERE id > 1000 ORDER BY id LIMIT 100 ``` > **关键总结**:`fetchSize` 是通过减少客户端与数据库的交互次数来优化性能的JDBC核心参数,但必须配合正确的游标类型和事务设置才能生效[^1][^4][^5]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值