本文介绍 Java 数据库连接(JDBC)和配置过程中发生的故障排除步骤。 重点是 JDBC for SQL Server。
注意
- 本文基于 C 驱动器根目录中安装的最新 JDBC 驱动程序(版本 12.4)。
- Microsoft不会排查存在第三方连接池管理器的 JDBC 连接问题。 使用第三方连接池管理器进行故障排除有可能公开知识产权信息。
用于 SQL Server 的 Microsoft JDBC 驱动程序
本文提供了 JDBC 的参考指南,包括驱动程序和支持文档、不同操作系统(OS)的安装说明以及 SQL Server 连接问题疑难解答。
JDBC 驱动程序版本更改
JDBC 要求
Java 运行时环境 (JRE) 版本必须与驱动程序与名称中指定的 JRE 版本匹配。 例如,mssql-jdbc-9.4.1.jre8.jar需要 JRE 1.8,mssql-jdbc-9.4.1.jre11.jar需要 JRE 11.0。
CLASSPATH 是一个 Java 环境变量,其中包含目录路径和二进制 jar 文件。 Java 需要它来执行所需的应用程序。 需要指定哪些驱动程序和依赖项二进制 jar 文件 Java 需要运行。 最小值
CLASSPATH
包括当前工作目录.;
和 JDBC 驱动程序 jar 文件的位置。
JDBC 配置和故障排除步骤
设置 CLASSPATH 变量
CLASSPATHs 可以在 OS 环境变量或应用程序环境本身(如 Tomcat)中定义。 如果在 CLASSPATH
应用程序环境中定义,则应用程序供应商或开发人员必须参与,以确保 CLASSPATH
正确配置到位。
若要设置 CLASSPATH
,请使用以下方法之一:
注意
命令提示符设置是临时的,关闭命令提示符窗口时将被删除。 图形用户界面(GUI)是永久设置,需要重新启动。
命令提示符示例
Set CLASSPATH=.;C:\sqljdbc_12.4\enu\mssql-jdbc-12.4.0.jre8.jar
GUI 示例
若要使用 GUI 进行设置 CLASSPATH
,请执行以下步骤:
打开控制面板并选择“系统和安全性”。
选择 系统>高级系统设置。
选择“环境变量>新建”,然后输入 CLASSPATH 作为变量名称。
选择“编辑”并输入 .;C:\sqljdbc_12.4\enu\mssql-jdbc-12.4.0.jre8.jar作为变量值。
选择“确定”。
具有传入凭据的连接字符串
具有传入凭据的连接字符串是指将身份验证凭据(如用户名和密码)作为字符串中的参数或值连接字符串。 当程序连接到数据库或其他服务时,需要提供身份验证信息来建立安全连接。
以下连接字符串演示了如何基于要使用的身份验证模式连接到 SQL Server 数据库的示例:
SQL Server 身份验证
连接字符串为 String connectionUrl = "jdbc:sqlserver://<ServerName>:<PortNum>;user=<MySQLAuthAccount>;password=<MyPassword>;trustServerCertificate=true;"
没有集成安全性的 Windows AD 身份验证
连接字符串为 String connectionUrl = "jdbc:sqlserver://<ServerName>:<PortNum>;user=<MyADAuthAccount>;password=<MyPassword>;Domain=<MyDomain>;trustServerCertificate=true;javaAuthentication=NTLM"
使用 Kerberos 和没有集成安全性的 Windows AD 身份验证
连接字符串为 String connectionUrl = "jdbc:sqlserver://<ServerName>:<PortNum>;user=<MyADAuthAccount>;password=<MyPassword>;Domain=<MyDomain>;trustServerCertificate=true;javaAuthentication=JavaKerberos"
集成 NTLM 连接
在此类连接中,客户端计算机必须位于 Windows 域中。
mssql-jdbc_auth-version-arch<><>.dll 文件必须位于以下路径中:
64 位 DLL
%Path%;C:\sqljdbc_12.4.1.0_enu\sqljdbc_12.4\enu\auth\x64\mssql-jdbc_auth-12.4.1.x64.dll
32 位 DLL
%Path%;C:\sqljdbc_12.4.1.0_enu\sqljdbc_12.4\enu\auth\x86\mssql-jdbc_auth-12.4.1.x86.dll
可以修改并添加路径,也可以将文件复制到已建立的路径中。 有关详细信息,请参阅 在 Windows 上使用集成身份验证进行连接。
连接字符串为 String connectionUrl = "jdbc:sqlserver://<ServerName>:<PortNum>;integratedSecurity=true;Domain=<MyDomain>;trustServerCertificate=true;javaAuthentication=NTLM"
集成的 Kerberos 连接
此类型的连接的先决条件包括:
- 必须是域的一部分。
- 必须在 Linux OS 上安装和配置 SSSD。
- 必须在 Linux OS 上安装并配置 Klist。
mssql-jdbc_auth-version-arch<><>.dll 文件必须位于以下路径中。 可以修改并添加路径,也可以将文件复制到已建立的路径中。
64 位 DLL
%Path%;C:\sqljdbc_12.4.1.0_enu\sqljdbc_12.4\enu\auth\x64\mssql-jdbc_auth-12.4.1.x64.dll
32 位 DLL
%Path%;C:\sqljdbc_12.4.1.0_enu\sqljdbc_12.4\enu\auth\x86\mssql-jdbc_auth-12.4.1.x86.dll
还必须创建 Jaas.conf 文件。 默认情况下,此文件不附带驱动程序,也不会随 Java 一起安装。 若要帮助环境找到此文件,请使用以下方法之一:
注意
Jaas.conf 文件将允许 Java 使用已登录用户的当前上下文。 它还会告知 Java 使用当前缓存的 Kerberos 票证。
修改 Java.Security 文件中的以下行:
# Default login configuration file login.config.url.1=C:=\<Path to the File>\jaas.conf
或者,在加载环境或应用程序时,通过参数添加 Jaas.conf 文件。 编译 Java 文件时,请确保使用相同的参数:
javac -Djava.security.auth.login.config=c:\myDirectory\Jaas.conf myapp.java java -Djava.security.auth.login.config=c:\myDirectory\Jaas.conf myapp
若要使用 Kerberos 集成身份验证与 SQL Server 建立连接,请配置 Jaas.conf 文件:
SQLJDBCDriver {
com.sun.security.auth.module.Krb5LoginModule required
useTicketCache=true;
};
连接字符串为 String connectionUrl = "jdbc:sqlserver://<ServerName>:<PortNum>;integratedSecurity=true;Domain=<MyyDomain>;trustServerCertificate=true;javaAuthentication=JavaKerberos;"
代码示例
所有 JDBC 驱动程序都附带了 \sqljdbc_12.4\enu\samples 目录中的示例代码。 最常用的一个是 \sqljdbc_12.4\enu\samples\connections\ConnectURR.java。 创建名为 ConnectURL.java的文件,或使用 驱动程序提供的示例中的ConnectURL.java 。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnectURL {
public static void main(String[] args) {
// Create a variable for the connection string. Base the connection string on the previous examples supplied in the above documentation.
String connectionUrl = "jdbc:sqlserver://ServerName:Port;user=SQLAuthAccount;password=SomePassword;trustServerCertificate=true;";
try (Connection con = DriverManager.getConnection(connectionUrl); Statement stmt = con.createStatement();)
{
String SQL = "SELECT @@version";
ResultSet rs = stmt.executeQuery(SQL);
// Iterate through the data in the result set and display it.
while (rs.next())
{
System.out.println(rs.getString(1));
}
}
// Handle any errors that may have occurred.
catch (SQLException e)
{e.printStackTrace(); }
}
}
JDBC 驱动程序跟踪
通常,我们始终希望将跟踪设置为 FINEST
更多详细信息。 驱动程序跟踪有两种方法: 以编程方式 启用跟踪,并使用 logging.properties 文件启用跟踪。
如果选择使用 logging.properties 文件,则必须找到 logging.properties 文件的正确环境。 $JAVA_HOME\conf\ 和 $JAVA_HOME\jre\lib 是两个可能的位置。
按照以下步骤配置此文件:
修改 logging.properties 文件,以确保它类似于以下全局属性:
############################################################ # Global properties ############################################################ # "handlers" specifies a comma-separated list of log Handler # classes. These handlers will be installed during VM startup. # Note that these classes must be on the system classpath. # By default, we only configure a ConsoleHandler, which will only # show messages at the INFO and above levels. handlers= java.util.logging.ConsoleHandler # To also add the FileHandler, use the following line instead. #handlers= java.util.logging.FileHandler # Default global logging level. # This specifies which kinds of events are logged across # all loggers. For any given facility this global level # can be overridden by a facility-specific level # Note that the ConsoleHandler also has a separate level # setting to limit messages printed to the console. .level= INFO
处理程序告知 Java 导出输出的位置。 FileHandler 写入文件的位置有两个,ConsoleHandler 将写入控制台窗口。 输出将生成大量数据,因此需要将其写入文件。
批注行
#handlers= java.util.logging.ConsoleHandler
取消注释行
handlers= java.util.logging.FileHandler
注意
OFF
设置为.level
控制台窗口,并且不会在控制台窗口中看到消息。.level=OFF
设置特定的 FileHandler 日志记录:
############################################################ # Handler specific properties. # Describes specific configuration info for Handlers. ############################################################ # default file output is in user's home directory. java.util.logging.FileHandler.pattern = %h/java%u.log java.util.logging.FileHandler.limit = 50000 java.util.logging.FileHandler.count = 1 # Default number of locks FileHandler can obtain synchronously. # This specifies maximum number of attempts to obtain lock file by FileHandler # implemented by incrementing the unique field %u as per FileHandler API documentation. java.util.logging.FileHandler.maxLocks = 100 java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter # Limit the messages that are printed on the console to INFO and above. java.util.logging.ConsoleHandler.level = INFO java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter # Example to customize the SimpleFormatter output format # to print one-line log message like this: # <level>: <log message> [<date/time>] # # java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
修改此部分以确保其类似于或包含以下行:
java.util.logging.FileHandler.pattern = /Path/java%u.log java.util.logging.FileHandler.limit = 5000000 java.util.logging.FileHandler.count = 20 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter java.util.logging.FileHandler.level = FINEST
修改行
java.util.logging.FileHandler.pattern = %h/java%u.log
并替换为%h/
要存储文件的路径。 例如:java.util.logging.FileHandler.pattern = c:/Temp/java%u.log
设置驱动程序日志记录级别:
在以下部分底部添加
com.microsoft.sqlserver.jdbc.level=FINEST
:############################################################ # Facility-specific properties. # Provides extra control for each logger. ############################################################ # For example, set the com.xyz.foo logger to only log SEVERE # messages: # com.xyz.foo.level = SEVERE
保存更改。
该文件应如下所示:
############################################################ # Default Logging Configuration File # # You can use a different file by specifying a filename # with the java.util.logging.config.file system property. # For example, java -Djava.util.logging.config.file=myfile ############################################################ ############################################################ # Global properties ############################################################ # "handlers" specifies a comma-separated list of log Handler # classes. These handlers will be installed during VM startup. # Note that these classes must be on the system classpath. # By default we only configure a ConsoleHandler, which will only # show messages at the INFO and above levels. #handlers= java.util.logging.ConsoleHandler # To also add the FileHandler, use the following line instead. handlers= java.util.logging.FileHandler # Default global logging level. # This specifies which kinds of events are logged across # all loggers. For any given facility this global level # can be overridden by a facility-specific level # Note that the ConsoleHandler also has a separate level # setting to limit messages printed to the console. .level= OFF ############################################################ # Handler specific properties. # Describes specific configuration info for Handlers. ############################################################ # default file output is in user's home directory. java.util.logging.FileHandler.pattern = c:/Temp/java%u.log java.util.logging.FileHandler.limit = 50000 java.util.logging.FileHandler.count = 1 # Default number of locks FileHandler can obtain synchronously. # This specifies maximum number of attempts to obtain lock file by FileHandler # implemented by incrementing the unique field %u as per FileHandler API documentation. java.util.logging.FileHandler.maxLocks = 100 java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter # Limit the messages that are printed on the console to INFO and above. #java.util.logging.ConsoleHandler.level = INFO #java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter # Example to customize the SimpleFormatter output format # to print one-line log message like this: # <level>: <log message> [<date/time>] # # java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n ############################################################ # Facility-specific properties. # Provides extra control for each logger. ############################################################ # For example, set the com.xyz.foo logger to only log SEVERE # messages: # com.xyz.foo.level = SEVERE com.microsoft.sqlserver.jdbc.level=FINEST
重现错误后,还原更改以阻止记录器创建文件。
或者,可以创建或复制上述文本,将其保存到文件,并在加载应用程序时将该文件添加到启动命令。
java -Djava.util.logging.config.file=c:\<Path to the file>\logging.properties myapp
这样,就可以识别默认目录中$JAVA_HOME\conf\
$JAVA_HOME\jre\lib
未通过命令行指定的 logging.properties 文件。
第三方信息免责声明
本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 不对这些产品的性能或可靠性提供任何明示或暗示性担保。