前两天实现了net中DataTable功能,虽说功能不是很强大,但是完全满足了java中的多表查询,带来的编程风格改变还是存在的。
现在拿出来说下,和各位大哥探讨下。
因为我本来就是搞net的,突然来了两个项目就是要用java以及oracle,便从各种方向上寻求net的影子,便有了今天这些工具类。
不知道好不好,bug测试了一下了,性能上也只有经过项目来验证吧!!!
其中一部分涉及到双数据库操作,所以也提了一种解决方案,写的不好,大家看看吧!
1 实现,net数据库参数化
01 | package cdu.yas.xykps.util; |
02 | |
03 | import java.sql.Blob; |
04 | import java.sql.Date; |
05 | |
06 | /** |
07 | * @功能描述 sql参数,sql执行时传递的参数用此类封装 |
08 | * @可能的错误 |
09 | * @作者 王磊 |
10 | * @修改说明 |
11 | * @修改人 |
12 | */ |
13 | public class SqlParameter { |
14 | |
15 | public SqlParameter(String type, String value) { |
16 | this .type = type; |
17 | this .value = value; |
18 | } |
19 | |
20 | public SqlParameter(String type, int intValue) { |
21 | this .type = type; |
22 | this .intValue = intValue; |
23 | } |
24 | |
25 | public SqlParameter(String type, boolean boolValue) { |
26 | this .type = type; |
27 | this .boolValue = boolValue; |
28 | } |
29 | |
30 | public SqlParameter(String type, Date dateValue) { |
31 | this .type = type; |
32 | this .dateValue = dateValue; |
33 | } |
34 | |
35 | public SqlParameter(String type, Blob blobValue) { |
36 | this .type = type; |
37 | this .blobValue = blobValue; |
38 | } |
39 | |
40 | String type; |
41 | String value; |
42 | int intValue; |
43 | boolean boolValue; |
44 | Date dateValue; |
45 | Blob blobValue; |
46 | public String getType() { |
47 | return type; |
48 | } |
49 | |
50 | public String getValue() { |
51 | return value; |
52 | } |
53 | |
54 | public int getIntValue() { |
55 | return intValue; |
56 | } |
57 | |
58 | public boolean getBoolValue() { |
59 | return boolValue; |
60 | } |
61 | |
62 | public Date getDateValue() { |
63 | return dateValue; |
64 | } |
65 | |
66 | public Blob getBlobValue() { |
67 | return blobValue; |
68 | } |
69 | |
70 | public void setType(String type) { |
71 | this .type = type; |
72 | } |
73 | |
74 | public void setValue(String value) { |
75 | this .value = value; |
76 | } |
77 | |
78 | public void setIntValue( int intValue) { |
79 | this .intValue = intValue; |
80 | } |
81 | |
82 | public void setBoolValue( boolean boolValue) { |
83 | this .boolValue = boolValue; |
84 | } |
85 | |
86 | public void setDateValue(Date dateValue) { |
87 | this .dateValue = dateValue; |
88 | } |
89 | |
90 | public void setBlobValue(Blob blobValue) { |
91 | this .blobValue = blobValue; |
92 | } |
93 | |
94 | } |
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了。
我们来试试如何用,我也写了一个测试数据
然后我们在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 |
好了暂时这个样子了,我还封装了一个分页控件,也有点类似于net里面的分页控件,等下次大家一起看看吧
希望各位大哥多指正!!!!!
http://www.cnblogs.com/yexiaochai/archive/2011/07/15/2107468.html
<script type="text/javascript"></script>