Updatable JTable
UPDATEABLE JTABLE
Trong bài viết này tôi sẽ hướng dẫn bạn cách cập nhật thay đổi cơ sở dữ liệu trên Jtable. Nguyên tắc thực hiện trong bài này là khi bạn hiệu chỉnh giá trị của 1 ô dữ liệu trên Jtable hoàn tất thì tương ứng 1 sự kiện được nảy sinh và ta xử lý việc cập nhật lên cơ sở dữ liệu tại sự kiện này.
Ưu điểm của phương pháp này là nó sẽ cập nhật ngay giá trị thay đồi xuống cơ sở dữ liệu.
Nhược điểm đó là sự kết nối liên tục đến cơ sở dữ liệu sẽ khiến cho tốc độ, hiệu năng không cao.
Chúng ta bắt đầu bằng việc tạo 1 cơ sở dữ liệu(ở đây tôi dùng microsoft sql server). Giả sử cơ sở dữ liệu chúng ta có tên là GC0563 với 1 bảng dữ liệu có tên Lophoc có cấu trúc như bảng sau:

Nhập vào 1 số mẫu tin để thử nhé!
Bây giờ bạn tạo 1 lớp đặc tả cho đối tượng tương ứng với bảng cơ sở dữ liệu này. Đối tượng có tên Lophoc có code như sau:
|
package vovanhai.wordpress.com; public class Lophoc { private String msLop; private String tenLop; private String tenGVCN; public String getMsLop() { return msLop; } public void setMsLop(String msLop) { this.msLop = msLop; } public String getTenLop() { return tenLop; } public void setTenLop(String tenLop) { this.tenLop = tenLop; } public String getTenGVCN() { return tenGVCN; } public void setTenGVCN(String tenGVCN) { this.tenGVCN = tenGVCN; } public Lophoc() { super(); } public Lophoc(String msLop, String tenLop, String tenGVCN) { super(); this.msLop = msLop; this.tenLop = tenLop; this.tenGVCN = tenGVCN; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime* result + ((msLop == null) ? 0 : msLop.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Lophoc other =(Lophoc) obj; if (msLop == null) { if (other.msLop != null) return false; } else if (!msLop.equals(other.msLop)) return false; return true; }
@Override public String toString() { return this.tenLop; } }
|
Giao diện của chúng ta sau khi bạn thành công như sau:

Ta sẽ xây dựng lớp kết nối cơ sở dữ liệu để điền lên Jtable. Trước khi chạy ứng dụng, bạn chú ý việc tham chiếu đến
driver kết nối cơ sở dữ liệu MS SQLServer nhé!
Lớp kết nối có code như sau:
|
package vovanhai.wordpress.com; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList;
public class DBActions { private Connection con; /** * Khởi gán connection. Ở đây giả sử dùng DB là MS SQL server * –Nhớ thêm driver — sqljdbc.jar – * @throws Exception */ public DBActions() throws Exception{ Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”); String url=“jdbc:sqlserver://localhost:1433;databaseName=GC0563″; con=DriverManager.getConnection(url,“sa”,“”); } /** * Lấy tất cả các dòng trong bảng Lớp học bỏ vào ArrayList để hiển * thị lên JTable * @return danh sách các lớp */ public ArrayList<Lophoc>getAllRows()throws Exception{ ArrayList<Lophoc>lst=new ArrayList<Lophoc>(); String sql=“select * from lophoc”; ResultSet rs=con.createStatement().executeQuery(sql); Lophoc lh=null; while(rs.next()){ lh=new Lophoc(rs.getString(“msLop”), rs.getString(“tenLop”), rs.getString(“tenGVCN”)); lst.add(lh); } return lst; } /** * Cập nhật giá trị trên lưới xuống cơ sở dữ liệu khi có sự thay đổi * trong sự kiện tableChanged * @param id là mã số của mẫu tin cần cập nhật. * @param updateField trường cần cập nhật * @param updateValue giá trị cập nhật mới cho * @return true nếu việc cập nhật là thành công * @throws Exception */ public boolean ExecuteLophoc(String id, String updateField, String updateValue)throws Exception{ String sql=“update lophoc set “; sql+=updateField+“=? “; sql+=“where msLop=?”; PreparedStatement pstmt=con.prepareStatement(sql); pstmt.setString(1,updateValue); pstmt.setString(2,id); return pstmt.executeUpdate()>0; } } |
Bây giờ chúng ta thiết kế giao diện
Chú ý là cột ID trên Jtable là không được phép thay đổi. Nếu thay đổi thì việc cập nhật sẽ không thành công do câu lệnh update không tìm thấy id. Ta sẽ nói việc thay đổi này ở 1 bài khác. Để cấm việc edit trên cột ID, ta xử lý như sau:
|
String []title={“Mã số lớp”,“Tên lớp”,“Tên GVCN”}; dtm=new DefaultTableModel(title,0){ public boolean isCellEditable(int x, int y){ //Không cho sửa dữ liệu trên cột ID – tương ứng y=0 if(y==0) return false; return true; } }; |
Code cho cả phần này như sau
|
package vovanhai.wordpress.com;
import java.awt.BorderLayout; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import import import import javax.swing.table.TableModel;
public class UpdatableJTableT1 extends JFrame{ private DefaultTableModel dtm; private JTable table; private DBActions action; private JLabel statusBar;
public MyDataGridViewDemo() throws Exception{ setTitle(“MyDataGridViewDemo”); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(600,400); this.add(statusBar=new JLabel(“ready…”),BorderLayout.SOUTH);
action=new DBActions();
String[]title={“Mã số lớp”,“Tên lớp”,“Tên GVCN”}; dtm=new DefaultTableModel(title,0){ public boolean isCellEditable(int x, int y){ //Không cho sửa dữ liệu trên cột ID if(y==0) return false; return true; } }; table=new JTable(dtm); this.add(new JScrollPane(table));
FillData();//điền dữ liệu lên JTable
//Đăng ký sự kiện Table change để khi có thay đổi trên table thì //cập nhật ngay lập tức xuống cơ sở dữ liệu dtm.addTableModelListener(new TableModelListener() { public void tableChanged(TableModelEvent e) { int row = e.getFirstRow(); int column = e.getColumn(); TableModel model = (TableModel)e.getSource(); //dữ liệu đã thay đổi trên JTable Object changedData = model.getValueAt(row, column); //Mã số cần thay đổi String id=model.getValueAt(row, 0).toString(); //Xác định field cần cập nhật String updateField=(column==1?“tenLop”:“tenGVCN”); String updateValue=changedData.toString(); try { //cập nhật xuồng cơ sở dữ liệu if(action.ExecuteLophoc(id,updateField,updateValue)) statusBar.setText(“Update successfull for editing row”); else statusBar.setText(“Update failed for id “+id); } catch (Exception e1) { e1.printStackTrace(); } } }); } /** * Điền dữ liệu từ bảng lên JTable */ private void FillData(){ try { ArrayList<Lophoc> lst=action.getAllRows(); for(Lophoc lh:lst){ String []row={lh.getMsLop(),lh.getTenLop(),lh.getTenGVCN()}; dtm.addRow(row); } } catch (Exception e) { e.printStackTrace(); } }
//Thực thi chương trình public static void main(String[] args)throws Exception { new UpdatableJTableT1().setVisible(true); } }
|
OK. Thưởng thức được rồi đấy!
ngocmai said
Dạ, em làm như thế mà cứ bị lỗi :Have no file for C:\Program Files\Java\jdk1.6.0_24\jre\lib\modules\jdk.boot.jar
Dạ loi do la loi gi ạ, mac dù da down lai jdk1.6 va jre rùi a
Võ Văn Hải said
Em gỡ bỏ JDK, JRE sau đó:
1. cài đặt lại JDK: Chọn thư mục cài đặt là C:\ thay vì trong “C:\Program Files” bởi vì nó mang lại rất nhiều bất lợi khi làm việc đặt biệt là trong Vista/Win7.
2. Cài đặt JRE bình thường
Tôi đoán là em dùng netbeans 6.5.1, em đổi lên 6.7.1 hoặc 6.9.1
thanhvt said
Em không thể nào chạy file kết nối tới cơ sở dữ liệu được.Chạy thì gặp phải lỗi sau:
ClassNotFoundException:com.microsoft.sqlserver.jdbc.SQLServerDriver.
E đã điền đầy đủ cổng,user,pass rồi.E cũng đã Add thư việ sqpjdbc.jar vào rồi nhưng vẫn không được.
Làm ơn hãy giúp em!
Võ Văn Hải said
Download lại file driver thử bạn.
muoidv said
thầy để code thế này khó nhìn quá
sao ko để link dow file về cho nó tiện
thanh said
E xin hỏi thầy một vấn đề đó là nếu một project lớn có nhiều dữ liệu cần được quản lý thì việc dùng JTable để qly là khó khăn phải không ah.Trong trường hợp e là một nhà phát triển được giao nhiệm vụ làm project này thì em sẽ phải lấy ý tưởng nào để thay đổi việc quản lý.Thưa thầy.
Còn một điều e chưa hiểu trong phần nầy đó là việc thầy lấy rất nhiều trường kiểu dl là String nhưng e thử thay vào vài trường là số(int) thì lại gặp trục trặc khi getdata thông qua Resultset vì có rất nhiều thứ liên quan.
Mong thầy chỉ giáo. Thanks.
Võ Văn Hải said
jtable chỉ là công cụ hiển thị dữ liệu mà thôi. lựa chọn cách hiển thị nào là tùy bạn.
CÒn kiểu dữ liệu kiểu khác kiểu String thì bạn phải biến nó về String để đưa vào JTable(do ở đây ta dùng row[] là kiểu String).
Nguyễn Thị Thu said
Thầy ơi nếu 1 trường trong bảng là trường PassWord nếu muốn nó mã hóa theo MD5 để mọi người ko nhìn thấy thì làm cách nào hả thầy?
daolvcntt said
Cho E hỏi E có 2 field là sex và status có kiểu bit khi show lên JTable thì nó show là 1 – 0 giờ E muốn thay đổi 1 – 0 thành Male – Ac thì mình làm ntn ak