Java 我们可以使用JDBC在Android中连接远程MySQL数据库吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26470117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:35:01  来源:igfitidea点击:

Can we connect remote MySQL database in Android using JDBC?

javaandroidmysqlrestjdbc

提问by xyz

I am developing a client-server application which requires remote database connection.

我正在开发一个需要远程数据库连接的客户端-服务器应用程序。

I know that tutorials on the web and more people are using PHP to interact with MySQL. But, I am not so good at PHP and my prior experience is with Core Java, Swing and JDBC.

我知道网络上的教程和更多人正在使用 PHP 与 MySQL 交互。但是,我不太擅长 PHP,我之前的经验是使用 Core Java、Swing 和 JDBC。

Can anyone guide me if it is possible to connect remote MySQL database using JAVA JDBC APIs in Android application?

任何人都可以指导我是否可以在 Android 应用程序中使用 JAVA JDBC API 连接远程 MySQL 数据库?

采纳答案by Luiggi Mendoza

Basically: you can connect to your MySQL (or whatever you use) server, but you should notdo this directly from your Android application.

基本上:您可以连接到您的 MySQL(或任何您使用的)服务器,但您不应直接从您的 Android 应用程序执行此操作。

Reasons:

原因:

  1. Android applications can be decompiled, and the client will have credentials to access to your database. If using the right hacking tools like Backtrack, then this malicious client can access, connect and exploit the data in your database.

  2. If your application is for clients all around the world, then the clients should open and maintain a connection to your database per operation or set of operations. Opening a physical database connection takes a lot of time, even when your pc client is in a LAN next to the database engine server. Now, imagine opening a connection from a country in the other side of the world e.g. China or Japan or from a country in South America like Brazil or Peru (where I live).

  1. Android 应用程序可以被反编译,并且客户端将拥有访问您的数据库的凭据。如果使用正确的黑客工具,如Backtrack,那么这个恶意客户端就可以访问、连接和利用您数据库中的数据。

  2. 如果您的应用程序面向世界各地的客户端,则客户端应打开并维护与每个操作或一组操作的数据库的连接。打开物理数据库连接需要很多时间,即使您的 PC 客户端位于数据库引擎服务器旁边的 LAN 中。现在,想象一下从世界另一端的国家(例如中国或日本)或南美洲的国家(例如巴西或秘鲁(我居住的地方))建立联系。

For these 2 reasons I can come up with, it's a bad idea even trying to connect to MySQL or any other database engine directly from your phone device.

由于我能想到的这两个原因,即使尝试直接从手机设备连接到 MySQL 或任何其他数据库引擎也是一个坏主意。

How to solve this problem? Use a service oriented architecture where you will have at least two applications:

如何解决这个问题呢?使用面向服务的架构,您将至少拥有两个应用程序:

  1. Service provider application. This application will create and publish web services (preferably RESTful) and may establish policies to consume the web services like user authentication and authorization. This application will also connect to the database and execute CRUD operations against it.

  2. Service consumer application. This would be your Android (or any other mobile) application.

  1. 服务提供商应用程序。此应用程序将创建和发布 Web 服务(最好是 RESTful),并可能建立使用 Web 服务(如用户身份验证和授权)的策略。此应用程序还将连接到数据库并对其执行 CRUD 操作。

  2. 服务消费者应用程序。这将是您的 Android(或任何其他移动)应用程序。

From your question, you're focusing on the point 1. As I've said in my comments, you can create a Web application in Java, create a RESTful service there, which boils down to a POJO (plain old java object) that has a method per service. In this method, since it's plain Java after all, you can add other functionality like JDBC usage.

从您的问题来看,您关注的是第 1 点。正如我在评论中所说,您可以用 Java 创建一个 Web 应用程序,在那里创建一个 RESTful 服务,这归结为一个 POJO(普通的旧 Java 对象)每个服务都有一个方法。在这种方法中,由于它毕竟是纯 Java,您可以添加其他功能,例如 JDBC 用法。

Here's a kickoff example using Jersey, Hymanson (JSON library) and JDBC:

这是使用 Jersey、Hymanson(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;
    }
}

