我完成了一些教程,但所有教程都非常简单,不能在我的解决方案中使用。
我通过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值(包含数据库名称)传递给现有连接以获取其表?
每个教程都已包含数据库名称。我正在尝试创建一个通用数据库客户端,所以你实际上不知道服务器上有哪些数据库。
String url = "jdbc:mysql://" + serverName + "/" + schema;
我不想关闭先前的连接并直接向数据库创建新连接
以某种方式可以“编辑”
(static Connection mysqlConn;)
DataStore.DataStoreClass.mysqlConn = DriverManager.getConnection(DataStore.DataStoreClass.connectionString);
以某种方式...或任何其他方式?
谢谢。
答案 0 :(得分:2)
如果我理解你的观点,你想连接到数据库,但是你事先并不知道数据库名称。正确?
如果满足以上条件,则无需提供数据库名称即可连接到数据库。只需提供DriverManager
的主机名和端口,如下所示:
String url="jdbc:mysql://{hostname}:{port}"
Connection conn = DriverManager.getConnection(url, username, password);
现在你有一个有效的Connection
,你需要找出那些数据库。你已经知道了,但是,无论如何我都会提供一个例子,所以我会涵盖所有内容。使用上面的java.sql.Statement
对象创建java.sql.Connection
,如下所示:
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);
}
}
假设我的数据库中只有db1
,db2
和db3
,那么打印时列表将包含以下内容
[db1, db2, db3]
现在我想检索上述每个数据库的表列表。我手动创建了表t1 and t2 in db1
数据库,x1 and x2 in db2
数据库,z1 and z2 in db3
数据库,看看我如何以不同的方式通过数据库表进行迭代:
方法1:您可以使用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.");
}
}
方法2:在此方法中,您可以通过将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.