为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

疯狂java实例-第13章_MySQL管理器

2012-03-09 48页 doc 700KB 26阅读

用户头像

is_182672

暂无简介

举报
疯狂java实例-第13章_MySQL管理器第13章 MySQL管理器 ·222· Eclipse从入门到精通 ·48· 第13章 MySQL管理器 第13章MySQL管理器 当前IT行业流行的关系型数据库有Oracle、SQL Server、DB2和MySQL等。其中MySQL是一个小型的关系型数据库,开发者是瑞典的MySQL AB公司,于2008年6月1日被Sun公司收购。MySQL拥有体积小、速度快等优点,被广泛的应用在中小型企业的IT系统中,更重要的一点是,它是开源的。由于MySQL应用广泛,因此涌现出许多MySQL的客户端,例如MySQL Front、...
疯狂java实例-第13章_MySQL管理器
第13章 MySQL管理器 ·222· Eclipse从入门到精通 ·48· 第13章 MySQL管理器 第13章MySQL管理器 当前IT行业流行的关系型数据库有Oracle、SQL Server、DB2和MySQL等。其中MySQL是一个小型的关系型数据库,开发者是瑞典的MySQL AB公司,于2008年6月1日被Sun公司收购。MySQL拥有体积小、速度快等优点,被广泛的应用在中小型企业的IT系统中,更重要的一点是,它是开源的。由于MySQL应用广泛,因此涌现出许多MySQL的客户端,例如MySQL Front、Navicat与MySQL自带的MySQL Administrator等,这些都是我们平时在开发MySQL数据库应用时十分常用的MySQL图形管理工具。这些优秀的工具为我们提供了十分方便的功能去管理MySQL数据库,例如提供浏览数据的图形界面、操作数据的界面、操作各个数据库元素(表、视图、存储过程等)的界面,这些功能为我们带来了极大的方便,可以在一个完全图形化的界面进行数据库处理。使用这些工具,你可以不懂如何编写SQL语句,只需要通过操作图形界面,就可以达到操作数据库的目的。 在本章中,我们将自己开发一个简单的MySQL管理器。在开发的过程中,让大家了解前面所讲到的那些优秀工具的实现原理。在本章开头已经提到,这些管理工具,提供了各种的图形界面让我们去进行各种的操作,因此,开发一个MySQL管理器,除了需要编写一些操作数据库的SQL以外,还需要注意的是图形界面的处理。这些管理工具,实现的原理并无太大差别,但是哪个工具更能得到多数使用者的青睐,更多的就是取决于这些工具给用户带来的使用体验及方便性。 本章所开发的MySQL管理器是基于MySQL5.0开发的,因此如果要得到最佳的运行效果,请使用MySQL5.0。由于MySQL各个版本间都存在差别,例如笔者在开发这个管理器的时候,就遇到MySQL5.0与MySQL5.1之间的微小差别,这些差别对我们开发所产生的影响,将在下面的章节中详细介绍。 13.1 MySQL管理器原理 MySQL管理器,主要功能是让用户可以轻松进行各种的MySQL操作,包括连接管理、数据库管理、表管理、视图管理、存储过程和函数管理,这些功能点我们都可以使用JDBC实现,例如表管理中包括创建表、修改表等功能,我们可以使用JDBC直接执行SQL语句中的CREATE TABLE和ALTER TABLE来达到目的。除了这些功能外,还需要对数据库中的数据进行导出和导与的操作,进行这些操作,我们可以编写程序来实现,但是,更好办法就是使用MySQL的命令(mysql或者mysqldump)来解决,这样可以轻松解决数据的导出与导入,但是,前提就是使用的客户端必须安装MySQL数据库,并且要告诉我们这个管理器,MySQL的具体目录,我们可以使用程序去调用这些MySQL的命令。下面,我们就开始实现这些所定义的功能。 13.2 建立界面 在编写程序前,我们需要准备各个界面,包括连接管理界面、表管理界面、视图管理界面、存储过程(函数)管理界面与查看数据界面等。表管理、视图管理、存储过程和函数管理我们可以建立一个主界面,根据不同的情况显示不同的菜单,而连接管理我们可以使用一棵树来进行管理,可以同时存在多个连接,这些连接下面的子节点就是该连接下面的数据库。 13.2.1 MySQL安装目录选择界面 当进入管理器时,我们就需要让用户去选择MySQL的安装目录,原因就是因为我们需要MySQL的内置命令,因此需要指定MySQL的安装目录。图13.1是安装目录选择界面。 图13.1 MySQL安装目录选择界面 让用户选择MySQL安装目录十分简单,只提供一个目录选择安装以及显示目录路径的JTextFeild,并且加入一个确定与取消按钮。当用户选择了MySQL的安装目录,点击了确定时,就显示我们的主界面,这里需要注意的是,我们在实现的时候,需要判断用户所选择的MySQL[安装目录是否正确,由于mysql与mysqldump等命令是存在于MySQL安装目录下的bin目录的,因此判断用户所选择的目录是否正确,可以判断在bin目录下是否存在相应的命令,这些将在下面的章节中描述。MySQL安装目录在本章代码中对应的是ConfigFrame类。 13.2.2 主界面 主界面提供各种功能的入口,可以让用户在该界面中使用或者进入各个功能,除了需要提供这些入口外,还需要提供一棵树,更直观的展示当前所使用的连接,以及该连接下面所有的数据库。主界面如图13.2所示。 图13.2 主界面 主界面由一个工具栏,一棵树以及一个JList组成,其中工具栏中包括的操作如下: · 添加连接:可以让用户添加一个连接。 · 查看表:查看当前数据库中所有的表。 · 查看视图:查看当前数据库中所有的视图。 · 查看存储过程(函数):查看数据库中所有的存储过程与函数。 · 打开执行SQL的界面:打开一个执行SQL语句的界面。 在主界面的左边部分,提供一棵树让用户十分直观的看到连接的相关信息,这棵树可以隐藏根节点,第一层节点就是连接,第二层节点就是该连接下所对应的所有的数据库,每一个数据库节点下面可以有三个子节点:表、视图和存储过程,当然,我们在平时使用其他管理工具的时候,还可以有触发器等内容,我们在本章的项目中不提供这些功能。 这里需要注意的是,我们更换了树的各个节点图片,因此需要为JTree添加一个DefaultTreeCellRenderer来设置各个节点的图片以及文字,当然,还需要将各个节点抽象成不同的对象,新建各个视图对象的接口ViewObject,该接口将是所有视图对象的父类,这些视图对象包括树的各个节点,主界面右边列表所显示的各个元素等。 代码:code\mysql-manager\src\org\crazyit\mysql\object\ViewObject.java public interface ViewObject { //返回显示的图片 Icon getIcon(); } 该接口只有一个getIcon方法,返回一个Icon对象,表示这些界面所对应的图片,另外,树上的各个节点对象,可以有两种形式,第一种就是需要带连接的节点,例如数据库连接节点和数据库节点,第二种就是不需要带有连接的节点,因此我们可以将带有连接的节点抽象成一个父类,让连接节点和数据库节点去继承。另外,还需要提供一个connect的抽象方法,需要让子类去实现。 代码清单:code\mysql-manager\src\org\crazyit\mysql\object\tree\ConnectionNode.java public abstract class ConnectionNode implements ViewObject { //JDBC的Connection对象 protected Connection connection; //连接方法,由子类去实现 public abstract Connection connect(); //省略setter和getter方法 } 代码清单:code\mysql-manager\src\org\crazyit\mysql\object\tree\ServerConnection.java public class ServerConnection extends ConnectionNode { private final static String DRIVER = "com.mysql.jdbc.Driver";//MySQL驱动 private String connectionName; //MySQL驱动 private String username; //用户名 private String password; //密码 private String host; //连接ip private String port; //连接端口 //省略setter和getter方法 //实现接口ViewObject的方法, 根据不同的连接状态显示不同的图片 public Icon getIcon() { if (super.connection == null) return ImageUtil.CONNECTION_CLOSE; else return ImageUtil.CONNECTION_OPEN; } //重写toString方法, 返回连接名称 public String toString() { return this.connectionName; } //实现父类的connect方法 public Connection connect() { } } 一个ServerConnection对象表示一个连接节点,一个连接节点当然需要包括一些连接的相关信息,包括连接名称、MySQL用户名、密码、连接的IP与端口等信息。该对象实现了ViewObject的getIcon方法,判断父类ConnectionNode的connection属性是否为空来显示不同的图片,还需要重写toString方法,返回连接的名称。 代码清单:code\mysql-manager\src\org\crazyit\mysql\object\tree\Database.java public class Database extends ConnectionNode { private String databaseName; //数据库名字 private ServerConnection serverConnection; //数据库所属的服务器连接 //需要使用数据库名称与服务器连接对象构造 public Database(String databaseName, ServerConnection serverConnection) { this.databaseName = databaseName; this.serverConnection = serverConnection; } //实现接口的方法, 判断该数据库是否连接, 再返回不同的图片 public Icon getIcon() { if (this.connection == null) return ImageUtil.DATABASE_CLOSE; return ImageUtil.DATABASE_OPEN; } //重写toString方法 public String toString() { return this.databaseName; } //实现父类的connect方法 public Connection connect() { } } Database节点对象包括数据库的名字,另外还需要一个ServerConnection对象,由于每个数据库都是某个连接节点下面的子节点,因此需要记录它的父节点,当然,并不是简单的进行记录,还可以让它们共享一些不会经常创建的实例,例如Connection。另外,需要注意的是,无论ServerConnection或者Database对象,都需要实现ViewObject的getIcon方法,当连接节点或者数据库节点被打开时,都需要改变它们的图片,而显示何种图片,由getIcon方法决定。 代码清单:code\mysql-manager\src\org\crazyit\mysql\object\tree\TableNode.java public class TableNode implements ViewObject { private Database database; //所属的数据库节点 //返回表的树节点图片 public Icon getIcon() { return ImageUtil.TABLE_TREE_ICON; } //重写toString方法 public String toString() { return "表"; } } 一个TableNode对象代表一个表的节点,需要提供一个Database属性来表示这个对象是属于哪个数据库下面的子节点。如图13.2所示,我们可以看树中每个数据库节点的表节点都是一致的(每个数据库里面都有表),可以将这个表节点理解成是导航栏的某一组成部分,当用户点击了这个节点后,就可以在右边的列表中显示对应数据库的表。 与TableNode一样,另外再次创建两个对象:ViewNode和ProcedureNode,分别代表数据库节点下面的视图节点和存储过程节点,实现方法与TableNode类似。下面为树节点添加一个DefaultTreeCellRenderer类,让其得到这些节点对象,并设置相应的文字和图片。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\tree\TreeCellRenderer.java public class TreeCellRenderer extends DefaultTreeCellRenderer { public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; //获得每个节点的ViewObject ViewObject obj = (ViewObject)node.getUserObject(); if (obj == null) return this; this.setText(obj.toString());//设置文字 this.setIcon(obj.getIcon());//设置图片 if (sel) this.setForeground(Color.blue); //判断是否选来设置字体颜色 else this.setForeground(getTextNonSelectionColor()); return this; } } 在节点处理类TreeCellRenderer类,得到每个节点的ViewObject后,就可以为节点设置文字和图片,我们的ViewObject接口提供了getIcon方法,所以我们就可以在节点处理类中得到每个节点所对应的图片与文字(从toString方法获得)。 树的相关处理就完成了,主界面的右边是一个列表,对应的是一个JList对象,JList里面的每一个元素,都是ViewObject的实现类,只需要实现getIcon方法与重写toString方法即可。每个列表的元素对象都可以将它们的name属性抽象到一个父类中,各个对象去继承它即可,在本例中,我们所涉及有三种数据类型:表、视图和存储过程(函数),我们需要建立三个对象,分别代表这三种数据类型。 在本章的代码中,我们创建了TableData、ViewData和ProcedureData三个类分别代表表数据、视图数据和存储过程数据,这三个对象都需要实现ViewObject接口,具体的实现与三个节点的实现类似,都需要实现getIcon方法并重写toString。表、视图和存储过程都是某一个数据库下面的元素,因此这三个数据对象都需要保存一个Database属性,表示该数据所属于的数据库。与树一样,还需要提供一个元素处理类,来指定显示的数据图片。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\list\ListCellRenderer.java public class ListCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); ViewObject vd = (ViewObject)value; //得到ViewObject对象 label.setIcon(vd.getIcon());//设置图片 label.setToolTipText(vd.toString()); //设置选中时的字体颜色 if (isSelected) { setBackground(Color.blue); setForeground(Color.white); } return this; } } 到这里,主界面的各个对象都创建好了,本章中对应的主界面对象是MainFrame类,可以在该类中创建对应的树与列表。这里需要注意的是,当创建列表(JList)的时候,可以将JList设置为横向滚动,调用以下代码即可实现: dataList.setLayoutOrientation(JList.VERTICAL_WRAP); //dataList是界面中的JList对象 创建主界面后,我们可以在创建树与创建列表的时候加入一些模拟数据来查看效果,具体的效果如图13.3所示: 图13.3 主界面效果 13.2.3 数据显示界面 在整个管理器中,我们需要一个数据显示的界面,而且只有一个。打开数据显示界面的途径有两种,一种是双击一个表查看数据的时候,另外一种就是执行SQL的时候(执行查询的SQL),就会打开数据显示界面,将用户感兴趣的数据显示出来。由于一般会存在打开多个表或者多次执行SQL的情况,因此我们在编写打开数据显示界面的代码的时候,每次都需要去创建这个界面对象的实例。在本章中,界面显示对象对应的类是DataFrame,数据显示界面如图13.4所示。 图13.4 数据显示界面 界面比较简单,一个工具条加一个表格即可,工具条中包括的功能有: · 刷新:刷新当前界面的数据。 · 降序:当用户选择了某一列并点击该图标的时候,就对该列所对应的字段进行降序排序。 · 升序:操作与降序一样,但是对所选字段进行升序排序。 在这个界面中,需要注意的是,这个列表对应的JTable对象并不像其他JTable一样,拥有固定的列,由于我们不可能知道用户将要打开的表有多少列,因此只能在用户打开表的时候,得到该表的信息再动态的生成列与数据。除了这里之外,我们还需要为这个JTable对象进行一些额外的处理,例如我们需要让这个JTable对象可以整列选择,就需要自己编写一个类去继承JTable。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\table\DataTable.java //当点击表头时, 表示当前所选择的列 private int selectColumn = -1; public DataTable(DefaultTableModel model) { //为表头添加鼠标事件监听器 header.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { header.getTable().clearSelection(); int tableColumn = header.columnAtPoint(e.getPoint()); selectColumn = tableColumn; } }); //为JTable添加鼠标监听器 this.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { selectColumn = -1; updateUI(); } }); } 注意以上代码中的类属性selectColumn,当我们用鼠标点击了表头的时候,就将该值设为当前选择的列的索引,当在JTable的其他地方点击了鼠标时,就设置该值为-1,表示没有选择表头。那么我们就需要重写JTable的isCellSelected方法,如果selectColumn不是-1,那么就需要将用户所选择的列整列设为选中状态,以下是isCellSelected方法的实现: //判断一个单元格是否被选中, 重写JTable的方法 public boolean isCellSelected(int row, int column) { if (this.selectColumn == column) return true; //如果列数与当前选择的列相同,返回true return super.isCellSelected(row, column); } 另外,我们还需要提供一个返回selecColumn值的public的方法。做完这些后,可以点击一列,看到效果如图13.5所示。 图13.5 数据显示界面选择整列 13.2.4 创建连接界面 连接是整个工具的最基础部分,没有连接,其他任何操作都不能进行,因此使用这个MySQL管理工具,就需要提供一个新增连接的界面,让用户去创建各个连接,界面如图13.6所示。 图13.6 新建连接界面 图13.6中新建连接的界面比较简单,普通的一个表单,界面中包括的元素如下: · 连接名称:该名称在管理器的树中显示,并且该名称不可以重复。 · 连接IP:需要连接到的MySQL服务器IP。 · 端口:MySQL的端口,默认为3306。 · 用户名:连接MySQL的用户名,例如root。 · 密码:连接MySQL的密码。 · 测试连接:测试输入的信息是否可以连接到MySQL服务器中,当然,如果测试不能连接,也可以添加这个连接。 · 确定和取消:点击确定添加连接并关闭该窗口,点击取消不保存连接并关闭窗口。 13.2.5 创建表界面 当用户需要创建一个表的时候,就需要提供一个界面让用户去输入表的各种数据,包括字段名称、类型、是否允许空和主键等信息。创建表界面是本章中最为复杂的界面,用户可以随意的在表中进行操作,最后执行保存,表界面如图13.7所示。 图13.7 创建表界面 界面如图13.7所示,该界面较为复杂,分成上下两个表格,上面的表格主要处理表的字段信息,包括字段名、类型、是否允许空和主键,在该表格下面,有一个输入默认值的文本框,并提供一个表示字段是否自动增长的多选框。当我们在表格中选中某行数据(字段)的时候,默认值就需要发生相应的改变,自动增长的多选框也要随着改变。在本章中表界面对应的是TableFrame类。 字段表格需要进行特别处理的是允许空和主键的单元格,这两个单元格都需要使用图片来显示。我们编写一个FieldTable类来表示字段表格,并为这个FieldTable提供一个DefaultTableCellRenderer的子类来对单元格进行处理。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\table\FieldTableIconCellRenderer.java public class FieldTableIconCellRenderer extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { //判断单元格的值类型,分别调用setIcon与setText方法 if (value instanceof Icon) this.setIcon((Icon)value); else this.setText((String)value); this.setHorizontalAlignment(CENTER); return this; } } FieldTableIconCellRenderer的实现十分简单,只是判断单格的值再进行处理。在FieldTable使用以下代码即可实现显示图片。 this.getColumn(ALLOW_NULL).setCellRenderer(this.cellRenderer); this.getColumn(PRIMARY_KEY).setCellRenderer(this.cellRenderer); 以上代码先得到允许空和主键的列后再设置单元格处理类。重新运行程序时,就可以看到效果如图13.7所示,但是否需要对FieldTable加入鼠标事件处理,当点击了允许空和主键的列单元格时,就需要改变它们图片。为FieldTable加入鼠标监听器。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\table\FieldTable.java //鼠标在JTable中点击的时候触发该方法 private void selectCell() { int column = this.getSelectedColumn(); int row = this.getSelectedRow(); if (column == -1 || row == -1) return; //修改图片列 selectAllowNullColumn(row, column); selectPrimaryKeyColumn(row, column); } //点击的单元格位于允许空列 private void selectAllowNullColumn(int row, int column) { //得到需要更改图片的列(允许空列) TableColumn tc = this.getColumn(ALLOW_NULL); if (tc.getModelIndex() == column) { Icon currentIcon = (Icon)this.getValueAt(row, column); //根据当前选中的图片来更改允许空的图片 if (ImageUtil.CHECKED_ICON.equals(currentIcon)) { this.setValueAt(ImageUtil.UN_CHECKED_ICON, row, column); } else { this.setValueAt(ImageUtil.CHECKED_ICON, row, column); } } } //如果鼠标点击的列是"主键列",去掉或者加上图标 private void selectPrimaryKeyColumn(int row, int column) { //得到需要更改图片的列(主键列) TableColumn tc = this.getColumn(PRIMARY_KEY); if (tc.getModelIndex() == column) { Object obj = this.getValueAt(row, column); if (ImageUtil.PRIMARY_KEY_BLANK.equals(obj)) { this.setValueAt(ImageUtil.PRIMARY_KEY, row, column); } else { this.setValueAt(ImageUtil.PRIMARY_KEY_BLANK, row, column); } } } 只需要在创建FieldTableIconCellRenderer的时候为表格加入鼠标监听器,该监听器调用以上代码的selectCell方法即可,selectCell方法再去调用点击允许空和主键单元格的方法,即以上的selectAllowNullColumn和selectPrimaryKeyColumn方法,这两个方法中判断用户所选择的列,是否为需要进行图片处理的列(允许空和主键),再对单元格的值(图片)进行修改,就可以达到点击单元格就显示不同图片的效果。另外,当我们点击了某行数据(字段)的时候,还需要处理默认值与自动增长,我们在下面章节将会实现。 实现了字段列表后,还需要注意的是该列表下面的三个按钮,分别是新字段、插入字段和删除字段,新字段与插入字段的区别是,新字段在列表的最后加入一行数据,插入字段在用户所选择的行的前面插入一行数据。 TableFrame下面的外键列表与字段列表不同的是,外键列表不需要进行图片处理,但是每个单元格都需要使用下拉框来代替普通的文字。与字段列表一样,新建一个ForeignTable的类来表示一个外键列表,外键列表有5列,而且每一列中的每个单元格都是下拉框,因此我们需要在ForeignTable中创建5个下拉框(JComboBox)以及5个单元格编辑器对象。 5个单元格编辑器对象,以下是ForeignTable的实现。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\table\ForeignTable.java private DefaultCellEditor fieldNameEditor; //字段名称编辑器对象 private DefaultCellEditor referenceTableEditor; //约束表 private DefaultCellEditor referenceFieldEditor; //约束字段 private DefaultCellEditor onDeleteEditor; //级联删除 private DefaultCellEditor onUpdateEditor; //级联更新 那么在创建这些单元格编辑器对象的时候,就分别以各个下拉框的对象作为构造参数: this.fieldNameEditor = new DefaultCellEditor(this.fieldNameComboBox); 接下来,得到相应的列,再设置编辑器对象即可: this.getColumn(FIELD_NAME).setCellEditor(this.fieldNameEditor); 做完这些工作后,外键列表中所有的单元格都变成可以使下拉来设定值,我们在开发界面的时候,由于缺乏真实的数据,因此我们可以提供一些模拟的数据来实现效果,到需要实现的时候,就可以替换上真实的数据。新增表与修改表的界面可以共用一个界面,但是同时需要做新增与修改操作的时候,就需要做多一些额外的判断,本章中新增表与修改表为同一个界面(TableFrame)。 13.2.6 视图界面 当用户需要编写一个视图的时候,我们可以提供一个视图界面。视图界面实现十分简单,只有一个JTextArea即可,并附带有保存操作。这里需要注意的是,用户点击保存的时候,需要将视图通过SQL的CREATE VIEW来创建,那么用户查看视图的时候,与查看表一样,都是需要打开数据浏览界面。图13.8是视图界面。 图13.8 视图界面 在本章中,创建表的界面一样,无论新增视图或者修改视图,都使用相同的一个界面,对应的是ViewFrame。 13.2.7 存储过程界面 用户需要新建一个存储过程或者函数的时候,可以提供一个新建存储过程界面让用户去操作。存储界面在本章中对应的类是ProcedureFrame。存储过程界面如图13.9所示。 图13.9 存储过程界面 界面元素说明: · 输入方法体的JTextArea:用户可以在此输入存储过程或者函数的方法体。 · 参数JTextField:输入存储过程或者函数的参数。 · 返回值JTextField:可以输入函数的返回值,因为函数才有返回值。如果选择的类型为存储过程,则该JTextField不可用。 · 类型下拉框:可以选择编写的类型,是存储过程还是函数。 13.2.8 查询界面 当用户需要执行一些SQL的时候,可以提供一个查询界面让用户去输入,该界面提供执行SQL与保存SQL的功能,执行SQL的时候,如果是普通的INSERT、UPDATE或者其他无需浏览数据的SQL语句,则可以直接操作。如果执行的是查询、调用存储过程或者函数的语句,那么就需要将结果显示到数据界面,即13.2.3的界面。本章对应的查询界面类是QueryFrame,查询界面如图13.10所示。 图13.10 查询界面 13.2.9 树节点右键菜单 在主界面的连接树中,当我们点击了树的某个节点的时候,可以提供一些右键菜单来执行一些相关的操作,例如点击了连接节点,就可以提供关闭连接、删除连接等右键菜单,如果点击了数据库节点,就可以提供关闭数据库或者删除数据库等右键菜单。 点击连接节点的右键菜单如图13.11所示。 图13.11 连接节点菜单 点击数据库节点的右键菜单如图13.12所示。 图13.12 数据库节点右键菜单 由于我们对连接节点或者数据库节点进行选择的时候,就可以打开连接或者数据库,因此并不需要提供打开的菜单,本章中使用JPopupMenu来实现鼠标右键菜单,MainFrame中提供一个JPopupMenu对象来存放各个菜单当点击了连接节点的时候JPopupMenu删除所有的子菜单,再加入连接节点的菜单(JMenuItem),数据库节点的实现方式与之相同。 13.2.10 数据列表右键菜单 主界面中除了连接树外,还有一个数据列表,当用户在树中点击了表节点、视图节点或者存储过程节点的时候,数据列表中就显示不同的数据,我们可以根据当前所显示的数据来创建不同的鼠标右键菜单。图13.13是数据列表显示表数据的时候的右键菜单。 图13.13 表数据菜单 表数据鼠标右键菜单说明: · 新建表:打开创建表的界面,即13.2.5中的界面。 · 编辑表:修改一个表,与新建表使用同一个界面。 · 删除表:删除列表中选择数据。 · 导出表:将一个表的数据导出。 视图数据的鼠标右键菜单如图13.14所示。 图13.14 视图数据菜单 视图数据鼠标右键菜单说明: · 新建视图:打开13.2.6中的视图界面,用于创建视图。 · 编辑视图:修改所选择的视图,与新建视图使用同一个界面。 · 删除视图:删除所选择的视图。 存储过程鼠标右键菜单如图13.15所示。 图13.15 存储过程数据菜单 存储过程鼠标右键菜单说明: · 新建存储过程:打开13.2.7中的存储过程界面,创建存储过程。 · 编辑存储过程:修改选择的存储过程,与新建存储过程使用相同的界面。 · 删除存储过程:删除所选择的存储过程或者函数。 以上为三种数据的右键菜单,实现方式与树节点的右键菜单一样,当界面的数据发生改变时,就相应的去删除JPopupMenu所有的子菜单,再添加相应的菜单(JMenuItem)即可。 以上的菜单均在主界面(MainFrame)中创建,程序并不知道当前显示的是哪种数据,因此我们需要在MainFrame中提供一个ViewObject的类来当前显示的类型,ViewObject是所有界面元素都需要实现的接口,表数据是TableData类,视图数据是ViewData类,存储过程数据是ProcedureData类,详细请看13.2.2中的各个界面对象。当用户点击了工具栏或者树上的某个节点时,就相应的改变MainFrame中的ViewObject即可。 到此,管理器的所有界面都创建完毕,接下来就可以实现相关的功能。 13.3 实现MySQL安装目录选择功能 实现MySQL安装目录选择功能,我们使用13.2.1的界面。当用户进入管理器的时候,就让用户选择本地的MySQL安装目录,由于我们需要使用MySQL的一些内置命令,因此选择MySQL的安装目录是一个必要的操作,得到MySQL安装目录后,我们就可以找到bin目录下面的命令。因此用户选择了安装目录后,我们的程序就需要对所选择目录进行验证,判断能否找到bin目录。 13.3.1 实现目录选择 选择目录实现十分简单,只需要提供一个文件选择器即可,而且这个文件选择器只可以选择目录,当用户选择了对应的目录后,就可以将其选择的目录显示到13.2.1界面的JTextField中。文件选择器的代码如下。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\ConfigFrame.java private JTextField field; public FileChooser(JTextField field) { this.field = field; //设置只可以选择目录 this.setFileSelectionMode(FileChooser.DIRECTORIES_ONLY); } //重写JFileChooser的方法 public void approveSelection() { //设置JTextField的值 this.field.setText(this.getSelectedFile().getAbsolutePath()); super.approveSelection(); } 用户选择目录后,就将其所选的目录的绝对路径显示到JTextField中,当点击确定的时候,就可以进行判断,以下代码为点击确定所执行的代码。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\ConfigFrame.java //取得用户输入值 String mysqlHome = this.mysqlHomeField.getText(); //寻找用户选择的目录,判断是否可以找到MySQL安装目录下的bin目录 File file = new File(mysqlHome + MySQLUtil.MYSQL_HOME_BIN); //找不到MySQL的安装目录,提示 if (!file.exists()) { showMessage("请选择正确MySQL安装目录", "错误"); return; } 以上代码的黑体部分,需要去判断MySQL安装目录下的bin目录是否存在,如果没有存该目录,则表示用户所选择的目录是错误的,弹出提示并返回。如果用户选择的目录是正确的话,就需要去读取管理器的配置文件。 13.3.2 读取和保存安装目录路径 用户选择了MySQL的安装目录后,我们需要将目录的绝对路径保存到一份配置文件中,这样做的话,就可以不必每一次都去进行目录选择。提供一份mysql.properties的配置文件,以下为该配置文件的读取代码。 代码清单:code\mysql-manager\src\org\crazyit\mysql\util\FileUtil.java //返回配置文件的MYSQL_HOME配置 public static String getMySQLHome() { File configFile = new File(MYSQL_PROPERTIES_FILE); Properties props = getProperties(configFile); return props.getProperty(MYSQL_HOME); } 以上代码中的MYSQL_PROPERTIES_FILE就是mysql.properties配置文件的相对路径,找到该文件后,就读取它的mysql.home属性。那么用户在进入MySQL安装目录选择界面的时候,就可以调用以上的方法去获得MySQL安装目录的值。 接下来实现保存安装目录的功能,在这之前,新建一个GlobalContext的类,用于保存管理器全局的一些信息,例如这里的mysql.home属性。以下代码实现保存配置的功能。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\ConfigFrame.java //省略其他代码... //如果配置文件的值与用户输入的值不相等,则重新写入配置文件中 if (!mysqlHome.equals(FileUtil.getMySQLHome())) { FileUtil.saveMysqlHome(this.mysqlHomeField.getText()); } GlobalContext ctx = new GlobalContext(mysqlHome); this.mainFrame = new MainFrame(ctx); this.mainFrame.setVisible(true); this.setVisible(false); 注意以上代码的判断,如果用户前一次所选择的MySQL安装目录与这一次所选择的目录不一致,则需要重新将新的目录信息保存到mysql.properties文件中。这些做的话,就不需要每一次进入系统都去修改配置文件。 13.3.3 读取连接信息 在得到MySQL安装目录,进入主界面时,还需要得到用户所有的连接信息,这些信息用来初始化主界面左边的树,管理器是针对MySQL数据库的,但是这些连接信息可以不记录到数据库,与保存MySQL安装目录一样,可以提供一些properties文件来保存,每一个连接作为一份properties文件。保存连接的信息我们在下面的章节中实现,这里主要实现读取的实现。 新建一个PropertiesHandler的接口,专门用于处理连接属性文件。该接口提供一个读取数据库连接配置文件的方法,并返回ServerConnection集合,ServerConnection代表一个连接节点,并保存有一些数据库连接的信息,详细请看13.2.2中的ServerConnection类。以下代码读取一份properties,并返回一个Properties对象。 代码清单:code\mysql-manager\src\org\crazyit\mysql\util\FileUtil.java //根据文件得到对应的properties文件 public static Properties getProperties(File propertyFile) throws IOException { Properties prop = new Properties(); FileInputStream fis = new FileInputStream(propertyFile); prop.load(fis); fis.close(); return prop; } 那么在PropertiesHandler实现类中,就可以读取相应目录下的所有properties文件。 代码清单:code\mysql-manager\src\org\crazyit\mysql\system\PropertiesHandlerImpl.java //得到所有的连接信息 public List getServerConnections() { File[] propertyFiles = getPropertyFiles(); List result = new ArrayList(); for (File file : propertyFiles) { ServerConnection conn = createServerConnection(file); result.add(conn); } return result; } //将一份properties文件封装成ServerConnection对象 private ServerConnection createServerConnection(File file) { Properties prop = FileUtil.getProperties(file); ServerConnection conn = new ServerConnection(FileUtil.getFileName(file), prop.getProperty(FileUtil.USERNAME), prop.getProperty(FileUtil.PASSWORD), prop.getProperty(FileUtil.HOST), prop.getProperty(FileUtil.PORT)); return conn; } 得到所有的连接信息后,先不需要初始化树,需要将这些信息存放到一个对象中,因为在下面的实现中,这些类或者连接信息需要经常使用到。在13.3.2中提供了一个GlobalContext的类来表示管理器的上下文,可以将这些连接信息放到该类中。 代码清单:code\mysql-manager\src\org\crazyit\mysql\object\GlobalContext.java //存放所有服务器连接的集合 private Map connections = new HashMap(); //添加一个连接到Map中 public void addConnection(ServerConnection connection) { this.connections.put(connection.getConnectionName(), connection); } 在GlobalContext中建立一个Map来保存这些连接信息,并提供add方法,由于这个Map是使用连接的名称作为key的,所以就决定了在管理器中不允许出现重名的连接。那么在用户选择MySQL安装目录,点击确定后,就可以将连接加入到GlobalContext中,用户点击确定按钮执行的部分代码。 代码清单:code\mysql-manager\src\org\crazyit\mysql\ui\ConfigFrame.java //读取全部的服务器连接配置 L
/
本文档为【疯狂java实例-第13章_MySQL管理器】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索