在JAVA实现DataTable对象
由于习惯了.net环境下的DataTable对象的方便和强大,遗憾的是JAVA下没有如此强大的对象支持。在网上找了好久都没有发现自己满意且能满足当前应用需求的实现,于是决定自己实现一套。我现在需要用JAVA实现对几类数据表的动态查询、汇总、计算,具体的需求如下:
大家都是行家,我就直接上代码了,我这个代码应该还是能看懂的,嘻嘻….
1: public class DataColumn {
2: private boolean readOnly; // 只读
3:
4: private DataTable table; //dataTable的引用
5:
6: private String columnName; //列名
7:
8: private String captionName; //显示名称
9:
10: private int columnIndex;//列索引
11:
12: private int dataType;//列数据类型
13:
14: private String dataTypeName;//数据类型名称
15:
16: public DataColumn() {
17: this("default1");
18: }
19:
20: public DataColumn(int dataType) {
21: this("default1", dataType);
22: }
23:
24: public DataColumn(String columnName) {
25: this(columnName, 0);
26: }
27:
28: public DataColumn(String columnName, int dataType) {
29: this.setDataType(dataType);
30: this.columnName = columnName;
31: }
32:
33: public String getColumnName() {
34: return this.columnName;
35: }
36:
37: public void setColumnName(String columnName) {
38: this.columnName = columnName;
39: }
40:
41: public String getCaptionName() {
42: return captionName;
43: }
44:
45: public void setCaptionName(String captionName) {
46: this.captionName = captionName;
47: }
48:
49: public boolean isReadOnly() {
50: return this.readOnly;
51: }
52:
53: public void setReadOnly(boolean readOnly) {
54: this.readOnly = readOnly;
55: }
56:
57: public DataTable getTable() {
58: return this.table;
59: }
60:
61: public void setTable(DataTable table) {
62: this.table = table;
63: }
64:
65: /**
66: * @param dataType
67: */
68: public void setDataType(int dataType) {
69: this.dataType = dataType;
70: }
71:
72: /**
73: * @return the dataType
74: */
75: public int getDataType() {
76: return dataType;
77: }
78:
79: /**
80: * @param columnIndex
81: */
82: public void setColumnIndex(int columnIndex) {
83: this.columnIndex = columnIndex;
84: }
85:
86: /**
87: * @return the columnIndex
88: */
89: public int getColumnIndex() {
90: return columnIndex;
91: }
92:
93: public String getDataTypeName() {
94: return DataTypes.getDataTypeName(dataType);
95: }
96:
97: /**
98: * 功能描述: 将输入数据转为当前列的数据类型返回
99: * @param
103: */
104: public Object convertTo(Object value) {
105: return value;
106: }
107:
108: @Override
109: public String toString(){
110: return this.columnName;
111: }
112: }
1: import java.util.LinkedHashMap;
2: import java.util.Map;
3:
4: public class DataRow {
5: //定义该行记录在table所处的行数
6: private int rowIndex = -1;
7: private DataColumnCollection columns;
8: //table的一个引用
9: private DataTable table;
10: //用于存储数据的Map对象,这里保存的对象不包括顺序信息,数据获取的索引通过行信息标识
11: private MapitemMap = new LinkedHashMap ();
12:
13: public DataRow() {
14:
15: }
16:
17: public DataRow(DataTable table) {
18: this.table = table;
19: }
20:
21: /**
22: * 功能描述: 获取当前行的行索引
23: * @param
24: * @return: int
25: */
26: public int getRowIndex() {
27: return rowIndex;
28: }
29:
30: /**
31: * 功能描述: 获取当前行所属数据表对象
32: * @param
33: * @return: DataTable
34: */
35: public DataTable getTable() {
36: return this.table;
37: }
38:
39: /**
40: * @param columns
41: */
42: public void setColumns(DataColumnCollection columns) {
43: this.columns = columns;
44: }
45:
46: /**
47: * @return the columns
48: */
49: public DataColumnCollection getColumns() {
50: return columns;
51: }
52:
53: public void setValue(int index,
54: Object value) {
55: setValue(this.columns.get(index), value);
56: }
57:
58: public void setValue(String columnName,
59: Object value) {
60: setValue(this.columns.get(columnName), value);
61: }
62:
63: public void setValue(DataColumn column,
64: Object value) {
65: if (column != null) {
66: String lowerColumnName = column.getColumnName().toLowerCase();
67: if (getItemMap().containsKey(lowerColumnName))
68: getItemMap().remove(lowerColumnName);
69: getItemMap().put(lowerColumnName, column.convertTo(value));
70: }
71: }
72:
73: public Object getValue(int index) {
74: String colName = this.columns.get(index).getColumnName().toLowerCase();
75: return this.getItemMap().get(colName);
76: }
77:
78: public Object getValue(String columnName) {
79: return this.getItemMap().get(columnName.toLowerCase());
80: }
81:
82: /**
83: * @return the itemMap
84: */
85: public MapgetItemMap() {
86: return itemMap;
87: }
88:
89: /**
90: * @param rowIndex
91: */
92: public void setRowIndex(int rowIndex) {
93: this.rowIndex = rowIndex;
94: }
95:
96: public void copyFrom(DataRow row) {
97: this.itemMap.clear();//首先请客当前记录
98: for (Object c : this.columns) {
99: this.itemMap.put(c.toString().toLowerCase(), row.getValue(c.toString()));
100: }
101: }
102: }
DataTable实现
1: import java.util.ArrayList;
2: import java.util.List;
3:
6:
7: public final class DataTable {
8:
9: private DataRowCollection rows; //用于保存DataRow的集合对象
10: private DataColumnCollection columns; //用于保存DataColumn的对象
11: private String tableName; //表名
12: private boolean readOnly = false;
13: private int nextRowIndex = 0;
14: private DataExpression dataExpression;
15: private Object tag;
16:
17: public DataTable() {
18: this.columns = new DataColumnCollection();
19: this.rows = new DataRowCollection();
20: this.rows.setColumns(columns);
21: dataExpression = new DataExpression(this);
22: }
23:
24: public DataTable(String dataTableName) {
25: this();
26: this.tableName = dataTableName;
27: }
28:
29: public int getTotalCount() {
30: return rows.size();
31: }
32:
33: public boolean isReadOnly() {
34: return this.readOnly;
35: }
36:
37: public void setReadOnly(boolean readOnly) {
38: this.readOnly = readOnly;
39: }
40:
41: /**
42: * 功能描述: 返回表名
43: * @param
44: */
45: public String getTableName() {
46: return this.tableName;
47: }
48:
49: /**
50: * 功能描述: 设置表名
51: * @param
52: */
53: public void setTableName(String tableName) {
54: this.tableName = tableName;
55: }
56:
57: /**
58: * 功能描述: 返回该表引用的封装类
59: * @param
60: * @return: DataRowCollection
61: */
62: public DataRowCollection getRows() {
63: return this.rows;
64: }
65:
66: public DataColumnCollection getColumns() {
67: return this.columns;
68: }
69:
70: /**
71: * 功能描述: 获取指定行指定列的数据
72: * @param
73: * @return: Object
74: */
75:
76: public Object getValue(int row,
77: String colName) {
78: return this.rows.get(row).getValue(colName);
79: }
80:
81: public Object getValue(int row,
82: int col) {
83: return this.rows.get(row).getValue(col);
84: }
85:
86: /**
87: * 功能描述: 为该表数据新建一行
88: * @param
89: * @return: DataRow
90: */
91: public DataRow newRow() throws Exception {
92: DataRow tempRow = new DataRow(this);
93: nextRowIndex = nextRowIndex < this.rows.size() ? this.rows.size()
94: : nextRowIndex;
95: tempRow.setColumns(this.columns);
96: tempRow.setRowIndex(nextRowIndex++);
97: return tempRow;
98: }
99:
100: public void setValue(int row,
101: int col,
102: Object value) {
103: this.rows.get(row).setValue(col, value);
104: }
105:
106: public void setValue(int row,
107: String colName,
108: Object value) {
109: this.rows.get(row).setValue(colName, value);
110: }
111:
112: /**
113: * @param tag
114: */
115: public void setTag(Object tag) {
116: this.tag = tag;
117: }
118:
119: /**
120: * @return the tag
121: */
122: public Object getTag() {
123: return tag;
124: }
125:
126: public DataColumn addColumn(String columnName,
127: int dataType) throws Exception {
128: return this.columns.addColumn(columnName, dataType);
129: }
130:
131: public boolean addRow(DataRow row) throws Exception {
132: if (row.getRowIndex() > this.rows.size())
133: row.setRowIndex(this.rows.size());
134: return this.rows.add(row);
135: }
136:
137: //以下为数据表扩展方法实现集合
138: /**
139: * 功能描述: 返回符合过滤条件的数据行集合,并返回
140: * @param
141: * @return: DataTable
142: */
143: public Listselect(String filterString) {
144: Listrows = new ArrayList ();
145: if (StringUtil.isNotEmpty(filterString)) {
146: for (Object row : this.rows) {
147: DataRow currentRow = (DataRow) row;
148: if ((Boolean) dataExpression.compute(filterString,
149: currentRow.getItemMap())) {
150: rows.add(currentRow);
151: }
152: }
153: return rows;
154: } else {
155: return this.rows;
156: }
157: }
158:
159: /**
160: * 功能描述: 对当前表进行查询 过滤,并返回指定列集合拼装的DataTable对象
161: * @param
162: * @return: DataTable
163: */
164: public DataTable select(String filterString,
165: String[] columns,
166: boolean distinct) throws Exception {
167: DataTable result = new DataTable();
168: Listrows = select(filterString);
169: //构造表结构
170: for (String c : columns) {
171: DataColumn dc = this.columns.get(c);
172: DataColumn newDc = new DataColumn(dc.getColumnName(),
173: dc.getDataType());
174: newDc.setCaptionName(dc.getCaptionName());
175: result.columns.add(newDc);
176: }
177: //填充数据
178: for (DataRow r : rows) {
179: DataRow newRow = result.newRow();
180: newRow.copyFrom(r);
181: result.addRow(newRow);
182: }
183: return result;
184: }
185:
186: public DataTable select(String tableName,
187: String selectField,
188: String filterString,
189: String groupField) {
190: DataTable result = new DataTable();
191: //
192: return result;
193: }
194:
195: /**
196: * 功能描述: 根据指定表达式对符合过滤条件的数据进行计算
197: * @param
198: * @return: Object
199: * @author: James Cheung
200: * @version: 2.0
201: */
202: public Object compute(String expression,
203: String filter) {
204: return dataExpression.compute(expression, select(filter));
205: }
206:
207: public Object max(String columns,
208: String filter) {
209: return null;
210: }
211:
212: public Object min(String columns,
213: String filter) {
214: return null;
215: }
216:
217: public Object avg(String columns,
218: String filter) {
219: return null;
220: }
221:
222: public Object max(String columns,
223: String filter,
224: String groupBy) {
225: return null;
226: }
227:
228: public Object min(String columns,
229: String filter,
230: String groupBy) {
231: return null;
232: }
233:
234: public Object avg(String columns,
235: String filter,
236: String groupBy) {
237: return null;
238: }
239:
240: private ListgetColumns(String colString) {
241: Listcolumns = new ArrayList ();
242:
243: return columns;
244: }
245: }
在实现DataTable的基本功能后,我们对我们实现的对象进行一下测试,测试代码如下:
1: import java.util.List;
2: import org.junit.After;
3: import org.junit.Assert;
4: import org.junit.Before;
5: import org.junit.Test;
6:
7:
8: /**
9: * 此类描述的是: 测试数据表对象DataTable对象相关功能是否正常
10: * @author: James Cheung
11: * @version: 2.0
12: */
13: public class DataTableTest {
14:
15: @Before
16: public void init() {
17:
18: }
19:
20: @After
21: public void dispose() {
22:
23: }
24:
25:
26: @Test
27: public void tableInitTest() {
28: DataTable table = new DataTable(); //新建一个数据表对象,不带构造函数参数
29: fillTable(table);//填充数据
30: Assert.assertNotNull(table);
31: Assert.assertEquals(20, table.getColumns().size());
32: Assert.assertEquals(100, table.getRows().size());
33: //printTable(table);
34: System.out.print("-------------------------------------------------------------------------------\n");
35: table = new DataTable("TestTable");//新建一个数据表对象,带表名为参数
36: //测试添加数据列
37: fillTable(table);//填充数据
38: Assert.assertNotNull(table);
39: //printTable(table);
40: }
41:
42: @Test
43: public void tableSelectTest() throws Exception {
44: //测试数据表的选择过滤方法
45: DataTable table = new DataTable(); //新建一个数据表对象,不带构造函数参数
46: fillTable(table);//填充数据
47: Listrows = table.select("col_1> 2 && col_2<10");
48: Assert.assertNotNull(rows);
49: Assert.assertEquals(2, rows.size());
50: //测试查询指定列
51: DataTable filterResult = table.select("col_1>2 && col_2<10",
52: "col_1,col_2,col_3,col_4".split(","),
53: true);
54: printTable(filterResult);
55:
56: }
57:
58: private void printTable(DataTable table) {
59:
60: for (int i = 0; i < table.getTotalCount(); i++) {
61: for (int j = 0; j < table.getColumns().size(); j++) {
62: System.out.print(table.getValue(i, j));
63: if (j < 19)
64: System.out.print(" , ");
65: }
66: System.out.print("\n");
67: }
68: }
69:
70: private void fillTable(DataTable table) {
71: try {
72: //填充20列数据
73: for (int i = 0; i < 20; i++) {
74: table.addColumn("Col_" + i, i % 13);
75: }
76: //填充100行数据
77: for (int i = 0; i < 100; i++) {
78: DataRow row = table.newRow();
79: for (int j = 0; j < 20; j++) {
80: //循环每列加入数据
81: row.setValue(j, i * j);
82: }
83: table.addRow(row);
84: }
85: } catch (Exception e) {
86: e.printStackTrace();
87: }
88: }
89: }
后记:仔细看的朋友可能发现了,DataTable里还有几个函数没有实现,那几个函数是我们后面要实现的基于DataTable进行分组汇总计算所需的功能, 有兴趣的朋友也可以自己来实现一套试试,我这里可以提个醒给大家,下面是类似功能的测试代码:
newTable = dataTable.Select("tableName", "count(Name),sum(11) aaa,sum(222) name,avg(aa),last,first,max,min aa,Name", "", "Name");