24/05/2018, 16:43

Truy cập CSDL

CSDL cần phải cho phép được truy nhập từ xa , cho phép nhiều NSD đồng thời. NSD cần có database client . database client giao tiếp với ...

CSDL cần phải cho phép được truy nhập từ xa ,

cho phép nhiều NSD đồng thời.

NSD cần có database client. database client giao tiếp với database server để phục vụ NSD.

ODBC và JDBC Drivers

Database clients sử dụng database drivers để gửi câu lệng SQL đến database servers và nhận kết quả trả lời .

Các ứng dụng Java và applet sử dụng JDBC drivers để giao tiếp với database servers.

Microsoft's ODBC

Nhiều database servers sử dụng các giao thức chuyên biệt của nhà sản xuất = một ngôn ngữ mới, riêng.

Microsoft : thiết lập một chuẩn chung để giao tiếp databases,

Open Database Connectivity (ODBC).

Trước khi có ODBC : database clients là phụ thuộc server.

ODBC drivers trừu tượng hoá các giao thức chuyên biệt của nhiều nhà sản xuất, cung cấp các API chung nhất cho database clients.

Xây dựng database clients sử dụng ODBC API, chương trình của bạn sẽ truy nhập được nhiều database servers.

Tại sao cần JDBC.

JDBC drivers không giao tiếp trực tiếp với nhiều sản phẩm CSDL như ODBC drivers.

Các JDBC drivers đầu tiên là JDBC-ODBC bridge driver do JavaSoft và Intersolv phát triển.

JDBC là giải pháp tốt hơn cho các ứng dụng Java và applets:

  • ODBC là API viết bằng C, Nếu viết lại ODBC bằng Java sẽ cần thay đổi đáng kể các ODBC API.
  • ODBC drivers phải được cài đặt trên máy khách.

Giải pháp gọi là thuần Java (pure Java) cần cho phép JDBC tự động tải xuống và cài đặt cùng với applet. Điều này làm cho NSD applet thuận lợi hợn.

JDBC-ODBC bridge driver chỉ là quá độ, không phải là một giải pháp đẹp.

Các kiểu JDBC driver.

JavaSoft đã phân loại JDBC drivers thành 4 kiểu driver :

  • JDBC-ODBC bridge + ODBC driver

Sử dụng ODBC driver của Microsoft để giao tiếp với server CSDL.

Phải được cài đặt trước trên máy khách trước khi sử dụng.

  • Native-API partly Java driver

Đây là các drivers mà nói với servers CSDL bằng các giao thức native của servers CSDL. Ví dụ Oracle driver sẽ nói bằng SQLNet, còn DB2 driver sẽ dùng giao thức CSDL của IBM .

Phải cài đặt trước trên máy khách.

  • JDBC-Net pure Java driver.

Drivers thuần Java, sử dụng giao thức mạng chuẩn ví dụ HTTP để nói với database access server.

database access server thông dịch giao thức mạng thành giao thức của nhà sản xuất CSDL.

  • Native-protocol pure Java driver

Driver thuần Java, sử dụng giao thức của nhà sản xuất CSDL được thiết kế để giao tác với nó.

Drivers thuần Java : kiểu 3, 4

Hỗ trợ zero installation đối với applets.

Driver kiểu 4 giao tiếp với server CSDL sử dụng giao thức riêng của nhà sản xuất.

Drives kiểu 3 sử dụng database access server, truyên thông với database access server bằng một giao thức mạng chuẩn.

Một ví dụ về kiẻu 3 là IDS JDBC driver

Tìm hiểu Driver

Để sử dụng JDBC, cần có database server và database driver.

Ví dụ Microsoft Access - phổ biến.

JDBC cung cấp truy nhập CSDL độc lập với server, dùng server nào là không quan trọng

Driver CSDL là cầu nối JDBC và CSDL.

JDBC đi kèm với JDBC-ODBC bridge.

Cầu nối này cho phép truy nhập CSDL thông qua Open Database Connectivity API của Microsoft.

Lớp DriverManager

java.sql

Lớp DriverManager : để quản trị các JDBC drivers được cài đặt trong hệ thống của bạn. Bằng cách thiết lập trực tiếp hoặc nạp dùng phương thức forName(). (Chương trình DriverApp dưới đây minh hoạ cách thức nạp JDBC driver dùng forName()).

DriverManager có Hai phương thức quan trọng nhất :

getDrivers() và getConnection()

GetDrivers() liệt kê mọi JDBC drivers được cài đặt trong hệ thống.

getConnection() sẽ thiết lập một kết nối tới CSDL. 3 dạng:

