60
CD1-CNPM - JAVA HIENLTH Chủ đề 4: JDBC (JAVA DATABASE CONNECTIVITY)

Chủ đề 4: JDBC - hienlth.info · CD1-CNPM - JAVA HIENLTH Nội dung •Các trình điềukhiểnJDBC •Nạptrình điềukhiểnvà kếtnốiCSDL •Câu lệnhStatement

  • Upload
    dokiet

  • View
    212

  • Download
    0

Embed Size (px)

Citation preview

CD1-CNPM - JAVA HIENLTH

Chủ đề 4: JDBC (JAVA DATABASE CONNECTIVITY)

CD1-CNPM - JAVA HIENLTH

Nội dung

• Các trình điều khiển JDBC

• Nạp trình điều khiển và kết nối CSDL

• Câu lệnh Statement

• Thực thi Statement

• ResultSet

• Các interface: DatabaseMetadata, ResultsetMetadata

• Transaction

2

CD1-CNPM - JAVA HIENLTH

Khái niệm JDBC

•Là một bộ API cung cấp cho java developer

khả năng kết nối tới CSDL.

•API này ở cấp độ SQL, có nghĩa là JDBC phải

cho phép người lập trình tạo dựng các câu lệnh

SQL và nhúng nó vào bên trong các lời gọi API

CD1-CNPM - JAVA HIENLTH

Kiến trúc JDBC

Java Application

JDBC Driver Manager

JDBC Drivers

Database

JDBC API

JDBC Driver API

CD1-CNPM - JAVA HIENLTH

Kiến trúc JDBC

•Một trong những mục tiêu khi thiết kế JDBC là phải cung cấp cho developer cách thức làm việc như nhau khi làm việc với các hệ quản trị cơ sở dữ liệu khác nhau.

• JDBC cung cấp một tập hợp các interface

• Java developer không cần phải quan tâm đến sự khác nhau khi giao tiếp với các HQTCSDL khác nhau.

CD1-CNPM - JAVA HIENLTH

Kiến trúc JDBC Java Application

JDBC Driver Manager

SQLServer

Driver

MySQL

Driver

Oracle

DriverODBC Bridge

Driver

DB2

Driver

ODBC Bridge

Manager

Access

DriverdBase

Driver

Access dBase SQL Server MySQL Oracle DB2

CD1-CNPM - JAVA HIENLTH

JDBC - Cơ chế hoạt động

CD1-CNPM - JAVA HIENLTH

JDBC

Java Application

1. Mở kết nối

2. Gửi SQL

3. Rút trích dữ liệu

4. Đóng kết nối

DBMS

1. Tạo phiên kết nối

2. Thực thi SQL

3. Trả kết quả

4. Đóng phiên kết nối

8

CD1-CNPM - JAVA HIENLTH

JDBC API

• JDBC API (Java Database Connectivity

Aplication Programming Interface): cung

cấp các lớp và interface hỗ trợ các ứng

dụng java tương tác với các hệ quản trị

CSDL.

• Chủ yếu nằm trong gói java.sql. Một vài

lớp và interface có các chức năng nâng

cao nằm trong gói javax.sql

CD1-CNPM - JAVA HIENLTH

Các trình điều khiển JDBC (JDBC Drivers)

• Hiện nay có rất nhiều Hệ quản trị CSDL

(DBMS) khác nhau như SQL Sever,

MySQL, Oracle, MS Access, FoxPro,…

• Để truy cập các DBMS khác nhau từ

chương trình viết bằng Java thì ta cần có

các JDBC driver tương ứng.

• Đảm bảo ứng dụng tương tác với DBMS

theo một cách thức chuẩn thống nhất.

CD1-CNPM - JAVA HIENLTH

Các trình điều khiển JDBC (JDBC Drivers)

• Hãng Sun đã đưa ra 4 loại JDBC driver.

• JDBC-ODBC Bridge.

• Native-API Driver.

• JDBC-Net Driver, Pure Java.

• Native-Protocol Driver, Pure Java.

• Tham khảo thêm tại:

http://industry.java.sun.com/products/jdbc/drivers

CD1-CNPM - JAVA HIENLTH

Cầu nối JDBC - ODBC

• Được cung cấp bởi Sun – jdk

• Có thể truy xuất bất kỳ DBMS nào được hỗ trợ bởi

ODBC Driver.

