Chương trình ứng dụng JDBC

Một phần của tài liệu Lap Trinh huong doi tuong JAVA (Trang 127 - 149)

1. Để xử lý được dữ liệu từ một CSDL, chương trình Java phải thực hiện lần lượt theo các bước sau:

 Trước tiên là gọi hàm getConnection() để nhận được đối tượng của lớp  Connection;

 Tạo ra một đối tượng của lớp Statement;

 Chuẩn bị một đối tượng để xử lý lệnh của SQL và truy vấn vào dữ liệu theo yêu cầu; Câu lệnh SQL có thể thực hiện trực tiếp thông qua đối tượng của Statement hoặc có thể được biên dịch dịch thông qua đối tượng của PreparedStatement hay gọi một thủ tục để lưu lại thông qua CallableStatement.

 Khi hàm executeQuery() được thực hiện, thì kết quả được cho lại là đối tượng của lớp ResualtSet bao gồm các dòng dữ liệu và có thể sử dụng hàm next() để xác định các dữ liệu theo yêu cầu.

Sau đây chúng ta xét một vài chương trình tương đối đơn giản để truy vấn, cập nhật vào một CSDL.

 Trước tiên, chúng ta hãy tạo ra một CSDL theo mô hình quan hệ, trong đó, mỗi mục dữ liệu được xem như một dòng tin về đối tượng được lưu trữ. Mỗi dòng sẽ chứa một số cột, được gọi là trường dữ liệu. Đặc điểm chính của mô hình quan hệ là dữ liệu được lưu trữ phải là thuần nhất, nghĩa là số trường của tất cả dòng dữ liệu phải bằng nhau. Một số các dòng và các trường dữ liệu được tổ chức thành bảng quan hệ (bảng dữ liệu) mô tả về một thực thể hay một mối quan hệ nào đó của hệ thống ứng dụng. Nhiều bảng dữ liệu như thế sẽ tạo thành CSDL.

 Khi các CSDL quan hệ trở nên phổ biến, các chuyên gia CSDL mong muốn có một ngôn ngữ CSDL vạn năng để thao tác trên các dữ liệu và SQL chính là ngôn ngữ đáp ứng được các yêu đó. SQL có những cấu trúc lệnh để tạo lập, cập nhật, xoá bỏ các bảng, dòng hay các trường dữ liệu trong hệ thống. Ngoài ra SQL còn hỗ trợ để quản lý quyền truy nhập tới các phần tử dữ liệu, quản lý người sử dụng, hay thực hiện sao chép dữ liệu, v.v. SQL có thể sử dụng kết hợp với những ngôn ngữ lập trình như Java, C++, v.v., để xử lý dữ liệu và tương tác với các hệ QTCSDL.

 Giả sử chúng ta có một CSDL bao gồm những bảng dữ liệu về sinh viên và các môn học của sinh viên. Ví dụ: Bảng Student gồm ba trường StudentNo, FName, và LName, trong đó StudentNo là khoá.

StudentNo Fname LName

1 Nguyễn Văn A

2 Nguyễn Văn B

3 Nguyễn Văn C

Bảng B9.1 Bảng dữ liệu Student

Bảng Subject có hai trường SubjectNo và SubjectName, SubjectNo là khoá.

SubjectNo SubjectName M1 Lập trình Java M2 Cơ sở dữ liệu M3 Toán rời rạc M4 Phân tích, thiết kế hệ thống Bảng B9.2 Bảng dữ liệu Subject

 Tất nhiên các bảng dữ liệu trong một hệ CSDL phải được liên kết với nhau thông qua các khoá ngoại . Để bảng Student liên kết được với bảng Subject, chúng ta phải tạo thêm bảng mới, ví dụ: bảng Student_Subject có ba trường:

Bảng B9.3 Bảng dữ liệu Student_Subject

 Chúng ta có thể sử dụng MS Access để tạo ra các bảng trên của CSDL SVDB.  Như vậy, trước khi viết chương trình JDBC, chúng ta cần phải biết được cấu trúc