getCon nection(String url )

getConnection(String url ,String userID ,String password )

getConnection(String url ,Properties arguments )

Quy định về cách viết URL để thiết lập kết nối đến CSDL là khác nhau tuỳ theo JDBC drivers

Nói chung có dạng sau:

jdbc:subprotocol:subname

Ví dụ, JDBC-ODBC bridge

jdbc:odbc:subname

IDS JDBC driver dùng giao thức dạng

jdbc:ids:subname.

Subname của một giao thức CSDL chỉ ra CSDL và các tham số khác.

Ví dụ, URL để thiết lập kết nối đến CSDL của Microsoft Access có tên là DataSetName tại máy chủ cx122974-a.cv1.sdca.home.com tại cổng 80, có dạng sau :

jdbc:ids://cx122974-a.cv1.sdca.home.com:80/ conn?dbtype=odbc&dsn=DataSetName

các phương thức khác :

  • getDriver()--cho biết driver hỗ trợ kết nối đến một URL cụ thể.
  • registerDriver()--để drivers tự đăng kí với DriverManager.
  • deregisterDriver()--để driver huỷ đăng kí.
  • getLoginTimeout()--cho biết thời gian hạn định tối đa một drivers cố thử log in vào CSDL.
  • setLoginTimeout()--thiết đặt thời gian hạn định tối đa trên.
  • getLogStream()--cho biết stream dùng để logging.
  • setLogStream()-- ấn định stream nói trên.
  • println()--Viết dữ liệu vào log stream.

Driver Interface

Xây dựng một JDBC driver là một lớp để triển khai Driver interface. Các phương thức của Driver interface:

  • connect()--thiết lập kết nối. DriverManager sẽ gọi nó để lập kết nối cho driver tương ứng.
  • acceptsURL()--Cho biết driver có thể mở một kết nối CSDL qua URL đã cho hay không.
  • getPropertyInfo()--Cho mảng DriverPropertyInfo cung cấp các thông tin về cách sử dụng driver để kết nối đến CSDL.
  • getMajorVersion()--Cho số chính của version của driver.
  • getMinorVersion()--Cho số phụ của version.
  • jdbcCompliant()--cho biết driver có hoàn toàn tương hợp JDBC-compliant hay không.

Chương trình DriverApp

Chương trình DriverApp minh hoạ cách sử dụng các lớp DriverManager và DriverPropertyInfo và Driver interface.

Chương trình DriverApp .

import java.sql.*;

import java.util.*;

class DriverApp {

public static void main(String args[]) {

try{

// Load the database drivers

Class.forName("ids.sql.IDSDriver");

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

// Obtain a list of the loaded drivers

Enumeration drivers = DriverManager.getDrivers();

System.out.println("Available drivers:");

while(drivers.hasMoreElements()){

Driver driver=(Driver)drivers.nextElement();

// Display information about each driver

System.out.println(" Driver: "+driver.getClass().getName());

System.out.println(" Major version: "+driver.getMajorVersion());

System.out.println(" Minor version: "+driver.getMinorVersion());

System.out.println(" JDBC compliant: "+driver.jdbcCompliant());

// Get driver properties

DriverPropertyInfo props[] = driver.getPropertyInfo("",null);

if(props!=null){

// Display each property and its value

System.out.println(" Properties: ");

for(int i=0;i<props.length;++i){

System.out.println(" Name: "+props[i].name);

System.out.println(" Description: "+props[i].description);

System.out.println(" Value: "+props[i].value);

if(props[i].choices!=null){

System.out.println(" Choices: ");

for(int j=0;j<props[i].choices.length;++j)

System.out.println(" "+props[i].choices[j]);

}

System.out.println(" Required: "+props[i].required);

}

}

}

}catch(Exception ex){

System.out.println(ex);

System.exit(0);

}

}

}

Khi chạy chương trình, sẽ cho kết quả dạng như sau:

Available drivers:

Driver: ids.sql.IDSDriver

Major version: 2

Minor version: 5

JDBC compliant: true

Properties:

Name: dsn

Description: Data Source Name or Database Name

Value: null

Required: true

Name: user

Description: User ID

Value: null

Required: false

Name: password

Description: Password

Value: null

Required: false

Driver: sun.jdbc.odbc.JdbcOdbcDriver

Major version: 1

Minor version: 2001

JDBC compliant: true

Thiết lập kết nối đến CSDL

Connection Interface

getConnection() : kết nối đến CSDL

trả về một đối tượng với Connection interface.

