Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

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
trường updateField

* @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
javax.swing.event.TableModelEvent;

import
javax.swing.event.TableModelListener;

import
javax.swing.table.DefaultTableModel;

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!

11 Responses to “Updatable JTable”

  1. 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

  2. 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

  3. 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!

  4. Võ Văn Hải said

    Download lại file driver thử bạn.

  5. muoidv said

    thầy để code thế này khó nhìn quá
    sao ko để link dow file về cho nó tiện

  6. 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.

  7. 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).

  8. 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?

  9. 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

  10. abclona said

    Thầy ơi cho em hỏi em cũng làm như thầy nhưng chỉ có phần giao diện là em kéo thả .Tại sao em vẫn không load lên được hả thầy.

    dưới đây là code , thầy coi giúp em với

    public StudentFrame() {
    initComponents();

    header=new Vector();

    header.add(“name”);
    header.add(“mark”);
    header.add(“grade”);
    header.add(“class”);
    }

    public ArrayList getAllRows() {

    try {
    Connection con = ConnectData.getConnection();

    ArrayList lst = new ArrayList();
    String sql = ” select * from StudentInfo”;
    PreparedStatement pr;

    pr = con.prepareStatement(sql);
    ResultSet rs = pr.executeQuery();

    Student std = new Student();

    while (rs.next()) {
    rs.getString(“name”);
    rs.getFloat(“mark”);
    rs.getString(“grade”);
    rs.getString(“class”);
    lst.add(std);
    }
    return lst;

    } catch (SQLException ex) {
    return null;
    }

    }

    public boolean ExcuteStudent(String name, String UpdateField, String UpdateValue) {
    try {
    Connection con = ConnectData.getConnection();

    String sql = “update StudentInfo set”;

    sql += UpdateField + “=? “;
    sql += “where name=?”;

    PreparedStatement pr = con.prepareStatement(sql);
    pr.setString(1, UpdateValue);
    pr.setString(2, name);

    return pr.executeUpdate() > 0;
    } catch (SQLException ex) {
    return false;
    }

    }
    private void btnSubmitActionPerformed(java.awt.event.ActionEvent evt) {

    data =new Vector();
    tablemodel=new DefaultTableModel(data, header);
    tablemodel.fireTableDataChanged();
    jTable1.setModel(tablemodel);
    btnSubmit.setEnabled(true);
    getAllRows();

    }

    private void btnEditActionPerformed(java.awt.event.ActionEvent evt) {

    ExcuteStudent(null, null, null);

  11. vunhinh92 said

    em thưa thầy, thầy cho em hỏi, trong ví dụ của thầy, các kiểu dữ liệu toàn là nchar, nên trong java ta để là String. Nếu kiểu dữ liệu trong sql mình không để là nchar hoặc nvarchar mà để là kiểu datetime, vậy thì trong java mình sẽ để kiểu datetime này như thế nào.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: