使用 GUI API 的 JDBC
原文:
docs.oracle.com/javase/tutorial/jdbc/basics/jdbcswing.html
示例CoffeesFrame.java
演示了如何将 JDBC 与 GUI API 集成,特别是 Swing API。它在表中显示了COFFEES
数据库表的内容,并包含字段和按钮,使您可以向表中添加行。以下是此示例的屏幕截图:
该示例包含五个文本字段,对应于COFFEES
表中的每一列。它还包含三个按钮:
- 向表中添加行:根据文本字段中输入的数据向示例表中添加一行。
- 更新数据库:根据示例表中的数据更新
COFFEES
表。 - 放弃更改:检索
COFFEES
表的内容,替换示例表中的现有数据。
这个示例(需要CoffeesTableModel.java
)演示了将 JDBC 与 Swing API 集成的一般步骤:
- 实现
TableModel
接口 - 实现
RowSetListener
接口 - 布局 Swing 组件
- 为示例中的按钮添加监听器
实现 javax.swing.event.TableModel
TableModel
接口使得 Java Swing 应用程序能够管理JTable
对象中的数据。示例CoffeesTableModel.java
实现了这个接口。它指定了JTable
对象应该如何从RowSet
对象中检索数据并在表中显示。
注意:尽管此示例在 Swing 应用程序中显示了COFFEES
表的内容,但CoffeesTableModel
类应该适用于任何 SQL 表,只要它的数据可以用String
对象表示。(但是,用于向COFFEES
添加行的字段,这些字段在CoffeesFrame
类中指定,必须针对其他 SQL 表进行修改。)
在实现TableModel
接口的方法之前,CoffeeTableModel
类的构造函数初始化了为这些实现方法所需的各种成员变量,如下所示:
public CoffeesTableModel(CachedRowSet rowSetArg) throws SQLException { this.coffeesRowSet = rowSetArg; this.metadata = this.coffeesRowSet.getMetaData(); numcols = metadata.getColumnCount(); // Retrieve the number of rows. this.coffeesRowSet.beforeFirst(); this.numrows = 0; while (this.coffeesRowSet.next()) { this.numrows++; } this.coffeesRowSet.beforeFirst(); }
以下描述了在这个构造函数中初始化的成员变量:
CachedRowSet coffeesRowSet
:存储COFFEES
表的内容。
本示例使用RowSet
对象,特别是CachedRowSet
对象,而不是ResultSet
对象,有两个原因。CachedRowSet
对象使应用程序的用户能够对其中包含的数据进行更改,而无需连接到数据库。此外,因为CachedRowSet
对象是一个 JavaBeans 组件,它可以在发生某些事情时通知其他组件。在本示例中,当向CachedRowSet
对象添加新行时,它会通知渲染表中数据的 Swing 组件刷新自身并显示新行。ResultSetMetaData metadata
: 检索表COFFEES
中的列数以及每个列的名称。int numcols, numrows
: 分别存储表COFFEES
中的列数和行数。
CoffeesTableModel.java
示例实现了TableModel
接口中的以下方法:
Class getColumnClass(int columnIndex)
: 返回列中所有单元格值的最具体的超类。int getColumnCount()
: 返回模型中的列数。String getColumnName(int columnIndex)
: 返回由参数columnIndex
指定的列的名称。int getRowCount()
: 返回模型中的行数。Object getValueAt(int rowIndex, int columnIndex)
: 返回交叉点处的单元格的值,该单元格位于列columnIndex
和行rowIndex
的交叉点处。boolean isCellEditable(int rowIndex, int columnIndex)
: 如果列rowIndex
和行columnIndex
的交叉点处的单元格可以编辑,则返回 true。
以下方法未实现,因为此示例不允许用户直接编辑表的内容:
void addTableModelListener(TableModelListener l)
: 向列表中添加一个侦听器,每当数据模型发生更改时通知该侦听器。void removeTableModelListener(TableModelListener l)
: 从列表中移除一个侦听器,每当数据模型发生更改时通知该侦听器。void setValueAt(Object aValue, int rowIndex, int columnIndex)
: 将交叉点处的单元格中的值设置为对象aValue
,该单元格位于列columnIndex
和行rowIndex
的交叉点处。
实现 getColumnCount 和 getRowCount
getColumnCount
和getRowCount
方法分别返回成员变量numcols
和numrows
的值:
public int getColumnCount() { return numcols; } public int getRowCount() { return numrows; }
实现 getColumnClass
getColumnClass
方法返回指定列的数据类型。为了保持简单,此方法返回String
类,从而将表中的所有数据转换为String
对象。JTable
类使用此方法确定如何在 GUI 应用程序中呈现数据。
public Class getColumnClass(int column) { return String.class; }
实现 getColumnName
getColumnName
方法返回指定列的名称。JTable
类使用此方法为其每一列加上标签。
public String getColumnName(int column) { try { return this.metadata.getColumnLabel(column + 1); } catch (SQLException e) { return e.toString(); } }
实现 getColumnAt
getColumnAt
方法检索行集coffeesRowSet
中指定行和列的值。JTable
类使用此方法来填充其表格。请注意,SQL 从 1 开始对其行和列进行编号,但TableModel
接口从 0 开始;这就是为什么rowIndex
和columnIndex
的值要增加 1 的原因。
public Object getValueAt(int rowIndex, int columnIndex) { try { this.coffeesRowSet.absolute(rowIndex + 1); Object o = this.coffeesRowSet.getObject(columnIndex + 1); if (o == null) return null; else return o.toString(); } catch (SQLException e) { return e.toString(); } }
实现 isCellEditable
因为此示例不允许用户直接编辑表的内容(行是由另一个窗口控件添加的),所以无论rowIndex
和columnIndex
的值如何,此方法都返回false
:
public boolean isCellEditable(int rowIndex, int columnIndex) { return false; }
实现 javax.sql.RowSetListener
类CoffeesFrame
仅实现接口RowSetListener
中的一个方法rowChanged
。当用户向表中添加行时,将调用此方法。
public void rowChanged(RowSetEvent event) { CachedRowSet currentRowSet = this.myCoffeesTableModel.coffeesRowSet; try { currentRowSet.moveToCurrentRow(); myCoffeesTableModel = new CoffeesTableModel( myCoffeesTableModel.getCoffeesRowSet()); table.setModel(myCoffeesTableModel); } catch (SQLException ex) { JDBCTutorialUtilities.printSQLException(ex); // Display the error in a dialog box. JOptionPane.showMessageDialog( CoffeesFrame.this, new String[] { // Display a 2-line message ex.getClass().getName() + ": ", ex.getMessage() } ); } }
此方法更新 GUI 应用程序中的表格。
布置 Swing 组件
类CoffeesFrame
的构造函数初始化并布置 Swing 组件。以下语句检索COFFEES
表的内容,将内容存储在CachedRowSet
对象myCachedRowSet
中,并初始化JTable
Swing 组件:
CachedRowSet myCachedRowSet = getContentsOfCoffeesTable(); myCoffeesTableModel = new CoffeesTableModel(myCachedRowSet); myCoffeesTableModel.addEventHandlersToRowSet(this); // Displays the table table = new JTable(); table.setModel(myCoffeesTableModel);
如前所述,此示例使用RowSet
对象(特别是CachedRowSet
对象)而不是ResultSet
对象来表示COFFEES
表的内容。
方法CoffeesFrame.getContentsOfCoffeesTable
检索表COFFEES
的内容。
方法CoffeesTableModel.addEventHandlersToRowSet
将在CoffeesFrame
类中定义的事件处理程序添加到行集成员变量CoffeesTableModel.coffeesRowSet
中。这使得CoffeesFrame
类能够通知行集coffeesRowSet
任何事件,特别是当用户点击按钮Add row to table、Update database或Discard changes时。当行集coffeesRowSet
被通知到这些变化之一时,方法CoffeesFrame.rowChanged
被调用。
语句table.setModel(myCoffeesTableModel)
指定使用CoffeesTableModel
对象myCoffeesTableModel
来填充JTable
Swing 组件table
。
以下语句指定CoffeesFrame
类使用布局GridBagLayout
来布置其 Swing 组件:
Container contentPane = getContentPane(); contentPane.setComponentOrientation( ComponentOrientation.LEFT_TO_RIGHT); contentPane.setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints();
有关使用布局GridBagLayout
的更多信息,请参见如何使用 GridBagLayout 中的 JFC/Swing 创建 GUI。
查看CoffeesFrame.java
的源代码,了解如何将此示例的 Swing 组件添加到布局GridBagLayout
中。
为按钮添加监听器
以下语句向按钮Add row to table添加了一个监听器:
button_ADD_ROW.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog( CoffeesFrame.this, new String[] { "Adding the following row:", "Coffee name: [" + textField_COF_NAME.getText() + "]", "Supplier ID: [" + textField_SUP_ID.getText() + "]", "Price: [" + textField_PRICE.getText() + "]", "Sales: [" + textField_SALES.getText() + "]", "Total: [" + textField_TOTAL.getText() + "]" } ); try { myCoffeesTableModel.insertRow( textField_COF_NAME.getText(), Integer.parseInt(textField_SUP_ID.getText().trim()), Float.parseFloat(textField_PRICE.getText().trim()), Integer.parseInt(textField_SALES.getText().trim()), Integer.parseInt(textField_TOTAL.getText().trim()) ); } catch (SQLException sqle) { displaySQLExceptionDialog(sqle); } } });
当用户点击此按钮时,它执行以下操作:
- 创建一个消息对话框,显示要添加到表中的行。
- 调用方法
CoffeesTableModel.insertRow
,将行添加到成员变量CoffeesTableModel.coffeesRowSet
中。
如果抛出SQLException
,则方法CoffeesFrame.displaySQLExceptionDialog
将创建一个消息对话框,显示SQLException
的内容。
以下语句向按钮更新数据库添加了一个监听器:
button_UPDATE_DATABASE.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { try { myCoffeesTableModel.coffeesRowSet.acceptChanges(); msgline.setText("Updated database"); } catch (SQLException sqle) { displaySQLExceptionDialog(sqle); // Now revert back changes try { createNewTableModel(); msgline.setText("Discarded changes"); } catch (SQLException sqle2) { displaySQLExceptionDialog(sqle2); } } } } );
当用户点击此按钮时,将使用行集myCoffeesTableModel.coffeesRowSet
的内容更新表COFFEES
。
以下语句向按钮放弃更改添加了一个监听器:
button_DISCARD_CHANGES.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { createNewTableModel(); } catch (SQLException sqle) { displaySQLExceptionDialog(sqle); } } });
当用户点击此按钮时,将调用方法CoffeesFrame.createNewTableModel
,该方法重新填充JTable
组件,其中包含COFFEES
表的内容。
路线:Java 管理扩展(JMX)
Java 管理扩展(JMX) 路线介绍了包含在 Java 平台标准版(Java SE 平台)中的 JMX 技术,通过示例展示了如何使用 JMX 技术的最重要特性。
提供了 JMX 技术的简要描述,包括其目的和主要特点。
介绍了 JMX 技术的基本概念,管理 bean,又称为 MBeans。本课程还介绍了 MXBeans。
介绍了 JMX 技术的通知机制。
展示了如何实现 JMX API 的远程管理能力以及如何创建 JMX 客户端应用程序。
提供了指向更高级文档的指针,描述了 JMX 技术。
教训:JMX 技术概述
Java 管理扩展(JMX)技术是 Java 平台标准版(Java SE 平台)的标准部分。JMX 技术是在 Java 2 平台标准版(J2SE)5.0 发布中添加到平台中的。
JMX 技术提供了一种简单、标准的管理资源(如应用程序、设备和服务)的方式。由于 JMX 技术是动态的,您可以使用它来监视和管理资源的创建、安装和实施过程。您还可以使用 JMX 技术来监视和管理 Java 虚拟机(Java VM)。
JMX 规范为管理和监视应用程序和网络定义了 Java 编程语言中的架构、设计模式、API 和服务。
使用 JMX 技术,一个给定的资源由一个或多个称为托管 Bean或MBeans的 Java 对象仪器化。这些 MBeans 注册在一个核心管理对象服务器中,称为MBean 服务器。MBean 服务器充当管理代理,并可以在大多数已启用 Java 编程语言的设备上运行。
规范定义了您用于管理已正确配置的任何资源的 JMX 代理。JMX 代理由一个 MBean 服务器(其中注册了 MBeans)和一组用于处理 MBeans 的服务组成。通过这种方式,JMX 代理直接控制资源并使其可供远程管理应用程序使用。
资源的仪器化方式与管理基础设施完全独立。因此,资源可以被管理,而不管它们的管理应用是如何实现的。
JMX 技术定义了标准连接器(称为 JMX 连接器),使您可以从远程管理应用程序访问 JMX 代理。使用不同协议的 JMX 连接器提供相同的管理接口。因此,管理应用程序可以透明地管理资源,而不管使用的通信协议是什么。只要这些系统或应用程序支持 JMX 代理,JMX 代理也可以被不符合 JMX 规范的系统或应用程序使用。
为什么使用 JMX 技术?
JMX 技术为开发人员提供了一种灵活的手段来为基于 Java 技术的应用程序(Java 应用程序)提供仪器化,创建智能代理,实现分布式管理中间件和管理器,并将这些解决方案顺利集成到现有的管理和监控系统中。
- JMX 技术使得 Java 应用程序可以在不需要大量投资的情况下进行管理。
基于 JMX 技术的代理(JMX 代理)可以在大多数支持 Java 技术的设备上运行。因此,Java 应用程序可以在设计上几乎没有影响地变得可管理。一个 Java 应用程序只需要嵌入一个托管对象服务器,并将部分功能作为一个或多个托管 bean(MBeans)注册到对象服务器中。这就是从管理基础设施中受益所需的全部。 - JMX 技术提供了一种标准的方式来管理 Java 应用程序、系统和网络。
例如,Java 平台企业版(Java EE)5 应用服务器符合 JMX 架构,因此可以使用 JMX 技术进行管理。 - JMX 技术可用于对 Java 虚拟机进行开箱即用的管理。
Java 虚拟机(Java VM)使用 JMX 技术进行高度仪器化。您可以启动一个 JMX 代理来访问内置的 Java VM 仪器,从而远程监视和管理 Java VM。 - JMX 技术提供了一个可扩展的、动态的管理架构。
每个 JMX 代理服务都是一个独立的模块,可以根据需求插入到管理代理中。这种基于组件的方法意味着 JMX 解决方案可以从小型设备扩展到大型电信交换机等更大的设备。JMX 规范提供了一组核心代理服务。可以开发额外的服务,并在管理基础设施中动态加载、卸载或更新这些服务。 - JMX 技术利用了现有的标准 Java 技术。
在需要时,JMX 规范引用现有的 Java 规范,例如 Java 命名和目录接口(J.N.D.I.)API。 - 基于 JMX 技术的应用程序(JMX 应用程序)可以通过 NetBeans IDE 模块创建。
您可以从 NetBeans 更新中心获取一个模块(在 NetBeans 界面中选择工具 -> 更新中心),该模块使您可以使用 NetBeans IDE 创建 JMX 应用程序。这降低了 JMX 应用程序开发的成本。 - JMX 技术与现有的管理解决方案和新兴技术集成。
JMX API 是任何管理系统供应商都可以实现的开放接口。JMX 解决方案可以使用查找和发现服务以及诸如 Jini 网络技术和服务位置协议(SLP)等协议。
JMX 技术的架构
原文:
docs.oracle.com/javase/tutorial/jmx/overview/architecture.html
JMX 技术可以分为三个级别,如下:
- 仪器化
- JMX 代理
- 远程管理
仪器化
要使用 JMX 技术管理资源,必须首先使用 Java 编程语言对资源进行仪器化。您使用称为 MBeans 的 Java 对象来实现对资源仪器化的访问。MBeans 必须遵循 JMX 规范中定义的设计模式和接口。这样做可以确保所有 MBeans 以标准化的方式提供受管理资源的仪器化。除了标准 MBeans 外,JMX 规范还定义了一种特殊类型的 MBean,称为 MXBean。MXBean 是仅引用预定义数据类型的 MBean。还有其他类型的 MBean,但本文将集中讨论标准 MBeans 和 MXBeans。
一旦资源被 MBeans 仪器化,就可以通过 JMX 代理进行管理。MBeans 不需要了解它们将操作的 JMX 代理。
MBeans 被设计为灵活、简单且易于实现。应用程序、系统和网络的开发人员可以使其产品以标准方式可管理,而无需了解或投资于复杂的管理系统。现有资源可以通过最小的努力变得可管理。
此外,JMX 规范的仪器化级别提供了通知机制。该机制使 MBeans 能够生成和传播通知事件给其他级别的组件。
JMX 代理
基于 JMX 技术的代理(JMX 代理)是一个标准的管理代理,直接控制资源并使其可供远程管理应用程序使用。JMX 代理通常位于控制资源的同一台机器上,但这并不是必需的。
JMX 代理的核心组件是MBean 服务器,一个注册 MBeans 的受管理对象服务器。JMX 代理还包括一组服务来管理 MBeans,并至少一个通信适配器或连接器,以允许管理应用程序访问。
当您实现一个 JMX 代理时,不需要了解它将管理的资源的语义或功能。事实上,JMX 代理甚至不需要知道它将服务的资源,因为任何按照 JMX 规范进行仪器化的资源都可以使用任何提供资源所需服务的 JMX 代理。同样,JMX 代理也不需要知道将访问它的管理应用程序的功能。
远程管理
JMX 技术仪器化可以通过许多不同的方式访问,可以通过现有的管理协议,如简单网络管理协议(SNMP)或专有协议来访问。 MBean 服务器依赖于协议适配器和连接器,使得 JMX 代理可以从代理的 Java 虚拟机(Java VM)外部的管理应用程序访问。
每个适配器通过特定协议提供了在 MBean 服务器中注册的所有 MBeans 的视图。例如,HTML 适配器可以在浏览器中显示一个 MBean。
连接器提供了一个管理端接口,处理管理者和 JMX 代理之间的通信。每个连接器通过不同的协议提供相同的远程管理接口。当远程管理应用程序使用此接口时,它可以通过网络透明地连接到 JMX 代理,而不受协议的限制。 JMX 技术提供了一种标准解决方案,用于基于 Java 远程方法调用(Java RMI)将 JMX 技术仪器化导出到远程应用程序。
监控和管理 Java 虚拟机
JMX 技术也可以用于监控和管理 Java 虚拟机(Java VM)。
Java VM 具有内置的仪器,使您可以使用 JMX 技术监控和管理它。这些内置的管理实用程序通常被称为 Java VM 的开箱即用管理工具。为了监控和管理 Java VM 的不同方面,Java VM 包括一个平台 MBean 服务器和专门的 MXBeans,供符合 JMX 规范的管理应用程序使用。
平台 MXBeans 和平台 MBean 服务器
平台 MXBeans是 Java SE 平台提供的一组 MXBeans,用于监控和管理 Java VM 和 Java 运行时环境(JRE)的其他组件。每个平台 MXBean 封装了 Java VM 功能的一部分,例如类加载系统、即时(JIT)编译系统、垃圾收集器等。这些 MXBeans 可以通过符合 JMX 规范的监控和管理工具显示和交互,以便您监控和管理这些不同的 VM 功能。其中一种监控和管理工具是 Java SE 平台的 JConsole 图形用户界面(GUI)。
Java SE 平台提供了一个标准的平台 MBean 服务器,其中注册了这些平台 MXBeans。平台 MBean 服务器还可以注册您希望创建的任何其他 MBeans。
JConsole
Java SE 平台包括符合 JMX 规范的 JConsole 监控和管理工具。JConsole 使用 Java VM 的广泛仪器(平台 MXBeans)提供关于在 Java 平台上运行的应用程序的性能和资源消耗的信息。
开箱即用的管理实用程序在操作中
因为标准的实现 JMX 技术的监控和管理实用程序内置于 Java SE 平台中,您可以在不编写一行 JMX API 代码的情况下看到开箱即用的 JMX 技术在操作中。您可以通过启动 Java 应用程序,然后使用 JConsole 监控它来实现。
使用 JConsole 监控应用程序
本过程展示了如何监控记事本 Java 应用程序。在 Java SE 平台版本 6 之前的版本中,您需要使用以下选项启动要使用 JConsole 监控的应用程序。
-Dcom.sun.management.jmxremote
然而,Java SE 6 平台提供的 JConsole 版本可以连接到支持 Attach API 的任何本地应用程序。换句话说,任何在 Java SE 6 HotSpot VM 中启动的应用程序都会被 JConsole 自动检测到,不需要使用上述命令行选项启动。
- 启动记事本 Java 应用程序,使用以下命令在终端窗口中:
java -jar *jdk_home*/demo/jfc/Notepad/Notepad.jar
- 其中
jdk_home
是安装 Java 开发工具包(JDK)的目录。如果您没有运行 Java SE 平台的 6 版本,您将需要使用以下命令:
java -Dcom.sun.management.jmxremote -jar *jdk_home*/demo/jfc/Notepad/Notepad.jar
- 一旦 Notepad 打开,在另一个终端窗口中,使用以下命令启动 JConsole:
jconsole
- 会显示一个新的连接对话框。
- 在新连接对话框中,从本地进程列表中选择
Notepad.jar
,然后点击连接按钮。
JConsole 会打开并连接到Notepad.jar
进程。当 JConsole 打开时,您将看到与 Notepad 相关的监控和管理信息概览。例如,您可以查看应用程序消耗的堆内存量,应用程序当前运行的线程数,以及应用程序消耗的中央处理单元(CPU)容量。 - 点击不同的 JConsole 选项卡。
每个选项卡提供了关于 Notepad 运行的 Java 虚拟机不同功能区域的更详细信息。所有呈现的信息都是从本教程中提到的各种 JMX 技术 MXBeans 获取的。所有平台 MXBeans 都可以在 MBeans 选项卡中显示。MBeans 选项卡将在本教程的下一部分中进行讨论。 - 要关闭 JConsole,选择连接 -> 退出。
Java 中文官方教程 2022 版(三十七)(2)https://developer.aliyun.com/article/1488144