Lỗi không thể sử dụng executeupdate trong java năm 2024

Phương thức này nên được sử dụng cho bất kỳ lời gọi SQL mà mong muốn kết quả trả về là dữ liệu từ CSDL

Thực thi SQL

  • excuteUptate()
    • Thực thi một câu lệnh SQL: INSERT, UPDATE, DELETE và các câu lệnh định nghĩa ngôn ngữ( DDL) như: create, drop, alter trong table.
    • Kết quả trả về là số dòng đã thực hiện trong câu lệnh INSERT, UPDATE, DELETE
    • Hoặc 0 câu lệnh SQL không ảnh hưởng tới dòng nào cả hoặc câu lệnh được thực thi là câu lệnh DDL

Thực thi SQL

  • Phương thức excute()
    • Được sử dụng trong tình huống chúng ta không biêt câu lệnh SQL là SQL Query hay SQL Update.
    • Thường được dùng khi ứng dụng gọi thực thi tự động một câu lệnh SQL.
    • Kết quả trả về là true nếu kết quả là một đối tượng ResultSet
    • False nếu kết quả là số lượng cập nhật, hoặc không có kết quả
    • Có thể dùng phương thức getResultSet() hoặc getUpdateCount() để lấy kết quả trả về.

ResultSet

  • Đối tượng ResultSet chứa một hay nhiều dòng data được trả về từ truy vấn dữ liệu.
  • Lớp ResultSet điều khiển con trỏ đơn một chiều trỏ dòng đầu tiên.
  • Ta có thể dùng phương thức next() để chuyển trỏ đến dòng kết quả tiếp theo.
  • Một số phương thức quan trọng ResultSet interface:
    • Next(): di chuyển con trỏ đến record tiếp theo.
    • isFirt(): con trỏ trỏ đến record đầu tiên trong ResultSet
    • isLast(): con trỏ trỏ đến record cuối cùng trong ResultSet

ResultSet

  • getDataMeta(): trả về đối tượng ResultSetMetaDate( nghiên cứu ở slide sau).
  • Có thể sử dụng các method getXXX() để lấy giá trị cụ thể của cột của dòng trả về.

Kiểu của SQL

Kiểu của Java

Hàm getXXX()

Char, varchar, longvarchar

String

getString()

Numberic, decimal

Math.BigDecimal

getBigDecimal()

Bit

Boolean

getBoolean()

TinyInt

Integer(byte)

getByte()

smallInt

Integer(short)

getShort()

ResultSet

Kiểu của SQL

Kiểu của Java

Hàm getXXX()

Integer

Integer( int)

getInt()

BigInt

Long( long)

getLong()

Real

Float( float)

getBoolean()

float

Double( double)

getDouble()

double

Double( double)

getDouble()

Binary, Varbinary, Longvarbinary

Byte[]

getBytes()

Date

Date

getDate()

Time

Time

getTime()

TimeStamp

Timestamp

getTimestamp()

ResultSet Metadata

  • Khi gởi lệnh “Select” đến ứng dụng JDBC, ta nhận được đối tượng ResultSet chứa data thỏa mãn ĐK nào đó.
  • Ta có thể lấy các thông tin các cột trong ResultSet bằng cách tạo đối tượng ResultSetMetadata.
    • Statement stmt = con.createStatement();
    • ResultSet rs = stmt.executeQuery("select * from COFFEES");
    • ResultSetMetaData rsmd = rs.getMetaData();

Using ResultSetMetadata methods

  • getColumnCount():
    • Trả về số cột của ResultSet trả về
  • getColumnLabel(), getColumnName()
  • getColumnType(), getColumnTypeName()
  • Đọc thêm trong Interface ResultSetMetaData

Using JDBC Parameterized Statements

  • Trong vài trường hợp ta cần sử dụng đối tượng Statement nhiều lần.
  • Để giảm thời gian thực thi ta sử dụng đối tượng PreparedStatement.
  • PreparedStatement kế thừa từ Statement nhưng khác Statement 2 điểm:
    • PreparedStatement chứa câu lệnh SQL đã được biên dịch
    • PreparedStatement chứa một hoặc nhiều tham số vào, dùng dấu( ?) để biểu thị.
    • Tham số vào phải được truyền trước khi PreparedStatement thực thi.

Creating PreparedStatement Objects and passing in parameters

  • Creating PreparedStatement Object:

  • Passing in parameters:
    • Gọi các phương thức thích hợp cho từng loại dữ liệu mà ta cần truyền vào.
    • Sử dụng các phương thức setXXX( parameter1, parameter2) được định nghĩa trong lớp PreparedStatement.
    • Trong đó:
      • parameter1: thứ tự tham số trong chuổi preparedStatement( bắt đầu từ 1).
      • Parameter2: giá trị truyền vào.

