java - Android 中的 JDBC 连接问题
问题描述
我按照youtube 上的教程制作了一个带有数据库的列表应用程序。现在我得到错误:
为 JDBC 引发了异常。
这是我的代码:
package com.example.jopri.databaseconnectie;
import android.content.AsyncQueryHandler;
import android.content.Context;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
ItemAdapter itemAdapter;
Context thisContext;
ListView myListView;
TextView progressTextView;
Map<String, Double> fruitsMap = new LinkedHashMap<String, Double>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
myListView = (ListView) findViewById(R.id.myListView);
progressTextView = (TextView) findViewById(R.id.progressTextView);
thisContext = this;
progressTextView.setText("");
Button btn = (Button) findViewById(R.id.getDataButton);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
GetData retrieveData = new GetData();
retrieveData.execute("");
}
});
}
private class GetData extends AsyncTask<String, String, String> {
String msg = "";
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://" +
DbStrings.DATABASE_URL + "/" +
DbStrings.DATABASE_NAME;
protected void onPreExecute() {
progressTextView.setText("Connecting to database...");
}
@Override
protected String doInBackground(String... params) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(DB_URL, DbStrings.USERNAME, DbStrings.PASSWORD);
stmt = conn.createStatement();
String sql = "SELECT * FROM fruit";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
String soort = rs.getString("soort");
double prijs = rs.getDouble("prijs");
fruitsMap.put(soort, prijs);
}
msg = "Process complete";
rs.close();
stmt.close();
conn.close();
} catch (SQLException connError) {
msg = "An exception was thrown for JDBC";
connError.printStackTrace();
} catch (ClassNotFoundException e) {
msg = "A class not found exception was thrown.";
e.printStackTrace();
} finally {
try {
if (stmt != null) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onPostExecute(String msg) {
progressTextView.setText(this.msg);
if(fruitsMap.size() > 0) {
itemAdapter = new ItemAdapter(thisContext, fruitsMap);
myListView.setAdapter(itemAdapter);
}
}
}
} // END
连接器:
package com.example.jopri.databaseconnectie;
import java.net.URL;
public class DbStrings {
static final String DATABASE_URL = "127.0.0.1:3306";
static final String DATABASE_NAME = "proef";
static final String USERNAME = "root";
static final String PASSWORD = "password";
}
物品适配器:
package com.example.jopri.databaseconnectie;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ItemAdapter extends BaseAdapter {
LayoutInflater mInflator;
Map<String, Double> map;
List<String> soort;
List<Double> prijs;
public ItemAdapter(Context c, Map m) {
mInflator = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
map = m;
soort = new ArrayList<String>(map.keySet());
prijs = new ArrayList<Double>(map.values());
};
@Override
public int getCount() {
return map.size();
}
@Override
public Object getItem(int position) {
return soort.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = mInflator.inflate(R.layout.item_layout, null);
TextView nameTextView = (TextView) v.findViewById(R.id.nameTextView);
TextView priceTextView = (TextView) v.findViewById(R.id.priceTextView);
nameTextView.setText(soort.get(position));
priceTextView.setText("€" + prijs.get(position).toString());
return v;
}
}
解决方案
static final String DATABASE_URL = "127.0.0.1:3306";
这条线意味着您正在 Android 设备本身上运行 MySQL 服务器,这对我来说似乎不太可能。如果您再次观看视频,他从未使用过 localhost/127.0.0.1。
此 URL 应该是可在您的网络中解析的远程 IP/主机名(理想情况下,应该通过 WiFi 和移动设备工作)
此外,通过这样做,您会将您的数据库密码暴露给任何可以访问您的应用程序/代码的人,因为它只是内存中的一个普通字符串。因此,在现实世界的环境中,您实际上会使用基于 HTTP 的 API,它可以更安全地隐藏数据库凭据并将其存储在一个位置,而不是将该信息复制到一堆移动设备上(如果您发布您的应用程序)供他人使用)。
如果您想要的只是一个带有列表视图的数据库,请从 SQLite 开始,它作为 Android SDK 的一部分嵌入并作为库提供
推荐阅读
- dart - 如何防止 Flutter Inkwell 上的多次触摸
- javascript - 如何避免页面刷新/渲染上的双重时间绑定控件
- javascript - JavaScript 打开输入日期选择器事件
- postfix-mta - Postfix 中的基本垃圾邮件过滤器
- spring-boot - 找到多个名为 [spring_web] 的片段
- android - 如何使用 OnPressed FAB 按钮在 Flutter 中设置计时器倒计时 30 秒?
- swift - 未显示 menuController 并且无法弄清楚如何使视图返回 True 以调用 .becomeFirstResponder
- wordpress - 使用 WPAPI 向 WordPress 发表评论
- javascript - 为什么我的圆锥在被鼠标拖动时旋转不顺畅
- c - 文本文件到排序的二进制文件,C 语言