JDBC面试总结

1、什么是JDBC,在什么时候会用到它?

  JDBC的全称是Java DataBase Connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。JDBC接口及相关类在java.sql包和javax.sql包里。我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。

  JDBC接口让Java程序和JDBC驱动实现了松耦合,使得切换不同的数据库变得更加简单。

2、JDBC是如何实现Java程序和JDBC驱动的松耦合的?

JDBC API使用Java的反射机制来实现Java程序和JDBC驱动的松耦合。随便看一个简单的JDBC示例,你会发现所有操作都是通过JDBC接口完成的,而驱动只有在通过Class.forName反射机制来加载的时候才会出现。

我觉得这是Java核心库里反射机制的最佳实践之一,它使得应用程序和驱动程序之间进行了隔离,让迁移数据库的工作变得更简单。在这里可以看到更多JDBC的使用示例。

3、什么是JDBC连接,在Java中如何创建一个JDBC连接?

JDBC连接是和数据库服务器建立的一个会话。你可以想像成是一个和数据库的Socket连接。

创建JDBC连接很简单,只需要两步:

  • A. 注册并加载驱动:使用Class.forName(),驱动类就会注册到DriverManager里面并加载到内存里。
  • B. 用DriverManager获取连接对象:调用DriverManager.getConnnection()方法并传入数据库连接的URL,用户名及密码,就能获取到连接对象。
Connection con = null;
try{
    // load the Driver Class
    Class.forName("com.mysql.jdbc.Driver");
    // create the connection now
    con = DriverManager.getConnection("jdbc:mysql://localhost:3306/UserDB",
                    "root",
                    "root");
    }catch (SQLException e) {
            System.out.println("Check database is UP and configs are correct");
            e.printStackTrace();
    }catch (ClassNotFoundException e) {
            System.out.println("Please include JDBC MySQL jar in classpath");
            e.printStackTrace();
    }

3、JDBC的DriverManager是用来做什么的?

JDBC的DriverManager是一个工厂类,我们通过它来创建数据库连接。当JDBC的Driver类被加载进来时,它会自己注册到DriverManager类里面,你可以看下JDBC Driver类的源码来了解一下。

然后我们会把数据库配置信息传成DriverManager.getConnection()方法,DriverManager会使用注册到它里面的驱动来获取数据库连接,并返回给调用的程序。

4、在Java程序中,如何获取数据库服务器的相关信息?

使用DatabaseMetaData可以获取到服务器的信息。当和数据库的连接成功建立了之后,可以通过调用getMetaData()方法来获取数据库的元信息。DatabaseMetaData里面有很多方法,通过它们可以获取到数据库的产品名称,版本号,配置信息等。

DatabaseMetaData metaData = con.getMetaData();
String dbProduct = metaData.getDatabaseProductName();

5、JDBC的Statement是什么?

Statement是JDBC中用来执行数据库SQL查询语句的接口。通过调用连接对象的getStatement()方法我们可以生成一个Statement对象。我们可以通过调用它的execute(),executeQuery(),executeUpdate()方法来执行静态SQL查询。

由于SQL语句是程序中传入的,如果没有对用户输入进行校验的话可能会引起SQL注入的问题。

6、execute,executeQuery,executeUpdate的区别是什么?

  • Statement的execute(String query)方法用来执行任意的SQL查询.
  • 如果是执行的sql是查询类型的select语句,此方法会返回true,需要自己再调用 statement.getResultSet() 方法来获取 Resultset结果集;
  • 如果是执行的更新类的sql语句如 update,delete,insert语句,此方法会返回false,自己调用statement.getUpdateCount() 返回sql语句影响的行数。
  • Statement的executeQuery(String query)接口用来执行select查询,并且返回ResultSet。即使查询不到记录返回的ResultSet也不会为null。
  • 我们通常使用executeQuery来执行查询语句,这样的话如果传进来的是insert或者update语句的话,它会抛出错误信息为 “executeQuery method can not be used for update”的java.util.SQLException。
  • Statement的executeUpdate(String query)方法用来执行insert、update、delete(DML)语句,或者 什么也不返回DDL语句。
  • 返回值是int类型,如果是DML语句的话,返回值就是更新的条数,如果是DDL的话,就返回0。

