日期:2014-05-16 浏览次数:20565 次
不知道市场上有多少这方面的尝试?
这里不讨论是否是直接JDBC连接、操作数据库,还是借助于EJB等服务,我只想介绍客户端的一些设计的简单的设计方法。
一个典型的客户端的界面应该包括了树、表格、文本框、日期时间框、选择下拉框、工具栏等控件。那么一个界面中也可能包括了上述的所有控件,所以必须剥离出逻辑业务层,来提供数据的缓存,业务处理,更新同步数据库等。我们暂且命名为DataSet吧。
在该DataSet中应该包括如下功能。
1、Columns 列信息,例如我用sql 语句select * from students, 那么DataSet的columns就包括student表的所有列信息:
???? private class Column
???? {
??????? String colName = ""; //列名 如: student_name
??????? String colLabel; //列标签 如: 学生姓名
??????? int index = 0;//序号 0列, 1列等 1 2 3 ,4
??????? int size;? // 长度 这个主要是控制table的列宽。
??????? int dbType ;//对应数据库的字段类型、参见? java Types类
??????? 另外还包括列信息的精度,可输入的宽度,可见性visible, 是否可编辑性enabled,关联信息(例如你存储到数据库? 的值是01,02,这些,而显示给用户的是男、女,可用Lookup类来单独包装。),是否提交,前景色,背景色,是否可以为NULL等属性
???? }
??? 类Column包装了数据库表的列信息。那么student有多个列信息,所以DataSet必须提供一个Columns数组或集合来对应数据库。Column[] 或 用ArrayList list ,list.add( column);
2、Rows行信息,有了列的对应关系后,行对应就先得自然了,你可以把行包装成Row类,而一个Row里边应该记录了对于相同列的一个数组或集合。在把row放到数组和集合中,就形成了对于数据库的行记录了。
???? 或者简单点,DataSet的数据就直接用ArrayList来记录。而该ArrayList中放置的还是一个一个的ArrayList :
???? ArrayList rows = new ArrayList();
???? for(int i = 0; i < 10; i++)
???? {
?????? ArrayList row = new ArrayList();
?????? row.add("1");//主键
?????? row.add("张山")//姓名
?????? ................
?????? rows.add(row);
???? }
???? 行记录有了,但重要的一点是你必须有一个很行的对应的字段来记录行的状态。原始、插入、修改等。
3、基本操作。包括行的跳转,增加,删除,排序,过滤等,所有的这些操作都是对于ArrayLilst的操作*(或数组,估计数组的效率高些,但操作没有ArrayList那么好)。跳转容易处理,在DataSet添加一个变量记录DatSet现在在第几行就可以。增加呢只需要在rows里边再添加一个ArrayList即可,排序过滤无非就是对ArrayLis的数据集合德一个筛选,不过我觉得应该有一个过滤区和删除区。删除时将该行对象从正常的rows中移除,放到删除区中,过滤也是将不符合条件的行放到过滤区中。
5、getValueAt(row, col) 和 setValueAt(row, col)//DataSet必须提供界面需要的数据和供界面修改后暂存数据的方法。
5、保存修改的方法。(由DataSet来实现保存数据的方法)
6、通知界面刷新数据的方法。
?
?
有了上边的部分之后那么界面的东西就只是显示数据就可以了。为每一个需要显示数据的控件提供一个方法? setDataSet(DataSet set)//设定控件关联的DataSet?? setFieldName(name)//设定关联到DataSet的那一列。
1、对于JTextArea,JTextField等控件来说,只需要在需要刷新数据的时候用从DataSet。getCellValueAt()读取DataSet当前行对于列的值然后用setText就可以了。当然要监听键盘事件如果有改动要同步到 DataSet,然后又DataSet发送通知给所有关联的控件,表明该字段已被修改。
2、工具栏。包括上、下、最后、第一条记录,增加,删除,详细,排序,过滤,打印等按钮,这些按钮在会根据DataSet的状态来设定自己是否可以用。如,DataSet一行数据没有的时候删除按钮就不可用,那么这个和DataSet事件通知机制连在一起的,所有的控件都是接受DataSet发送的事件(包括刷新,停止编辑,删除(beforeDel ,afterDel两个事件)等等事件)完成自己的状态设定的。
3、table。table 的使用比较复杂,其实table本身已经实现了MVC结构,但是有了DataSet后,table本身的Model中不再存取数据,而是直接来自DataSet,即扩展AbstractTableModel作为Table的model。
???? getRowcount()返回DataSet的getRowCount
???? getColumnCount()返回DataSet的getColumnCountil()
???? getValueAt()--setValueAt都是有DataSet的方法来就可以了。
???? table也会根据DataSet来生成ColumnModel,那么这样Table的基本就架起来了。然后再根据dataset的列的类型(数值型,日期型,字符型等)来设定渲染器和编辑器。
所有与数据挂钩的控件在数据集中都会用一个数组来暂存,那么有一个控件做了修改的时候,dataset就会通知其他控件刷新。
4、树控件,树控件的节点信息一般不会只记录标签那么简单, 树的节点一般记录的该节点的标签和数据库对应的ID,例如我有一个现实部门的分级树,那么该树节点要记录部门ID,和部门名称,所以扩展树节点类:
??? public class DBTreeNode extends DefaultMutableTreeNode
??? {
????? ??? private Object nodeID;
? ? ?? ?? private Object otherInfo;。。。。。。。。。。。。可以扩展记录多个信息。
??? }
?
DataSet数据库保存问题:
有了行信息和列信息,很容易生成一条SQL语句,一般来说,你需要使用PreparedStatement而不要使用Statement来更新数据,因为Statement保存数据容易产生语法错误,
脏数据问题:由于每个客户端都有了一个数据缓冲的DataSet暂存数据,所以容易产生脏读和脏写。一般来说你保存数据的时候可以即时读取数据库对应的行数据状态,然后你可以使用全匹配的提交方式或只提交客户修改的数据的放来来尽量减少这方的数据错误。
?
下边是一个集成了树、表格、工具栏、输入控件的窗口
?
?
?
?
?
?
?