我正在开发一个需要远程数据库连接的客户端 - 服务器应用程序。
我知道网络上的教程和更多人正在使用PHP与MySQL进行交互。但是,我并不擅长PHP,而我之前的经验是使用Core Java,Swing和JDBC。
如果可以在Android应用程序中使用JAVA JDBC API连接远程MySQL数据库,那么有人可以指导我吗?
答案 0 :(得分:30)
基本上:您可以连接到您的MySQL(或任何您使用的)服务器,但您不应该直接从您的Android应用程序执行此操作。
原因:
可以反编译Android应用程序,客户端将拥有访问您的数据库的凭据。如果使用正确的黑客工具(如Backtrack),则此恶意客户端可以访问,连接和利用数据库中的数据。
如果您的应用程序适用于世界各地的客户端,则客户端应按照每个操作或一组操作打开并维护与数据库的连接。打开物理数据库连接需要花费大量时间,即使您的PC客户端位于数据库引擎服务器旁边的LAN中也是如此。现在,想象一下从世界另一端的国家打开连接,例如中国或日本,或来自南美洲的国家,如巴西或秘鲁(我住的地方)。
出于这两个原因,我可以提出,即使尝试直接从手机设备连接MySQL或任何其他数据库引擎也是一个坏主意。
如何解决这个问题?使用面向服务的体系结构,您将至少拥有两个应用程序:
服务提供商申请。此应用程序将创建和发布Web服务(最好是RESTful),并可以建立使用用户身份验证和授权等Web服务的策略。此应用程序还将连接到数据库并对其执行CRUD操作。
服务消费者应用程序。这将是您的Android(或任何其他移动)应用程序。
从你的问题,你关注的重点是1.正如我在评论中所说,你可以用Java创建一个Web应用程序,在那里创建一个RESTful服务,归结为一个POJO(普通的旧java) object)每个服务都有一个方法。在这种方法中,因为它毕竟是普通的Java,所以你可以添加其他功能,如JDBC使用。
这是使用Jersey,Jackson(JSON库)和JDBC的启动示例:
@Path("/product")
public class ProductRestService {
@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public List<Product> getProducts() {
List<Product> productList = new ArrayList<>();
Connection con = ...; //retrieve your database connection
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name FROM product");
while (rs.next()) {
Product product = new Product();
product.setId(rs.getInt("id"));
product.setName(rs.getString("name"));
productList.add(product);
}
//ALWAYS close the resources
rs.close();
stmt.close();
conn.close();
return productList;
}
}
您可以在mkyong's或Vogella's或其他任何类似的教程中检查Java Web应用程序的进一步配置(在此答案中放置太多信息)。
请注意,此应用程序可以演变为分层应用程序,JDBC代码将进入DAO类,然后ProductRestService
类将通过此DAO类访问数据库。这是另一个启动示例:
public class ProductDao {
public List<Product> getProducts() {
List<Product> productList = new ArrayList<>();
Connection con = ...; //retrieve your database connection
//the rest of the code explained above...
return productList;
}
}
@Path("/product")
public class ProductRestService {
@GET
@Path("/list")
@Produces(MediaType.APPLICATION_JSON)
public List<Product> getProducts() {
ProductDao productDao = new ProductDao();
return productDao.getProducts();
}
}
您可以对此项目应用其他更改以及不断发展。
你能告诉我PHP在这里做什么吗? (如果我用PHP开发)
不是用Java编写服务提供者应用程序(如上所示),而是用PHP完成。或者使用Python,Ruby,C#,Scala或任何其他为您提供此技术的编程语言。同样,我不确定你正在阅读什么样的教程,但这应该在某处解释并解释为了本教程的目的,你将使用PHP创建服务。如果您觉得用Java而不是PHP或任何其他语言编写这些服务会更舒服,那就没问题了。您的Android应用程序并不真正关心使用哪种技术来生成Web服务,它只关心使用服务并且可以使用它们的数据。
答案 1 :(得分:7)
可以这样做但不推荐。之前我和你在同一条船上做过,所以我会分享一些代码。
我特意使用了这个jdbc jar:https://www.dropbox.com/s/wr06rtjqv0q1vgs/mysql-connector-java-3.0.17-ga-bin.jar?dl=0
现在代码:
package com.example.test.databaseapp;
import java.sql.DriverManager;
import java.sql.SQLException;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
public class MainActivity extends Activity {
static final String url = "jdbc:mysql://x.x.x.x:xxxx/DBNAME";
static final String user = "client";
static final String pass = "password";
public static List<objClass> objList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Download(MainActivity.this, internalUrl).execute(); //async task for getting data from db
}
}
现在我的异步任务:
public class Download extends AsyncTask<Void, Void, String> {
ProgressDialog mProgressDialog;
Context context;
private String url;
public Download(Context context, String url) {
this.context = context;
this.url = url;
}
protected void onPreExecute() {
mProgressDialog = ProgressDialog.show(context, "",
"Please wait, getting database...");
}
protected String doInBackground(Void... params) {
try {
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con = DriverManager.getConnection(url, user, pass);
java.sql.Statement st = con.createStatement();
java.sql.ResultSet rs = st.executeQuery("select * from table");
list = new ArrayList<objClass>();
while (rs.next()) {
String field= rs.getString("field");
MainActivity.playerList.add(new objectClass(field));
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return "Complete";
}
protected void onPostExecute(String result) {
if (result.equals("Complete")) {
mProgressDialog.dismiss();
}
}
}
确保在清单中包含互联网权限。 如果您有任何关于我的代码的问题,请随时提出更多问题。
答案 2 :(得分:2)
您无法本机访问Android的MySQL数据库。编辑:实际上你可以使用JDBC,但不推荐(或者可能不起作用?)...见Android JDBC not working: ClassNotFoundException on driver
见
http://www.helloandroid.com/tutorials/connecting-mysql-database
Android无法直接连接到数据库服务器。所以我们 需要创建一个简单的Web服务,将请求传递给 数据库并将返回响应。
http://codeoncloud.blogspot.com/2012/03/android-mysql-client.html
对于大多数[好]用户来说,这可能没问题。但想象一下,你会得到一个能够掌握你的程序的黑客。我已经反编译了我自己的应用程序,可怕的是我见过的。如果他们将您的用户名/密码输入您的数据库并造成严重破坏,该怎么办?坏。