của nguồn dữ liệu. Chính hàm getConnection() sẽ cho lại tên miền của nguồn dữ liệu (DSN), ID của người sử dụng và mật khẩu (password) để truy nhập vào nguồn dữ liệu cần kết nối.

Ví dụ 9.1 Truy vấn vào CSDL.

 Trong ví dụ này chúng ta muốn liệt kê tất cả họ (FName) và tên sinh viên (LName) từ bảng Student trong CSDL StudentDB bằng lệnh SELECT của SQL.

// Một ví dụ đơn giản sử dụng JDBC để đọc dữ liệu từ CSDL: JDBCSample.java.

import java.sql.*;

public class JDBCSample{

public static void main(String[] args){ try{// Nạp Driver JdbcOdbcDriver

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); }catch (ClassNotFoundException e){

System.out.println("Khong nap duoc lop Driver"); return;

}

try{// Mọi truy nhập vào CSDL đều thực hiện trong khối try - catch

// Xác định tên của CSDL, tên người sử dụng và mật khẩu

Connection con =

DriverManager.getConnection("jdbc:odbc:StudentDB","", "");

// Thiết lập và thực hiện các lệnh của SQL Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT FName, LName FROM SINHVIEN");

// Hiển thị kết quả sau khi đã sử dụng các lệnh của SQL để truy vấn

while(rs.next()){

System.out.print(rs.getString("FName")+ “ ”); System.out.println(rs.getString("LName")); }

// Đóng lại các nguồn dữ liệu đã được mở rs.close();

stmt.close(); con.close(); }catch(SQLException se){ System.out.println("Loi o SQL: " + se.getMessage()); se.printStackTrace(System.out); } } }

 Đây là chương trình Java đơn giản sử dụng JDBC API. Chương trình này minh hoạ các bước cơ sở, cần thiết để truy nhập vào các bảng dữ liệu và liệt kê một số trường dữ liệu từ các bảng dữ liệu đó.

Lớp DriverManager

 Trước khi sử dụng một bộ điều khiển (Driver) thì nó phải được đăng ký với DriverManager. Điều này thực hiện được bằng cách sử dụng hàm forName() của lớp Class:

