利用JDBC連線伺服器資料庫(Android)
1、Android平臺下與伺服器資料庫通訊的方法
在Android平臺下,連線電腦伺服器的MySQL、PostgreSQL、Oracle、Sybase、Microsoft SQLServer等資料庫管理系統DBMS(database management system),主要有以下兩種方法:
方法1、直接連線
在Android工程中引入JDBC驅動,直接連線。(本文主要介紹此種方法)
方法2、間接連線
在伺服器上用PHP+DBMS做伺服器端,PHP將DBMS中的資料用json或者xml進行封裝。然後再發封裝好的資料返回給Android平臺。
注意:
採用JDBC方法主要問題是安全性不高,而且一旦要訪問的資料量過多,容易出問題。另外,Android系統本身有對json或者xml直接解析的api,所以建議採用第二種方法,實用性與安全性都提高了。
2、JDBC簡介
JDBC是Java Data Base Connectivity的縮寫,意思為“java資料庫連線”,由一組用Java語言編寫的類和介面組成,為java層直接操作關係型資料庫提供了標準的API。原理很簡單,主要是先伺服器DBMS傳送SQL(結構化查詢語言)指令。實現各種資料庫的操作。
3、如何在Android中使用JDBC與伺服器資料庫通訊
在Android工程使用JDBC連線資料庫的主要步驟如下:
載入JDBC驅動程式------->建立連線--------->傳送SQL語句
3.1、載入JDBC驅動程式
在Android工程中要使用JDBC的話,要匯入JDBC的驅動。
詳細過程:
在eclipse選擇工程,右鍵---->Properties---->在左側選項“Java Build Path”---->切換到“Libraries”---->選擇“Add External JARs”---->選中jtds的jar包---->完畢
然後在java程式碼的開始處 import JDBC的包,這一步根據不同的驅動,目錄可能不一樣,找到Driver的路徑即可。
import net.sourceforge.jtds.jdbc.Driver;
接下來在java程式碼中使用以下語句,載入jdbc驅動。
Class.forName("net.sourceforge.jtds.jdbc.Driver");// 載入驅動程式
注意:ADT版本和android-sdk_Tools最好為16,我試過版本20老是出現找不到驅動的問題。
降級方法:
離線安裝ADT
下載SDK Tools
新增下載任務
下載完畢之後,安裝到一個任意位置,然後把裡面的檔案和資料夾copy到之前的sdk tools目錄,覆蓋新版本的。然後從eclipse裡面開啟 Android Sdk Manager,然後在第一項的tools裡面,再勾選Android SDK Platform-tools就行了,記得不要勾選Android SDK Tool。
3.2、建立連線
每種DBMS的JDBC驅動是不一樣的,同一個DBMS也會有幾種JDBC驅動,如Microsoft SQL Server的JDBC驅動主要有兩種,Microsoft 官方提供的JDBC驅動和民間開源的JDBC驅動(JTDS),推薦JTDS,bug少,而且是完全開放原始碼的。目前JTDS只能支援Microsoft SQL Server和Sybase。
由於DBMS與JDBC驅動的不同,所以每種JDBC連線資料庫的字串書寫方法也是不一樣的。
下面給出幾種常見的JDBC與DBMS建立連線的字串書寫格式,(本博文是JTDS連線msserver ,所以是第5種)
//1. MySQL(http://www.mysql.com)mm.mysql-2.0.2-bin.jar
Connection con = null;
Class.forName( "org.gjt.mm.mysql.Driver" );// 載入驅動程式
con = DriverManager.getConnection( "jdbc:mysql://DbComputerNameOrIPAddr:3306/DatabaseName", UserName, Password );
//2. PostgreSQL(http://www.de.postgresql.org)pgjdbc2.jar
Connection con = null;
Class.forName( "org.postgresql.Driver" );// 載入驅動程式
con = DriverManager.getConnection( "jdbc:postgresql://DbComputerNameOrIPAddr/DatabaseName", UserName, Password );
//3. Oracle(http://www.oracle.com/ip/deploy/database/oracle9i/)classes12.zip
Connection con = null;
Class.forName( "oracle.jdbc.driver.OracleDriver" );// 載入驅動程式
con = DriverManager.getConnection( "jdbc:oracle:thin:@DbComputerNameOrIPAddr:1521:DatabaseName", UserName, Password );
//4. Sybase(http://jtds.sourceforge.net)jconn2.jar
Connection con = null;
Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );// 載入驅動程式
con = DriverManager.getConnection( "jdbc:sybase:Tds:DbComputerNameOrIPAddr:2638/DatabaseName", UserName, Password );
//(Default-Username/Password: "dba"/"sql")
//5. Microsoft SQLServer(http://jtds.sourceforge.net)
Connection con = null;
Class.forName( "net.sourceforge.jtds.jdbc.Driver" );// 載入驅動程式
con = DriverManager.getConnection( "jdbc:jtds:sqlserver://DbComputerNameOrIPAddr:1433/DatabaseName", UserName, Password );
//6. Microsoft SQLServer(http://www.microsoft.com)
Connection con = null;
Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );// 載入驅動程式
con = DriverManager.getConnection( "jdbc:microsoft:sqlserver://DbComputerNameOrIPAddr:1433;databaseName=master", UserName, Password );
3.3、傳送SQL語句
當成功連線資料庫之後,就可以傳送操作資料庫的語句並處理結果了。
在傳送SQL語句之前,首先要建立一個Statement物件,Statement主要工作是把 SQL 語句傳送給 DBMS 。
Statement stmt = con.createStatement();//建立Statement
然後傳送SQL語句。對於SELECT操作,使用的是Statement物件的executeQuery(sql)方法,對於一些建立table和修改table的操作,使用的是Statement物件的executeUpdate(sql)方法。
如:
String sql = "SELECT * FROM table_test";//查詢表名為“table_test”的所有內容
Statement stmt = con.createStatement();//建立Statement
ResultSet rs = stmt.executeQuery(sql);
4、簡單demo程式
由於要聯網,所以要在AndroidManifest.xml裡面加入連線網路的許可權:
<uses-permission android:name="android.permission.INTERNET" />
完整的AndroidManifest.xml如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.conowen.sqlserver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="9" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".Android_connect_sqlserverActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
連線到Microsoft SQL Server,然後後臺System.out.println輸出結果:
結果圖:
/*author:conowen
* date:2012.4.7
* Android_connect_sqlserverActivity
*/
package com.conowen.sqlserver;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import android.app.Activity;
import android.database.SQLException;
import android.os.Bundle;
public class Android_connect_sqlserverActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String UserName = "test";//使用者名稱
String Password = "test";//密碼
Connection con = null;
try { // 載入驅動程式
Class.forName("net.sourceforge.jtds.jdbc.Driver");
con = DriverManager.getConnection(
"jdbc:jtds:sqlserver://192.168.1.2:1433/testDB", UserName,
Password);
} catch (ClassNotFoundException e) {
System.out.println("載入驅動程式出錯");
} catch (SQLException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
testConnection(con);//測試資料庫連線
} catch (java.sql.SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void testConnection(Connection con) throws java.sql.SQLException {
try {
String sql = "SELECT * FROM table_test";//查詢表名為“table_test”的所有內容
Statement stmt = con.createStatement();//建立Statement
ResultSet rs = stmt.executeQuery(sql);//ResultSet類似Cursor
while (rs.next()) {//<code>ResultSet</code>最初指向第一行
System.out.println(rs.getString("test_id"));//輸出第n行,列名為“test_id”的值
System.out.println(rs.getString("test_name"));
}
rs.close();
stmt.close();
} catch (SQLException e) {
System.out.println(e.getMessage().toString());
} finally {
if (con != null)
try {
con.close();
} catch (SQLException e) {
}
}
}
}