注意:只有当你不确定是什么语句的时候才应该使用execute()方法,否则应该使用executeQuery或者executeUpdate方法。

7、JDBC的PreparedStatement是什么?

PreparedStatement对象代表的是一个预编译的SQL语句。用它提供的setter方法可以传入查询的变量。

由于PreparedStatement是预编译的,通过它可以将对应的SQL语句高效的执行多次。由于PreparedStatement自动对特殊字符转义,避免了SQL注入攻击,因此应当尽量的使用它。

8、PreparedStatement中如何注入NULL值?

可以使用它的setNull方法来把null值绑定到指定的变量上。setNull方法需要传入参数的索引以及SQL字段的类型,像这样:

ps.setNull(10, java.sql.Types.INTEGER);.

9、Statement中的getGeneratedKeys方法有什么用?

有的时候表会生成主键,这时候就可以用Statement的getGeneratedKeys()方法来获取这个自动生成的主键的值了。

10、相对于Statement,PreparedStatement的优点是什么?

它和Statement相比优点在于:

  • PreparedStatement有助于防止SQL注入,因为它会自动对特殊字符转义。
  • PreparedStatement可以用来进行动态查询。
  • PreparedStatement执行更快。尤其当你重用它或者使用它的拼量查询接口执行多条语句时。
  • 使用PreparedStatement的setter方法更容易写出面向对象的代码,而Statement的话,我们得拼接字符串来生成查询语句。如果参数太多了,字符串拼接看起来会非常丑陋并且容易出错。

11、PreparedStatement的缺点是什么,怎么解决这个问题?

PreparedStatement的一个缺点是,我们不能直接用它来执行in条件语句;需要执行IN条件语句的话,下面有一些解决方案:

  • 分别进行单条查询——这样做性能很差,不推荐。
  • 使用存储过程——这取决于数据库的实现,不是所有数据库都支持。
  • 动态生成PreparedStatement——这是个好办法,但是不能享受PreparedStatement的缓存带来的好处了。
  • 在PreparedStatement查询中使用NULL值——如果你知道输入变量的最大个数的话,这是个不错的办法,扩展一下还可以支持无限参数。

12、JDBC的批处理是什么,有什么好处?

  有时候类似的查询我们需要执行很多遍,比如从CSV文件中加载数据到关系型数据库的表里。我们也知道,执行查询可以用Statement或者PreparedStatement。除此之外,JDBC还提供了批处理的特性,有了它,我们可以在一次数据库调用中执行多条查询语句。

  JDBC通过Statement和PreparedStatement中的addBatch和executeBatch方法来支持批处理。

  批处理比一条条语句执行的速度要快得多,因为它需要很少的数据库调用。

13、JDBC的事务管理是什么,为什么需要它?

  默认情况下,我们创建的数据库连接,是工作在自动提交的模式下的。这意味着只要我们执行完一条查询语句,就会自动进行提交。因此我们的每条查询,实际上都是一个事务,如果我们执行的是DML或者DDL,每条语句完成的时候,数据库就已经完成修改了。

  有的时候我们希望由一组SQL查询组成一个事务,如果它们都执行OK我们再进行提交,如果中途出现异常了,我们可以进行回滚。

  JDBC接口提供了一个setAutoCommit(boolean flag)方法,我们可以用它来关闭连接自动提交的特性。我们应该在需要手动提交时才关闭这个特性,不然的话事务不会自动提交,每次都得手动提交。数据库通过表锁来管理事务,这个操作非常消耗资源。因此我们应当完成操作后尽快的提交事务。在这里有更多关于事务的示例程序。

14、如何回滚事务?

  通过Connection对象的rollback方法可以回滚事务。它会回滚这次事务中的所有修改操作,并释放当前连接所持有的数据库锁。

15、常见的JDBC异常有哪些?

  有以下这些:

  • java.sql.SQLException——这是JDBC异常的基类。
  • java.sql.BatchUpdateException——当批处理操作执行失败的时候可能会抛出这个异常。这取决于具体的JDBC驱动的实现,它也可能直接抛出基类异常java.sql.SQLException。
  • java.sql.SQLWarning——SQL操作出现的警告信息。
  • java.sql.DataTruncation——字段值由于某些非正常原因被截断了(不是因为超过对应字段类型的长度限制)。