try{

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Class.forName(“com.oracle.jdbc.OracleDriver”); }catch (ClassNotFoundException e){

// Xử lý ngoại lệ khi không nạp được }

 Bộ điều khiển JDBC sử dụng lớp JDBC URL (Uniform Resource Locator) đểxác định và kết nối với một CSDL. Dạng tổng quát của nó là: jdbc:driver:databaseName

Lớp Connection

 Đối tượng của lớp java.sql.Connection có thể sử dụng hàm DriverManager.getConnection() để thiết lập một kết nối:

Connection con =DriverManager.getConnection("url","userName","password");  Trong đó, url là đối tượng của JDBC URL xác định tên của CSDL cần truy nhập,

userName tên của người sử dụng và mật khẩu password. Đối với những CSDL khi mở không yêu cầu khai báo tên người sử dụng và mật khẩu thì các tham biến đó có thể là rỗng.

Connection con = DriverManager.getConnection("url","","");

 Sau khi đã thiết lập được đối tượng con để kết nối, chúng ta có thể sử dụng các câu lệnh của SQL để truy vấn vào CSDL. Trong JDBC có ba lớp xử lý các câu lệnh đó. Statement Đại diện cho các lệnh của SQL. PreparedStatement Đại diện cho các lệnh được tiền xử lý của SQL nhằm tăng hiệu quả xử lý. CallableStatement Cho phép các chương trình sử dụng JDBC để truy nhập vào bên trong một CSDL.

Lớp Statement

 Trong ví dụ trên, chúng ta sử dụng đối tượng của lớp Statement để tạo ra khả năng xử lý các câu lệnh của SQL.

Statement stmt = con.createStatement();

 Sau đó có thể sử dụng câu lệnh SELECT của SQL để truy vấn và thao tác trên những dữ liệu nhận được.

Lớp ResultSet

(trường dữ liệu) có thể sử dụng hàm dạng getXXX(), trong đó XXX được thay thế tương ứng bằng tên các lớp, như getString(), getByte(), getInt(), v.v. tuỳ thuộc vào các kiểu của các trường dữ liệu. Hàm next() cho phép đọc dòng dữ liệu tiếp theo.

while(rs.next()){

System.out.println(rs.getString("TEN_SV")); }

 Lưu ý: Giá trị trả lại của hàm getXXX(args) là dữ liệu của trường có tên là

args của các dòng dữ liệu đã được chọn ra. Ngoài ra cũng cần phân biệt các kiểu của Java với các kiểu dữ liệu của SQL. Bảng B9.4 mô tả các kiểu dữ liệu tương ứng của Java, SQL và các hàm getXXX().

Kiểu của SQL Kiểu của Java getXXX()

CHAR String getString()

VARCHAR String getString()

LONGVARCHAR String getString()

NUMBERIC java.math.BigDecimal getBigDecimal()

DECIMAL java.math.BigDecimal getBigDecimal

BIT Boolean (boolean) getBoolean()

TINYINT Integer (byte) getByte()

SMALLINT Integer (short) getShort()

INTEGER Integer (int) getInt()

BIGINT Long (long) getLong()

REAL Float (float) getFloat()

FLOAT Double (double) getDouble()

DOUBLE Double (double) getDouble()

BINARY byte[] getBytes()

VARBINARY byte[] getBytes()

LONGVARBINARY byte[] getBytes()

DATE java.sql.Date getDate()

TIME java.sql.Time getTime()

TIMESTAMP java.sql.Timestamp getTimestamp()

Bảng B9.4 Các kiểu dữ liệu tương ứng của Java, SQL và các hàm getXXX()

Lớp Statement còn có hàm executeUpdate() để cập nhật dữ liệu và cho lại kết quả là số nguyên chỉ ra số dòng của CSDL đã được kết nối, hàm execute() được sử dụng để thực hiện các lệnh của SQL.

Ví dụ 9.2 Đọc, hiển thị và cập nhật dữ liệu trong CSDL: StudentDB.

import java.sql.*;

public class UpdateStudentName{ int i,NoOfColumns;

String StNo, StFName, StLName; String uid, pw;

public void ListStudent() throws SQLException { // Khởi tạo và nạp JDBC-ODBC driver. try{

}catch(ClassNotFoundException e){

System.out.println("Unable to load Driver Class"); return;

}

// Thiết lập đối tượng kết nối Connection ExlCon=

DriverManager.getConnection("jdbc:odbc:StudentDB", uid="admin", pw="sa");

// Tạo lập đối tượng của Statment

Statement ExlStmt=ExlCon.createStatement();

// Thực hiện lệnh truy vấn SQL thông qua lệnh SELECT

ResultSet Exlrs=ExlStmt.executeQuery(

"SELECT StudentNo, FName, LName FROM Student");// Thực hiện đọc từng dòng từ kết quả truy vấn và hiển thị lên màn hình

System.out.println("Student Number First Name LastName"); while (Exlrs.next()){

// Đọc từng trường dữ liệu và gán cho các biến của Java StNo= Exlrs.getString(1); // Lấy kết quả của trường số 1 StFName=Exlrs.getString(2); // Lấy kết quả của trường số 2 StLName=Exlrs.getString(3); // Lấy kết quả của trường số 3 System.out.println(StNo + " " + StFName + " " + StLName); }

}

// Thay họ (StFName) và tên (StLName) sinh viên có số hiệu là

STNo: cập nhật lại

public void UpdateName (String StFName,

String StLName,String StNo) throws SQLException {

int RetValue;

// Khởi tạo và nạp JDBC-ODBC driver. try{

Class.forName("jdbc.odbc.JdbcOdbcDriver"); }catch(ClassNotFoundException e){

System.out.println("Unable to load Driver Class"); return;

}

// Thiết lập đối tượng kết nối Connection ExlCon=

DriverManager.getConnection("jdbc:odbc:StudentDB", uid="admin",pw="sa");

// Tạo lập đối tượng của Statment

Statement ExlStmt=ExlCon.createStatement();

// Tạo ra một xâu gồm các tham số cho lệnh executeUpdate() String SQLBuffer = "UPDATE Studends SET FirstName = " + StFName +

",LastName = " + StLName + " WHERE StudentsNo = "+StNo; // Thực hiện cập nhật dữ liệu trong SQL thông qua

System.out.println("Updated " +RetValue+ "rows in the Database.");

}

public static void main(String[] args){

UpdateStudentName sv = new UpdateStudentName(); try{

// Liệt kê tất cả họ, tên sinh viên ở bảng Student như đã được xây dựng

ở trên

sv.ListStudent();

// Cập nhật: Thay sinh viên có mã số 2 có họ Vu Thuy và tên là Lan

sv.UpdateName ("Vu Thuy ","Lan","2"); }catch(SQLException se){

System.out.println("SQL Error" + se); return;

} } }

