連接數據庫
所有與數據庫有關的對象和方法都在 java.sql 包中,因此在使用 JDBC 的程序中必須加入 "import java.sql.* "。 JDBC 要連接 ODBC 數據庫,您必須首先加載 JDBC-ODBC 橋驅動程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
該語句加載驅動程序,并創建該類的一個實例。然后,要連接一個特定的數據庫,您必須創建 Connect 類的一個實例,并使用 URL 語法連接數據庫。
String url = "jdbc:odbc:Grocery prices";
Connection con = DriverManager.getConnection(url);
請注意,您使用的數據庫名是您在 ODBC 設置面板中輸入的“數據源”名稱。
URL 語法可能因數據庫類型的不同而變化極大。
jdbc:subprotocol:subname
第一組字符代表連接協議,并且始終是 jdbc。還可能有一個子協議,在此處,子協議被指定為 odbc。它規定了一類數據庫的連通性機制。如果您要連接其它機器上的數據庫服務器,可能也要指定該機器和一個子目錄:
jdbc:bark//doggie/elliott
最后,您可能要指定用戶名和口令,作為連接字符串的一部分:
jdbc:bark//doggie/elliot;UID=GoodDog;PWD=woof
*******************************************************************************************
*******************************************************************************************
上面給出了連接數據庫的一種方法,其實還有另外一種方法,如下:
System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:Grocery prices";
Connection con=DriverManager.getConnection(url);
說明:
我們可以用System.getProperty("jdbc.drivers")對設定的System屬性值進行查詢。其實,對于System屬性,系統認可的屬性如下:
java.version Java Runtime Environment version
java.vendor Java Runtime Environment vendor
java.vendor.url Java vendor URL
java.home Java installation directory
java.vm.specification.version Java Virtual Machine specification version
java.vm.specification.vendor Java Virtual Machine specification vendor
java.vm.specification.name Java Virtual Machine specification name
java.vm.version Java Virtual Machine implementation version
java.vm.vendor Java Virtual Machine implementation vendor
java.vm.name Java Virtual Machine implementation name
java.specification.version Java Runtime Environment specification version
java.specification.vendor Java Runtime Environment specification vendor
java.specification.name Java Runtime Environment specification name
java.class.version Java class format version number
java.class.path Java class path
java.library.path List of paths to search when loading libraries
java.io.tmpdir Default temp file path
java.compiler Name of JIT compiler to use
java.ext.dirs Path of extension directory or directories
os.name Operating system name
os.arch Operating system architecture
os.version Operating system version
file.separator File separator ("/" on UNIX)
path.separator Path separator (":" on UNIX)
line.separator Line separator ("\n" on UNIX)
user.name User's account name
user.home User's home directory
user.dir User's current working directory
大家可以看到其中并沒有jdbc.drivers這一個屬性,但是System的屬性可以隨意的由我們來添加,比如我們用setProperty設定了一個名為“bacoo”的屬性,并指定該屬性值為“test”的話,那么當我們用getProperty時就可以檢索到屬性bacoo的值為test。這里之所以要加入“jdbc.drivers”這個屬性值,是因為DriverManager這個類默認的會在初始化時去System中搜索這一屬性的值,在這個屬性值中我們可以將多個需要加載的驅動用冒號“:”隔開,又由于DriverManager是一個靜態類(其實在定義一個類時,不允許用static修飾,只允許public、final、abstract三個修飾符,這里說其是靜態類指的是該類的所有方法和屬性<其實該類也沒有屬性,連構造函數都沒有>均是靜態的),因此在調用DriverManager.getConnection(url)時,DriverManager需要先初始化,就會加載驅動了。
訪問數據庫
一旦連接到數據庫,就可以請求表名以及表列的名稱和內容等信息,而且您可以運行 SQL 語句來查詢數據庫或者添加或修改其內容。可用來從數據庫中獲取信息的對象有:
DatabaseMetaData
有關整個數據庫的信息:表名、表的索引、數據庫產品的名稱和版本、數據庫支持的操作。
DatabaseMetaData dbmd;
dbmd=con.getMetaData();
下面重點介紹一下DatabaseMetaDat中的兩個重要函數getTables和getColumns:
ResultSet
getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
僅返回與目錄、模式、表名稱和(表)類型標準匹配的表描述。
catalog:要在其中查找表名的目錄名。對于 JDBC-ODBC 數據庫以及許多其他數據庫而言,可將其設置為 null。這些數據庫的目錄項實際上是它在文件系統中的絕對路徑名稱。
schemaPattern:要包括的數據庫“方案”。許多數據庫不支持方案,而對另一些數據庫而言,它代表數據庫所有者的用戶名。一般將它設置為 null。
tableNamePattern:一個掩碼,用來描述您要檢索的表的名稱。如果您希望檢索所有表名,則將其設為通配符 %。請注意,SQL 中的通配符是 % 符號,而不是一般 PC 用戶的 * 符號。
types[]:這是描述您要檢索的表的類型的 String 數組。數據庫中通常包括許多用于內部處理的表,而對作為用戶的您沒什么價值。如果它是空值,則您會得到所有這些表。如果您將其設為包含字符串“TABLES”的單元素數組,您將僅獲得對用戶有用的表格。
例子:
String [] types=new String[1];
types[0]="TABLE";
rs=dbmd.getTables(null, null, "%", types);
Java Doc中說該函數返回的表描述信息都包括以下10種信息,TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKS、TYPE_CAT、TYPE_SCHEM、TYPE_NAME、SELF_REFERENCING_COL_NAME、REF_GENERATION,但是在實際測試時,返回的結果中只有TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKS這5項。順便要說一聲的是,變量types可以取的值有:"TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM",通常只取TABLE。
*************************************************************************************************************************************************************************************************
ResultSet
getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
僅返回與目錄、模式、表和列名稱標準匹配的列描述。
通常在得到有關指定表(比如我們這里指定了表名為FoodPrice)的列的描述信息的結果集(rs)之后,我們重點關心的是COLUMN_NAME、DATA_TYPE(數據類型占用的字節數,比如整型就是4)、TYPE_NAME(INTEGER、CURRENCY之類的類型名稱),當然最關心的肯定是COLUMN_NAME了。下面把結果集中所有可以得到的信息列給出如下:
TABLE_CAT、TABLE_SCHEM、TABLE_NAME、COLUMN_NAME、DATA_TYPE、TYPE_NAME、COLUMN_SIZE、BUFFER_LENGTH、DECIMAL_DIGITS、NUM_PREC_RADIX、NULLABLE、REMARKS、COLUMN_DEF、SQL_DATA_TYPE、SQL_DATETIME_SUB、CHAR_OCTET_LENGTH、ORDINAL_POSITION、IS_NULLABLE、ORDINAL。
例子:
rs=dbmd.getColumns(null, null, "FoodPrice", null);
因此我們通常用
while(rs.next()){
System.out.print(rs.getString("COLUMN_NAME")+"\t");
}來得到該表中所有的列名稱。其實這就是一個從結果集中檢索的結果。
ResultSet
關于某個表的信息或一個查詢的結果。您必須逐行訪問數據行,但是您可以任何順序訪問列。
對于數據庫中表的描述信息的結果集可以這樣得到:rs=dbmd.getTables(null, null, "%", null);
對于某張表中的列的描述信息的結果集可以這樣得到:rs=dbmd.getColumns(null, null, "FoodPrice", null);
對于要從表中檢索具體的符合要求的結果集(而不僅僅是一些描述信息了)就必須使用如下的方法:
Statement st=con.createStatement();
String query="SELECT FoodName FROM FOOD;";//注意字符串中要包含“;”!
rs=st.executeQuery(query);
ResultSetMetaData
有關 ResultSet 中列的名稱和類型的信息。
ResultSetMetaData rsmd;
rsmd = rs.getMetaData();
numCols = rsmd.getColumnCount();
// 打印列名
for (i = 1; i <= numCols; i++)
System.out.print(rsmd.getColumnName(i) + " ");
System.out.println();
最后,給出一些零散的知識:
(1)對于數據庫的連接、訪問等等操作都需要放在try和catch塊中進行,都有可能拋出SQLException異常,使用該異常類需要import java.sql.*;
(2)前面提到的DatabaseMetaDat、ResultSet、ResultSetMetaData均是接口,而不是類,在下面的例子中,通過跟蹤調試,可以發現在程序運行過程中產生的都是基于JdbcOdbc驅動的類,即JdbcOdbcResultSet等類,把這些類(它們都實現了相應的接口)實例化后賦值給ResultSet接口,如ResultSet rs=dbmd.getColumns(null, null, "FoodPrice", null);因此,我們們不難推斷出對于其他類型的數據庫驅動,均是這樣一個原理,同時也理解了為什么Java中有許多接口,而并沒有與這些接口對應的實現了它們的類,再一次驗證了接口就是一種標準,一種規范。
給出一個完整的例子:
package com.bacoo.www;
import java.sql.*;
public class JdbcOdbcTest {
ResultSet rs;
ResultSetMetaData rsmd;
DatabaseMetaData dbmd;
Connection con;
int numCols,i;
public JdbcOdbcTest(){
System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver");
String url="jdbc:odbc:Groceries";
String query="SELECT DISTINCTROW FoodName FROM Food " +
"WHERE (FoodName like 'C%');";
try{
//Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection(url);
dbmd=con.getMetaData();
System.out.println("Connected to:"+dbmd.getURL());
System.out.println("Driver "+ dbmd.getDriverName());
String [] types=new String[1];
types[0]="TABLE";
rs=dbmd.getTables(null, null, "%", null);
dumpResults("--Tables--");
rs.close();
}catch(Exception e){
System.out.println(e);
}
System.out.println("--Column Names--");
try{
rs=dbmd.getColumns(null, null, "FoodPrice", null);
while(rs.next()){
System.out.print(rs.getString("COLUMN_NAME")+" ");
}
System.out.println();
rs.close();
}catch(Exception e){
System.out.println(e);
}
try{
Statement st=con.createStatement();
rs=st.executeQuery("SELECT FoodName FROM FOOD;");
}catch(Exception e){
System.out.println("query exception");
}
dumpResults("--contents of FoodName column--");
try{
Statement st=con.createStatement();
rs=st.executeQuery(query);
}catch(Exception e){
System.out.println("query exception");
}
dumpResults("--Results of Query--");
}
private void dumpResults(String head) {
// 這是打印列標頭和每列的內容的
// 通用方法
System.out.println(head);
try {
// 從元數據中獲取列數
rsmd = rs.getMetaData();
numCols = rsmd.getColumnCount();
// 打印列名
for (i = 1; i <= numCols; i++)
System.out.print(rsmd.getColumnName(i) + "、");
System.out.println();
// 打印列內容
while (rs.next()) {
for (i = 1; i <= numCols; i++)
System.out.print(rs.getString(i) + "\t");
System.out.println();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new JdbcOdbcTest();
System.out.println(System.getProperty("jdbc.drivers"));
}
}
運行的結果是:
Connected to:jdbc:odbc:Groceries
Driver JDBC-ODBC Bridge (odbcjt32.dll)
--Tables--
TABLE_CAT、TABLE_SCHEM、TABLE_NAME、TABLE_TYPE、REMARKS、
C:\Documents and Settings\Administrator\桌面\db1 null MSysAccessObjects SYSTEM TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null MSysAccessXML SYSTEM TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null MSysACEs SYSTEM TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null MSysObjects SYSTEM TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null MSysQueries SYSTEM TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null MSysRelationships SYSTEM TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null Food TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null FoodPrice TABLE null
C:\Documents and Settings\Administrator\桌面\db1 null Stores TABLE null
--Column Names--
FSKey StoreKey FoodKey Price
--contents of FoodName column--
FoodName、
Apples
Oranges
Hamburger
Butter
Milk
Coca Cola
Green beans
--Results of Query--
FoodName、
Coca Cola
sun.jdbc.odbc.JdbcOdbcDriver
當然使用該例子,必須要先建立一個數據源。