You can check for further configurations of the Java web application in a tutorial like mkyong'sor Vogella'sor any other of your like (it's too much info to place in this answer).

您可以在mkyongVogella或任何其他类似教程中检查 Java Web 应用程序的进一步配置(在此答案中放置的信息太多)。

Note that then this application can evolve into a layered application, and the JDBC code will go in a DAO class, and then the ProductRestServiceclass will access to the database through this DAO class. Here's another kickoff example:

注意,那么这个应用程序可以演化为一个分层的应用程序,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();
    }
}

And you can apply other changes to this project as well as is evolving.

您可以将其他更改应用于此项目以及不断发展。

Can you say me what PHP does here? (if I develop with PHP)

你能告诉我 PHP 在这里做什么吗?(如果我用 PHP 开发)

Instead of writing the Service provider application in Java (as shown above), you can do it in PHP. Or in Python, Ruby, C#, Scala or any other programming language that provides this technology to you. Again, I'm not sure what kind of tutorial you're reading, but this should be explained somewhere and explain that for the purposes of that tutorial you will create the services using PHP. If you feel more comfortable writing these services in Java rather than in PHP or any other language, there's no problem. Your android app doesn't really care which technology is used to produce the web services, it will only care about consuming the services and that the data from them can be consumed.

您可以用 PHP 来完成,而不是用 Java 编写服务提供者应用程序(如上所示)。或者使用 Python、Ruby、C#、Scala 或任何其他为您提供此技术的编程语言。同样,我不确定您正在阅读哪种类型的教程,但是应该在某处对此进行解释,并说明出于该教程的目的,您将使用 PHP 创建服务。如果您觉得用 Java 编写这些服务比用 PHP 或任何其他语言编写这些服务更舒服,那也没有问题。您的 android 应用程序并不真正关心使用哪种技术来生成 Web 服务,它只关心使用服务以及可以使用它们中的数据。

回答by stacktry

You can't access a MySQL DB from Android natively. EDIT: Actually you may be able to use JDBC, but it is not recommended (or may not work?) ... see Android JDBC not working: ClassNotFoundException on driver

您无法从 Android 本地访问 MySQL 数据库。编辑:实际上您可以使用 JDBC,但不推荐(或可能不起作用?)...请参阅Android JDBC not working: ClassNotFoundException on driver

See

http://www.helloandroid.com/tutorials/connecting-mysql-database

http://www.helloandroid.com/tutorials/connecting-mysql-database

http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/8339-connect-android-mysql-database-tutorial.html

http://www.basic4ppc.com/forum/basic4android-getting-started-tutorials/8339-connect-android-mysql-database-tutorial.html

Android cannot connect directly to the database server. Therefore we need to create a simple web service that will pass the requests to the database and will return the response.

Android 无法直接连接到数据库服务器。因此,我们需要创建一个简单的 Web 服务,它将请求传递到数据库并返回响应。

http://codeoncloud.blogspot.com/2012/03/android-mysql-client.html

http://codeoncloud.blogspot.com/2012/03/android-mysql-client.html

For most [good] users this might be fine. But imagine you get a hacker that gets a hold of your program. I've decompiled my own applications and its scary what I've seen. What if they get your username / password to your database and wreak havoc? Bad.

对于大多数[好]用户来说,这可能没问题。但是想象一下,你有一个黑客控制了你的程序。我已经反编译了我自己的应用程序,并且看到了可怕的东西。如果他们将您的用户名/密码获取到您的数据库并造成严重破坏怎么办?坏的。

回答by Aaron C

It is possible to do it but not recommended. I have done it before as I was in the same boat as you so I will share some code.

可以这样做,但不推荐。我以前做过,因为我和你在同一条船上,所以我会分享一些代码。

I used this jdbc jar specifically: https://www.dropbox.com/s/wr06rtjqv0q1vgs/mysql-connector-java-3.0.17-ga-bin.jar?dl=0

我专门使用了这个 jdbc jar:https: //www.dropbox.com/s/wr06rtjqv0q1vgs/mysql-connector-java-3.0.17-ga-bin.jar?dl =0

now for the code:

现在是代码:

    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
        }
    }

Now for my async task:

现在我的异步任务:

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();
        }
    }
}

Make sure to include internet permissions in the manifest. Feel free to ask more questions about my code if you have any.

确保在清单中包含 Internet 权限。如果您有任何问题,请随时询问有关我的代码的更多问题。