Toggle Theme Editor
Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Charcoal

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

Discussion in 'My sql' started by kienxx, 11/4/18.

  1. kienxx

    kienxx Member

    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.
     
    Last edited: 17/4/18
  2. kienxx

    kienxx Member

    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
     
    Last edited: 11/4/18
  3. D.A.N_3002

    D.A.N_3002 Active Member

    Bạn có thể show code dùng Runable dc ko ?? Mk nghĩ cách đó dùng khả thi nhất
     
  4. kienxx

    kienxx Member

    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?
     
  5. D.A.N_3002

    D.A.N_3002 Active Member

    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 FileNotFoundExceptionIOException
        
    {
            
    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"118)); // 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(141414)
                    .
    addComponent(Textjavax.swing.GroupLayout.DEFAULT_SIZE300Short.MAX_VALUE)
                    .
    addContainerGap())
            );
            
    layout.setVerticalGroup(
                
    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .
    addGroup(layout.createSequentialGroup()
                    .
    addContainerGap()
                    .
    addComponent(Textjavax.swing.GroupLayout.DEFAULT_SIZE61Short.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.SEVEREnullex);
                    } catch (
    IOException ex) {
                        
    Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVEREnullex);
                    }
                }
            });
        }

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

            
    FileInputStream fi null;
            try {
                
    fi = new FileInputStream(new File("Input.txt"));
            } catch (
    FileNotFoundException ex) {
                
    Logger.getLogger(Auto_Update.class.getName()).log(Level.SEVEREnullex);
            }
            
    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.SEVEREnullex);
            }
            
    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.SEVEREnullex);
            } catch (
    InstantiationException ex) {
                
    java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVEREnullex);
            } catch (
    IllegalAccessException ex) {
                
    java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVEREnullex);
            } catch (
    javax.swing.UnsupportedLookAndFeelException ex) {
                
    java.util.logging.Logger.getLogger(Auto_Update.class.getName()).log(java.util.logging.Level.SEVEREnullex);
            }       
        }
        
    // 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 :)
     
  6. kienxx

    kienxx 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 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
     
  7. D.A.N_3002

    D.A.N_3002 Active Member

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

    hoithegiantinhlagi Active Member

    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 and D.A.N_3002 like this.
  9. kienxx

    kienxx Member

    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ả
     
  10. kienxx

    kienxx Member

    Thanks D.A.N nha
     
    D.A.N_3002 likes this.
  11. JackV

    JackV Administrator Staff Member

    À 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.
     
    kienxx and D.A.N_3002 like this.
  12. JackV

    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.
     
    kienxx and D.A.N_3002 like this.
  13. kency

    kency Thành viên BQT Staff Member

    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.
     
  14. kienxx

    kienxx Member

    @hoithegiantinhlagi Bạn ơi, mình đang qua dùng Google Cloud SQL, mình thấy nó ghi là MySQL, vậy nó cũng ko hỗ trợ SQLDependency phải ko?
     
    hoithegiantinhlagi likes this.
  15. hoithegiantinhlagi

    hoithegiantinhlagi Active Member

    Đúng rồi bạn.
     

Chia sẻ trang này

Loading...