PreparedStatement pstmt = con.prepareStatement(

"UPDATE table4 SET m = ? WHERE x = ?");

Callable Statement

  • Đối tượng Callable Statement cung cấp cách thức để gọi stored procedure trong các HQTCSDL.
  • Cấu trúc gọi stored procedure trong JDBC:
    • Gọi stored procedure không có đối số: { call procedure_name}
    • Có đối số vào, ra hoặc vào-ra: {call procedure_name(?, ?, …)}
    • Có đối số trả về, có hoặc không có đối số vào, ra, hoặc vào-ra: { ?= call procedure_name[(?, ?, …)]}

Callable Statement

  • Creating a CallableStatement Object:

  • Passing in parameter:
    • Sử dụng các phương thức setXXX(par1, par2) kế thừa từ lớp PreparedStatement
    • trong đó:
      • Par1: thứ tự tham số, hoặc tên tham số đã được định nghĩa trong stored procedure
      • Par2: giá trị truyền cho tham số

CallableStatement cstmt = con.prepareCall(

"{call getTestData(?, ?)}");

Callable Statement

  • OUT Parameters:
    • Nếu stored procedure có tham số trả về, loại dữ liệu tham số trả về phải được đăng ký trước khi đối tượng CallableStatement được thực thi
    • Dùng phương thức registerOutParameter đăng ký tham số xuất
    • Làm phù hợp với kiểu dữ liệu mà CSDL sẽ trả về.
    • Sau khi Statement được thực thi, phương thức getXXX() được dùng để lấy giá trị tham số trả về.

Types of Result sets

  • Mặc định, đối tượng ResultSet không thể cập nhật và có một con trỏ chỉ move 1 chiều từ trên xuống.
  • Ta có thể tạo đối tượng ResultSet có thể cập nhật được, có thể trượt theo hai chiều.

  • resultSetType: ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE
  • resultSetConcurrency: ResultSet.CONCUR_READ_ONLY ResultSet.CONCUR_UPDATABLE

createStatement(int resultSetType, int resultSetConcurrency)

prepareStatement(String sql, int resultSetType, int resultSetConcurrency)

prepareCall(String sql, int resultSetType, int resultSetConcurrency)

ResultSet có thể cập nhật

  • Update record hiện hành:
    • Dùng phương thức updateXXX(, )
    • Hoặc updateXXX(, )
    • Xác lập việc cập nhật bằng phương thức: updateRow()
    • Hoặc hủy bỏ các lệnh trước đó bằng lệnh: cancelRowUpdate()

rs.absolute(4);

rs.updateString(2, "321 Kasten");

rs.updateFloat(3, 10101.0f);

rs.updateRow();

ResultSet có thể cập nhật

  • Đối tượng ResultSet có thể update được luôn tồn tại một record đặc biệt: insertrow
  • Không phải là thành phần của ResultSet mà nằm trong vùng đệm khác.

  • Di chuyển đến vị trị insertrow: moveToInsertRow()
  • Điền các giá trị cho từng field: updateXXX()
  • Thêm record mới vào bảng và ResultSet: insertRow()

rs.moveToInsertRow();

rs.updateObject(1, myArray);

rs.updateInt(2, 3857);

rs.updateString(3, "Mysteries");

rs.insertRow();

rs.first();

Using Transactions

  • Thiết lập một hoặc nhiều statement được thực thi với nhau như một unit.
  • Khi một kết nối được tạo, chế độ auto-commit được thiết lập cho từng SQL riêng lẽ.
  • Để hai hay nhiều statement được nhóm vào một transaction, ta phải thiết lập lại chế độ auto-commit.
    • con.setAutoCommit(false);

Using Transactions

  • con.setAutoCommit(false);
  • PreparedStatement updateSales = con.prepareStatement(
  • "UPDATE COFFEES SET SALES = ? WHERE COF_NAME = ?");
  • updateSales.setInt(1, 50);
  • updateSales.setString(2, "Colombian");
  • updateSales.executeUpdate();
  • PreparedStatement updateTotal = con.prepareStatement(
  • "UPDATE COFFEES SET TOTAL = TOTAL + ? WHERE COF_NAME = ?");
  • updateTotal.setInt(1, 50);
  • updateTotal.setString(2, "Colombian");
  • updateTotal.executeUpdate();
  • con.commit();

Using Transactions to Preserve Data Integrity

  • Việc sử dụng transaction để đảm bảo tính toàn vẹn dữ liệu trong bảng. Cung cấp một vài mức độ bảo vệ để tránh xung đột xẩy ra khi hai người dùng cùng truy cập đến CDSL trong cùng thời gian.