所以我已经为此开/关奋斗了几天,感觉好像我已经用尽了所有相关的搜索词。首先我要说的是,我对此进行了大量研究,但毫无结果;我得出的结论是,这要么是非常异常的事情(不太可能),要么是我不知何故忽略了一些微小的细节。让我也立即说,是的,我知道直接从应用程序连接到数据库并不理想,我应该使用网络服务器,但就我的意图和目的而言,这个解决方案不是一个问题。
我知道这篇文章非常长,但我非常感谢大家的时间。如果不出意外的话,至少它可以帮助其他最近开始使用 JDBC 并开始遇到问题的人。 “我尝试过的方法”部分概述了您可以在网上找到的绝大多数可以尝试的方法。
我正在尝试做什么:
使用 JDBC 驱动程序,通过 Android Studio 连接到我的 Azure 托管的 SqlServer 数据库。
我遇到的错误:
W/System.err: com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host vet-to-go.database.windows.net, port 1433 has failed. Error: "Connection timed out: no further information. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
我尝试/验证的内容(简短列表):
-连接代码发生在 Activity 类中,但它位于 AsyncTask 中。
-uses-permission android:name="android.permission.INTERNET"
-Azure 防火墙已配置为允许我的 IP 连接。
-Windows 防火墙已制定规则,允许端口 1433 上的传入和传出流量。
-从 SQLServer 配置管理器中,我启用了命名管道和 TCP/IP。在“IP 地址”选项卡上,我已启用所有端口并将 TCP 端口设置为 1433。已尝试使用和关闭 TCP 动态端口。
-已尝试使用 SQL Server Browser 运行和停止(另一篇文章提到这样做)。
-已尝试使用 jre7 和 jre8 JDBC 驱动程序。
-sourceCompatibility 和 targetCompatibility 在各自的 1_7 或 1_8 版本中设置。
-编译文件('libs/sqljdbc41.jar') [或 42 for jre8]
-更绝望的是,为了确保它们不是问题,在完全关闭 Windows 防火墙并允许任何 IP 通过 Azure 防火墙连接(起始/结束 IP 为 0.0.0.0 - 255.255)后,我也无法连接。 255.255)
-我可以 ping 和 telnet 到 (mydbname).database.windows.net 1433(DNS 和实际 IP)
考虑到上述所有内容,我只能假设错误发生在我的代码中的某个地方,但我绝对无法弄清楚在哪里。为了给棺材上钉上钉子,应该提到的是,我能够能够成功查询数据库并在我的项目中返回一个值,但仅在静态、非 Activity 类。当添加到实际 Activity 类时,几乎完全复制代码没有产生任何结果。
这是工作代码:
import java.sql.*;
public class DatabaseHelper {
public static void main(String[] args) throws Exception {
String custID = "1";
String connectionString = "jdbc:sqlserver://vet-to-go.database.windows.net:1433;database=Vet To Go DB;user=myLogin@vet-to-go;password=myPass;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";
String queryString = "SELECT FirstName, LastName FROM Tbl_Customer WHERE CustomerID = " + custID;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection myConnection = DriverManager.getConnection(connectionString);
Statement myStatement = myConnection.createStatement();
ResultSet myResultSet = myStatement.executeQuery(queryString);
myResultSet.next();
String firstName = myResultSet.getString("FirstName");
String lastName = myResultSet.getString("LastName");
System.out.println(firstName);
System.out.println(lastName);
myStatement.close();
myConnection.close();
}
}
我知道其中一些代码看起来很奇怪,这只是因为我希望将其合并到另一个类中。这是我最近的尝试(正如我提到的,我已经这样做了一段时间,所以我尝试了几种不同的组合)
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import java.sql.*;
public class LandingPage extends AppCompatActivity {
TextView txtFirst, txtLast;
String firstName, lastName, customerID;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_landing_page);
txtFirst = (TextView)findViewById(R.id.txtFirstName);
txtLast = (TextView)findViewById(R.id.txtLastName);
customerID = getIntent().getStringExtra("custID");
new myAsyncTask(LandingPage.this).execute();
txtFirst.setText(firstName);
txtLast.setText(lastName);
}
public class myAsyncTask extends AsyncTask<Void, Void, String> {
String connectionString = "jdbc:sqlserver://vet-to-go.database.windows.net:1433;database=Vet To Go DB;user=myLogin@vet-to-go;password=myPass;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;";
String queryString = "SELECT FirstName, LastName FROM Tbl_Customer WHERE CustomerID = " + customerID;
Context context;
public myAsyncTask(Context context) {
System.out.println("Async instantiated.");
this.context = context;
}
protected void onPreExecute() {
System.out.println("Pre-executing Async task.");
}
protected String doInBackground(Void... params) {
try {
System.out.println("Attempting to connect to DB...");
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection con = DriverManager.getConnection(connectionString);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(queryString);
while (rs.next()) {
System.out.println("Sorting through ResultSet...");
firstName = rs.getString("FirstName");
lastName = rs.getString("LastName");
}
} catch (SQLException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
return "Complete";
}
protected void onPostExecute(String result) {
if (result.equals("Complete")) {
System.out.println("Async task complete.");
}
}
}
}
运行上述代码后,我收到“与主机 vet-to-go.database.windows.net 的 TCP/IP 连接,端口 1433 失败”。此行错误:
Connection con = DriverManager.getConnection(connectionString);
我认为这不相关,但为了以防万一,以下是 MainActivity 中当前的所有内容:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etID = (EditText)findViewById(R.id.etCustID);
btnSubmit = (Button)findViewById(R.id.btnSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
customerID = etID.getText().toString();
myIntent = new Intent(MainActivity.this, LandingPage.class);
myIntent.putExtra("custID", customerID);
startActivity(myIntent);
}
});
}
Android Studio 2.3
Build #AI-162.3764568, built on February 24, 2017
JRE: 1.8.0_112-release-b06 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Gradle version 3.3
Target API 22: Android 5.1
Min Sdk V 21
Build tools v 25.0.0
最佳答案
首先,在Android上直接连接Azure SQL数据库并不是一个好主意。通常,推荐的方法是通过调用一些 REST API 来访问数据库,这些 API 在 Azure 上创建为 Web 应用程序或移动应用程序。
其次,许多现有的 SO 线程与您有类似的问题,解决方法是使用 jTDS
驱动程序而不是 Android 上的 MS SQL Server 驱动程序 sqljdbc
进行连接,因为 Android 上似乎不完全支持 sqljdbc
驱动程序。作为引用,请参阅以下已解决的这些线程。
- https://social.msdn.microsoft.com/forums/sqlserver/en-US/4799819a-27fd-4292-a3d8-f114207c20b2/using-the-jdbc-driver-with-android
- Sql Database connect Using the JDBC Driver with android
- how to connect sql server using JTDS driver in Android
希望有帮助。
关于java - Android Studio 中与 Azure 的 JDBC 连接失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43199830/