16、JDBC中存在哪些不同类型的锁?

  从广义上讲,有两种锁机制来防止多个用户同时操作引起的数据损坏。

  乐观锁——只有当更新数据的时候才会锁定记录。 悲观锁——从查询到更新和提交整个过程都会对数据记录进行加锁。

  不仅如此,一些数据库系统还提供了行锁,表锁等锁机制。

17、DDL和DML语句分别代表什么?

  DDL(数据定义语言,Data Definition Language)语句用来定义数据库模式。Create,Alter, Drop, Truncate, Rename都属于DDL语句,一般来说,它们是不返回结果的。

  DML(数据操作语言,Data Manipulation Language)语句用来操作数据库中的数据。select, insert, update, delete, call等,都属于DML语句。

18、JDBC里的CLOB和BLOB数据类型分别代表什么?

  CLOB意思是Character Large OBjects,字符大对象,它是由单字节字符组成的字符串数据,有自己专门的代码页。这种数据类型适用于存储超长的文本信息,那些可能会超出标准的VARCHAR数据类型长度限制(上限是32KB)的文本。

  BLOB是Binary Larget OBject,它是二进制大对象,由二进制数据组成,没有专门的代码页。它能用于存储超过VARBINARY限制(32KB)的二进制数据。这种数据类型适合存储图片,声音,图形,或者其它业务程序特定的数据。

19、如何把图片或者原始数据插入到数据库中?

  可以使用BLOB类型将图片或者原始的二进制数据存储到数据库里。

20、什么是JDBC的最佳实践?

下面列举了其中的一些:

  • 数据库资源是非常昂贵的,用完了应该尽快关闭它。Connection, Statement, ResultSet等JDBC对象都有close方法,调用它就好了。
  • 养成在代码中显式关闭掉ResultSet,Statement,Connection的习惯,如果你用的是连接池的话,连接用完后会放回池里,但是没有关闭的ResultSet和Statement就会造成资源泄漏了。
  • 在finally块中关闭资源,保证即便出了异常也能正常关闭。
  • 大量类似的查询应当使用批处理完成。
  • 尽量使用PreparedStatement而不是Statement,以避免SQL注入,同时还能通过预编译和缓存机制提升执行的效率。
  • 如果你要将大量数据读入到ResultSet中,应该合理的设置fetchSize以便提升性能。
  • 你用的数据库可能没有支持所有的隔离级别,用之前先仔细确认下。
  • 数据库隔离级别越高性能越差,确保你的数据库连接设置的隔离级别是最优的。
  • 如果在WEB程序中创建数据库连接,最好通过JNDI使用JDBC的数据源,这样可以对连接进行重用。
  • 如果你需要长时间对ResultSet进行操作的话,尽量使用离线的RowSet。