• Tính khả chuyển cao nhưng kém hiệu quả.

CD1-CNPM - JAVA HIENLTH

Database

Network Interface

Server

Aplication

JDBC Driver

Native Database Library

Network Interface

Disk

Client

CD1-CNPM - JAVA HIENLTH

Native-API

•Tương tác trực tiếp với database API

•Gồm 1 phần mã Java, một phần mã của

DBMS.

CD1-CNPM - JAVA HIENLTH

JDBC - Net

• Tương tác với nhiều database theo phương thức mở

• 100% java code

• Cài đặt driver cả 2 phía client và server

Database

Network Interface

Server

Aplication

JDBC Driver Client

Network Interface

Disk

Client

JDBC Driver Server

Native Database Library

CD1-CNPM - JAVA HIENLTH

Native Protocol

• 100% java code

• Truy xuất trực tiếp DBMS theo giao thức độc quyền

• Hiệu quả nhất.

Database

Network Interface

Server

Aplication

JDBC Driver

Network Interface

Disk

Client

CD1-CNPM - JAVA HIENLTH

Các bước truy xuất CSDL

import java.sql

1. Tạo kết nối đến DBMS.

2. Tạo câu lệnh SQL nhằm thực hiện tác vụ mong muốn

3. Thi hành câu lệnh SQL

4. Xử lý kết quả trả về

5. Đóng kết nối.

CD1-CNPM - JAVA HIENLTH

Tạo kết nối

• Có 2 cách để tạo kết nối đến Datasource (DBMS, a legacy file

system,…):

• DriverManager

• DataSource

• Kết nối connection tiêu tốn tài nguyên của máy chủ DBMS

• Mở connection khi cần.

• Đóng connection khi kết thúc tác vụ.

• Connection Pool là giải pháp đa người dùng cho các ứng dụng

CSDL với số lượng người dùng lớn.

CD1-CNPM - JAVA HIENLTH

Nạp trình điều khiển JDBC (JDBC version < 4.0)

• Sử dụng phương thức tĩnh forName() của lớp Class

Class.forName (String dbDriver_Name);

• Trình điều khiển của MySQL:

dbDriver_Name = “com.mysql.jdbc.Driver”

• Trình điều khiển của Oracle:

dbDriver_Name = “oracle.jdbc.driver.OracleDriver”

• Trình điều khiển của Sybase:

dbDriver_Name = "com.sybase.jdbc.SybDriver"

• Trình điều khiển qua cầu nối ODBC (MS SQL, Access):

dbDriver_Name = “sun.jdbc.odbc.JdbcOdbcDriver”

CD1-CNPM - JAVA HIENLTH

Tạo kết nối dùng DriverManager

• Tùy theo DBMS việc kết nối có thể yêu cầu định danh

người dùng.

• DriverManager.getConnection(dbURL, user, passwd)

• DriverManager.getConnection(dbURL)

CD1-CNPM - JAVA HIENLTH

Database Connection URLs

• Là chuỗi biểu diễn địa chỉ DBMS quy định bởi JDBC driver

• Cú pháp

jdbc:<subprotocol name>: other_stuff

• subprotocol name: quy định bởi driver ghi trong tài liệu sử dụng

của driver (VD: với JDBC-ODBC driver là “odbc”)

• Other_stuff: phụ thuộc driver (VD: đối với JDBC-ODBC là Data

Source Name khai báo trong Datasource ODBC của windows)

• VD (kết nối đến MS Access)

Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”)

Connection con = DriverManager.getConnection(“jdbc: odbc:ATM”);

CD1-CNPM - JAVA HIENLTH

MySQL Connector/J Database URL

• jdbc:mysql://[host][,failoverhost...] [:port]/[database]

[?propertyName1][=propertyValue1]

[&propertyName2][=propertyValue2]...

• host:port : hostname/IP and port của database server (default: 127.0.0.1:3306)

• database: Tên của database đang muốn kết nối.

• failover is the name of a standby database (MySQL Connector/J supports failover).

• propertyName=propertyValue represents an optional, ampersand-separated list of properties. These attributes enable you to instruct MySQL Connector/J to perform various tasks.

Download gói msql-connector-java-5.1.22-bin (http://www.mysql.com/products/connector/)

CD1-CNPM - JAVA HIENLTH

JDBC URL for SQL Server

jdbc:sqlserver://[serverName[\instanceName][:portNumber]][;prop

erty=value[;property=value]]