Lớp DatabaseMetaData

Muốn xử lý tốt các dữ liệu của một CSDL thì chúng ta phải biết được những thông tin chung về cấu trúc của CSDL đó như: hệ QTCSDL, tên của các bảng dữ liệu, tên gọi của các trường dữ liệu, v.v .

Để biết được những thông tin chung về cấu trúc của một hệ CSDL, chúng ta có thể sử dụng giao diện java.sql.DatabaseMetaData thông qua hàm getMetaData().

DatabaseMetaData dbmeta = con.getMetaData();

trong đó, con là đối tượng kết nối đã được tạo ra bởi lớp Connection.

Lớp DatabaseMetaData cung cấp một số hàm được nạp chồng để xác định được những thông tin về cấu hình của một CSDL. Một số hàm cho

lại đối tượng của String (getURL()), một số trả lại giá trị logic (nullsAreSortedHigh()) hay trả lại giá trị nguyên như hàm getMaxConnection()). Những hàm khác cho lại kết quả là các đối tượng của ResultSet như: getColumns(), getTableType(), getPrivileges(), v.v. Ví dụ 9.3 Chương trình xác định những thông tin chung về cấu trúc của CSDL.

import java.sql.*;

import java.util.StringTokenizer; public class DBViewer {

final static String jdbcURL = "jdbc:odbc:StudentDB";

final static String jdbcDriver =

"sun.jdbc:odbc:JdbcOdbcDriver";

public static void main(String[] args) {

System.out.println("---Database Viewer ---"); try {

// Đăng ký bộ điều khiển JdbcOdbcDriver Class.forName(jdbcDriver);

// Kết nối với CSDL StudentDB Connection con =

DriverManager.getConnection(jdbcURL, "", "");

// Tạo ra dbmd để nhận các thông tin về cấu trúc của CSDL đã kết nối

DatabaseMetaData dbmd = con.getMetaData();

// In ra những thông tin về cấu trúc của CSDL đã kết nối

System.out.println("Drive Name: " + dbmd.getDriverName()); System.out.println("Database Product: " +

dbmd.getDatabaseProductName());

System.out.println("SQL Keywords Supported:" ); // Tạo ra đối tượng st để nhận các từ khoá của SQL StringTokenizer st =

new StringTokenizer(dbmd.getSQLKeywords(),","); while(st.hasMoreTokens())

// Hiển thị các từ khoá của SQL

System.out.println(""+st.nextToken());

// Đối tượng allTables chứa tất cả các bảng trong CSDL String[]tableTypes = {"TABLE"};

ResultSet allTables =

dbmd.getTables(null,null,null,tableTypes); while (allTables.next()) {

// Đọc và in ra tên, kiểu của từng bảng String table_name =

allTables.getString("TABLE_NAME");

System.out.println("Table Name:" + table_name); System.out.println("Table Type:" +

allTables.getString("TABLE_TYPE")); System.out.println("Indexs: ");

// Xác định tên của chỉ số (Index) và tên các trường dữ liệu ResultSet indexList = dbmd.getIndexInfo(null,null,

table_name,false,false); while (indexList.next()) {

// In ra tên của chỉ số (Index) và ten các trường dữ liệu System.out.println("Index Name:" + indexList.getString("INDEX_NAME")); System.out.println("Column Name:" + indexList.getString("COLUMN_NAME")); } indexList.close(); } allTables.close(); con.close();

}catch (ClassNotFoundException ce) {

System.out.println("Unable to load database driver class"); }catch (SQLException se) {

System.out.println("SQL Exception: " + se.getMessage()); }

--- Dabase Viewer ---

Driver Name: JDBC-ODBC Bridge Database Product: Access

SQL Keywords Supported: ALPHANUMERIC

BYTE . . .

Table Name: Student Table Type: TABLE Indexs:

Index Name: PrimaryKey Column Name: StudentNo . . .

Lớp ResultSetMetaData

 Giao diện ResultSetMetaData cung cấp các thông tin về cấu trúc cụ thể của

ResultSet, bao gồm cả số cột, tên và giá trị của chúng. Ví dụ sau là một chương trình hiển thị các kiểu và giá trị của từng trường của một bảng dữ liệu.

Ví dụ 9.3 Chương trình hiển thị một bảng dữ liệu.

import java.sql.*;

import java.util.StringTokenizer; public class TableViewer {

final static String jdbcURL = "jdbc:odbc:StudentDB"; final static String jdbcDriver =

"sun.jdbc:odbc:JdbcOdbcDriver"; final static String table = "STUDENT"; public static void main(java.lang.String[]args) {

System.out.println("---Table Viewer ---"); try { Class.forName(jdbcDriver); Connection con = DriverManager.getConnection(jdbcURL, "", ""); Statement stmt = con.createStatement();

// Đọc ra cả bảng Student và đưa vào đối tượng rs

ResultSet rs = stmt.executeQuery("SELECT * FROM " + table); // Đọc ra các thông tin về rs

ResultSetMetaData rsmd = rs.getMetaData(); // Xác định số cột của rsmd

int colCount = rsmd.getColumnCount(); for(int col = 1; col <= colCount; col++) {

// In ra tên và kiểu của từng trường dữ liệu trong rsmd System.out.print(rsmd.getColumnLabel(col)); System.out.print(" (" + rsmd.getColumnTypeName(col) + ")"); if(col < colCount) System.out.print(", "); } System.out.println(); while(rs.next()){

// In ra dòng dữ liệu trong rsmd

for(int col = 1; col <= colCount; col++) { System.out.print(rs.getString(col)); if(col < colCount) System.out.print(" "); } System.out.println(); } rs.close(); stmt.close(); con.close(); } catch (ClassNotFoundException e) {

System.out.println("Unable to load database driver class"); }

catch (SQLException se) {

System.out.println("SQL Exception: " + se.getMessage()); }

} }

Dịch và thực hiện chương trình trên chúng ta có được kết quả dạng: - - Table Viewer - - -

StudentNo (SHORT), FName (VARCHAR), LName (VARCHAR) 1 Vũ Văn An

2 Trần Anh Tuấn, . . .

Những vấn đề sâu hơn về kết nối CSDL và ứng dụng, bạn có thể tham khảo ở tài liệu số [4].

9.3 Lập trình trên mạng

 Để trao đổi được giữa các ứng dụng với nhau trên mạng, Java sử dụng TCP/IP để kết nối mạng thông qua kết nối các socket (hốc) để gửi và nhận các thông điệp (message). Đó chính là sự trao đổi điểm với điểm (point - to - point), trong đó một điểm cuối là ứng dụng của bạn.

 Một socket đóng vai trò như là một đầu cuối của quá trình trao đổi trong một hệ thống hay giữa các hệ thống với nhau. Java cung cấp nhiều lớp để thực hiện các nhiệm vụ của socket phục vụ và socket khách hàng.

Tên lớp / giao diện Mô tả các chức năng InetAddress Biểu diễn địa chỉ của Internet ServerSocket Biểu diễn cho Server Socket

Socket Biểu diễn cho Client Socket

DatagramSocket Biểu diễn cho Datagram Socket, một dạng cài đặt của giao lễ kết nối DatagramPacket Biểu diễn cho Datagram Packet, mô

Bảng B9.5 Các lớp xử lý socket trên mạng Socket của Java

 Trong Java có lớp Socket ở gói java.net để thực hiện các kết nối theo TCP/IP. Ví dụ, để kết nối một socket với Web Server thực hiện qua cổng mặc định (port 80) ở địa chỉ: http://www.javasoft.com thì cần phải tạo ra một đối tượng của Socket như sau:

Socket soc = new Socket(“www.javasoft.com”,80);

Khi đó có thể xảy ra hai ngoại lệ:

1. Gặp ngoại lệ UnknownHostException: không xác định được máy chủ hay máy chủ khai báo không hợp lệ;

2. Gặp ngoại lệ IOException: nếu kết nối socket với máy chủ hợp lệ nhưng không thực hiện được.

Khi kết nối thành công thì việc tiếp theo là thực hiện trao đổi các thông điệp thông qua InputStream và OutputStream.

InputStream instream = soc.getInputStream(); OutputStream instream = soc.getOutputStream();

Ví dụ 9.4 Sử dụng lớp Socket để tìm thông tin (đọc các tệp html ) từ Web Server. Giả sử chúng ta muốn truy nhập thông tin ở địa chỉ:

http://www.nus.edu.sg:80/NUSinfo/UG/ug.html

Lưu ý: Cú pháp của HTTP URL có dạng chính: http://hostName[:portNumber]/directory/fileName

// WebRetriever.java import java.io.*; import java.net.*; class WebRetriever {

Socket soc; // Đối tượng để thực hiện kết nối socket

OutputStream os; // Đối tượng để gửi thông điệp InputStream is; // Đối tượng để nhận thông điệp

WebRetriever(String server, int port) throws IOException, UnknownHostException{

soc = new Socket(server, port); os = soc.getOutputStream(); is = soc.getInputStream(); }

void request(String path){// Gửi đi một thông điệp (yêu cầu) try{

String msg = "GET " + path + "\n\n"; os.write(msg.getBytes());

}catch(IOException e){

System.err.println("Error in HTTP request!"); }

}

void getResponse(){ // Nhận một thông điệp (để trả lời) int c;

try{

while((c = is.read()) != -1) // Đọc từng ký tự System.out.print((char)c); // In ra từng ký tự }catch(IOException e){

System.err.println("Error in reading from Web Server!"); }

}

public void finalize(){ // Dọn dẹp (giải phóng các đối tượng) try{

is.close();os.close();soc.close(); }catch(IOException e){

System.err.println("Error in closing connection!"); }

}

public static void main(String args[]){ try{

WebRetriever w = new WebRetriever("www.nus.edu.sg",80); w.request("/NUSinfo/UG/ug.html");

w.getResponse();

}catch(UnknownHostException h){

System.err.println("Hostname Unknown!"); }catch(IOException e){

System.err.println("Error in connecting to Host!");

Một phần của tài liệu Lap Trinh huong doi tuong JAVA (Trang 127 - 149)

Tải bản đầy đủ (DOC)

(149 trang)
w