Java 在JTable中显示数据库中的数据

Java 在JTable中显示数据库中的数据,java,swing,design-patterns,jtable,crud,Java,Swing,Design Patterns,Jtable,Crud,我正在使用jdbc编写一个程序,它将成为数据库的接口(类似smth的CRUD应用程序)。我假设我必须编写一个类(例如,DBCLass),该类将对数据库执行所有操作(select、update、insert、delete,可能还有一些其他逻辑将简化为这些操作)。用户界面由一组表和几个按钮组成。要使用Jtable,我需要实现一个类(例如Model),它是AbstractTableModel的一个子类。所以这个类将向用户显示我的数据。我需要为数据库模式中的所有表实现这样的模型。我不想在向用户显示数据的

我正在使用jdbc编写一个程序,它将成为数据库的接口(类似smth的CRUD应用程序)。我假设我必须编写一个类(例如,
DBCLass
),该类将对数据库执行所有操作(
select、update、insert、delete
,可能还有一些其他逻辑将简化为这些操作)。用户界面由一组表和几个按钮组成。要使用Jtable,我需要实现一个类(例如
Model
),它是AbstractTableModel的一个子类。所以这个类将向用户显示我的数据。我需要为数据库模式中的所有表实现这样的模型。我不想在向用户显示数据的类中编写逻辑,我认为在这样的类中编写逻辑代码不是一件很好的事情。但是,将db表中的所有数据加载到内存(例如ArrayList)然后在
模型中显示也是不正确的。
所以,我想知道解决这个问题的最好方法是什么

编辑: 一个小例子:

Statement stmt = ....;
ResaultSet rs = stmt.executeQuery("SELECT * FROM table1");
javadoc说executeQuery方法返回一个ResultSet对象,该对象包含给定查询生成的数据。因此,如果我们有大量数据(其大小超过了虚拟机允许的大小),我们的程序就会失败。
所以我的问题仍然是相关的

有一些想法。

这里有一个类,它从数据库中提取数据行和数据列

查看table=newjtable(rows(),columns())

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PrinterException;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import com.swtdesigner.SwingResourceManager;
import java.util.*;
import java.sql.*;
import javax.swing.*;
public class listing extends JDialog {


private JTable table;
public static Vector rows() {

    Vector data = new Vector();
    String sql= null;
    Connection C;


        try {

            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            C = (Connection) DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
                    "system", "manager");

            Statement stmt = C.createStatement();
            ResultSet rset = stmt.executeQuery("SELECT * FROM site ");
            ResultSetMetaData md = rset.getMetaData();
            int columns = md.getColumnCount();



            while (rset.next()) {
                Vector row = new Vector(columns);

                for (int i = 1; i <= columns; i++) {
                    row.addElement(rset.getObject(i));
                }

                data.addElement(row);

            }

            rset.close();
            stmt.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace());
        }

        //System.out.println("lignes :  "+data);
        return data;
}


   public static Vector columns()
    {   Connection c ;
        Vector cols = new Vector ();
        String sql2=null;
        try { 
            DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
            c = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
                    "system", "manager");

            sql2 = "select * from SITE";

            Statement stmt = c.createStatement();
            ResultSet rs = stmt.executeQuery(sql2);
            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();

              //récupération des noms des colonnes dans la table site

            for (int i = 1; i <= columns; i++) {
            cols.addElement(md.getColumnName(i));
            }
           } catch (Exception e) {
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace());
        }
        //System.out.println("colonnes ::: "+cols);
        return cols;
    }