• serverName: host name or IP address of the machine on which

SQL server is running

• instanceName: name of the instance to connect to on serverName.

The default instance is used if this parameter is not specified.

• portNumber: port number of SQL server, default is 1433. If this

parameter is missing, the default port is used

• property=value: specify one or more additional connection

properties. To see the properties specific to SQL server,

visit Setting the Connection Properties.

Download Microsoft JDBC Driver 4.0 for SQL Server which supports

(http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=11774)

CD1-CNPM - JAVA HIENLTH

JDBC URL for SQL Server -Example

• Connect to default instance of SQL server running on the same machine

as the JDBC client, using Windows authentication:

jdbc:sqlserver://localhost;integratedSecurity=true;

• Connect to an instance named sqlexpress on the host dbServer, using

SQL Server authentication:

jdbc:sqlserver://dbHost\sqlexpress;user=sa;password=secret

• Connect to a named database QLHocSinh on localhost using Windows

authentication:

jdbc:sqlserver://localhost:1433;databaseName=QLHocSinh;integratedSecurity=true;

CD1-CNPM - JAVA HIENLTH

Câu lệnh Statement

• Có 3 loại Statement:

• Statement: thi hành câu lệnh tùy ý tại thời điểm chạy

• PreparedStatement: câu lệnh SQL được biên dịch trước

• CallableStatement: gọi thủ tục trên DBMS

• Sử dụng kết nối connection để tạo câu lệnh

• Statement s = con.createStatement();

• PreparedStatement ps = con.prepareStatement(String);

• CallableStatement cs = con.prepareCon(String);

• Câu lệnh Statement có thể được sử dụng nhiều lần cho

những tác vụ khác nhau, những câu lệnh SQL không

liên quan nhau.

CD1-CNPM - JAVA HIENLTH

PreparedStatements

• Câu lệnh được biên dịch trước → tăng hiệu quả thực thi.

• Cho phép thay đổi tham số mỗi lần thi hành câu lệnh SQL.

Dùng dấu chấm hỏi “?” để giữ chỗ cho mỗi tham số.

• Trước khi thi hành câu lệnh SQL, giá trị cho mỗi tham số sẽ

được đưa vào bởi hàm set<Type>() thích hợp.

• Sau khi thiết lập giá trị tham số, chúng được giữ nguyên cho

đến khi thiết lập giá trị mới hoặc gọi phương thức

clearParameter() để xóa giá trị các tham số.

CD1-CNPM - JAVA HIENLTH

PreparedStatements - VD

Connection conn = getConnection();

PreparedStatement pstmt = conn.prepareStatement(“UPDATE HocSinh

SET TenHS = ? , DiemTB = ? WHERE MaHS = ?”);

pstmt.setString(1, “Lê Tèo”);

pstmt.setDouble(2, 8.9);

pstmt.setString(3, “HS001”);

pstmt.executeUpdate();

CD1-CNPM - JAVA HIENLTH

PreparedStatements - VD

Connection conn = getConnection();

String sql = “SELECT * FROM HocSinh WHERE DiemTB > ?”;