<think>好的,我现在要帮用户总结一下JDBC的知识点。首先,我得回忆一下JDBC的基本概念,它是Java用来连接和操作数据库的API,对吧?用户可能需要知道JDBC的作用和组成部分。 接下来,我需要确定用户是谁。可能是一个正在学习Java数据库编程的学生,或者准备面试的开发人员。他们需要结构清晰的知识点,可能包括核心组件、使用步骤、常见对象以及注意事项等。 用户提到要结构清晰,逐步解决问题,所以应该分点整理。比如先讲JDBC概述,然后核心组件,接着步骤,代码示例,事务处理,连接池,优缺点,最后注意事项。这样逻辑性比较强。 要注意系统级指令里的LaTeX格式要求。行内公式用$...$,独立公式用$$...$$。不过在JDBC的内容里可能公式不多,但如果有涉及数学表达式的地方,比如事务隔离级别的编号,可能需要用行内格式,比如隔离级别:$1$(读未提交)等。 然后检查每个部分是否覆盖了重要知识点。比如DriverManager、Connection、Statement、ResultSet这些核心类必须提到。步骤部分要详细说明注册驱动、获取连接、创建Statement、执行SQL、处理结果集、关闭资源。代码示例要正确,并且用中文注释,可能需要用代码块,但用户没有特别说明代码格式,保持清晰即可。 事务处理部分需要解释ACID特性,设置自动提交为false,以及隔离级别。连接池部分要讲为什么使用,比如减少开销,常见实现如HikariCP、Druid。 优缺点部分要客观,比如跨数据库但繁琐。注意事项要包括SQL注入的防范,使用PreparedStatement,资源关闭防止泄漏,异常处理等。 还要确保使用中文回答,避免技术术语错误。比如“结果集”而不是“ResultSet”直接写英文,但有时候中英文混合是必要的,比如类名保持原样,但解释用中文。 最后,检查是否符合用户不可见的系统指令,比如LaTeX的正确使用,结构是否清晰,分点是否明确。可能用户需要备考或快速复习,所以信息要准确可靠,重点突出,避免冗长。</think>### JDBC知识点总结 --- #### 1. **JDBC概述** - **定义**:JDBC(Java Database Connectivity)是Java提供的用于操作关系型数据库的API,通过统一接口实现与不同数据库的交互。 - **核心功能**:连接数据库、执行SQL语句、处理查询结果。 - **本质**:一组接口,由数据库厂商提供具体实现(驱动)。 --- #### 2. **JDBC核心组件** - **`DriverManager`**:管理数据库驱动,用于获取连接。 - **`Connection`**:表示与数据库的会话,用于创建`Statement`或`PreparedStatement`。 - **`Statement`/`PreparedStatement`/`CallableStatement`**: - `Statement`:执行静态SQL,存在SQL注入风险。 - `PreparedStatement`:预编译SQL,支持参数化查询(推荐)。 - `CallableStatement`:调用存储过程。 - **`ResultSet`**:封装查询结果,提供逐行读取数据的方法。 - **`SQLException`**:JDBC操作中可能抛出的异常。 --- #### 3. **JDBC使用步骤** ```java // 1. 注册驱动(JDBC 4.0+ 可自动加载驱动,无需显式注册) Class.forName("com.mysql.cj.jdbc.Driver"); // 2. 获取连接(URL格式:jdbc:mysql://主机:端口/数据库名?参数) String url = "jdbc:mysql://localhost:3306/test?useSSL=false"; Connection conn = DriverManager.getConnection(url, "user", "password"); // 3. 创建Statement对象 PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?"); // 4. 设置参数并执行SQL ps.setInt(1, 1001); ResultSet rs = ps.executeQuery(); // 5. 处理结果集 while (rs.next()) { String name = rs.getString("name"); System.out.println(name); } // 6. 关闭资源(倒序关闭) rs.close(); ps.close(); conn.close(); ``` --- #### 4. **事务管理** - **ACID特性**:原子性、一致性、隔离性、持久性。 - **关键操作**: ```java conn.setAutoCommit(false); // 关闭自动提交 try { // 执行多个SQL conn.commit(); // 提交事务 } catch (SQLException e) { conn.rollback(); // 回滚事务 } ``` - **隔离级别**:通过`conn.setTransactionIsolation(level)`设置: - `TRANSACTION_READ_UNCOMMITTED`(读未提交) - `TRANSACTION_READ_COMMITTED`(读已提交,推荐) - `TRANSACTION_REPEATABLE_READ`(可重复读) - `TRANSACTION_SERIALIZABLE`(串行化) --- #### 5. **数据库连接池** - **作用**:减少频繁创建/关闭连接的开销。 - **常见实现**: - **HikariCP**:高性能,轻量级。 - **Druid**:阿里开源,支持监控。 - **配置参数**:初始连接数、最大连接数、超时时间等。 --- #### 6. **JDBC的优缺点** - **优点**: - 跨数据库(通过更换驱动实现)。 - 直接控制底层SQL,灵活性高。 - **缺点**: - 代码冗余(需手动管理连接、资源)。 - 安全性依赖开发者(如SQL注入防范)。 --- #### 7. **注意事项** - **SQL注入防范**:必须使用`PreparedStatement`替代字符串拼接。 - **资源关闭**:确保`Connection`、`Statement`、`ResultSet`在`finally`块或try-with-resources中关闭。 - **异常处理**:捕获`SQLException`并妥善处理(如日志记录)。 --- #### 8. **扩展知识** - **ORM框架**:MyBatis、Hibernate等基于JDBC的更高层封装。 - **JDBC Template**:Spring框架对JDBC的简化工具。 --- 通过掌握以上知识点,可以系统性地理解JDBC的核心原理与应用场景,为进一步学习数据库操作框架打下基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值