【问题标题】:Android JDBC MySQL get tables by DatabaseAndroid JDBC MySQL 按数据库获取表
【发布时间】:2016-03-09 08:41:42
【问题描述】:

我完成了一些教程,但它们都很简单,无法在我的解决方案中使用。

我通过 JDBC MySQL 连接到数据库。

public class ConnCore extends AsyncTask<Void, Void, Boolean> {

Activity activity;
    Context context;
    public ConnCore(Context context, Activity currActivity) {
        this.context = context.getApplicationContext();
        this.activity = currActivity;
    }


    @Override
    protected Boolean doInBackground(Void... params) {


        try{Class.forName("com.mysql.jdbc.Driver");}
        catch(Exception e){
           DataStore.DataStoreClass.connExc = e;
            return false;}


        try{

          DataStore.DataStoreClass.mysqlConn = DriverManager.getConnection(DataStore.DataStoreClass.connectionString);

            return true;
        }catch(Exception e){
            DataStore.DataStoreClass.connExc = e;
            return false;
        }





    }

    @Override
    protected void onPostExecute (Boolean b) {


         if(b == true) {

            Intent intent = new Intent(context, DBList.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);



        } else {
            AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
            alertDialog.setTitle("Error");
            alertDialog.setMessage(DataStore.DataStoreClass.connExc.toString());
            alertDialog.show();

        }
}

这将与此字符串相关:

static String connectionString = "jdbc:mysql://XXX.XXX.XXX.XXX:3306?user=root&password=test&autoReconnect=true&failOverReadOnly=false&maxReconnects=10";

如果连接成功,它会启动新的活动 DBList,它会启动新的 AsyncTask 以获取数据库。 AsyncTask 看起来像这样:

public class GetDBList extends AsyncTask<Void, Void, Boolean> {
    Activity activity;
    Context context;
    public GetDBList(Context context, Activity activity){
        this.activity = activity;
        this.context = context;
    }

    @Override
    protected Boolean doInBackground(Void... params){


        Statement stmt = null;
        String query = "SHOW DATABASES";
        DataStore.DataStoreClass.DBResponse = new ArrayList<String>();



        try {
            DatabaseMetaData meta = DataStore.DataStoreClass.mysqlConn.getMetaData();
            ResultSet res = meta.getCatalogs();
            while (res.next()) {
                DataStore.DataStoreClass.DBResponse.add(res.getString("TABLE_CAT"));

            }
            res.close();
            return true;
        }
        catch (SQLException e){

            AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
            alertDialog.setTitle("Error");
            alertDialog.setMessage(e.toString());
            alertDialog.show();
            return false;
        }





    }

    @Override
    protected void onPostExecute(Boolean b){
       if(b) {
           ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, DataStore.DataStoreClass.DBResponse){
               @Override
               public View getView(int position, View convertView, ViewGroup parent) {
                   View view = super.getView(position, convertView, parent);
                   TextView text = (TextView) view.findViewById(android.R.id.text1);
                   text.setTextColor(Color.BLACK);
                   return view;
               }
           };
           ListView lv = (ListView) activity.findViewById(R.id.db_lv);
           lv.setAdapter(arrayAdapter);

           lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
               public void onItemClick(AdapterView<?> parent, View view,
                                       int position, long id) {


                   DataStore.DataStoreClass.currentDB = ((TextView) view).getText().toString();
                   Toast.makeText(context, DataStore.DataStoreClass.currentDB,
                           Toast.LENGTH_SHORT).show();

                   AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
                   alertDialog.setTitle("Error");
                   alertDialog.setMessage(DataStore.DataStoreClass.connExc.toString());
                   alertDialog.show();

               }
           });

       }


    }
}

到目前为止,一切正常,我可以获取带有数据库的 ListView。

现在。每个 List_Item 都有 onClickListener。 如何将字符串值(包含数据库名称)传递给现有连接以获取其表?

每个教程都已经有了数据库的名称。我正在尝试创建一个通用数据库客户端,所以您实际上不知道服务器上有哪些数据库。

String url = "jdbc:mysql://" + serverName +  "/" + schema;

我不想关闭以前的连接并直接与数据库建立一个新连接

那么有没有可能“编辑”

(static Connection mysqlConn;)
DataStore.DataStoreClass.mysqlConn = DriverManager.getConnection(DataStore.DataStoreClass.connectionString);

不知何故...或任何其他方式?

谢谢。