public static void main(String args[]) {
    try {
        listing dialog = new listing();
        dialog.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        dialog.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public listing() {
    super();
    getContentPane().setLayout(null);
    setTitle("Listing de la table \"SITE\"");
    setBounds(100, 100, 500, 363);
    setResizable(false);

    final JLabel laTablesiteLabel = new JLabel();
    laTablesiteLabel.setText("La table \"SITE\" contient . . . ");
    laTablesiteLabel.setBounds(10, 34, 274, 16);
    getContentPane().add(laTablesiteLabel);

    final JLabel label = new JLabel();
    label.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/130.png"));
    label.setBounds(402, 18, 49, 48);
    getContentPane().add(label);

    final JButton okButton = new JButton();
    okButton.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent arg0) {
            dispose();
            setVisible(false);
        }


    });
    okButton.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/33-32x32.png"));
    okButton.setText("Ok");
    okButton.setBounds(10, 291, 148, 32);
    getContentPane().add(okButton);

    final JButton refeshButton_1 = new JButton();
    refeshButton_1.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/48-32x32.png"));
    refeshButton_1.setText("Actualiser");
    refeshButton_1.setBounds(171, 291, 148, 32);
    getContentPane().add(refeshButton_1);

    final JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBounds(10, 85, 474, 187);
    getContentPane().add(scrollPane);

    table = new JTable(rows(), columns()); // chargement de JTable 
    scrollPane.setViewportView(table);

    final JButton printButton_1_1 = new JButton();
    printButton_1_1.addActionListener(new ActionListener() {
        public void actionPerformed(final ActionEvent arg0) {
            try {
                table.print();
            } catch (PrinterException e) {

                e.printStackTrace();
            }
        }
    });
    printButton_1_1.setIcon(SwingResourceManager.getIcon(listing.class, "/pictures/Printer_h.png"));
    printButton_1_1.setText("Imprimer");
    printButton_1_1.setBounds(336, 291, 148, 32);
    getContentPane().add(printButton_1_1);




    }

}
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入java.awt.print.PrinterException;
导入javax.swing.JDialog;
导入javax.swing.JLabel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入com.swtdesigner.SwingResourceManager;
导入java.util.*;
导入java.sql.*;
导入javax.swing.*;
公共类列表扩展了JDialog{
专用JTable表;
公共静态向量行(){
向量数据=新向量();
字符串sql=null;
连接C;
试一试{
registerDriver(新的oracle.jdbc.OracleDriver());
C=(Connection)DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521:XE”,
“系统”、“经理”);
语句stmt=C.createStatement();
ResultSet rset=stmt.executeQuery(“从站点选择*);
ResultSetMetaData md=rset.getMetaData();
int columns=md.getColumnCount();
while(rset.next()){
矢量行=新矢量(列);
对于(inti=1;iMaks

下面是关于一般sql到表实现的另一个示例:

这可能是一个寻找答案的好地方

此外,此本地问题/答案还可以帮助您确定结果集大小:

希望这有帮助

Robert

下载的源代码并查看表实现

需要注意的一些事项:

数据库表不是Java JTables。数据库中的表实际上是一个集合(诅咒使用错误术语的傻瓜),每个项都有属性(通常称为“列”,它不是JColumn,这解释了为什么很难将两者映射)

一个集合可以增长到任何大小。它没有内在的顺序。你可以对它做很多集合操作,比如:并集、差集、子集

因此,它不是一个表,尤其不是一个UI表

没有简单的UI范例可以将“set”映射到“table”

  • 加载N条记录并翻阅结果

  • 用户向下滚动时,可以加载更多内容

  • 您可以计算集合的大小,并相应地调整滚动条。当用户滚动数据时,数据将从数据库中提取并显示

  • 利与弊:

    解决方案1是最容易实现的,也是用户最讨厌的解决方案。为什么他们需要等到数据返回时再查看数据?如果每次提取都需要15秒,这尤其令人沮丧。Page…wait…Page…oops!原来是这样!该死!等等…back…等等…啊哈

    此外,数据库通常很难对数据进行分页。对于某些查询,性能可能是灾难性的

    解决方案2很容易实现,特别是如果你可以永远打开
    结果集
    。但是100%的时候,你不能。如果你将结果集打开几个小时或一天,它就会开始失败。在那之后,数据库会想“哦,它死了,吉姆”然后关闭连接,您的用户将收到一条漂亮的错误消息,您将收到一个愤怒的用户

    因此,你也需要在这里翻页,但不要经常翻页。从积极的一面来看,用户不必再等待他们已经拥有的数据。一个重要的问题是:如果集合包含数百万行,用户直观地理解,他们需要在向下滚动时从不同的角度解决问题。最终,他们会感到厌倦,并要求更好的解决方案(而不是因为你愚蠢的程序不能在少于0.000000000 1s的时间内显示1500万行而对你生气)

    解决方案3同样比#2更糟糕。如果表格增长,UI将变得不可用:即使查看滚动条“知道”也会将您移动到表格中的随机位置。因此,它会使您的鼠标变得无用。用户会感到愤怒

    因此,我通常会尝试以下解决方案:

  • 读取1000行,最大值。如果读取行的时间超过1秒,我会在100行之后停止(因此用户至少有一些数据)。通常,查询速度很慢,读取结果集几乎不需要时间,但我喜欢在这里进行防御

  • 在每列的顶部都有一个过滤器和一个可以直接映射到SQL的“order by”。这样,我可以确保如果您希望数据按列排序,它将按所有值(而不仅仅是屏幕上可以看到的值)排序

  • 这允许用户将大量数据切碎成有意义的子集。

    这篇博客文章