Java笔试面试题AI答之JDBC(3)

2024-09-07 21:20
文章标签 java ai 笔试 面试题 jdbc

本文主要是介绍Java笔试面试题AI答之JDBC(3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 13. 编写JDBC连Oracle的程序?
  • 14. 简述JDBC的主要组件有哪些 ?
  • 15. JDBC中如何防止SQL注入攻击?
      • 1. 使用预处理语句(PreparedStatement)
      • 2. 避免在SQL查询中直接拼接用户输入的数据
      • 总结
  • 16. JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?
      • 脏读(Dirty Read)
      • 哪种数据库隔离级别能防止脏读?
  • 17. 简述JDBC execute,executeQuery,executeUpdate的区别 ?
      • 1. executeQuery(String sql)
      • 2. executeUpdate(String sql)
      • 3. execute(String sql)
      • 总结
  • 18. 编写JDBC - SQL查询出来的结果分页展示 ?
      • 1. 准备JDBC连接
      • 2. 实现分页查询
      • 3. 调用分页查询方法
      • 注意事项

13. 编写JDBC连Oracle的程序?

要使用JDBC(Java Database Connectivity)连接到Oracle数据库,你需要首先确保你的开发环境中已经包含了Oracle JDBC驱动(通常是ojdbc.jar文件)。然后,你可以按照以下步骤编写一个基本的JDBC程序来连接Oracle数据库并执行简单的SQL查询。

以下是一个简单的示例,展示如何连接到Oracle数据库,并执行一个查询来获取一些数据:

  1. 添加JDBC驱动到你的项目

    • 如果你在使用IDE(如IntelliJ IDEA, Eclipse等),可以通过项目的库管理功能添加ojdbc.jar文件。
    • 或者,如果你在使用构建工具(如Maven或Gradle),可以添加相应的依赖项(但注意,Oracle JDBC驱动可能不在公共Maven仓库中,你可能需要手动下载并添加到项目中)。
  2. 编写JDBC程序

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class OracleJDBCExample {public static void main(String[] args) {// 数据库URL,包含协议、数据库IP、端口号、数据库名称String url = "jdbc:oracle:thin:@localhost:1521:XE"; // XE是Oracle Express Edition的默认SID// Oracle数据库的用户名和密码String user = "system";String password = "your_password";try {// 加载Oracle JDBC驱动Class.forName("oracle.jdbc.driver.OracleDriver");// 获取数据库连接Connection conn = DriverManager.getConnection(url, user, password);// 创建Statement对象Statement stmt = conn.createStatement();// 执行SQL查询String sql = "SELECT * FROM your_table_name"; // 替换your_table_name为你的表名ResultSet rs = stmt.executeQuery(sql);// 处理查询结果while (rs.next()) {// 假设表有两列,分别名为column1和column2int id = rs.getInt("column1");String name = rs.getString("column2");System.out.println("ID: " + id + ", Name: " + name);}// 关闭资源rs.close();stmt.close();conn.close();} catch (Exception e) {e.printStackTrace();}}
}

注意

  • 你需要将jdbc:oracle:thin:@localhost:1521:XE中的localhost1521XE替换为你的Oracle数据库的实际地址、端口号和SID(或ServiceName)。
  • systemyour_password应替换为你的Oracle数据库的实际用户名和密码。
  • 确保Oracle数据库正在运行,并且可以从你的Java应用程序访问。
  • 你需要替换your_table_name以及对应的列名(column1column2)以匹配你的数据库表结构。
  • 处理JDBC连接时,不要忘记处理可能抛出的异常,并且在最后关闭ResultSet、Statement和Connection资源,以避免资源泄露。

以上就是使用JDBC连接Oracle数据库并执行简单查询的基本步骤。

14. 简述JDBC的主要组件有哪些 ?

JDBC(Java Database Connectivity)是一个Java API,用于执行SQL语句,并访问存储在数据库中的数据。JDBC为Java应用程序提供了一套完整的接口来连接数据库,发送SQL语句,并处理结果。JDBC的主要组件包括以下几个方面:

  1. JDBC API

    • 这是一组Java类和接口,它们定义了在Java应用程序中如何连接到数据库、发送SQL语句、处理结果以及关闭数据库连接的标准方法。JDBC API主要由java.sql包提供,包括用于数据库连接(Connection)、执行SQL语句(Statement, PreparedStatement, CallableStatement)、处理结果集(ResultSet)、管理元数据(DatabaseMetaData, ResultSetMetaData)等的类和接口。
  2. JDBC Driver(JDBC驱动程序):

    • JDBC驱动程序是实现JDBC API的类库,它负责将JDBC调用转换为特定数据库系统能理解的协议。JDBC驱动程序有四种类型:JDBC-ODBC桥接器、本地API部分Java驱动程序、纯Java网络协议JDBC驱动程序(中间层驱动程序)和纯Java数据库JDBC驱动程序(直接驱动程序)。
  3. JDBC URL

    • JDBC URL(统一资源定位符)用于标识数据库的位置和如何连接到数据库。它包含了数据库的位置、数据库的名称以及连接数据库所需的其他参数(如用户名和密码)。JDBC URL的格式依赖于所使用的JDBC驱动程序。
  4. Connection

    • Connection接口代表与特定数据库的连接。它提供了创建StatementPreparedStatementCallableStatement对象的方法,以及控制事务边界(例如,提交和回滚)的方法。
  5. Statement

    • Statement接口用于执行静态SQL语句并返回它所产生结果的对象。它提供了执行SQL语句(executeQuery用于返回结果集的SQL查询,executeUpdate用于更新数据的SQL语句,如INSERT、UPDATE或DELETE)的方法。
  6. PreparedStatement

    • PreparedStatement接口继承自Statement接口,它表示预编译的SQL语句。与Statement相比,PreparedStatement对象可以具有不同的SQL语句,但它允许数据库预编译这些语句,从而提高性能,并防止SQL注入攻击。
  7. ResultSet

    • ResultSet接口表示数据库查询的结果集,它封装了从数据库表中检索的数据。ResultSet对象具有指向其当前行的光标,并提供了遍历其数据、检索列值以及更新行中列值的方法。
  8. SQLException

    • SQLException是处理数据库操作时可能抛出的异常类型。它是所有JDBC异常的超类,用于表示在数据库访问过程中发生的错误。

这些组件共同构成了JDBC的核心,使得Java应用程序能够以一种统一和标准化的方式访问各种数据库系统。

15. JDBC中如何防止SQL注入攻击?

在JDBC(Java Database Connectivity)中防止SQL注入攻击主要依赖于两个策略:使用预处理语句(PreparedStatement)和避免在SQL查询中直接拼接用户输入的数据。下面详细介绍这两个策略:

1. 使用预处理语句(PreparedStatement)

预处理语句是防止SQL注入的首选方法。PreparedStatement对象允许你发送参数化SQL语句到数据库,而不必将用户输入数据直接拼接到SQL语句中。这样,数据库就会知道哪些部分是SQL语句本身,哪些部分是参数值,从而避免了SQL注入的风险。

示例代码

String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
try (Connection conn = DriverManager.getConnection(url, username, password);PreparedStatement pstmt = conn.prepareStatement(sql)) {pstmt.setString(1, userInputUsername);pstmt.setString(2, userInputPassword);ResultSet rs = pstmt.executeQuery();while (rs.next()) {// 处理结果集}
} catch (SQLException e) {e.printStackTrace();
}

在这个例子中,?是参数占位符,它们将在执行前被setString方法提供的实际值替换。

2. 避免在SQL查询中直接拼接用户输入的数据

如果你不使用PreparedStatement,而是选择构建动态SQL语句,那么你需要非常小心地处理用户输入,避免SQL注入。这通常涉及到对用户输入进行严格的验证和清理,但这并不是一个可靠的防御措施,因为总有可能遗漏某些攻击模式。

不推荐的做法(仅为说明问题,不应在生产代码中这样做):

String userInput = "someUser; DROP TABLE users;";
String sql = "SELECT * FROM users WHERE username = '" + userInput + "'";
// 这里存在SQL注入的风险

总结

  • 始终使用PreparedStatement:这是防止SQL注入的最有效方法。
  • 避免在SQL语句中直接拼接用户输入:这种做法极易受到SQL注入攻击。
  • 验证和清理用户输入:虽然不是防止SQL注入的主要手段,但在处理用户输入时仍应进行基本的验证和清理,以防止其他类型的攻击或错误。

通过使用预处理语句,你可以大大减少应用程序中SQL注入的风险,同时保持代码的清晰和可维护性。

16. JDBC的脏读是什么?哪种数据库隔离级别能防止脏读?

JDBC(Java Database Connectivity)是Java语言中用于执行SQL语句的API,它允许Java应用程序连接到数据库,并执行查询或更新操作。在数据库操作中,尤其是涉及到多个事务时,会出现一些并发问题,如脏读(Dirty Read)、不可重复读(Non-Repeatable Read)和幻读(Phantom Read)。

脏读(Dirty Read)

脏读是指一个事务读取到了另一个事务未提交的数据。这通常发生在两个事务并发执行时,其中一个事务修改了数据但尚未提交,而另一个事务却读取了这些尚未提交的数据。如果第一个事务回滚(撤销其更改),则第二个事务读取的数据将是不一致的或“脏”的。

哪种数据库隔离级别能防止脏读?

数据库事务的隔离级别决定了事务可能受并发操作影响的程度。SQL标准定义了四个隔离级别,从低到高依次为:

  1. READ UNCOMMITTED(读未提交):最低级别,允许脏读,即一个事务可能读取到另一个事务未提交的数据。
  2. READ COMMITTED(读已提交):保证一个事务不会读取到另一个事务未提交的数据,从而避免了脏读。但是,它不能保证一个事务重新读取它之前读取过的数据时,数据不会发生变化(即可能遇到不可重复读)。
  3. REPEATABLE READ(可重复读):保证在同一个事务中多次读取同一数据的结果是一致的,从而避免了脏读和不可重复读。但是,它仍然可能遇到幻读(即当事务重新执行一个查询时,可能会看到之前不存在的额外记录)。
  4. SERIALIZABLE(可串行化):最高的隔离级别,它通过强制事务串行执行,来避免脏读、不可重复读和幻读。但是,这会严重影响性能,因为它实际上是通过锁定表或行来阻止其他事务插入、更新或删除同一表中的数据。

因此,能够防止脏读的最低数据库隔离级别是READ COMMITTED。在这个级别下,一个事务只能读取到已经被其他事务提交的数据,从而避免了脏读的问题。

17. 简述JDBC execute,executeQuery,executeUpdate的区别 ?

JDBC(Java Database Connectivity)是Java编程语言中用于执行SQL语句的一套API,它允许Java程序与数据库进行交互。在JDBC中,executeexecuteQueryexecuteUpdateStatement接口中用于执行SQL语句的三个重要方法,它们各自有不同的用途和返回值。

1. executeQuery(String sql)

  • 用途:用于执行返回单个ResultSet对象的SQL语句,通常是SELECT语句。
  • 返回值:返回一个ResultSet对象,该对象包含SQL查询的结果。如果查询不返回任何结果,则返回的ResultSet对象将为空。
  • 注意:如果执行的SQL语句不是SELECT语句,那么executeQuery方法将抛出SQLException

2. executeUpdate(String sql)

  • 用途:用于执行INSERT、UPDATE、DELETE或DDL(数据定义语言)语句,如CREATE TABLE、DROP TABLE等,这些语句不返回结果集。
  • 返回值:返回一个整数,表示受影响的行数(即,由于执行该语句而更新、插入或删除的行数)。对于不返回任何行数的SQL语句,返回0。
  • 注意:如果执行的SQL语句是SELECT语句,那么executeUpdate方法将抛出SQLException

3. execute(String sql)

  • 用途:是一个更通用的方法,可以用来执行任何类型的SQL语句,并返回一个布尔值来指示返回的结果类型。
  • 返回值
    • 如果返回的结果是一个ResultSet对象,则此方法返回true
    • 如果返回的是更新计数(即受影响的行数)或没有结果,则返回false
  • 注意execute方法需要额外的步骤来检索ResultSet对象或更新计数。如果返回true,可以通过调用getResultSet方法来获取ResultSet对象;如果返回false,可以通过调用getUpdateCount方法来获取受影响的行数。

总结

  • executeQuery:用于执行SELECT语句,返回查询结果集。
  • executeUpdate:用于执行INSERT、UPDATE、DELETE或DDL语句,返回受影响的行数。
  • execute:是一个更通用的方法,可以执行任何类型的SQL语句,并返回一个布尔值来指示返回的结果类型,需要额外的步骤来获取结果集或更新计数。

18. 编写JDBC - SQL查询出来的结果分页展示 ?

在Java中,使用JDBC进行数据库操作时,分页查询通常不会直接在SQL查询语句中完成(虽然某些数据库如MySQL、PostgreSQL等提供了分页的SQL语法),而是通过应用层代码来控制。这里我将展示一个通用的方法来使用JDBC实现分页查询,并通过修改查询的起始点和查询的行数来分页展示结果。

以下是一个基本的步骤和示例代码,假设我们使用MySQL数据库,并且有一个users表,它包含id(主键)、nameemail等字段。

1. 准备JDBC连接

首先,你需要准备JDBC连接到你的数据库。这通常包括加载数据库驱动、建立连接等步骤。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class PaginationExample {private static final String URL = "jdbc:mysql://localhost:3306/your_database";private static final String USER = "your_username";private static final String PASSWORD = "your_password";public static Connection getConnection() throws SQLException {return DriverManager.getConnection(URL, USER, PASSWORD);}// ... 其他代码
}

2. 实现分页查询

接下来,我们需要编写一个方法来执行分页查询。这个方法将接受页码(pageNo)和每页显示的记录数(pageSize)作为参数,并返回该页的记录。

public static void fetchDataWithPagination(int pageNo, int pageSize) {String sql = "SELECT * FROM users LIMIT ?, ?";try (Connection conn = getConnection();PreparedStatement pstmt = conn.prepareStatement(sql)) {// 计算LIMIT语句中的起始索引(注意:LIMIT的起始索引是从0开始的)int offset = (pageNo - 1) * pageSize;pstmt.setInt(1, offset);pstmt.setInt(2, pageSize);ResultSet rs = pstmt.executeQuery();while (rs.next()) {// 假设users表有id, name, email字段int id = rs.getInt("id");String name = rs.getString("name");String email = rs.getString("email");// 打印或其他处理...System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);}} catch (SQLException e) {e.printStackTrace();}
}

3. 调用分页查询方法

现在,你可以通过调用fetchDataWithPagination方法来获取不同页的数据了。

public static void main(String[] args) {// 假设我们想要获取第1页的数据,每页显示5条记录fetchDataWithPagination(1, 5);// 如果你想获取第2页的数据,只需更改pageNo的值// fetchDataWithPagination(2, 5);
}

注意事项

  • 在实际应用中,你还需要处理一些额外的逻辑,比如计算总页数、处理用户输入的页码等。
  • 如果数据库本身支持分页查询(如MySQL的LIMIT、PostgreSQL的LIMITOFFSET),则可以直接在SQL语句中完成分页,但JDBC中的处理方式通常更为灵活和通用。
  • 考虑到性能和资源使用,分页查询时应该尽量避免一次性加载大量数据。

答案来自文心一言,仅供参考
在这里插入图片描述

这篇关于Java笔试面试题AI答之JDBC(3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146197

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory