Làm Thế Nào Để Chương Trình Tự Thay Đổi Theo Dữ Liệu Từ Database?

kienxx

Member
26/3/18
70
17
8
TPHCM
Mình VD là có 1 trang index hiển thị các thông số đc lấy từ MySQL. Khi dữ liệu từ database thay đổi, mình bắt các sự kiện như di chuột để run các hàm cập nhật dữ liệu. Nhưng nó vẫn là 1 thao tác, làm thế nào để mình ko cần làm gì mà khi dữ liệu từ database thay đổi, chương trình trên máy tính của mình tự refesh theo? (ko cần phải click, bấm, di chuột, mở cửa sổ chương trình v..v...)
Đây là 1 kết quả mình search được https://stackoverflow.com/questions/12618915/how-to-implement-a-db-listener-in-java nhưng mình chưa hiểu và chưa làm được.
Còn Runable 1 luồng chạy song song cập nhật dữ liệu liên tục thì ko thấy thay đổi gì.
Ai có thể cho mình xin chút kiến thức về vấn đề này đi.
----------------------
Do đây là MySQL nên mình đã giải quyết bằng chạy Thread.
 
Sửa lần cuối:

kienxx

Member
26/3/18
70
17
8
TPHCM
Có phải này ko, mình đang tìm hiểu SqlDependency
Search rất nhiều ra dòng này để enable broker mysql: ALTER DATABASE sample_database SET ENABLE_BROKER
mà mình dùng thì cứ báo lỗi dù đã tắt hết kết nối tới database
 
Sửa lần cuối:

D.A.N_3002

Active Member
14/11/17
177
49
28
17
Mình VD là có 1 trang index hiển thị các thông số đc lấy từ MySQL. Khi dữ liệu từ database thay đổi, mình bắt các sự kiện như di chuột để run các hàm cập nhật dữ liệu. Nhưng nó vẫn là 1 thao tác, làm thế nào để mình ko cần làm gì mà khi dữ liệu từ database thay đổi, chương trình trên máy tính của mình tự refesh theo? (ko cần phải click, bấm, di chuột, mở cửa sổ chương trình v..v...)
Đây là 1 kết quả mình search được https://stackoverflow.com/questions/12618915/how-to-implement-a-db-listener-in-java nhưng mình chưa hiểu và chưa làm được.
Còn Runable 1 luồng chạy song song cập nhật dữ liệu liên tục thì ko thấy thay đổi gì.
Ai có thể cho mình xin chút kiến thức về vấn đề này đi.
Bạn có thể show code dùng Runable dc ko ?? Mk nghĩ cách đó dùng khả thi nhất
 

kienxx

Member
26/3/18
70
17
8
TPHCM
DAN ơi tối mình về mình làm lại rồi mình post code lên
Đêm qua ko làm được nhưng search thấy cách người ta nói đến là set database enable broker. Rồi khi có thay đổi database sẽ báo cho chương trình, rồi mình gọi các hàm cập nhật. Khổ nỗi là toàn hướng dẫn thuộc C#. Cách ấy DAN thấy sao?
 

D.A.N_3002

Active Member
14/11/17
177
49
28
17
DAN ơi tối mình về mình làm lại rồi mình post code lên
Đêm qua ko làm được nhưng search thấy cách người ta nói đến là set database enable broker. Rồi khi có thay đổi database sẽ báo cho chương trình, rồi mình gọi các hàm cập nhật. Khổ nỗi là toàn hướng dẫn thuộc C#. Cách ấy DAN thấy sao?
Mình không bt rõ cái này có thể làm dc ko @@ Nhưng mình sẽ đưa cho bạn tham khảo code Auto_Update từ Text file sử dụng Thread, bạn có thể tham khảo :
PHP:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import static java.lang.Thread.sleep;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Auto_Update extends javax.swing.JFrame {
    
    public Auto_Update() throws FileNotFoundException, IOException
    {
        initComponents();
        FileInputStream fi = new FileInputStream(new File("Input.txt"));
        Scanner scan = new Scanner(fi);
        Text.setText(scan.nextLine().substring(1));   
        fi.close();
        scan.close();
        new Thread()
        {
            public void run()
            {
                while (true)
                {         
                    Update();
                }
            }
        }.start();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                         
    private void initComponents() {

        Text = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        Text.setFont(new java.awt.Font("Times New Roman", 1, 18)); // NOI18N
        Text.setText("jLabel1");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(14, 14, 14)
                .addComponent(Text, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(Text, javax.swing.GroupLayout.DEFAULT_SIZE, 61, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                       

    public static void main(String args[]) {
        Set_Look_And_Feel();
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    new Auto_Update().setVisible(true);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public void Update()
    {
        try {
            sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVERE, null, ex);
        }

        FileInputStream fi = null;
        try {
            fi = new FileInputStream(new File("Input.txt"));
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVERE, null, ex);
        }
        Scanner scan = new Scanner(fi);

        String input = scan.nextLine().substring(1);
        if(!Text.getText().equals(input));
        {
            Text.setText(input);
        }

        try {
            fi.close();
        } catch (IOException ex) {
            Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVERE, null, ex);
        }
        scan.close();       
    }
    
    public static void Set_Look_And_Feel()
    {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }       
    }
    // Variables declaration - do not modify                     
    private javax.swing.JLabel Text;
    // End of variables declaration                   
}
Đây là Demo :

P/s : Toàn bộ các lệnh để Update dc để ở trong void Update(), bạn hãy tùy chỉnh lại với code của bạn :)
 

kienxx

