在Java中实现.net中DataTable功能以及操作双数据库的List连接问题解决方案探究
前两天实现了net中DataTable功能,虽说功能不是很强大,但是完全满足了java中的多表查询,带来的编程风格改变还是存在的。
现在拿出来说下,和各位大哥探讨下。
因为我本来就是搞net的,突然来了两个项目就是要用java以及oracle,便从各种方向上寻求net的影子,便有了今天这些工具类。
不知道好不好,bug测试了一下了,性能上也只有经过项目来验证吧!!!
其中一部分涉及到双数据库操作,所以也提了一种解决方案,写的不好,大家看看吧!
我们先看效果,再说说怎么弄!
我们来试试如何用,我也写了一个测试数据
然后我们在Junit中测试
@Test public void joinTable() { JingZongDB jzdb= new JingZongDB(); DataTable dt1=jzdb.getDataTable( "select * from newsType" ); DataTable dt2=jzdb.getDataTable( "select * from news" ); DataTable dt=DataTable.joinTable(dt1, dt2, "id" , "typeid" ); wl( "新闻类型表:" +dt1.getRow().size()); DataTable.outTable(dt1); wl( "新闻表:" +dt2.getRow().size()); DataTable.outTable(dt2); wl( "合并后:" +dt.getRow().size()); DataTable.outTable(dt); } private void wl(String s) { System.out.println(s); } |
最后结果为
新闻类型表: 4 id: 1 typeName:学生工作 id: 2 typeName:通知公告 id: 3 typeName:招生简章 id: 4 typeName:教务信息 新闻表: 16 id: 1 typeid: 1 newsName:学生工作 1 id: 2 typeid: 1 newsName:学生工作 2 id: 3 typeid: 1 newsName:学生工作 3 id: 4 typeid: 1 newsName:学生工作 4 id: 5 typeid: 2 newsName:通知公告 1 id: 6 typeid: 2 newsName:通知公告 2 id: 7 typeid: 2 newsName:通知公告 3 id: 8 typeid: 2 newsName:通知公告 4 id: 9 typeid: 3 newsName:招生简章 1 id: 10 typeid: 3 newsName:招生简章 2 id: 11 typeid: 3 newsName:招生简章 3 id: 12 typeid: 3 newsName:招生简章 4 id: 13 typeid: 4 newsName:教务信息 1 id: 14 typeid: 4 newsName:教务信息 2 id: 15 typeid: 4 newsName:教务信息 3 id: 16 typeid: 4 newsName:教务信息 4 合并后: 16 id: 1 typeName:学生工作 id: 1 typeid: 1 newsName:学生工作 1 id: 1 typeName:学生工作 id: 2 typeid: 1 newsName:学生工作 2 id: 1 typeName:学生工作 id: 3 typeid: 1 newsName:学生工作 3 id: 1 typeName:学生工作 id: 4 typeid: 1 newsName:学生工作 4 id: 2 typeName:通知公告 id: 5 typeid: 2 newsName:通知公告 1 id: 2 typeName:通知公告 id: 6 typeid: 2 newsName:通知公告 2 id: 2 typeName:通知公告 id: 7 typeid: 2 newsName:通知公告 3 id: 2 typeName:通知公告 id: 8 typeid: 2 newsName:通知公告 4 id: 3 typeName:招生简章 id: 9 typeid: 3 newsName:招生简章 1 id: 3 typeName:招生简章 id: 10 typeid: 3 newsName:招生简章 2 id: 3 typeName:招生简章 id: 11 typeid: 3 newsName:招生简章 3 id: 3 typeName:招生简章 id: 12 typeid: 3 newsName:招生简章 4 id: 4 typeName:教务信息 id: 13 typeid: 4 newsName:教务信息 1 id: 4 typeName:教务信息 id: 14 typeid: 4 newsName:教务信息 2 id: 4 typeName:教务信息 id: 15 typeid: 4 newsName:教务信息 3 id: 4 typeName:教务信息 id: 16 typeid: 4 newsName:教务信息 4 |
现在说如何实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | package cdu.yas.xykps.util; import java.sql.Blob; import java.sql.Date; /** * @功能描述 sql参数,sql执行时传递的参数用此类封装 * @可能的错误 * @作者 叶小钗 * @修改说明 * @修改人 */ public class SqlParameter { public SqlParameter(String type, String value) { this .type = type; this .value = value; } public SqlParameter(String type, int intValue) { this .type = type; this .intValue = intValue; } public SqlParameter(String type, boolean boolValue) { this .type = type; this .boolValue = boolValue; } public SqlParameter(String type, Date dateValue) { this .type = type; this .dateValue = dateValue; } public SqlParameter(String type, Blob blobValue) { this .type = type; this .blobValue = blobValue; } String type; String value; int intValue; boolean boolValue; Date dateValue; Blob blobValue; public String getType() { return type; } public String getValue() { return value; } public int getIntValue() { return intValue; } public boolean getBoolValue() { return boolValue; } public Date getDateValue() { return dateValue; } public Blob getBlobValue() { return blobValue; } public void setType(String type) { this .type = type; } public void setValue(String value) { this .value = value; } public void setIntValue( int intValue) { this .intValue = intValue; } public void setBoolValue( boolean boolValue) { this .boolValue = boolValue; } public void setDateValue(Date dateValue) { this .dateValue = dateValue; } public void setBlobValue(Blob blobValue) { this .blobValue = blobValue; } } |
2 后台参数执行
/** * @功能描述 执行一条select语句返回一张数据表,支持多表查询 * @可能的错误 * @作者 叶小钗 * @修改说明 * @修改人 */ public DataTable getDataTable(String sql, SqlParameter[] p) { Connection conn = DB.createConn(); PreparedStatement ps = DB.prepare(conn, sql); DataTable t = null ; try { addSqlParameter(ps, p); ResultSet rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); List<DataRow> row = new ArrayList<DataRow>(); // 表所有行集合 List<DataColumn> col = null ; // 行所有列集合 DataRow r = null ; // 单独一行 DataColumn c = null ; // 单独一列 // 此处开始循环读数据,每次往表格中插入一行记录 while (rs.next()) { // 初始化行集合, // 初始化列集合 col = new ArrayList<DataColumn>(); // 此处开始列循环,每次向一行对象插入一列 for ( int i = 1 ; i <= rsmd.getColumnCount(); i++) { String columnName = rsmd.getColumnName(i); Object value = rs.getObject(columnName); // 初始化单元列 c = new DataColumn(columnName, value); // 将列信息加入列集合 col.add(c); } // 初始化单元行 r = new DataRow(col); // 将行信息降入行结合 row.add(r); } // 得到数据表 t = new DataTable(row); rs.close(); rs = null ; } catch (SQLException e) { e.printStackTrace(); } finally { DB.close(ps); DB.close(conn); } return t; } |
3 增加参数的方法:
/** * @功能描述 增加参数方法 * @可能的错误 需要测试全局数据共享问题,以及可能会扩展参数类型 * @作者 叶小钗 * @修改说明 * @修改人 */ private void addSqlParameter(PreparedStatement ps, SqlParameter[] p) throws SQLException { for ( int j = 0 ; j < p.length; j++) { // wl(p[j].getValue() + "--" + p[j].getType() + "--" + j); if (p[j].getType().equals( "int" )) { ps.setInt(j + 1 , p[j].getIntValue()); } if (p[j].type.equals( "String" )) { ps.setString(j + 1 , p[j].getValue()); } if (p[j].type.equals( "boolean" )) { ps.setBoolean(j + 1 , p[j].getBoolValue()); } if (p[j].type.equals( "Date" )) { ps.setDate(j + 1 , p[j].getDateValue()); } if (p[j].type.equals( "Blob" )) { ps.setBlob(j + 1 , p[j].getBlobValue()); } } } |
4 看看我们如何调用方法
public DataTable getByParentId( int pId) { String sql = "select * from kpxz where fbh=? order by kpxzsx asc" ; SqlParameter[] p = new SqlParameter[ 1 ]; p[ 0 ] = new SqlParameter( "int" , pId); return db.getDataTable(sql, p); } |
上面就是调用函数的具体方法,现在我们来详细说下DataTable,具体实现如下
package cdu.yas.xykps.util; import java.util.ArrayList; import java.util.List; /** * @功能描述 数据表,即是表格集合,为List类型,其中List中每一个对象是一个DataRow类(List) * @可能的错误 * @作者 叶小钗 * @修改说明 * @修改人 */ public class DataTable { List<DataRow> row; public DataTable() { } public DataTable(List<DataRow> r) { row = r; } public List<DataRow> getRow() { return row; } public void setRow(List<DataRow> row) { this .row = row; } /** * @功能描述 双表根据两表关联字段连接,要求两表必须包含公告字段,并且每一行数据公共字段相等 。dt1对应colname1 ,dt2 * 对应colName2 * @可能的错误 未完成 * @作者 叶小钗 * @修改说明 * @修改人 */ public static DataTable joinTable(DataTable dt1, DataTable dt2, String colName1, String colName2) { List<DataRow> newRows = new ArrayList<DataRow>(); List<DataRow> rows1 = dt1.getRow(); List<DataRow> rows2 = dt2.getRow(); int i1 = rows1.size(); int i2 = rows2.size(); List<DataRow> temp = new ArrayList<DataRow>(); String tempC = "" ; if (i1 > i2) { temp = rows1; rows1 = rows2; rows2 = temp; tempC = colName1; colName1 = colName2; colName2 = tempC; } for (DataRow r1 : rows1) { String value1 = r1.eval(colName1); for (DataRow r2 : rows2) { String value2 = r2.eval(colName2); if (value1.equals(value2)) { List<DataColumn> cols = new ArrayList<DataColumn>(); for (DataColumn c : r1.getCol()) { cols.add(c); } for (DataColumn c : r2.getCol()) { cols.add(c); } DataRow rr = new DataRow(cols); newRows.add(rr); } } } DataTable dt = new DataTable(newRows); return dt; } public static void outTable(DataTable dt) { for (DataRow r : dt.getRow()) { for (DataColumn c : r.getCol()) { System.out.print(c.getKey() + ":" + c.getValue() + " " ); } wl( "" ); } } public static void wl(String s) { System.out.println(s); } } |
对应DataRow
package cdu.yas.xykps.util; import java.sql.Blob; import java.sql.Date; import java.util.List; /** * @功能描述 数据行,即是表格中的每一行数据的集合,为List类型,其中List中每一个对象是一个DataColumn类(键值对) * @可能的错误 当需要取得行数据中某一列时,若是类型转换不匹配会出错(例:1 若是数据项为字符串,我们取时候想取整形;); * @作者 叶小钗 * @修改说明 由于取为空字符串时候会报类型转换的错误,便使用了异常处理 * @修改人 叶小钗 */ public class DataRow { List<DataColumn> col; /** * @功能描述 返回指定DataColumn类型数据列对象 * @作者 叶小钗 */ public DataColumn getColumnObject(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return c; } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return null ; } /** * @功能描述 返回指定Object类型数据列对象 * @作者 叶小钗 */ public Object getColumn(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return c.getValue(); } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return null ; } /** * @功能描述 返回指定int类型数据列对象 * @作者 叶小钗 */ public int getIntColumn(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return Integer.parseInt(c.getValue().toString()); } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return 0 ; } /** * @功能描述 返回指定String类型数据列对象 * @作者 叶小钗 */ public String getStringColumn(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return c.getValue().toString(); } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return null ; } /** * @功能描述 返回指定String类型数据列对象 * @作者 叶小钗 */ public String eval(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return c.getValue() + "" ; // 此方法将屏蔽错误!!! } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return null ; } /** * @功能描述 返回指定Date类型数据列对象 * @作者 叶小钗 */ public Date getDateColumn(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return Date.valueOf(c.getValue().toString()); } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return null ; } /** * @功能描述 返回指定Blob类型数据列对象 * @作者 叶小钗 */ public Blob getBlobColumn(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return (Blob) c.getValue(); } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return null ; } /** * @功能描述 返回指定Blob类型数据列对象 * @作者 叶小钗 */ public float getFloatColumn(String colName) { for (DataColumn c : col) { if (c.getKey().toUpperCase().equals(colName.toUpperCase())) { try { return Float.parseFloat(c.getValue().toString()); } catch (Exception e) { System.out.println( "错误描述:" + e.toString()); } } } return 0 ; } public DataRow(List<DataColumn> c) { col = c; } public List<DataColumn> getCol() { return col; } public void setCol(List<DataColumn> col) { this .col = col; } } |
然后数据列
package cdu.yas.xykps.util; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * @功能描述 数据列,也是最简单的数据项,相当于表格中的一个单元项目。 * 采用健值对思想,key为列名,value对应key值的单元格元素,为Object类型 * @可能的错误 * @作者 叶小钗 * @修改说明 * @修改人 */ public class DataColumn { String key; Object value; public DataColumn(String k, Object v) { key = k; value = v; } public String getKey() { return key; } public Object getValue() { return value; } public void setKey(String key) { this .key = key; } public void setValue(Object value) { this .value = value; } } |
如此一来便实现了java中的DataTable了。
好了暂时这个样子了,我还封装了一个分页控件,也有点类似于net里面的分页控件,等下次大家一起看看吧
希望各位大哥多指正!!!!!

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)