Một số phương thức quan trọng :

  • close()--đóng kết nối.
  • getMetaData()--Trả về một DatabaseMetaData interface dùng để lấy các thông tin chi tiết về cấu trúc và khả năng của CSDL.
  • createStatement()--Tạo một câu lệnh SQL.
  • prepareStatement()--Tạo một đối tượng PreparedStatement SQL, từ một SQL string. PreparedStatement là một câu lệnh SQL tiền biên dịch, thực hiện hiệu qủa hơn.
  • prepareCall()--Tạo một CallableStatement SQL từ SQL string.

Ta đã biết có 4 kiểu JDBC drivers:

  • JDBC-ODBC bridge và ODBC driver
  • Native-API partly Java driver
  • JDBC-Net pure Java driver
  • Native-protocol pure Java driver

Thiết lập ODBC Drivers để làm việc với CSDL Microsoft Access.

Các bước

Thiết đặt CSDL như một ODBC data source.

Control Panel, chạy 32-bit ODBC, chọn System DSN (Data Source Name), Add .

Gõ tên của tệp csdl ; Select để thiết đặt đường dẫn tới thư mục chứa tệp CSDL.

Nếu dùng IDS JDBC driver của IDS Software ( kiểu 3) cần đọc tài liệu hướng dẫn sử dụng.

Cần thêm đưòng dẫn vào CLASSPATH.

Chương trình AccessApp

Chương trình AccessApp

import java.awt.*;

import java.awt.event.*;

import java.sql.*;

public class AccessApp extends Frame {

TextField driver = new TextField(60);

TextField url = new TextField(60);

TextField sql = new TextField(60);

Button doIt = new Button("Do it!");

TextArea resultArea = new TextArea(10,60);

public static void main(String args[]){

AccessApp app = new AccessApp();

}

public AccessApp() {

super("AccessApp");

setup();

pack();

addWindowListener(new WindowEventHandler());

show();

}

void setup() {

setupMenuBar();

setLayout(new GridLayout(2,1));

Panel topPanel = new Panel();

topPanel.setLayout(new GridLayout(4,1));

Panel panels[]=new Panel[4];

for(int i=0;i<panels.length;++i){

panels[i]=new Panel();

panels[i].setLayout(new FlowLayout(FlowLayout.LEFT));

}

panels[0].add(new Label("Driver:"));

panels[0].add(driver);

panels[1].add(new Label("URL: "));

panels[1].add(url);

panels[2].add(new Label("SQL: "));

panels[2].add(sql);

doIt.addActionListener(new ButtonHandler());

panels[3].add(doIt);

for(int i=0;i<panels.length;++i)

topPanel.add(panels[i]);

add(topPanel);

add(resultArea);

}

void setupMenuBar() {

MenuBar menuBar = new MenuBar();

Menu fileMenu = new Menu("File");

MenuItem fileExit = new MenuItem("Exit");

fileExit.addActionListener(new MenuItemHandler());

fileMenu.add(fileExit);

menuBar.add(fileMenu);

setMenuBar(menuBar);

}

void accessDB() {

try{

// Load JDBC driver

Class.forName(driver.getText());

// Connect to database

Connection connection=DriverManager.getConnection(url.getText());

Statement statement = connection.createStatement();

// Execute SQL

boolean hasResults = statement.execute(sql.getText());

if(hasResults){

// Get results of query

ResultSet result = statement.getResultSet();

if(result!=null) displayResults(result);

}else resultArea.setText("");

// Close database connection

connection.close();

}catch(Exception ex){

resultArea.setText(ex.toString());

}

}

void displayResults(ResultSet r) throws SQLException {

ResultSetMetaData rmeta = r.getMetaData();

// Use meta data to obtain the number of columns

int numColumns=rmeta.getColumnCount();

String text="";

for(int i=1;i<=numColumns;++i) {

if(i<numColumns)

text+=rmeta.getColumnName(i)+" | ";

else

text+=rmeta.getColumnName(i);

}

text+=" ";

while(r.next()){

for(int i=1;i<=numColumns;++i) {

if(i<numColumns)

text+=r.getString(i)+" | ";

else

text+=r.getString(i).trim();

}

text+=" ";

}

resultArea.setText(text);

}

class ButtonHandler implements ActionListener {

public void actionPerformed(ActionEvent ev){

String s=ev.getActionCommand();

if(s=="Do it!") accessDB();

}

}

class MenuItemHandler implements ActionListener {

public void actionPerformed(ActionEvent ev){

String s=ev.getActionCommand();

if(s=="Exit"){

System.exit(0);

}

}

}

class WindowEventHandler extends WindowAdapter {

public void windowClosing(WindowEvent e){

System.exit(0);

}

}

}

