创建一个以JDBC连接数据库的程序,包含7个步骤:
1、JDBC所需的四个参数(user,password,url,driverClass)
(1)user用户名;
(2)password密码;
(3)URL定义了连接数据库时的协议、子协议、数据源标识。
书写形式:协议:子协议:数据源标识。
协议:在JDBC中总是以jdbc开始。
子协议:是桥连接的驱动程序或是数据库管理系统名称。
数据源标识:标记找到数据库来源的地址与连接端口。
例如:(MySql的连接URL)
jdbc:mysql:
//localhost:3306/testuseUnicode=true&characterEncoding=gbk ;
useUnicode=true:表示使用Unicode字符集。如果characterEncoding设置为
gb2312或GBK,本参数必须设置为true 。characterEncoding=gbk:字符编码方式。
(4)driverClass连接数据库所需的驱动。
2、加载JDBC驱动程序
在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过javalangClass类的静态方法forName(String className)实现。
例如:
成功加载后,会将Driver类的实例注册到DriverManager类中。
3、创建数据库的连接
要连接数据库,需要向javasqlDriverManager请求并获得Connection对象,该对象就代表一个数据库的连接。使用DriverManager的getConnectin(String url , String username ,String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。
例如:
4、创建一个preparedStatement
要执行SQL语句,必须获得javasqlStatement实例,Statement实例分为以下3种类型:
(1)执行静态SQL语句。通常通过Statement实例实现。
(2)执行动态SQL语句。通常通过PreparedStatement实例实现。
(3)执行数据库存储过程。通常通过CallableStatement实例实现。
具体的实现方式:
5、执行SQL语句
Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate 和execute
(1)ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句 ,返回一个结果集(ResultSet)对象。
(2)int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等。
(3)execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。
具体实现的代码:
6、遍历结果集
两种情况:
(1)执行更新返回的是本次 *** 作影响到的记录数。
(2)执行查询返回的结果是一个ResultSet对象。
ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。
使用结果集(ResultSet)对象的访问方法获取数据:
注:列是从左到右编号的,并且从列1开始。
7、处理异常,关闭JDBC对象资源
*** 作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反:
(1)先关闭requestSet
(2)再关闭preparedStatement
(3)最后关闭连接对象connection
实现代码如下:
requestSetclose();
preparedStatementclose();
connectionclose();
import javasqlConnection;
import javasqlDriverManager;
import javasqlSQLException;
import javasqlStatement;
public class xxxx {
public static void main(String[] args) {
Connection con = null ;
Statement stmt = null ;
try {
ClassforName("commysqljdbcDriver"); //mysql为例 不一样的数据库所需的驱动包不一样 连接语句略有不同
con = DriverManagergetConnection("jdbc:mysql://127001:3306/数据库名", "root", "密码");
stmt = concreateStatement();
String sql = "insert into info values ('用户', 'mima', 'piapiapia~')";
stmtexecuteUpdate(sql);
} catch (ClassNotFoundException e) {
eprintStackTrace();
} catch (SQLException e) {
eprintStackTrace();
} finally {
try {
if(stmt != null) {
stmtclose();
stmt = null;
}
if (con != null) {
conclose();
con = null;
}
} catch (SQLException e) {
eprintStackTrace();
}
}
}
}
JDBC
入门
--
建立联接
你需要做的第一事情是你与想要使用的
DBMS
建立一个连接。这包含
2
个步骤:装载驱动程序并建立连接。
装载驱动程序
装载驱动程序只需要非常简单的一行代码。例如,你想要使用
JDBC-ODBC
桥驱动程序,
可以用下列代码装载它:
ClassforName("sunjdbcodbcJdbcOdbcDriver");
你的驱动程序文档将告诉你应该使用的类名。例如,
如果类名是
jdbcDriverXYZ
,你将用代码以下的代码装载驱动程序:
ClassforName("jdbcDriverXYZ");
你不需要创建一个驱动程序类的实例并且用
DriverManager
登记它,因为调用
ClassforName
将自动将加载驱动程序类。如果你曾自己创建实例,你将创建一个不必要的副本,但它不会带来什么坏处。
加载
Driver
类后,它们即可用来与数据库建立连接。
建立连接
第二步就是用适当的驱动程序类与
DBMS
建立一个连接。下列代码是一般的做法:
Connection
con
=
DriverManagergetConnection(url,
"myLogin",
"myPassword");
这个步骤也非常简单,最难的是怎么提供
url。如果你正在使用
JDBC-ODBC
桥,
JDBC
URL
将以
jdbc:odbc
开始:余下
URL
通常是你的数据源名字或
数据库系统
。因此,假设你正在使用
ODBC
存取一个叫
"Fred"
的
ODBC
数据源,你的
JDBC
URL
是
jdbc:odbc:Fred
。把
"myLogin"
及
"myPassword"
替换为你登陆
DBMS
的用户名及口令。如果你登陆数据库系统的用户名为
"Fernanda"
口令为
"J8",只需下面的
2
行代码就可以建立一个连接:
String
url
=
"jdbc:odbc:Fred";
Connection
con
=
DriverManagergetConnection(url,"Fernanda",
"J8");
如果你使用的是第三方开发了的
JDBC驱动程序
,文档将告诉你该使用什么
subprotocol,
就是在
JDBC
URL
中放在
jdbc
后面的部分。例如,
如果驱动程序开发者注册了
acme
作为
subprotocol,
JDBC
URL
的第一和第二部分将是
jdbc:acme。驱动程序文档也会告诉你余下
JDBC
URL
的格式。JDBC
URL
最后一部分提供了定位数据库的信息。
如果你装载的驱动程序识别了提供给
DriverManagergetConnection
的
JDBC
URL
,那个驱动程序将根据
JDBC
URL
建立一个到指定
DBMS
的连接。正如名称所示,DriverManager
类在幕后为你管理建立连接的所有细节。除非你是正在写驱动程序,你可能无需使用此类的其它任何方法,一般程序员需要在此类中直接使用的唯一方法是
DriverManagergetConnection。
DriverManagergetConnection
方法返回一个打开的连接,你可以使用此连接创建
JDBC
statements
并发送
SQL
语句到数据库。在前面的例子里,con
对象是一个打开的连接,并且我们要在以后的例子里使用它。
建议你在baidu所搜你所用的数据库以及其JDBC(例如mysql
jdbc); java数据库连接(jdbc)api是一系列能够让java编程人员访问数据库的接口,各个开发商的接口并不完全相同。以下是一些技巧,这些技巧能够使我们更好地发挥系统的性能和实现更多的功能。
1、在客户端软件开发中使用thin驱动程序
在开发java软件方面,oracle的数据库提供了四种类型的驱动程序,二种用于应用软件、applets、servlets等客户端软件,另外二种用于数据库中的java存储过程等服务器端软件。在客户机端软件的开发中,我们可以选择oci驱动程序或thin驱动程序。oci驱动程序利用java本地化接口(jni),通过oracle客户端软件与数据库进行通讯。thin驱动程序是纯java驱动程序,它直接与数据库进行通讯。为了获得最高的性能,oracle建议在客户端软件的开发中使用oci驱动程序,这似乎是正确的。但我建议使用thin驱动程序,因为通过多次测试发现,在通常情况下,thin驱动程序的性能都超过了oci驱动程序。
2、关闭自动提交功能,提高系统性能
在第一次建立与数据库的连接时,在缺省情况下,连接是在自动提交模式下的。为了获得更好的性能,可以通过调用带布尔值false参数的connection类的setautocommit()方法关闭自动提交功能,如下所示:
connsetautocommit(false);
值得注意的是,一旦关闭了自动提交功能,我们就需要通过调用connection类的commit()和rollback()方法来人工的方式对事务进行管理。
3、在动态sql或有时间限制的命令中使用statement对象
在执行sql命令时,我们有二种选择:可以使用preparedstatement对象,也可以使用statement对象。无论多少次地使用同一个sql命令,preparedstatement都只对它解析和编译一次。当使用statement对象时,每次执行一个sql命令时,都会对它进行解析和编译。这可能会使你认为,使用preparedstatement对象比使用statement对象的速度更快。然而,我进行的测试表明,在客户端软件中,情况并非如此。因此,在有时间限制的sql *** 作中,除非成批地处理sql命令,我们应当考虑使用statement对象。
此外,使用statement对象也使得编写动态sql命令更加简单,因为我们可以将字符串连接在一起,建立一个有效的sql命令。因此,我认为,statement对象可以使动态sql命令的创建和执行变得更加简单。
4、利用helper函数对动态sql命令进行格式化
在创建使用statement对象执行的动态sql命令时,我们需要处理一些格式化方面的问题。例如,如果我们想创建一个将名字o'reilly插入表中的sql命令,则必须使用二个相连的“''”号替换o'reilly中的“'”号。完成这些工作的最好的方法是创建一个完成替换 *** 作的helper方法,然后在连接字符串心服用公式表达一个sql命令时,使用创建的helper方法。与此类似的是,我们可以让helper方法接受一个date型的值,然后让它输出基于oracle的to_date()函数的字符串表达式。
5、利用preparedstatement对象提高数据库的总体效率
在使用preparedstatement对象执行sql命令时,命令被数据库进行解析和编译,然后被放到命令缓冲区。然后,每当执行同一个preparedstatement对象时,它就会被再解析一次,但不会被再次编译。在缓冲区中可以发现预编译的命令,并且可以重新使用。在有大量用户的企业级应用软件中,经常会重复执行相同的sql命令,使用preparedstatement对象带来的编译次数的减少能够提高数据库的总体性能。如果不是在客户端创建、预备、执行preparedstatement任务需要的时间长于statement任务,我会建议在除动态sql命令之外的所有情况下使用preparedstatement对象。
6、在成批处理重复的插入或更新 *** 作中使用preparedstatement对象
如果成批地处理插入和更新 *** 作,就能够显著地减少它们所需要的时间。oracle提供的statement和 callablestatement并不真正地支持批处理,只有preparedstatement对象才真正地支持批处理。我们可以使用addbatch()和executebatch()方法选择标准的jdbc批处理,或者通过利用preparedstatement对象的setexecutebatch()方法和标准的executeupdate()方法选择速度更快的oracle专有的方法。要使用oracle专有的批处理机制,可以以如下所示的方式调用setexecutebatch():
preparedstatement pstmt3d null;
try {
((oraclepreparedstatement)
pstmt)setexecutebatch(30);
pstmtexecuteupdate();
}
调用setexecutebatch()时指定的值是一个上限,当达到该值时,就会自动地引发sql命令执行,标准的executeupdate()方法就会被作为批处理送到数据库中。我们可以通过调用preparedstatement类的sendbatch()方法随时传输批处理任务。
7、使用oracle locator方法插入、更新大对象(lob)
oracle的preparedstatement类不完全支持blob和clob等大对象的处理,尤其是thin驱动程序不支持利用preparedstatement对象的setobject()和setbinarystream()方法设置blob的值,也不支持利用setcharacterstream()方法设置clob的值。只有locator本身中的方法才能够从数据库中获取lob类型的值。可以使用preparedstatement对象插入或更新lob,但需要使用locator才能获取lob的值。由于存在这二个问题,因此,我建议使用locator的方法来插入、更新或获取lob的值。
8、使用sql92语法调用存储过程
在调用存储过程时,我们可以使用sql92或oracle pl/sql,由于使用oracle pl/sql并没有什么实际的好处,而且会给以后维护你的应用程序的开发人员带来麻烦,因此,我建议在调用存储过程时使用sql92。
9、使用object sql将对象模式转移到数据库中
既然可以将oracle的数据库作为一种面向对象的数据库来使用,就可以考虑将应用程序中的面向对象模式转到数据库中。目前的方法是创建java bean作为伪装的数据库对象,将它们的属性映射到关系表中,然后在这些bean中添加方法。尽管这样作在java中没有什么问题,但由于 *** 作都是在数据库之外进行的,因此其他访问数据库的应用软件无法利用对象模式。如果利用oracle的面向对象的技术,可以通过创建一个新的数据库对象类型在数据库中模仿其数据和 *** 作,然后使用jpublisher等工具生成自己的java bean类。如果使用这种方式,不但java应用程序可以使用应用软件的对象模式,其他需要共享你的应用中的数据和 *** 作的应用软件也可以使用应用软件中的对象模式。
和其他库一样,只要把桥的属性替换为SQLServer即可,网上有的是案例,由于本人以抄袭为耻,就不复制粘贴了,留下链接一枚:>//应用场景: 如以下SQL : String sql = "INSERT INTO to_order_return_info VALUES(seq_order_return_infonextval,,,,,,)"; 该语句为向to_order_return_info表中插入新记录 但如需要N条数据插入 正常的方案为 执行N次插入数据 *** 作 jdbc jdbc驱动
java jdbc连接_2019最新JDBC面试题(附JDBC教程)
weixin_39665379
关注
0点赞·410人阅读
1什么是JDBC API,何时使用它?
Java DataBase Connectivity API允许我们使用关系数据库。JDBC API接口和类是part javasql和javaxsqlpackage的一部分。我们可以使用JDBC API来获取数据库连接,在数据库服务器中运行SQL查询和存储过程并处理结果。
JDBC API的编写方式允许我们的Java程序和实际的JDBC驱动程序之间的松散耦合,这使我们可以轻松地从一个数据库切换到另一个数据库服务器。
2JDBC驱动程序有哪几种类型?
有四种类型的JDBC驱动程序。任何与数据库一起工作的java程序都有两个部分,第一部分是JDBC API,第二部分是执行实际工作的驱动程序。
JDBC-ODBC Bridge加ODBC驱动程序(类型1):它使用ODBC驱动程序连接到数据库。我们应该安装ODBC驱动程序来连接数据库,这就是为什么这个驱动程序几乎已经过时的原因。
Native API部分支持Java技术的驱动程序(类型2):此驱动程序将JDBC类转换为数据库服务器的客户端API。我们应该安装数据库客户端API。由于对数据库客户端API驱动程序的额外依赖性,这也不是首选驱动程序。
用于数据库中间件的纯Java驱动程序(类型3):此驱动程序将JDBC调用发送到可以连接到不同类型数据库的中间件服务器。我们应该安装一个中间件服务器来使用这个驱动程序。这增加了额外的网络调用和性能降低,这就是为什么不广泛使用JDBC驱动程序。
直接到数据库的纯Java驱动程序(类型4):此驱动程序将JDBC调用转换为数据库服务器可以理解的网络协议。该解决方案简单,适用于网络上的数据库连接。但是对于此解决方案,我们应该使用特定于数据库的驱动程序,例如Oracle for Oracle DB的OJDBC jar和MySQL Connector的MySQL Connector / J
3JDBC API如何帮助我们实现Java程序和JDBC驱动程序API之间的松散耦合?
JDBC API使用Java Reflection API实现java程序和JDBC驱动程序之间的松散耦合。如果你看一个简单的JDBC例子,你会发现所有的编程都是用JDBC API完成的,而驱动程序只有在通过反射使用ClassforName()方法加载时才会出现。
我认为这是在核心java类中使用Reflection的最佳示例之一,以确保我们的应用程序不能直接使用Drivers API,这使得从一个数据库移动到另一个数据库变得非常容易。
4什么是JDBC连接?解释在简单的java程序中获取数据库连接的步骤。
JDBC Connection就像使用数据库服务器创建的Session。您还可以将Connection 视为来自数据库服务器的Socket连接。
创建JDBC连接非常简单,需要两个步骤:
注册并加载驱动程序:使用ClassforName(),驱动程序类注册到DriverManager并加载到内存中。
使用DriverManager获取Connection对象:我们DriverManagergetConnection()通过传递数据库URL字符串,用户名和密码作为参数来获取连接对象。
Connection
5JDBC DriverManager类有什么用?
JDBC DriverManager是我们通过它获取数据库连接对象的工厂类。当我们加载JDBC Driver类时,它将自己注册到DriverManager,您可以查找JDBC Driver类源代码来检查它。
当我们通过传递数据库配置细节来调用方法DriverManagergetConnection()时,DriverManager使用已注册的驱动程序来获取Connection并将其返回给调用者程序。
6如何在java程序中获取数据库服务器的详细信息?
我们可以使用DatabaseMetaDataobject来获取数据库服务器的详细信息。成功创建数据库连接后,我们可以通过调用getMetaData()方法获取元数据对象。我们可以使用DatabaseMetaData中的方法来获取数据库产品名称,版本和详细的配置信息。
DatabaseMetaData
7什么是JDBC Statement?
JDBC API Statement用于在数据库中执行SQL查询。我们可以通过调用Connection createStatement()方法来创建Statement对象。我们可以使用Statement通过不同的执行方法传递查询来执行静态SQL查询,例如execute(),executeQuery(),executeUpdate()等。
由于查询是在java程序中生成的,如果未正确验证用户输入,则可能导致SQL注入问题,可以在SQL注入示例中找到更多详细信息。
默认情况下,每个Statement对象只能同时打开一个ResultSet对象。因此,如果我们想要使用多个ResultSet对象,则每个对象必须由不同的Statement对象生成。Statement接口中的所有execute()方法都隐式关闭一个statment的当前ResultSet对象(如果存在open对象)。
8execute,executeQuery,executeUpdate有什么区别?
Statement execute(String query)用于执行任何SQL查询,如果结果是ResultSet(如运行Select查询),则返回TRUE。当没有ResultSet对象(如运行Insert或Update查询)时,输出为FALSE。我们可以使用getResultSet()获取ResultSet和getUpdateCount()方法来检索更新计数。
Statement executeQuery(String query)用于执行Select查询并返回ResultSet。即使没有与查询匹配的记录,返回的ResultSet也永远不会为null。执行select查询时,我们应该使用executeQuery方法,这样如果有人试图执行insert / update语句,它将抛出javasqlSQLException,并显示消息“executeQuery方法不能用于更新”。
语句executeUpdate(String query)用于执行不返回任何内容的Insert / Update / Delete(DML)语句或DDL语句。输出为int,等于SQL数据 *** 作语言(DML)语句的行数。对于DDL语句,输出为0。
只有在不确定语句类型时才应使用execute()方法,否则使用executeQuery或executeUpdate方法。
9什么是JDBC PreparedStatement?
JDBC PreparedStatement对象表示预编译的SQL语句。我们可以使用它的setter方法来设置查询的变量。
由于PreparedStatement是预编译的,因此可以使用它多次有效地执行此语句。PreparedStatement是Statement的更好选择,因为它会自动转义特殊字符并避免SQL注入攻击。
10如何在JDBC PreparedStatement中设置NULL值?
我们可以使用PreparedStatement setNull()方法将null变量绑定到参数。例如,setNull方法将index和SQL Types作为参数 pssetNull(10, javasqlTypesINTEGER);。
11Statement中的getGeneratedKeys()方法有什么用?
有时,表可以使用自动生成的键来插入主键的唯一列值。我们可以使用Statement getGeneratedKeys()方法获取此自动生成密钥的值。
12PreparedStatement对Statement有什么好处?
PreparedStatement对Statement的一些好处是:
PreparedStatement帮助我们防止SQL注入攻击,因为它会自动转义特殊字符。
PreparedStatement允许我们使用参数输入执行动态查询。
PreparedStatement比Statement快。当我们重用PreparedStatement或使用它的批处理方法执行多个查询时,它变得更加明显。
PreparedStatement帮助我们使用setter方法编写面向对象的代码,而使用Statement我们必须使用String Concatenation来创建查询。如果要设置多个参数,则使用字符串连接编写查询看起来非常难看并且容易出错。
13PreparedStatement的限制是什么以及如何克服它?
PreparedStatement的一个限制是我们不能直接在IN子句中使用它。将PreparedStatement与IN子句一起使用的一些替代方法是:
执行单一查询 性能非常慢,不推荐使用
使用存储过程 特定于数据库,因此不适用于多个数据库应用程序。
动态创建PreparedStatement查询 良好的方法但失去了缓存的PreparedStatement的好处。
在PreparedStatement查询中使用NULL 当您知道变量输入的最大数量时,这是一种很好的方法,可以通过部分执行来扩展以允许无限制的参数。可以在JDBC PreparedStatement IN子句替代中找到更详细的分析。
14什么是JDBC ResultSet?
JDBC ResultSet就像一个表示数据库结果集的数据表,通常通过执行查询数据库的语句来生成。
ResultSet对象维护指向其当前数据行的游标。最初,光标位于第一行之前。next()方法将光标移动到下一行。如果没有更多行,则next()方法返回false,并且可以在while循环中使用它来迭代结果集。
默认的ResultSet对象不可更新,并且只有一个向前移动的游标。因此,您只能迭代一次,并且只能从第一行到最后一行。可以使用以下语法生成可滚动和/或可更新的ResultSet对象。
Statement stmt = concreateStatement(ResultSetTYPE_SCROLL_INSENSITIVE,
ResultSetCONCUR_UPDATABLE);
当生成它的Statement对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,ResultSet对象将自动关闭。
我们可以使用ResultSet getter方法,列名或索引号从1开始检索列数据。
15ResultSet有哪些不同的类型?
在创建Statement时,我们可以根据用户输入获得不同类型的ResultSet对象。如果您将查看Connection方法,您将看到createStatement()和prepareStatement()方法被重载以提供ResultSet类型和并发作为输入参数。
ResultSet对象有三种类型。
ResultSetTYPEFORWARDONLY:这是默认类型,游标只能在结果集中向前移动。
ResultSetTYPESCROLLINSENSITIVE:游标可以前后移动,结果集对创建结果集后其他人对数据库所做的更改不敏感。
ResultSetTYPESCROLLSENSITIVE:游标可以向前和向后移动,结果集对创建结果集后其他人对数据库所做的更改很敏感。基于并发性,有两种类型的ResultSet对象。
ResultSetCONCURREADONLY:结果集是只读的,这是默认的并发类型。
ResultSetCONCUR_UPDATABLE:我们可以使用ResultSet更新方法来更新行数据。
16Statement中的setFetchSize()和setMaxRows()方法有什么用?
我们可以使用setMaxRows(int i)方法来限制数据库从查询返回的行数。您可以使用SQL查询本身实现相同的功能。例如,在MySQL中,我们可以使用LIMIT子句来设置查询返回的最大行数。
理解fetchSize可能很棘手,因为你应该知道Statement和ResultSet是如何工作的。当我们在数据库中执行查询时,将在数据库缓存中获取并维护结果,并返回ResultSet。ResultSet是具有对数据库中结果的引用的游标。
假设我们有一个返回100行的查询,并且我们将fetchSize设置为10,因此在每次数据库访问时,JDBC驱动程序将只获取10行,因此将有10次访问以获取所有行。如果每行需要大量处理时间并且结果中的行数很大,那么设置最佳fetchSize会很有帮助。
我们可以通过Statement对象设置fetchSize,但可以通过ResultSet对象setFetchSize()方法覆盖它。
17如何使用JDBC API调用存储过程?
存储过程是一组SQL查询,它们在数据库中编译,可以从JDBC API执行。JDBC CallableStatement可用于在数据库中执行存储过程。初始化CallableStatement的语法是;
CallableStatement
//我们需要在调用存储过程之前注册外部参数
stmt
我们需要在执行CallableStatement之前注册OUT参数。
18什么是JDBC批处理,它有什么好处?
有时我们需要为数据库运行类似的批量查询,例如将数据从CSV文件加载到关系数据库表。我们知道我们可以选择使用Statement或PreparedStatement来执行查询。除此之外,JDBC API还提供了批处理功能,通过该功能,我们可以一次性为数据库执行大量查询。
JDBC API支持通过Statement和PreparedStatement addBatch()以及executeBatch()方法进行批处理。
批处理比一次执行一个语句更快,因为数据库调用的数量较少。
19什么是JDBC事务管理?我们为什么需要它?
默认情况下,当我们创建数据库连接时,它以自动提交模式运行。这意味着无论何时执行查询并完成查询,都会自动触发提交。因此,我们触发的每个SQL查询都是一个事务,如果我们运行一些DML或DDL查询,则每个SQL语句完成后,更改都会保存到数据库中。
有时我们希望一组SQL查询成为事务的一部分,以便我们可以在所有查询运行正常时提交它们,如果我们得到任何异常,我们可以选择回滚作为事务的一部分执行的所有查询。
JDBC API提供了一种方法,setAutoCommit(boolean flag)通过该方法我们可以禁用连接的自动提交功能。我们应该仅在需要时禁用自动提交,因为除非我们在连接上调用commit()方法,否则不会提交事务。数据库服务器使用表锁来实现事务管理,这是资源密集型过程。所以我们应该在完成交易后立即提交交易。
20如何回滚JDBC事务?
我们可以使用Connection对象rollback()方法来回滚事务。它将回滚事务所做的所有更改,并释放此Connection对象当前持有的所有数据库锁。
21什么是JDBC Savepoint?如何使用它?
有时,事务可以是多个语句的组,我们希望回滚到事务中的特定点。JDBC Savepoint帮助我们在事务中创建检查点,并且我们可以回滚到该特定检查点。
为事务创建的任何保存点都会自动释放,并在提交事务时或在回滚整个事务时变为无效。将事务滚动回保存点会自动释放并使在相关保存点之后创建的任何其他保存点无效。
22什么是JDBC DataSource?它的好处是什么?
JDBC DataSource是javaxsql包中定义的接口,它比DriverManager更强大,可用于数据库连接。我们可以使用DataSource来创建数据库连接,而Driver实现类可以用来获取连接的实际工作。除了获取数据库连接外,DataSource还提供了一些其他功能,例如:
缓存PreparedStatement以加快处理速度 连接超时设置 记录功能 ResultSet最大大小阈值 使用JNDI支持在servlet容器中连接池 在JDBC DataSource上阅读有关DataSource的更多信息。
23如何在Apache Tomcat Server中使用JDBC DataSource和JNDI实现JDBC连接池?
对于部署在servlet容器中的Web应用程序,创建JDBC连接池非常简单,只需要几个步骤。
在容器配置文件中创建JDBC JNDI资源,通常是serverxml或contextxml。例如
server
在Web应用程序中,使用InitialContext查找在第一步中配置的JNDI资源,然后获取连接。
Context
24什么是Apache DBCP API?
如果您使用DataSource获取数据库连接,通常用于获取连接的代码与特定于驱动程序的DataSource实现紧密耦合。除了选择DataSource实现类之外,大多数代码都是样板代码。
Apache DBCP通过提供DataSource实现来帮助我们摆脱这些问题,DataSource实现充当我们的程序和不同JDBC驱动程序之间的抽象层。Apache DBCP库依赖于Commons Pool库,因此请确保它们都在构建路径中。
25什么是JDBC连接隔离级别?
当我们使用JDBC事务来实现数据完整性时,DBMS使用锁来阻止其他人访问事务所访问的数据。DBMS使用锁来防止脏读,不可重复读和幻像读问题。
DBMS使用JDBC事务隔离级别来使用锁定机制,我们可以通过Connection getTransactionIsolation()方法获取隔离级别信息,并使用setTransactionIsolation()方法设置它。
26什么是JDBC RowSet?RowSet有哪些类型?
JDBC RowSet以更灵活的方式保存表格数据,即ResultSet。所有RowSet对象都是从ResultSet派生的,因此它们具有ResultSet的所有功能以及一些其他功能。RowSet接口在javaxsql包中定义。
RowSet提供的一些附加功能包括:
具有属性的Java Bean及其getter-setter方法。RowSet使用JavaBeans事件模型,它们可以向任何已注册的组件发送通知,用于事件,例如光标移动,更新/插入/删除行以及更改为RowSet内容。
默认情况下,RowSet对象是可滚动和可更新的,因此如果DBMS不支持可滚动或可更新的ResultSet,我们可以使用RowSet来获取这些功能。
RowSet大致分为两种类型:
已连接的RowSet对象 - 这些对象连接到数据库,与ResultSet对象最相似。JDBC API仅提供一个连接的RowSet对象javaxsqlrowsetJdbcRowSet,它的标准实现类是comsunrowsetJdbcRowSetImpl 断开连接的RowSet对象 - 这些RowSet对象不需要连接到数据库,因此它们更轻量级且可序列化。它们适合通过网络发送数据。有四种类型的断开连接的RowSet实现。
CachedRowSet - 它们可以获取连接并执行查询并读取ResultSet数据以填充RowSet数据。我们可以在数据断开连接时 *** 作和更新数据,并重新连接到数据库并写入更改。WebRowSet派生自CachedRowSet - 它们可以读写XML文档。JoinRowSet派生自WebRowSet - 它们可以形成SQL JOIN而无需连接到数据源。从WebRowSet派生的FilteredRowSet - 我们可以应用过滤条件,以便只有选定的数据可见。
27ResultSet和RowSet有什么不同?
RowSet对象派生自ResultSet,因此它们具有ResultSet的所有功能以及一些附加功能。RowSet的一大好处是它们可以断开连接,使其轻量级,并且易于通过网络传输。
是否使用ResultSet或RowSet取决于您的要求,但如果您计划使用ResultSet更长的持续时间,则断开连接的RowSet是释放数据库资源的更好选择。
28常见的JDBC异常有哪些?
一些常见的JDBC异常是:
javasqlSQLException - 这是JDBC异常的基本异常类。javasqlBatchUpdateException - 当Batch *** 作失败时抛出此异常,但它依赖于JDBC驱动程序是否抛出此异常或基本SQLException。javasqlSQLWarning - 用于SQL *** 作中的警告消息。javasqlDataTruncation - 当数据值因超出MaxFieldSize而被意外截断时。
29JDBC中的CLOB和BLOB数据类型是什么?
字符大对象(CLOB)是由具有关联代码页的单字节字符组成的字符串。此数据类型适用于存储面向文本的信息,其中信息量可能超出常规VARCHAR数据类型的限制(上限为32K字节)。
二进制大对象(BLOB)是由字节组成的二进制字符串,没有关联的代码页。此数据类型可以存储大于VARBINARY(32K限制)的二进制数据。此数据类型适用于存储图像,语音,图形和其他类型的业务或特定于应用程序的数据。
30什么是JDBC中的“脏读”?哪个隔离级别可防止脏读?
当我们处理事务时,有可能更新行,同时其他查询可以读取更新的值。这会导致脏读,因为更新后的值不是永久性的,已更新行的事务可以回滚到先前的值,从而导致无效数据。
隔离级别TRANSACTIONREADCOMMITTED,TRANSACTION_REPEATABLEREAD和TRANSACTIONSERIALIZABLE阻止了脏读。
31什么是2阶段提交?
当我们在涉及多个数据库的分布式系统中工作时,我们需要使用2阶段提交协议。2阶段提交协议是分布式系统的原子承诺协议。在第一阶段,事务管理器向所有事务资源发送commit-request。如果所有事务资源都正常,则事务管理器将为所有资源提交事务更改。如果任何事务资源响应为Abort,则事务管理器可以回滚所有事务更改。
32JDBC中有哪些不同类型的锁定?
从广义上讲,有两种类型的锁定机制可以防止数据损坏,因为多个用户使用相同的数据。
乐观锁定 - 使用代码实现此锁定。表中引入了一个额外的列以保持更新计数。当您选择该行时,您也会阅读此列,比如“version”。现在,当您尝试更新/删除行时,将在where子句中传递此“version”。因此,如果在其间执行其他线程的更新,则更新将失败。这是避免数据损坏的好方法,但如果有人错过更新其更新语句中的“version”,则可能容易出错。通过这种锁定方式,更新查询看起来如下所示。
mysql> update emp SET name = ‘David’, version = 5 WHERE id = 10 and version = 4;
悲观锁定 - 将记录从选择锁定到读取,更新和提交阶段。这通常由数据库供应商软件完成,并通过使用SELECT FOR UPDATE查询触发。如果线程处理锁定较长时间,则这种锁定行的方式可能导致性能降低和死锁。
除此之外,一些DBMS系统提供锁定机制来锁定单行,表或数据库。
33你对DDL和DML语句有什么了解?
数据定义语言(DDL)语句用于定义数据库模式。创建,更改,删除,截断,重命名语句属于DDL语句,通常它们不返回任何结果。
数据 *** 作语言(DML)语句用于 *** 纵数据库模式中的数据。选择,插入,更新,删除,调用等是DML语句的示例。
34javautilDate和javasqlDate有什么区别?
javautilDate包含有关日期和时间的信息,而javasqlDate包含仅有关日期的信息,它没有时间信息。因此,如果您必须在数据库中保留时间信息,建议使用Timestamp或DateTime字段。
35如何将图像或原始数据插入数据库?
我们可以使用BLOB将图像或原始二进制数据插入数据库。
36什么是幻像读取以及哪种隔离级别阻止了它?
虚拟读取是指事务多次执行查询并获取不同数据的情况。假设事务正在执行查询以根据条件获取数据,然后另一个事务插入与条件匹配的行。现在,当同一事务再次执行查询时,新行将成为结果集的一部分。这个新行被称为Phantom Row,这种情况称为Phantom Read。
只有使用TRANSACTION_SERIALIZABLE隔离级别才能阻止幻像读取。
37什么是SQL警告?如何在JDBC程序中检索SQL警告?
SQLWarning是SQLException的子类,我们可以通过在Connection,Statement和ResultSet对象上调用getWarnings()方法来检索它。SQL警告不会停止脚本的执行,但会警告用户警告。
38如何使用数据库对象作为IN / OUT调用Oracle存储过程?
如果Oracle存储过程具有作为数据库对象的IN / OUT参数,那么我们需要在程序中创建相同大小的Object数组,然后使用它来创建Oracle STRUCT对象。然后我们可以通过调用setSTRUCT()方法为数据库对象设置此STRUCT对象并使用它。
39我们什么时候得到javasqlSQLException:找不到合适的驱动程序?
当SQL URL字符串格式不正确时,您将得到没有合适的驱动程序发现异常。您可以在使用DriverManager的简单Java应用程序或使用DataSource的JNDI资源中获取此异常。异常堆栈跟踪如下所示。
org
在调试此异常时,只需检查日志中打印的URL,如上面的日志中URL URL是’jdbc:mysql:// localhost:3306 / UserDB,而它应该是jdbc:mysql:// localhost:3306 / UserDB 。
40JDBC有哪些最佳实践?
一些JDBC最佳实践是:
数据库资源很重,因此请确保在完成后立即关闭它。Connection,Statement,ResultSet和所有其他JDBC对象都定义了close()方法来关闭它们。
始终在代码中显式关闭结果集,语句和连接,因为如果您在连接池环境中工作,则可能会将连接返回到池,从而导致打开的结果集和语句对象导致资源泄漏。
关闭finally块中的资源,以确保即使在异常情况下它们也会关闭。
使用批处理进行类似的批量 *** 作。
始终对Statement使用PreparedStatement以避免SQL注入并获得PreparedStatement的预编译和缓存优势。
如果要将批量数据检索到结果集中,则为fetchSize设置最佳值有助于获得良好的性能。
数据库服务器可能不支持所有隔离级别,因此请在假设之前进行检查。
更严格的隔离级别会导致性能降低,因此请确保为数据库连接设置了最佳隔离级别。
如果要在Web应用程序中创建数据库连接,请尝试使用JNDI上下文使用JDBC DataSource资源来重用连接。
当您需要长时间使用ResultSet时,请尝试使用断开连接的RowSet。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)