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

Posted

技术标签:

【中文标题】我们可以使用 JDBC 在 Android 中连接远程 MySQL 数据库吗? [关闭]【英文标题】:Can we connect remote MySQL database in Android using JDBC? [closed] 【发布时间】:2014-12-15 16:46:45 【问题描述】:

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

我知道网络上的教程和越来越多的人正在使用 phpmysql 进行交互。但是,我不太擅长 PHP,而且我之前的经验是使用 Core Java、Swing 和 JDBC。

如果可以在 android 应用程序中使用 JAVA JDBC API 连接远程 MySQL 数据库,谁能指导我?

【问题讨论】:

我不知道您正在阅读什么样的教程,但是对于要与数据库交互的 Android 应用程序,您应该使用 RESTful 服务。这些服务可以使用 PHP、Java 或其他编程语言构建。 @LuiggiMendoza 我对两者都进行了搜索 - 用于 PHP 的 REST 和用于 JAVA 的 RESTLET ......但是,我对客户端-服务器应用程序非常陌生。我不知道我们如何将 JDBC 与 RESTLET webservices 一起使用。 你应该专注于一件事。搜索有关如何使用 Java 构建 RESTful 服务的简单教程,可能使用 Tomcat 或 Jetty。然后,当你发现这个 RESTful 服务由一个类和一个方法支持后,你可能会注意到你可以在这个类/方法中使用 JDBC 并发展你的服务的目的。然后这可能会演变成分层架构并继续发展。更重要的是:您将在练习所有这些东西的同时学习。 【参考方案1】:

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

原因:

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

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

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

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

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

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

从您的问题来看,您关注的是第 1 点。正如我在我的 cmets 中所说,您可以在 Java 中创建一个 Web 应用程序,在那里创建一个 RESTful 服务,归结为 POJO(普通的旧 java对象),每个服务都有一个方法。在这种方法中,由于它毕竟是纯 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 开发)

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

【讨论】:

您能推荐任何关于使用 jersey web 服务将 Android 应用程序连接到 MySQL 数据库的好文章吗? @userX 我在搜索我的 SEO 时发现了这个:programmerguru.com/android-tutorial/… Tutorial TL;DR 调用外部 Web 服务的方法是 invokeWS。我不支持那个教程。 一个web服务不能被ddos攻击,那么它是如何完美的呢?是的,它保护了 pw,但我是否还需要 oauth 或另一层悲伤?我倾向于使用 mysql-procedures 而不是 webservice。这样我就可以使用他们的 IP 地址来限制使用,不良行为。是的,IP 是可欺骗的,但在与 php 中介解决方案斗争了 10 年后,我倾向于使用 mysql-procedures.... @jim 任何通过网络可用的服务都可能受到 DDoS 或任何其他技术的攻击。只需将您的设备连接到 WAN 等接入点,然后使用嗅探器查看网络流量,您将看到您的设备实现调用的服务器,即使是通过 IP,然后是 DDoS 该服务器,无论那里有什么。使用 MySQL 过程不会改变这一事实。【参考方案2】:

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

我专门用了这个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();
        
    

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

【讨论】:

【参考方案3】:

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

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

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

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

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

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

【讨论】:

@xyz 正如我在 cmets 中对您的问题所指出的那样,PHP 不是必需的,这就是本教程向您解释的内容。 RESTful 服务可以用 PHP、Java、Python、Ruby、C# 或任何其他支持创建一组 RESTful 服务的编程语言编写。 Web 服务客户端(在本例中为您的 Android 应用)与创建 Web 服务的技术无关。 @LuiggiMendoza 你能告诉我 PHP 在这里做什么吗? (如果我使用 PHP 开发)

以上是关于我们可以使用 JDBC 在 Android 中连接远程 MySQL 数据库吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中使用 JDBC 优化 mysql DB 执行

Android JDBC 连接器

在android中使用JDBC连接在mySQL上插入行的问题

如何使用 Mysql JDBC 驱动程序将 Android 与 MySQL 连接 [重复]

Android中的JDBC连接

Android JDBC 连接问题