5.3 Sử dung chương trình AccessApp.

Trước khi chạy AccessApp cần khởi động IDS Server. AccessApp sẽ hiển thị cửa sổ cho phép gõ vào các input.

Trường Driver để nhập tên của JDBC driver.

Trường URL để nhập URL của CSDL .

Trường SQL để nhập câu lệnh SQL.

Dưới đây sẽ minh hoạ từng trường hợp cụ thể.

JDBC-ODBC bridge.

Driver này kèm liền trong bộ JDK 1.2.

1. TrườngDriver : gõ vào sun.jdbc.odbc.JdbcOdbcDriver nghĩa là dùng JDBC-ODBC bridge driver.

2. Trường URL : jdbc:odbc: <tên của Data source> .

3. TrườngSQL : gõ vào ví dụ SELECT * FROM <tên bảng csdl>

4. Nhấn nútDo it! .

chương trình sẽ liêt kê tào bộ nội dung của tệp.

Tương tự đối với trường hợp dùng IDS JDBC driver.

1. TrườngDriver : gõ vào ids.sql.IDSDriver nghĩa là dùng IDS driver.

2. Trường URL : gõ vàojdbc:ids://your.host.com:port/conn?dbtype=odbc&dsn=' tên của Data source' . IDS Server dùng cổng mặc định là 12.

3. TrườngSQL : gõ vào ví dụ SELECT * FROM <tên bảng csdl>

4. Nhấn nút Do it!.

Hoạt động của AccessApp

Đối tượng của lớp ButtonHandler xử lí nhấn nút Do it! Bằng cách gọi phương thức accessDB(). accessDB() gọi forName() để nạp JDBC driver có tên trong biến driver . ItSau đó nó gọi getConnection() của lớp DriverManager để lập kết nối đến CSDL trong URL đã cho.

Phương thức createStatement() của lớp Connection sẽ tạo câu lệnh.

Phương thức execute() sẽ cho thực hiện câu lệnh SQL đã nhập vào trong biến sql.

Phương thức getResultSet() dùng để lấy kết quả.

Phương thức displayResults() hiển thị kết quả.

Phương thức close() của Connection sẽ đóng kết nối.

Dùng java.sql với Applets

Applets có thể giao tiếp với CSDL sử dụng bất kì kiểu JDBC driver nào. Tuy nhiên hiệu quả phụ thuộc vào kiểu driver đã chọn. Có 4 kiểu như ta đã biết.

Các drivers kiểu 3 và 4 hỗ trợ applets với zero installation. Vì các JDBC drivers được viết hoàn toàn bằng Java, chúng được tải xuống từ Web server cùng với applet. Để hỗ trợ zero installation, các drivers phải đặt trên Web server trong cùng thư mục với applet.

Trusted vs. Untrusted Applets

Server CSDL và access server nằm ở đâu là rất quan trọng. Untrusted applets chỉ có thể truy cập host chứa nó, nghĩa là nó chỉ có thể trao đổi với Web server mà từ đó nó được tải về. Mục đích là hạn chế applets truy cập các thông tin nhậy cảm.

Khi sử dụng JDBC drivers kiểu 1, 2, hay 4, bạn phải đặt server CSDL trong cùng host với Web server. Điều này ảnh hương đến hiệu năng làm việc nếu Web site quá bận rộn. Nếu muốn nối đến các host khác trên Internet, phải yêu cầu NSD tin cậy -trust- applets của mình. Đây là một áp đặt đối với NSD.

Với driver kiểu 3, chỉ cần đặt database access server trên cùng host với Web server. Có thể đặt server CSDL trên máy khác. Điều này tăng hiệu quả đáng kể. Một số database access servers đã tích hợp sẵn với Web server và cùng chia sẻ cổng HTTP. Thêm nữa, một database access server riêng cho phép sử dụng nhiều servers CSDL nằm trên các hosts độc lập. Tóm lại drivers kiểu 3 cho giải pháp mềm dẻo và dễ dùng hơn.

Xử lý form và thâm nhập CSDL

Ta sẽ xây dựng một applet cho hiển thị một form và cập nhật CSDL theo các thông tin mà NSD gõ vào.

Khi cho chạy applet Survey dưới đây cần sửa lại input về JDBC driver và tên của host trong phương thức updateDatabase()