【问题讨论】:

  • 首先 - 它可以连接访问多个数据库。只要用户对他们有oermissions就可以了。
  • @Jan 我想,你没有明白这一点。我能够列出数据库。然后,我需要从返回的列表中选择一个,并获取它的表格列表。我的问题是,当所有教程都在计算“我在创建连接时知道数据库名称”时该怎么做 - 而我不知道。我需要从列表中选择数据库,我无法将其硬核到解决方案中。我一次只需要编辑一个数据库
  • "显示来自 " + dbname 的表
  • 抱歉 - 在移动设备上。换句话说:即使您没有通过连接字符串连接到该数据库,您也可以列出表、读取数据等。您甚至可以执行“使用”+dbname as sql,从而更改活动连接的默认数据库。
  • 您可以在没有数据库名称的情况下连接到数据库 String url="jdbc:mysql://{hostname}:{port}" 并且查询时必须附加{dbname} 例如 select * from dbname.dbtable

标签: java android jdbc


【解决方案1】:

如果我正确理解您的意思,您想连接到数据库,但是您事先不知道数据库名称。正确的?

如果上述情况属实,那么您无需提供数据库名称即可连接到数据库。只需将主机名和端口提供给DriverManager,如下所示:

String url="jdbc:mysql://{hostname}:{port}"
Connection conn = DriverManager.getConnection(url, username, password);

既然您有一个有效的Connection,您需要找出那里有哪些数据库。你已经知道了,但是无论如何我都会提供一个例子,以便我涵盖所有内容。使用上面的java.sql.Connection对象创建一个java.sql.Statement如下图:

Statement stmt = conn.createStatement();
String SQL = "SHOW DATABASES";

运行上面的SQL语句,得到一个数据库名称列表如下:

ResultSet rs = stmt.executeQuery(SQL);

遍历返回的数据库名称列表,并将重要的名称添加到跳过系统和其他内部数据库的列表中。见下文:

List<String> dbNames = new ArrayList<String>(); 

while (rs.next()) {
    // Retrieve by column name
    String name = rs.getString("Database");
    if(!name.equals("information_schema") && !name.equals("mysql") && !name.equals("performance_schema") && !name.equals("sys")) {
        dbNames.add(name); 
    }
}

假设我的数据库中只有db1db2db3,那么打印时列表将包含以下内容

[db1, db2, db3]

现在我想检索上述每个数据库的表列表。我手动创建了表 t1 and t2 in db1 数据库、x1 and x2 in db2 数据库、z1 and z2 in db3 数据库,看看我如何以不同的方式遍历数据库表:

方法一:您可以使用java.sql.Connection 类的setCatalog(String dbname) 方法将数据库名称设置为Connection 对象。这类似于USE {dbname} sql 命令。请参阅下面的示例

for(int i = 0; i < dbNames.size(); i++) {
    //here I am setting the dbname in connection obj
    conn.setCatalog(dbNames.get(i));
    //then I am creating a new Statement
    stmt = conn.createStatement();

    sql = "SHOW TABLES";
    rs = stmt.executeQuery(sql);
    while(rs.next()) {
        System.out.println(rs.getString(1) 
           + " is a table in " + dbNames.get(i) + " database.");
    }
}

方法二:在该方法中,可以通过将SQL命令改成如下方式避免使用java.sql.Connection类的setCatalog(String dbname)方法:

sql = "SHOW TABLES FROM " + dbNames.get(i);

这两种方法都应该给你相同的输出,如下所示:

[db1, db2, db3]
t1 is a table in db1 database.
t2 is a table in db1 database.
x1 is a table in db2 database.
x2 is a table in db2 database.
z1 is a table in db3 database.
z2 is a table in db3 database.

【讨论】:

  • 非常感谢,我今天就试试。方法 1 似乎没问题,据我所知,就像看代码一样,我想到了非常相似的东西。方法 2 对我不可用,因为从表列表中,我需要显示所有行表,从该表的所有行中,我将需要编辑一行,依此类推......所以我需要在数据库中“设置一个指针”以进行进一步的工作。
  • @Zorak 欢迎您。如果此答案有助于解决您的问题,那么您可以选择将其标记为已接受
  • 抱歉让您久等了。试图实现method1,它正在工作!!!!非常感谢您花时间帮助我。真的很感激。玩得开心:)
猜你喜欢
  • 2014-12-13
  • 2019-12-15
  • 2014-04-25
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-06
相关资源
最近更新 更多