Member
26/3/18
70
17
8
TPHCM
Nếu dùng update như thế này thì có phải chương trình sẽ chạy liên tục, thay txt file = database online thì tài nguyên sẽ ảnh hưởng rất nhiều nhỉ DAN. Nãy giờ chạy deadline nên giờ mới post được. Hàm của mình đơn giản mà có sẵn trên IDE
Code:
 java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Index().GetData();
            }
        });
Trong đó GetData() là hàm update các dữ liệu, Run được mà lại ko thấy có tác dụng :v
 

D.A.N_3002

Active Member
14/11/17
177
49
28
17
Nếu dùng update như thế này thì có phải chương trình sẽ chạy liên tục, thay txt file = database online thì tài nguyên sẽ ảnh hưởng rất nhiều nhỉ DAN. Nãy giờ chạy deadline nên giờ mới post được. Hàm của mình đơn giản mà có sẵn trên IDE
Code:
 java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Index().GetData();
            }
        });
Trong đó GetData() là hàm update các dữ liệu, Run được mà lại ko thấy có tác dụng :v
Bạn phải bỏ nó vào hàm while để nó chạy liên tục chứ, như ở VD của mk :
PHP:
            public void run()
            {
                while (true)
                {        
                    Update();
                }
            }
Còn về vấn đề tốn tài nguyên thì mk có đặt lệnh sleep của Thread, tức là dau khi chạy hết câu lệnh trong hàm while thì nó sẽ delay 1 giây rồi mới chạy lại từ đầu
 

hoithegiantinhlagi

Active Member
13/3/13
333
104
43
BR-VT
Thật ra problem này nếu dùng nền tản Microsoft có thể giải quyết bằng SQLDependency, còn MySQL ko có technology nào tương đương cả, Oracle thì có Database Change Notification nhưng cũng có tính phí.
Còn việc chạy 1 thread liên tục trên 1 client app là bất khả thi, vì resource ko thể nào chịu nỗi đâu, ở đây bạn vd 1 trường hợp thay đổi data quá nhỏ so với thực tế có thể có hàng chục table thay đổi và lượng data be changed mỗi giây có thể là hàng nghìn record thì 1 ngay cả 1 con server tầm middle cũng chưa chắc chịu nỗi huống hồ gì là client.
Solution đưa ra là:
1/ Bạn nên request với customer là change technology platform.
2/ Nếu customer ko chịu thì phải trả phí license 2 technologies trên thôi.
 

kienxx

Member
26/3/18
70
17
8
TPHCM
Thật ra problem này nếu dùng nền tản Microsoft có thể giải quyết bằng SQLDependency, còn MySQL ko có technology nào tương đương cả, Oracle thì có Database Change Notification nhưng cũng có tính phí.
Còn việc chạy 1 thread liên tục trên 1 client app là bất khả thi, vì resource ko thể nào chịu nỗi đâu, ở đây bạn vd 1 trường hợp thay đổi data quá nhỏ so với thực tế có thể có hàng chục table thay đổi và lượng data be changed mỗi giây có thể là hàng nghìn record thì 1 ngay cả 1 con server tầm middle cũng chưa chắc chịu nỗi huống hồ gì là client.
Solution đưa ra là:
1/ Bạn nên request với customer là change technology platform.
2/ Nếu customer ko chịu thì phải trả phí license 2 technologies trên thôi.
Thì ra là vậy, đêm hôm ấy mình cứ chạy câu lệnh Enable Broker trên MySQL mà ko được là vì đây :(
Cảm ơn hoithegiantinhlagi, mình chỉ là newbie java đang tự luyện tập thôi chớ ko customer gì cả
 

kienxx

Member
26/3/18
70
17
8
TPHCM
Bạn phải bỏ nó vào hàm while để nó chạy liên tục chứ, như ở VD của mk :
PHP:
            public void run()
            {
                while (true)
                {       
                    Update();
                }
            }
Còn về vấn đề tốn tài nguyên thì mk có đặt lệnh sleep của Thread, tức là dau khi chạy hết câu lệnh trong hàm while thì nó sẽ delay 1 giây rồi mới chạy lại từ đầu
Thanks D.A.N nha
 
  • Like
Reactions: D.A.N_3002

JackV

Administrator
Staff member
Nếu dùng update như thế này thì có phải chương trình sẽ chạy liên tục, thay txt file = database online thì tài nguyên sẽ ảnh hưởng rất nhiều
À có 1 cách khác nữa là check db status, tất nhiên là check riêng cho từng phần, ví dụ checkProduct() hoặc checkUserChage() chẳng hạn, các tác vụ check chỉ trả về kết quả là staus number (một dãy số thay đổi theo mỗi lần udpate, có thể chỉ là thời gian update cuối cùng) , tương đương với kết quả check mà hành động thôi, và như thế thì ta hiểu là mỗi khi dữ liệu thay đổi thì có 1 trường dữ liệu tham chiếu để xác định trạng thái của dữ liệu.
 

JackV

Administrator
Staff member
@kienxx nếu hệ thống có giới hạn số lượng người dùng trong mạng nội bộ thì bạn có thể tìm hiểu về lập trình RMI (Triệu gọi phương thức từ xa), với rmi thì thằng chạy server tự quản lý dữ liệu, khi dữ liệu thay đổi thì server gọi phương thức thông báo cho client thông tin hoặc gọi thẳng phương thức cập nhật dữ liệu của client để truyền dữ liệu về cho client luôn.
 

kency

Thành viên BQT
Staff member
22/5/10
885
9
18
Theo mình thấy nếu vậy bạn cứ dùng Design Pattern là Observer, 1 Object và 1 Subscriber. hoặc nhiều object thì subcriber sẽ lắng nghe object đó, mỗi lần change db thì dùng Ajax Trigger tự động refresh lại page.