void updateDatabase(){

try{

Class.forName("-----------");

String url=" ---------------";

url+=" ------------------";

Connection connection=DriverManager.getConnection(url);

import java.applet.*;

import java.awt.*;

import java.awt.event.*;

import java.sql.*;

public class Survey extends Applet {

Label blankLine = new Label(" ");

TextField email = new TextField(50);

TextField name = new TextField(50);

Checkbox home = new Checkbox("I use Java at home.");

Checkbox school = new Checkbox("I use Java at school.");

Checkbox work = new Checkbox("I use Java at work.");

Checkbox jdk12 = new Checkbox("I use the JDK 1.2 or later.");

Checkbox standalone = new Checkbox("I develop standalone Java applications.");

Checkbox applets = new Checkbox("I develop Java applets.");

Checkbox database = new Checkbox("I develop database applications using Java.");

Checkbox rmi = new Checkbox("I use remote method invocation in my applications/applets.");

Checkbox intranet = new Checkbox("I use Java-based applications for the intranet.");

Checkbox internet = new Checkbox("I develop Java-based applications for the Internet.");

Button submitButton = new Button("Submit survey data.");

public void init() {

setLayout(new GridLayout(21,1));

Panel panels[]=new Panel[21];

for(int i=0;i<panels.length;++i){

panels[i]=new Panel();

panels[i].setLayout(new FlowLayout(FlowLayout.LEFT));

}

submitButton.addActionListener(new ButtonHandler());

panels[0].add(blankLine);

panels[1].add(new Label("Please provide your e-mail address and name (optional)."));

panels[2].add(blankLine);

panels[3].add(new Label("E-mail address:"));

panels[3].add(email);

panels[4].add(new Label("Name:"));

panels[4].add(name);

panels[5].add(blankLine);

panels[6].add(new Label("Please check all that apply."));

panels[7].add(blankLine);

panels[8].add(home);

panels[9].add(school);

panels[10].add(work);

panels[11].add(jdk12);

panels[12].add(standalone);

panels[13].add(applets);

panels[14].add(database);

panels[15].add(rmi);

panels[16].add(intranet);

panels[17].add(internet);

panels[18].add(blankLine);

panels[19].add(submitButton);

panels[20].add(blankLine);

for(int i=0;i<panels.length;++i) add(panels[i]);

}

void updateDatabase(){

try{

// Load IDS driver

Class.forName("ids.sql.IDSDriver");

String url="jdbc:ids://cx122974-a.cv1.sdca.home.com:80/";

url+="conn?dbtype=odbc&dsn='Survey'";

// Connect to database

Connection connection=DriverManager.getConnection(url);

Statement statement = connection.createStatement();

String sql="INSERT INTO RawData VALUES (`"+email.getText()+"'";

sql+=",'"+name.getText()+"'";

sql+=toDigit(home);

sql+=toDigit(school);

sql+=toDigit(work);

sql+=toDigit(jdk12);

sql+=toDigit(standalone);

sql+=toDigit(applets);

sql+=toDigit(database);

sql+=toDigit(rmi);

sql+=toDigit(intranet);

sql+=toDigit(internet);

sql+=")";

// Execute SQL

statement.executeUpdate(sql);

// Close database connection

connection.close();

displayPanel("Thank you!");

}catch(Exception ex){

displayPanel(ex.toString());

}

}

String toDigit(Checkbox ch){

boolean state = ch.getState();

if(state) return ",'1'";

else return ",'0'";

}

void displayPanel(String s){

removeAll();

setLayout(new BorderLayout());

Font currentFont = getFont();

setFont(new Font(currentFont.getName(),Font.ITALIC+Font.BOLD,18));

add("Center",new Label(s,Label.CENTER));

invalidate();

doLayout();

}

class ButtonHandler implements ActionListener {

public void actionPerformed(ActionEvent e){

String s = e.getActionCommand();

if("Submit survey data.".equals(s)){

updateDatabase();

}

}

}

}

Tệp survey.htm.

<HTML>

<HEAD>

<TITLE>Java Survey</TITLE>

</HEAD>

<BODY>

<APPLET CODE="Survey.class" WIDTH=550 HEIGHT=475>

[Survey applet]

</APPLET>

</BODY>

</HTML>

Hoạt động của Survey Applet

Phần lớn câu lệnh của Survey applet là để tạo form điều tra.

Khi nhấn nút Submit đối tượng ButtonHandler sẽ gọi phương thức updateDatabase() để cập nhật các thông tin từ form.

updateDatabase() nạp JDBC driver và thiết lập kết nối đến CSDL trong URL đã cho. Nó thực hiện câu lệnh "INSERT INTO RawData VALUE (...)" với các giá trị nhận từ form.

Phương thức toDigit() chuyển đổi các giá trị input từ các ô kiểm của form thành 0/1 theo đúng dạng của Microsoft Access.

0