PreparedStatement pstmt = conn.prepareStatement(sql,

ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

pstmt.setDouble(1, 9);

ResultSet rs = pstmt.executeQuery();

CD1-CNPM - JAVA HIENLTH

CallableStatement

• CallableStatement cung cấp câu lệnh gọi thi hành các thủ tục đã

cài đặt sẵn trên DBMSs.

• Cú pháp:

• {call procedure_name}

• {call procedure_name [(arg1, arg2, …)]}

• {? = call procedure_name [(arg1, arg2, …)]}

• Dấu ? thay chỗ cho các đối số

• Các đối số có thể là input (IN parameters), output (OUT

parameters) hoặc cả 2 (INOUT parameters).

CD1-CNPM - JAVA HIENLTH

CallableStatement

• CallableStatement cstmt = con.prepareCall(“{call Proc(?,?)}”);

• Truyền đối số IN bằng hàm set<Type>() kế thừa từ PreparedStatement

• Đăng ký đối số OUT trước khi thi hành thủ tục

cstmt.registerOutParameter(1, Types.VARCHAR);

• Đối số INOUT

stmt1.setString(1,”00000”);

stmt1.registerOutParameter(1, Types.VARCHAR);

• Sử dùng hàm get<Type>() để nhận giá trị trả về của stored Procedure hoặc của đối số OUT.

• Các store procedure không phù hợp trong môi trường phân tán phức hợp vì nó gắn chặt với 1 DBMS cụ thể.

CD1-CNPM - JAVA HIENLTH

CallableStatements - VD

//…

try{

Connection conn = getConnection();

String proc = “CREATE PROCEDURE LayDiemCaoNhat as SELECT max(DiemTB) FROM HocSinh”;

Statement s = conn.createStatement();

s.execute(proc);

CallableStatement pstmt = conn.prepareCall(“{call LayDiemCaoNhat}”);

ResultSet rs = pstmt.executeQuery();

rs.next();

int x = rs.getDouble(1);

System.out.println(x);

//…

}catch(SQLException e){ System.out.println(e); }

//.

CD1-CNPM - JAVA HIENLTH

Thực thi Statement

• Có 3 cách thi hành Statement:

• executeQuery(select)

• executeUpdate(insert, update, delete)

• execute()

• ExecuteQuery()

• Dùng để thi hành các câu lệnh truy vấn

Select… from… where

• Trả về kết quả truy vấn qua đối tượng ResultSet

• VD: ResultSet rs = s.executeQuery(“Select * from HocSinh”);

CD1-CNPM - JAVA HIENLTH

Thực thi Statement

• executeUpdate()• Dùng cho câu lệnh cập nhật dữ liệu• Trả về số bản ghi chịu ảnh hưởng bởi câu lệnh Update,

Insert, hay Delete.• Trả về 0 khi:

• Không có bản ghi nào bị ảnh hưởng

• Hoặc thực thi câu lệnh DDL định nghĩa dữ liệu

• execute()• Khi không biết rõ câu lệnh là truy vấn hay cập nhật.• Dùng cho các trường hợp thực thi SQL động.• Trả về true nếu câu lệnh là truy vấn

• Gọi getResultSet() để nhận kết quả truy vấn.

• Gọi getUpdateCount() để biết số bản ghi đã cập nhật.

CD1-CNPM - JAVA HIENLTH

ResultSet Types

• ResultSet cho phép truy xuất đến dữ liệu trả về từ kết quả truy vấn

database

• Có 3 loại ResultSet

• TYPE_FORWARD_ONLY (default): chỉ có thể di chuyển con trỏ

theo 1 chiều tiến.

• TYPE_SCROLL_INSENSITIVE: có thể di chuyển con trỏ theo

cả 2 chiều hoặc đến vị trí bất kỳ.

• TYPE_SCROLL_SENSITIVE: có thể di chuyển con trỏ theo cả

2 chiều hoặc đến vị trí bất kỳ và có cập nhật thay đổi.

CD1-CNPM - JAVA HIENLTH

ResultSet Concurrency

• CONCUR_READ_ONLY (default): The ResultSet object

cannot be updated using the ResultSet interface.

• CONCUR_UPDATABLE: The ResultSet object can be

updated using the ResultSet interface.

• Not all JDBC drivers and databases support concurrency.

The

method DatabaseMetaData.supportsResultSetConcurrency

returns true if the specified concurrency level is supported by

the driver and false otherwise.

CD1-CNPM - JAVA HIENLTH

Cursor Holdability

• The following ResultSet constants may be supplied to the Connection methods createStatement, prepareStatement, and prepareCall:

• HOLD_CURSORS_OVER_COMMIT: ResultSet cursors are not closed; they are holdable: they are held open when the method commit is called. Holdable cursors might be ideal if your application uses mostly read-only ResultSet objects.

• CLOSE_CURSORS_AT_COMMIT: ResultSet objects (cursors) are closed when the commit method is called. Closing cursors when this method is called can result in better performance for some applications.

• The default cursor holdability varies depending on your DBMS.

CD1-CNPM - JAVA HIENLTH

ResultSet

• Loại của ResultSet phụ thuộc vào tham số truyền vào hàm

createStatement().

• VD:

Statement stmt = conn.createStatement(

ResultSet.TYPE_SCROLL_SENSITIVE,

ResultSet.CONCUR_UPDATABLE);

• Có thể sử dụng cấu trúc lặp sau để duyệt một ResultSet

while(rs.next())

{

//examine a row from the results

}

CD1-CNPM - JAVA HIENLTH

ResultSet Cursors – Một số phương thứcđiều hướng

• next(): di chuyển con trỏ đến dòng kế, trả về true nếu còn dòng kế tiếp, false nếu đến cuối ResultSet.

• previous(): di chuyển con trỏ đến dòng trước.

• first(): di chuyển con trỏ đến dòng đầu tiên.

• last(): di chuyển con trỏ đến dòng cuối cùng.

• beforeFirst(): di chuyển con trỏ đến trước dòng đầu tiên.

• afterLast(): di chuyển con trỏ đến sau dòng cuối cùng.

• relative (int rows): di chuyển con trỏ tương đối với vị trí hiện tại của nó với số dòng là rows.

• absolute(int row): di chuyển con trỏ đến dòng thứ row.

• getRow(): trả về dòng hiện tại con trỏ đang đứng

• isFirst(), isLast(), isBeforeFirst(), isAfterLast(): các hàm kiểm tra.

CD1-CNPM - JAVA HIENLTH

ResultSet – Retrieving Column Values from Rows

• Lấy ra dữ liệu tại 1 cộtcủa bản ghi (dòng)

• returnTypeget<Type>(intcolumnIndex);

• returnTypeget<Type>(String columnLabel);

returnType có thể là int, double, String, Date,… Tương ứng <Type> sẽlà Int, Double, String, Date,…

CD1-CNPM - JAVA HIENLTH

ResultSet – Update rows

• Cập nhật 1 bản ghi

• Update<Type> (int

columnIndex, String x);

• Update<Type>(String

columnLabel, String x);

• updateRow(): phải gọi

hàm này để cập nhật

database

CD1-CNPM - JAVA HIENLTH

ResultSet – Insert rows

• Thêm 1 bản ghi

• moveToInsertRow();

• Update<Type> (int

columnIndex, String x);

• insertRow();

CD1-CNPM - JAVA HIENLTH

DatabaseMetadata Interface

• DatabaseMetadata là các lớp cung cấp thông tin về bản thân CSDL.

• getDatabaseProductName();• getDatabaseProductVersion();• getTableTypes();• getTables();• getTablePrivileges();

• DatabaseMetadata cũng cung cấp thông tin về JDBC Drivers

• GetDrivername();• GetDriverVersion();• GetDriverMajorVersion();• GetDriverMinorVersion();

CD1-CNPM - JAVA HIENLTH

DatabaseMetadata Interface

• DatabaseMetadata còn cung cấp thông tin về Stored

Procedures

• String getStoreProcedureTerm();

• boolean supportsStoredProcedures();

• ResultSet getProcedures();

• ResultSet getProcedureColumns();

CD1-CNPM - JAVA HIENLTH

ResultSetMetadata Interface

• ResultSetMetadata là lớp cung cấp thông tin về bản thân

ResultSet.

• getColumnCount();

• getColumnName(int column);

• getColumnType();

• VD:

ResultSet rs = stmt.executeQuery(SQLString);

ResultSetMetadata rsmd = rs.getMetaData();

int numberOfColumns = rsmd.getColumnCount();

CD1-CNPM - JAVA HIENLTH

Bài tập

•Cho cơ sở dữ liệu HocSinh

CD1-CNPM - JAVA HIENLTH

Bài tập (tt)

•Yêu cầu: Viết chương trình cho phép thực hiện

các thao tác sau:

• Xem danh sách các học sinh.

• Tìm kiếm học sinh (theo mọi tiêu chí)

• Xem thông tin chi tiết một học sinh (có kèm hình

ảnh)

• Thêm/Cập nhật thông tin một học sinh

•Nộp tính điểm cộng

CD1-CNPM - JAVA HIENLTH

Transaction (Giao dịch)

• Theo mặc định, JDBC thực thi trọn vẹn các câu lệnh SQL, tức dữ

liệu sẽ được cập nhật ngay vào CSDL, gọi là autocommit.

• Một số ứng dụng mang đặc điểm transaction, tức trong 1 số

trường hợp ta muốn dữ liệu chỉ được cập nhật vào CSDL sau khi

một số câu lệnh SQL được thực hiện. Một nhóm câu lệnh như thế

gọi là 1 giao dịch.

• VD

• Đối với trang ứng dụng bán hàng qua mạng, để CSDL được thống nhất, ta chỉ muốn lưu các dữ liệu liên quan tới 1 đơn đặt hàng cùng 1 lúc.

• Đối với giao dịch chuyển tiền thông qua ATM.

CD1-CNPM - JAVA HIENLTH

Transaction - Cài đặt

Trước hết, cần tắt chế độ Autocommit. Lớp connection cung cấp

hàm setAutoCommit() để bật tắt chế độ autocommit.

con.setAutocommit(false);

• Thực hiện các câu lệnh trong một giao dịch

• Thực hiện lưu xuống CSDL.

con.commit();

• Nếu không cần dùng ở chế độ giao dịch nữa, ta nên trả lại chế độ

Autocommit

con.setAutocommit(true);

CD1-CNPM - JAVA HIENLTH

Transaction – Ví dụ

CD1-CNPM - JAVA HIENLTH

Transaction – Ví dụ

CD1-CNPM - JAVA HIENLTH

Transaction – Ví dụpublic void transaction(){

String a= “INSERT INTO PriceList VALUE (?,?);”;

if(conn != Null){

try{

conn.setAutocommit (false);

PreparedStatement ps = conn.prepareStatement(s);

ps.setString(1, “Biscuit”);

ps.setDouble(2, 1.2);

ps.executeUpdate();

ps.setString(1, “Pen”);

ps.setDouble(2, 0.5);

ps.executeUpdate();

ps.close();

conn.commit();

conn.setAutocommit(true);

} catch (SQLException e){

e.printStackTrace();

}

}

}

CD1-CNPM - JAVA HIENLTH

Transaction – Hủy

• Trong quá trình thực hiện một giao dịch, nếu có sai sót xảy

ra, ta có thể hủy giao dịch đang được thực hiện nữa chừng

bằng cách sử dụng:

conn. rollback().

• Dữ liệu ở thời điểm được commit gần nhất sẽ bị hủy. (Tùy

thuộc vào hệ quản trị CSDL mà cách rollback có thể khác

nhau).

• Dữ liệu sau khi được commit sẽ không hủy được bằng

rollback.

CD1-CNPM - JAVA HIENLTH

Transaction – Setting and rollback to a savepoint

• Save1 = con.setSavepoint: sets a Savepoint object

within the current transaction.

• Rollback to Savepoint save1: con.rollback(save1)

• Connection.releaseSavepoint takes a Savepoint object

as a parameter and removes it from the current

transaction

CD1-CNPM - JAVA HIENLTH

Transaction – Ví dụpublic void transaction(){

String a= “INSERT INTO Lop VALUES (?,?,?);”;

if(conn != Null){

try{

conn.setAutocommit (false);

PreparedStatement ps = conn.prepareStatement(s);

ps.setString(1, “10A2”); ps.setString(2, “Lớp 10A2”); ps.setDouble(3, 12);

ps.executeUpdate();

conn.commit();

ps.setString(2, “10A3”); ps.setString(2, “Lớp 10A3”); ps.setDouble(3, 1);

ps.executeUpdate();

ps.close();

conn.rollback(); //Thông tin về Lớp sẽ không được lưu vào CSDL

conn.commit();

conn.setAutocommit(true);

} catch (SQLException e){

e.printStackTrace();

}

}

}

CD1-CNPM - JAVA HIENLTH

SQLException

• SQLException.getMessage()

• SQLException.getSQLState()

• SQLException.getErrorCode()

• SQLException.getCause()

• SQLException.getNextException()

• SubClasses

• SQLNonTransientException

• SQLTransientException

• SQLRecoverableException

• BatchUpdateException

• SQLClientInfoException

CD1-CNPM - JAVA HIENLTH

SQL Exception - Example

CD1-CNPM - JAVA HIENLTH

Handling SQL Exception

try (Statement stmt = con.createStatement())

{

// ...

}

catch (SQLException e) {

JDBCTutorialUtilities.printSQLException(e);

}

CD1-CNPM - JAVA HIENLTH

References

• http://docs.oracle.com/javase/tutorial/jdbc/index.html

• http://codejava.net/java-se/jdbc/connect-to-microsoft-

sql-server-via-jdbc

• http://www.microsoft.com/en-

us/download/details.aspx?displaylang=en&id=11774

CD1-CNPM - JAVA HIENLTH

Câu hỏi và thảo luận

CD1-CNPM - JAVA HIENLTH