標籤:manifest turn -- target 下一步 cep 運行時 sys 擷取
JDBC為java程式訪問各種類型的關係型資料庫提供了統一的介面,使用者不必針對不同資料庫寫出不同的代碼,但是使用JDBC必須得下載相應的驅動,比如我這裡是要串連mysql,於是就到mysql官網去下載x相應驅動 https://dev.mysql.com/downloads/connector/j/
這裡我下載解壓得到 mysql-connector-java-5.1.43-bin.jar
在Eclipse中建立java項目只需要Build Path --> Add External Archives把該jar包的路徑添加進來就可以使用。在Android Studio中更是只需要複製粘貼到項目目錄的app\libs下即可,IDE會自動載入。——看似如此。
本地Android Studio的配置
我的Android Studio版本是Community Edition2016.2.5,系統是win7 64位。在添加該jar檔案後,build出錯。
按照提示,需要在項目最外層的build.gradle檔案中的allprojects { ... }地區(具體見代碼下的圖片,之後就不附圖了)內添加下列代碼
tasks.withType(JavaCompile) { sourceCompatibility = ‘1.7‘ targetCompatibility = ‘1.7‘ }
這還沒完,此時會提示Error: Unable to find a JDK,起初我懷疑jdk沒添加進環境變數,但是cmd視窗測試無誤,而且Android Studio建立項目也能編譯運行。那麼,還是jar包的問題。查了很久後找到瞭解決方案,看起來是java8的不相容所致,所以需要全面改為Java7來編譯
Android Studio2.1.2 Java8環境下引用Java Library編譯出錯
1、在所有module的build.gradle檔案中的android { ... }地區中添加
compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 }
就我這個建立的項目,沒有添加module,所以需要修改的檔案就只有app\build.gradle
2、在主module的build.gradle檔案(也就是app\build.gradle)的android { defaultConfig { ... } }地區中添加
jackOptions { enabled true }
此時編譯成功了,但是注意,這才是第一步,僅僅只是成功引用了java庫。Android Studio預設是不允許訪問Internet的。
因此需要在app/src/main/AndroidManifest.xml中的<manifest>...</manifest>地區內添加一行
<uses-permission android:name="android.permission.INTERNET"/>
遠程mysql的配置
然後我的mysql是安裝在Linux虛擬機器(Ubuntu 16.04)上的,預設mysql是禁止遠端連線的,所以在Linux上也要進行配置
首先是要讓mysql支援中文字元,登陸mysql使用者後,輸入命令STATUS;可以看到幾個字元集是這樣的
Server characterset:latin1Db characterset:latin1Client characterset:utf8Conn. characterset:utf8
因此需要用超級使用者權限修改/etc/mysql/my.cnf,添加下列代碼(這裡順便綁定了連接埠為3306,雖然一般預設連接埠也是3306)
[client]default-character-set=utf8[mysqld]default-storage-engine=INNODBcharacter-set-server=utf8collation-server=utf8_general_ci
port=3306
然後重啟mysql,命令如下
$ /etc/init.d/mysql stop$ /etc/init.d/mysql start
之後再登陸mysql後使用STATUS命令就可以看到字元集全部變成了utf8。
然後mysql預設綁定的IP是127.0.0.1,連接埠3306,在shell下可以通過shell命令netstat -apn | grep 3306查看連接埠佔用情況,若連接埠3306對應的第三項(Local Address)是127.0.0.1:3306,那麼mysql綁定的就是本地地址,不能遠端連線。
還是用超級使用者權限修改/etc/mysql/my.cnf,添加下列代碼並重啟mysql
bind-address=0.0.0.0
重啟後再用netstat -apn | grep 3306查看第三項就會變成0.0.0.0:3306,那麼mysql就支援了遠端連線。
還沒完,雖然mysql賦予了遠端連線的許可權,但是mysql使用者並沒有。我這裡的mysql使用者名稱是team,密碼是java123,用root登陸mysql後輸入下列命令
mysql> grant all on *.* to [email protected]‘%‘ identified by ‘java123‘ with grant option;mysql> flush privileges;
[email protected]‘%‘代表使用者team支援遠端連線,[email protected]‘localhost‘則代表使用者team支援本地串連
代碼實現
好了,終於可以寫代碼了,於是迫不可待地在MainAcitivity.java的onCreate()方法內部添加下列代碼(先嘗試串連)
// 1.載入JDBC驅動 try { Class.forName("com.mysql.jdbc.Driver"); Log.v(TAG, "載入JDBC驅動成功"); } catch (ClassNotFoundException e) { Log.e(TAG, "載入JDBC驅動失敗"); return; } // 2.設定好IP/連接埠/資料庫名/使用者名稱/密碼等必要的串連資訊 String ip = "192.168.183.134"; int port = 3306; String dbName = "XYZ"; String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName; // 構建串連mysql的字串 String user = "team"; String password = "java123"; // 3.串連JDBC try { Connection conn = DriverManager.getConnection(url, user, password); conn.close(); } catch (SQLException e) { Log.e(TAG, "遠端連線失敗!"); return; }
這裡使用了andorid.util.Log而不是System.out.println來列印訊息,因為可以設定過濾符,通過TAG、記錄層級等資訊來篩選出特定的日誌
這裡我就是通過TAG來篩選,也可以通過Message和Package來篩選,並且支援Regex,程式運行時會有大量日誌混雜在一起,所以使用Log而不是System.out來列印訊息更好。
於是,通過日誌過濾符篩選,可以發現串連失敗了。
這個問題折磨了我一天多,參考了很多網上的代碼,和我的基本無異,而且也copy過來測試過都不行,最後在stackoverflow上找到瞭解答
https://stackoverflow.com/questions/12233145/connecting-to-mysql-from-android-with-jdbchttps://stackoverflow.com/questions/12233145/connecting-to-mysql-from-android-with-jdbc
mysql的串連必須在非同步任務類中,也就是說必須建立線程來串連mysql,而不能在主線程中執行代碼。
final Thread thread = new Thread(new Runnable() { @Override public void run() { // 反覆嘗試串連,直到串連成功後退出迴圈 while (!Thread.interrupted()) { try { Thread.sleep(100); // 每隔0.1秒嘗試串連 } catch (InterruptedException e) { Log.e(TAG, e.toString()); } // 2.設定好IP/連接埠/資料庫名/使用者名稱/密碼等必要的串連資訊 String ip = "192.168.183.134"; int port = 3306; String dbName = "XYZ"; String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName; // 構建串連mysql的字串 String user = "team"; String password = "java123"; // 3.串連JDBC try { Connection conn = DriverManager.getConnection(url, user, password); Log.i(TAG, "遠端連線成功!"); conn.close(); return; } catch (SQLException e) { Log.e(TAG, "遠端連線失敗!"); } } } }); thread.start();
成功了,總算可以繼續下一步,向遠端連線的mysql發送命令了,將上述代碼稍作修改
// 3.串連JDBC Connection conn = null; try { conn = DriverManager.getConnection(url, user, password); Log.i(TAG, "遠端連線成功!"); } catch (SQLException e) { Log.e(TAG, "遠端連線失敗!"); } if (conn != null) { String sql = "SELECT * FROM pokemon"; try { // 建立用來執行sql語句的對象 java.sql.Statement statement = conn.createStatement(); // 執行sql查詢語句並擷取查詢資訊 ResultSet rSet = statement.executeQuery(sql); // 迭代列印出查詢資訊 Log.i(TAG, "寶可夢列表"); Log.i(TAG, "ID\tName\tAttr1\tAttr2"); while (rSet.next()) { Log.i(TAG, rSet.getString("id") + "\t" + rSet.getString("name") + "\t" + rSet.getString("attr1") + "\t" + rSet.getString("attr2")); } } catch (SQLException e) { Log.e(TAG, "createStatement error"); } try { conn.close(); } catch (SQLException e) { Log.e(TAG, "關閉串連失敗"); }
懶得仔細研究java格式化字串,直接把結果列印出來了,這裡只用到了執行查詢語句的executeQuery,返回結果到一組迭代對象。
而execute則可以執行任何sql語句,更多API可以參考JDBC官方教程 http://docs.oracle.com/javase/tutorial/jdbc/basics/index.html
Android Studio使用JDBC遠端連線mysql的注意事項(附樣本)