什么是JDBC API以及何时使用它?
Java数据库连接API允许我们使用关系数据库.JDBC API接口和类是java.sql和javax.sql包的一部分。我们可以使用JDBC API来获取数据库连接,在数据库服务器中运行SQL查询和存储过程并处理结果。JDBC API的编写方式允许我们的Java的程序和实际的JDBC驱动程序之间的松散耦合,这使我们可以轻松地从一个数据库切换到另一个数据库服务器。
什么是不同类型的JDBC驱动程序?
有四种类型的JDBC驱动程序。任何与数据库一起使用的java程序都有两个部分,第一部分是JDBC API,第二部分是执行实际工作的驱动程序。- JDBC-ODBC Bridge加ODBC驱动程序(类型1):它使用ODBC驱动程序连接到数据库。我们应该安装ODBC驱动程序来连接数据库,这就是为什么这个驱动程序几乎已经过时的原因。
- Native API部分支持Java技术的驱动程序(类型2):此驱动程序将JDBC类转换为数据库服务器的客户端API。由于对数据库客户端API驱动程序的额外依赖性,这也不是首选驱动程序。
- 用于数据库中间件的纯Java驱动程序(类型3):此驱动程序将JDBC调用发送到可以连接到不同类型数据库的中间件服务器。我们应该安装一个中间件服务器来使用这个驱动程序。这增加了额外的网络调用和降低性能,这就是为什么不广泛使用JDBC驱动程序。
- 直接到数据库的纯Java驱动程序(类型4):此驱动程序将JDBC调用转换为数据库服务器可以理解的网络协议。该解决方案简单,适用于网络上的数据库连接。但是对于此解决方案,我们应该使用特定于数据库的驱动程序,例如Oracle for Oracle DB的OJDBC jar和MySQL Connector的MySQL Connector / J.
JDBC API如何帮助我们实现Java程序和JDBC驱动程序API之间的松散耦合?
JDBC API使用Java Reflection API实现java程序和JDBC驱动程序之间的松散耦合。如果你看一个简单的JDBC例子,你会注意到所有的编程都是用JDBC API完成的,而驱动程序只有在使用类.forName()方法通过反射加载时才会出现。我认为这是在核心java类中使用Reflection的最佳示例之一,以确保我们的应用程序不能直接使用Drivers API,这使得从一个数据库移动到另一个数据库变得非常容易。请在JDBC示例中阅读更多内容。
什么是JDBC连接?解释在简单的java程序中获取数据库连接的步骤。
JDBC连接就像使用数据库服务器创建的会话。您还可以将连接视为来自数据库服务器的Socket连接。创建JDBC连接非常简单,需要两个步骤:
- 注册并加载驱动程序:使用Class.forName(),将驱动程序类注册到DriverManager并加载到内存中。
- 使用DriverManager获取Connection对象:我们通过传递数据库URL字符串,用户名和密码作为参数从DriverManager.getConnection()获取连接对象。
JDBC DriverManager类有什么用?
JDBC DriverManager是我们通过它获取数据库连接对象的工厂类。当我们加载JDBC驱动程序类时,它将自己注册到DriverManager,您可以查找JDBC驱动程序类源代码来检查它。然后,当我们通过传递数据库配置详细信息调用DriverManager.getConnection()方法时,DriverManager使用已注册的驱动程序获取Connection并将其返回给调用者程序。
什么是JDBC声明?
JDBC API语句用于在数据库中执行SQL查询。我们可以通过调用Connection getStatement()方法来创建语句对象。我们可以使用语句通过不同的执行方法传递查询来执行静态SQL查询,例如execute(),executeQuery( ),executeUpdate()等。由于查询是在java程序中生成的,如果用户输入没有正确验证它可以导致SQL注入问题,更多细节可以在SQL注入示例中找到。默认情况下,每个Statement对象只能同时打开一个ResultSet对象。因此,如果我们想要使用多个ResultSet对象,则每个对象必须由不同的语句对象生成。如果存在打开的对象,则语句接口中的所有execute()方法都会隐式关闭语句的当前ResultSet对象。
execute,executeQuery,executeUpdate有什么区别?
语句执行(字符串查询)用于执行任何SQL查询,如果结果是ResultSet(例如运行选择查询),则返回TRUE。当没有ResultSet对象(如运行插入或更新查询)时,输出为FALSE。我们可以使用getResultSet()来获取ResultSet和getUpdateCount()方法来检索更新计数。语句executeQuery(String query)用于执行选择查询并返回ResultSet。即使没有与查询匹配的记录,返回的ResultSet也永远不会为null。执行选择查询时,我们应该使用executeQuery方法,这样如果有人试图执行insert / update语句,它将抛出java.sql.SQLException,并显示消息“executeQuery方法不能用于更新”。语句executeUpdate(String query)用于执行不返回任何内容的插入/更新/删除(DML)语句或DDL语句。输出为INT,等于SQL数据操作语言(DML)语句的行数。对于DDL语句,输出为0。只有在不确定语句类 时才应使用的execute()方法,否则使用的executeQuery或executeUpdate的方法。
什么是JDBC PreparedStatement?
JDBC PreparedStatement对象表示预编译的SQL语句。我们可以使用它的setter方法来设置查询的变量。由于PreparedStatement是预编译的,因此可以使用它多次有效地执行此语句.PreparedStatement 是Statement的更好选择,因为它会自动转义特殊字符并避免SQL注入攻击。
如何在JDBC PreparedStatement中设置NULL值?
我们可以使用PreparedStatement setNull()方法将null变量绑定到参数.setNull 方法将index和SQL类型作为参数,例如ps.setNull(10,java.sql.Types.INTEGER);.
PreparedStatement对Statement的好处是什么?
PreparedStatement对Statement的一些好处是:PreparedStatement帮助我们防止SQL注入攻击,因为它会自动转义特殊字符.PreparedStatement 允许我们使用参数输入执行动态查询.PreparedStatement比语句更快。当我们重用PreparedStatement或使用它的批处理方法执行多个查询时,它变得更加明显.PreparedStatement帮助我们使用setter方法编写面向对象的代码,而使用语句我们必须使用String Concatenation来创建查询。如果要设置多个参数,则使用字符串连接编写查询看起来非常难看并且容易出错。
PreparedStatement的限制是什么以及如何克服它?
- PreparedStatement的一个限制是我们不能直接在IN子句中使用它。将PreparedStatement与IN子句一起使用的一些替代方法是:
- 执行单一查询 - 性能非常慢,不推荐使用
- 使用存储过程 - 特定于数据库,因此不适用于多个数据库应用程序。
- 动态创建PreparedStatement查询 - 良好的方法但失去了缓存的PreparedStatement的好处。
- 在PreparedStatement查询中使用NULL - 当你知道输入的最大变量数时,这是一种很好的方法,可以通过部分执行来扩展以允许无限制的参数。
什么是JDBC ResultSet?
JDBC ResultSet类似于表示数据库结果集的数据表,通常通过执行查询数据库的语句来生成数据库结果集.ResultSet对象维护指向其当前数据行的游标。最初,光标位于第一行之前.next ()方法将光标移动到下一行。如果没有更多行,则下一个()方法返回假,并且可以在同时循环中使用它来迭代结果集。默认的ResultSet的对象不可更新,并且只有一个向前移动的游标。因此,你只能迭代一次,并且只能从第一行到最后一行。可以使用以下语法生成可滚动和/或可更新的ResultSet对象。语句stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); 当生成它的陈述对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,ResultSet对象将自动关闭。我们可以使用ResultSet getter方法,从1开始的列名或索引号来检索列数据。
什么是不同类型的ResultSet?
在创建声明时,我们可以根据用户输入获得不同类型的结果集对象。如果您将查看连接方法,您将看到的createStatement()和prepareStatement()方法被重载以提供结果集类型和并发作为输入参数。结果集对象有三种类型。
- ResultSet.TYPE_FORWARD_ONLY:这是默认类型,游标只能在结果集中向前移动。
- ResultSet.TYPE_SCROLL_INSENSITIVE:游标可以前后移动,结果集对创建结果集后其他人对数据库所做的更改不敏感。
- ResultSet.TYPE_SCROLL_SENSITIVE:游标可以向前和向后移动,结果集对创建结果集后其他人对数据库所做的更改很敏感。
基于并发性,有两种类型的ResultSet对象。
- 为ResultSet.CONCUR_READ_ONLY:结果集是只读的,这是默认的并发类型。
- ResultSet.CONCUR_UPDATABLE:我们可以使用ResultSet更新方法来更新行数据。
Statement中的setFetchSize()和setMaxRows()方法有什么用?
我们可以使用setMaxRows(int i)方法来限制数据库从查询返回的行数。例如,在MySQL中,我们可以使用LIMIT子句来设置查询返回的最大行数。解解fetchSize可能很棘手,因为你应该知道Statement和ResultSet是如何工作的。当我们在数据库中执行查询时,将在数据库缓存中获取并维护结果,并返回ResultSet。结果集是具有对数据库中结果的引用的游标。假设我们有一个返回100行的查询,并且我们已将fetchSize设置为10,因此在每次数据库访问时,JDBC驱动程序将只获取10行,因此将有10次访问以获取所有行。如果每行需要大量处理时间并且结果中的行数很大,那么设置最佳fetchSize会很有帮助。我们可以通过Statement对象设置fetchSize,但可以通过ResultSet对象setFetchSize()方法覆盖它。
如何使用JDBC API调用存储过程?
存储过程是一组SQL查询,它们在数据库中编译,可以从JDBC API执行.JDBC CallableStatement可用于在数据库中执行存储过程。初始化CallableStatement的语法是; CallableStatement stmt = con.prepareCall(“{call insertEmployee(?,?,?,?,?,?)}”); stmt.setInt(1,ID); stmt.setString(2,姓名); stmt.setString(3,作用); stmt.setString(4,城市); stmt.setString(5,国家); //在调用存储过程stmt.registerOutParameter(6,java.sql.Types.VARCHAR)之前注册OUT参数; stmt.executeUpdate(); 我们需要在执行CallableStatement之前注册OUT参数。
什么是JDBC批处理,它有什么好处?
有时我们需要为数据库运行类似的批量查询,例如将数据从CSV文件加载到关系数据库表。我们知道我们可以选择使用语句或PreparedStatement来执行查询。除了JDBC API提供了批处理功能,通过它我们可以一次性为数据库执行大量查询。JDBC API支持通过声明和PreparedStatement的addBatch()和则ExecuteBatch()方法进行批处理。批处理比一次执行一个语句更快,因为数据库调用的数量较少,请参阅JDBC批处理示例。
什么是JDBC事务管理以及我们为什么需要它?
默认情况下,当我们创建数据库连接时,它以自动提交模式运行。这意味着无论何时执行查询并完成查询,都会自动触发提交。因此,我们触发的每个SQL查询都是一个事务,如果我们运行一些DML或DDL查询,则在每个SQL语句完成后,更改将保存到数据库中。有时我们希望一组SQL查询成为事务的一部分,以便我们可以在所有查询运行正常时提交它们,如果我们JDBC API提供方法setAutoCommit(boolean flag),通过它我们可以禁用连接的自动提交功能。我们应该仅用于需要时禁用自动提交功能。因为任何异常,我们可以选择回滚作为事务的一部分执行的所有查询。除非我们在连接上调用commit()方法,否则不会提交事务。数据库服务器使用表锁来实现事务管理,这是资源密集型过程。所以我们应该在完成交易后立即提交交易。
如何回滚JDBC事务?
我们可以使用Connection对象rollback()方法来回滚事务。它将回滚事务所做的所有更改,并释放此Connection对象当前持有的所有数据库锁。
什么是JDBC Savepoint?如何使用它?
有时,事务可以是多个语句的组,我们希望回滚到事务中的特定点.JDBC Savepoint帮助我们在事务中创建检查点,并且我们可以回滚到该特定检查点。为事务创建的任何保存点都会自动释放,并在提交事务时或在回滚整个事务时变为无效。将事务滚动回保存点会自动释放并使在相关保存点之后创建的任何其他保存点无效。
什么是JDBC DataSource以及它的好处是什么?
JDBC DataSource是javax.sql包中定义的接口,它比DriverManager更强大,可用于数据库连接。我们可以使用DataSource来创建数据库连接,而驱动器实现类可以用来获取连接的实际工作。除了获取数据库连接外,DataSource还提供了一些其他功能,例如:
- 缓存PreparedStatement以加快处理速度
- 连接超时设置
- 记录功能
- ResultSet最大大小阈值
- 使用JNDI支持在servlet容器中连接池
什么是JDBC最佳实践?
一些JDBC最佳实践是:
- 数据库资源很多,因此请确保在完成后立即关闭它.Connection ,Statement,ResultSet和所有其他JDBC对象都定义了close()方法来关闭它们。
- 始终在代码中显式关闭结果集,语句和连接,因为如果您在连接池环境中工作,则可能会将连接返回到池,从而导致打开的结果集和语句对象导致资源泄漏。
- 关闭finally块中的资源,以确保即使在异常情况下它们也会关闭。
- 使用批处理进行类似的批量操作。
- 始终对语句使用PreparedStatement以避免SQL注入并获得PreparedStatement的预编译和缓存优势。
- 如果要将批量数据检索到结果集中,则为fetchSize设置最佳值有助于获得良好的性能。
- 数据库服务器可能不支持所有隔离级别,因此请在假设之前进行检查。
- 更严格的隔离级别会导致性能降低,因此请确保为数据库连接设置了最佳隔离级别。
- 如果要在Web应用程序中创建数据库连接,请尝试使用JNDI上下文使用JDBC DataSource资源来重用连接。
- 当你需要长时间使用ResultSet时,请尝试使用断开连接的RowSet。
关注公众号:「Java知己」,发送「1024」,免费领取 30 本经典编程书籍。与 10 万程序员一起进步。每天更新Java知识哦,期待你的到来!