如何使用jTDS连接到Azure SQL数据库

时间:2016-06-10 08:26:47

标签: java azure ssl jdbc azure-sql-database

我尝试使用以下命令连接到Azure SQL:

import java.sql.*;

public class ExampleJTDS {

    public static void main(String[] args) {

        // Setting.
        String connectionUrl = "jdbc:jtds:sqlserver://SERVER.database.windows.net:1433/DATABASE;ssl=off";
        String user = "USER@SERVER";
        String pass = "PASSWORD";

        // Declare the JDBC object.
        Connection conn = null;

        try {
            // Establish the connection.
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            conn = DriverManager.getConnection(connectionUrl, user, pass);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

但我得到了:

java.sql.SQLException: I/O Error: DB server closed connection.
    at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2481)
    at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:632)
    at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:371)
    at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at run.ExampleJTDS.main(ExampleJTDS.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

如果我通过用 ssl = require 替换 ssl = off 来强制加密,我得到:

java.sql.SQLException: Network error IOException: Connection reset
    at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:436)
    at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)
    at run.ExampleJTDS.main(ExampleJTDS.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

有趣的是,我可以使用SQuirreL SQL从同一台计算机连接到数据库,并使用相同的JDBC驱动程序(尽管没有SSL - SQuirreL SQL设法将凭据放入第一个TDS数据包,Azure接受它)。因此,问题不应该出现在防火墙的设置中。

元数据:

  • 服务器:Azure V12
  • 司机:jtds-1.3.1
  • JRE:1.8.0_72-b15(来自Oracle)
  • _JAVA_OPTIONS:-Djsse.enableCBCProtection = false
  • security.provider.1:sun.security.provider.Sun
  • OS:OS X 10.11.5
  • SQuirreL SQL:3.7.1

如何从Java连接到Azure SQL?

1 个答案:

答案 0 :(得分:0)

根据我的经验,我认为问题是由连接字符串引起的,该字符串是代码的变量connectionUrl。我已回答您关于SO线程的类似问题,请参阅How to connect to Azure SQL with JDBC

但是,对于SQL Server使用jTDS而不是Microsoft JDBC驱动程序有一些区别,您可以参考the step 3 of the tutorial中的注释来了解它。作为参考,我在这里发布了注释的内容。

  

注意:

     

如果您使用的是JTDS JDBC驱动程序,则需要在连接字符串的URL中添加“ssl = require”,并且需要为JVM设置以下选项“-Djsse.enableCBCProtection = false”。此JVM选项会禁用针对安全漏洞的修复,因此请确保在设置此选项之前了解所涉及的风险。

希望它有所帮助。如有任何疑虑,请随时告诉我。