package com.zt.generator.data; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import java.io.Serializable; import java.sql.*; import java.util.*; import java.util.Date; public class DataTable implements Serializable, Cloneable { private boolean isWebMode;// 默认值为false,True表示getString的结果是null或者""时转成  private DataRow[] rows; private DataColumn[] columns; public DataTable() { this.rows = new DataRow[0]; this.columns = new DataColumn[0]; } public DataTable(DataColumn[] types, Object[][] values) { if (types == null) { types = new DataColumn[0]; } columns = null; rows = null; // 判断是否有相同列名 if (this.checkColumns(types)) { columns = types; } if (values != null) { rows = new DataRow[values.length]; for (int i = 0; i < rows.length; i++) { rows[i] = new DataRow(columns, values[i]); } } else { this.rows = new DataRow[0]; } } // 判断是否有相同列名 public boolean checkColumns(DataColumn[] types) { if (types == null) { return false; } for (int i = 0; i < types.length; i++) { String columnName = types[i].getColumnName(); for (int j = 0; j < i; j++) { if (columnName == null) { throw new RuntimeException("DataTable中第" + i + "列列名为null!"); } if (columnName.equals(types[j].getColumnName())) { throw new RuntimeException("一个DataTable中不充许有重名的列:" + columnName); } } } return true; } public DataTable(ResultSet rs) { this(rs, Integer.MAX_VALUE, 0); } public DataTable(ResultSet rs, int pageSize, int pageIndex) { ResultSetMetaData rsmd; try { // 以下准备DataColumn[] rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); DataColumn[] types = new DataColumn[columnCount]; for (int i = 1; i <= columnCount; i++) { String name = rsmd.getColumnLabel(i); boolean b = rsmd.isNullable(i) == ResultSetMetaData.columnNullable; DataColumn dc = new DataColumn(); dc.setAllowNull(b); dc.setColumnName(name); // 以下设置数据类型 int dataType = rsmd.getColumnType(i); if (dataType == Types.CHAR || dataType == Types.VARCHAR || dataType == Types.LONGVARCHAR) { dc.ColumnType = DataColumn.STRING; } else if (dataType == Types.TIMESTAMP || dataType == Types.DATE) { dc.ColumnType = DataColumn.DATETIME; } else if (dataType == Types.DECIMAL) { dc.ColumnType = DataColumn.DECIMAL; } else if (dataType == Types.FLOAT) { dc.ColumnType = DataColumn.FLOAT; } else if (dataType == Types.INTEGER) { dc.ColumnType = DataColumn.INTEGER; } else if (dataType == Types.SMALLINT) { dc.ColumnType = DataColumn.SMALLINT; } else if (dataType == Types.BIGINT) { dc.ColumnType = DataColumn.LONG; } else if (dataType == Types.BLOB) { dc.ColumnType = DataColumn.BLOB; } else if (dataType == Types.CLOB) { dc.ColumnType = DataColumn.CLOB; } else if (dataType == Types.NUMERIC) { int dataScale = rsmd.getScale(i); int dataPrecision = rsmd.getPrecision(i); if (dataScale == 0) { if (dataPrecision == 0) { dc.ColumnType = DataColumn.BIGDECIMAL; } else { dc.ColumnType = DataColumn.LONG; } } else { dc.ColumnType = DataColumn.BIGDECIMAL; } } else { DatabaseMetaData md = rs.getStatement().getConnection().getMetaData(); String DBType = md.getDatabaseProductName().toUpperCase(); if (dataType == Types.LONGVARBINARY && DBType.equals(DBConnConfig.MYSQL)) { dc.ColumnType = DataColumn.BLOB; } else { dc.ColumnType = DataColumn.STRING; } } types[i - 1] = dc; } if (this.checkColumns(types)) { columns = types; } // 以下准备ColumnValues[] List list = new ArrayList(); int index = 0; int begin = pageIndex * pageSize; int end = (pageIndex + 1) * pageSize; while (rs.next()) { if (index >= end) { break; } if (index >= begin) { Object[] t = new Object[columnCount]; for (int j = 1; j <= columnCount; j++) { if (columns[j - 1].getColumnType() == DataColumn.CLOB) { t[j - 1] = LobUtil.clobToString(rs.getClob(j)); } else if (columns[j - 1].getColumnType() == DataColumn.BLOB) { t[j - 1] = LobUtil.blobToBytes(rs.getBlob(j)); } else { t[j - 1] = rs.getObject(j); } } DataRow tmpRow = new DataRow(columns, t); list.add(tmpRow); } index++; } this.rows = new DataRow[list.size()]; list.toArray(this.rows); } catch (SQLException e) { e.printStackTrace(); } } public void deleteColumn(int columnIndex) { if (columns.length == 0) { return; } if (columnIndex < 0 || (columns != null && columnIndex >= columns.length)) { throw new RuntimeException("DataRow中没有指定的列:" + columnIndex); } this.columns = (DataColumn[]) ArrayUtils.remove(this.columns, columnIndex); for (int i = 0; i < rows.length; i++) { rows[i].columns = null; rows[i].columns = this.columns; rows[i].values = ArrayUtils.remove(rows[i].values, columnIndex); } } public void deleteColumn(String columnName) { if (columns.length == 0) { return; } for (int i = 0; i < columns.length; i++) { if (columns[i].getColumnName().equalsIgnoreCase(columnName)) { deleteColumn(i); break; } } } public void insertColumn(String columnName) { insertColumn(new DataColumn(columnName, DataColumn.STRING), null, columns.length); } public void insertColumn(String columnName, Object columnValue) { Object[] cv = new Object[rows.length]; for (int i = 0; i < cv.length; i++) { cv[i] = columnValue; } insertColumn(new DataColumn(columnName, DataColumn.STRING), cv, columns.length); } public void insertColumns(String[] columnNames) { for (int i = 0; i < columnNames.length; i++) { insertColumn(new DataColumn(columnNames[i], DataColumn.STRING), null, columns.length); } } public void insertColumn(String columnName, Object[] columnValue) { insertColumn(new DataColumn(columnName, DataColumn.STRING), columnValue, columns.length); } public void insertColumn(DataColumn dc) { insertColumn(dc, null, columns.length); } public void insertColumn(DataColumn dc, Object[] columnValue) { insertColumn(dc, columnValue, columns.length); } public void insertColumn(String columnName, Object[] columnValue, int index) { insertColumn(new DataColumn(columnName, DataColumn.STRING), columnValue, index); } public void insertColumn(DataColumn dc, Object[] columnValue, int index) { if (index > columns.length) { throw new RuntimeException("DataRow中没有指定的列:" + index); } for (int i = 0; i < columns.length; i++) { if (columns[i].getColumnName().equalsIgnoreCase(dc.getColumnName())) { throw new RuntimeException("DataTable中已经存在列:" + dc.getColumnName()); } } this.columns = (DataColumn[]) ArrayUtils.add(columns, index, dc); if (columnValue == null) { columnValue = new Object[rows.length]; } if (rows.length == 0) { rows = new DataRow[columnValue.length]; for (int i = 0; i < rows.length; i++) { rows[i] = new DataRow(this.columns, new Object[] { columnValue[i] }); } } else { for (int i = 0; i < rows.length; i++) { rows[i].columns = null; rows[i].columns = this.columns; rows[i].values = ArrayUtils.add(rows[i].values, index, columnValue[i]); } } } public void insertRow(DataRow dr) { insertRow(dr, rows.length); } public void insertRow(DataRow dr, int index) { if (columns.length == 0) { columns = dr.columns; } insertRow(dr.getDataValues(), index); } public void insertRow(Object[] rowValue) { insertRow(rowValue, rows.length); } public void insertRow(Object[] rowValue, int index) { if (index > rows.length) { throw new RuntimeException(index + "超出范围,最大允许值为" + rows.length + "!"); } if (rowValue != null) { if (columns.length == 0) { columns = new DataColumn[rowValue.length]; for (int i = 0; i < columns.length; i++) { columns[i] = new DataColumn("_Columns_" + i, DataColumn.STRING); } } if (rowValue.length != columns.length) { throw new RuntimeException("新增行的列数为" + rowValue.length + ",要求的列数为" + columns.length + "!"); } for (int i = 0; i < columns.length; i++) { if (columns[i].ColumnType == DataColumn.DATETIME) { if (rowValue[i] != null && !Date.class.isInstance(rowValue[i])) { throw new RuntimeException("第" + i + "列必须是Date对象!"); } } } } else { rowValue = new Object[columns.length]; } DataRow[] newRows = new DataRow[rows.length + 1]; System.arraycopy(rows, 0, newRows, 0, index); if (index < rows.length) { System.arraycopy(rows, index, newRows, index + 1, rows.length - index); } newRows[index] = new DataRow(columns, rowValue); rows = newRows; } public void deleteRow(int index) { if (index >= rows.length) { throw new RuntimeException(index + "超出范围,最大允许值为" + (rows.length - 1) + "!"); } rows = (DataRow[]) ArrayUtils.remove(rows, index); } public void deleteRow(DataRow dr) { for (int i = 0; i < rows.length; i++) { if (dr == rows[i]) { deleteRow(i); return; } } throw new RuntimeException("指定的DataRow对象不属于此DataTable!"); } public DataRow get(int rowIndex) { if (rowIndex >= rows.length || rowIndex < 0) { throw new RuntimeException("指定的行索引值超出范围"); } return rows[rowIndex]; } public void set(int rowIndex, int colIndex, Object value) { getDataRow(rowIndex).set(colIndex, value); } public void set(int rowIndex, String columnName, Object value) { getDataRow(rowIndex).set(columnName, value); } public void set(int rowIndex, int colIndex, int value) { getDataRow(rowIndex).set(colIndex, value); } public void set(int rowIndex, String columnName, int value) { getDataRow(rowIndex).set(columnName, value); } public void set(int rowIndex, int colIndex, long value) { getDataRow(rowIndex).set(colIndex, value); } public void set(int rowIndex, String columnName, long value) { getDataRow(rowIndex).set(columnName, value); } public void set(int rowIndex, int colIndex, double value) { getDataRow(rowIndex).set(colIndex, value); } public void set(int rowIndex, String columnName, double value) { getDataRow(rowIndex).set(columnName, value); } public Object get(int rowIndex, int colIndex) { return getDataRow(rowIndex).get(colIndex); } public Object get(int rowIndex, String columnName) { return getDataRow(rowIndex).get(columnName); } public String getString(int rowIndex, int colIndex) { return getDataRow(rowIndex).getString(colIndex); } public String getString(int rowIndex, String columnName) { return getDataRow(rowIndex).getString(columnName); } public int getInt(int rowIndex, int colIndex) { return getDataRow(rowIndex).getInt(colIndex); } public int getInt(int rowIndex, String columnName) { return getDataRow(rowIndex).getInt(columnName); } public long getLong(int rowIndex, int colIndex) { return getDataRow(rowIndex).getLong(colIndex); } public long getLong(int rowIndex, String columnName) { return getDataRow(rowIndex).getLong(columnName); } public double getDouble(int rowIndex, int colIndex) { return getDataRow(rowIndex).getDouble(colIndex); } public double getDouble(int rowIndex, String columnName) { return getDataRow(rowIndex).getDouble(columnName); } public Date getDate(int rowIndex, int colIndex) { return getDataRow(rowIndex).getDate(colIndex); } public Date getDate(int rowIndex, String columnName) { return getDataRow(rowIndex).getDate(columnName); } public DataRow getDataRow(int rowIndex) { if (rowIndex >= rows.length || rowIndex < 0) { throw new RuntimeException("指定的行索引值超出范围"); } return rows[rowIndex]; } public DataColumn getDataColumn(int columnIndex) { if (columnIndex < 0 || columnIndex >= columns.length) { throw new RuntimeException("指定的列索引值超出范围"); } return columns[columnIndex]; } public DataColumn getDataColumn(String columnName) { for (int i = 0; i < columns.length; i++) { if (columns[i].getColumnName().equalsIgnoreCase(columnName)) { return (getDataColumn(i)); } } return null; } public Object[] getColumnValues(int columnIndex) { if (columnIndex < 0 || columnIndex >= columns.length) { throw new RuntimeException("指定的列索引值超出范围"); } Object[] arr = new Object[this.getRowCount()]; for (int i = 0; i < arr.length; i++) { arr[i] = this.rows[i].values[columnIndex]; } return arr; } public Object[] getColumnValues(String columnName) { for (int i = 0; i < columns.length; i++) { if (columns[i].getColumnName().equalsIgnoreCase(columnName)) { return getColumnValues(i); } } return null; } public void sort(Comparator c) { Arrays.sort(rows, c); } public void sort(String columnName) { sort(columnName, "desc", false); } public void sort(String columnName, String order) { sort(columnName, order, false); } public void sort(String columnName, String order, final boolean isNumber) { final String cn = columnName; final String od = order; sort(new Comparator() { public int compare(Object obj1, Object obj2) { DataRow dr1 = (DataRow) obj1; DataRow dr2 = (DataRow) obj2; Object v1 = dr1.get(cn); Object v2 = dr2.get(cn); if (v1 instanceof Number && v2 instanceof Number) { double d1 = ((Number) v1).doubleValue(); double d2 = ((Number) v2).doubleValue(); if (d1 == d2) { return 0; } else if (d1 > d2) { return "asc".equalsIgnoreCase(od) ? 1 : -1; } else { return "asc".equalsIgnoreCase(od) ? -1 : 1; } } else if (v1 instanceof Date && v2 instanceof Date) { Date d1 = (Date) v1; Date d2 = (Date) v1; if ("asc".equalsIgnoreCase(od)) { return d1.compareTo(d2); } else { return -d1.compareTo(d2); } } else if (isNumber) { double d1 = 0, d2 = 0; try { d1 = Double.parseDouble(String.valueOf(v1)); d2 = Double.parseDouble(String.valueOf(v2)); } catch (Exception e) { } if (d1 == d2) { return 0; } else if (d1 > d2) { return "asc".equalsIgnoreCase(od) ? -1 : 1; } else { return "asc".equalsIgnoreCase(od) ? 1 : -1; } } else { int c = dr1.getString(cn).compareTo(dr2.getString(cn)); if ("asc".equalsIgnoreCase(od)) { return c; } else { return -c; } } } }); } // public DataTable filter(Filter filter) { // List valueList = new ArrayList(); // for (int i = 0; i < rows.length; i++) { // if (filter.filter(rows[i])) { // valueList.add(rows[i]); // } // } // DataTable dt = new DataTable(); // dt.columns = this.columns; // dt.rows = new DataRow[valueList.size()]; // valueList.toArray(dt.rows); // dt.setWebMode(this.isWebMode); // return dt; // } /** * 还存在一些问题,只是浅层拷贝,有待于类型更为严格之后再来修改 */ public Object clone() { DataColumn[] dcs = new DataColumn[columns.length]; for (int i = 0; i < columns.length; i++) { dcs[i] = (DataColumn) this.columns[i].clone(); } DataTable dt = new DataTable(); dt.columns = dcs; dt.rows = (DataRow[]) this.rows.clone(); dt.setWebMode(this.isWebMode); return dt; } /** * 以指定的列字段值为key,以另一指定的列值为value,填充到一个Map中,并返回此Map */ public Map toMap(String keyColumnName, String valueColumnName) { if (StringUtils.isEmpty(keyColumnName)) { throw new RuntimeException("不能存取列名为空的列"); } if (StringUtils.isEmpty(valueColumnName)) { throw new RuntimeException("不能存取列名为空的列"); } int keyIndex = 0, valueIndex = 0; boolean keyFlag = false, valueFlag = false; for (int i = 0; i < columns.length; i++) { if (columns[i].getColumnName().equalsIgnoreCase(keyColumnName)) { keyIndex = i; keyFlag = true; if (valueFlag) { break; } } if (columns[i].getColumnName().equalsIgnoreCase(valueColumnName)) { valueIndex = i; valueFlag = true; if (keyFlag) { break; } } } return toMap(keyIndex, valueIndex); } /** * 以指定的列字段值为key,以另一指定的列值为value,填充到一个Map中,并返回此Map */ public Map toMap(int keyColumnIndex, int valueColumnIndex) { if (keyColumnIndex < 0 || keyColumnIndex >= columns.length) { throw new RuntimeException("DataRow中没有指定的列:" + keyColumnIndex); } if (valueColumnIndex < 0 || valueColumnIndex >= columns.length) { throw new RuntimeException("DataRow中没有指定的列:" + valueColumnIndex); } Map map = new HashMap(); for (int i = 0; i < rows.length; i++) { Object key = this.rows[i].values[keyColumnIndex]; if (key == null) { map.put(key, this.rows[i].values[valueColumnIndex]); } else { map.put(key.toString(), this.rows[i].values[valueColumnIndex]); } } return map; } /** * 以指定列的值为key,去map中寻找对应的值,并把值置到新增的列中,新增列的列名=指定列列名+"Name" */ public void decodeColumn(String colName, Map map) { for (int i = 0; i < columns.length; i++) { if (columns[i].getColumnName().equalsIgnoreCase(colName)) { decodeColumn(i, map); return; } } } public void decodeColumn(int colIndex, Map map) { String newName = this.columns[colIndex].ColumnName + "Name"; this.insertColumn(newName); for (int i = 0; i < getRowCount(); i++) { String v = getString(i, colIndex); set(i, newName, map.get(v)); } } /** * 将两个表的内容合并 */ public void union(DataTable anotherDT) { if (anotherDT.getRowCount() == 0) { return; } if (this.getRowCount() == 0) { this.rows = anotherDT.rows; return; } if (this.getColCount() != anotherDT.getColCount()) { throw new RuntimeException("两个DataTable的列数不一致,列数1:" + this.getColCount() + " ,列数2:" + anotherDT.getColCount()); } int srcPos = rows.length; DataRow[] newRows = new DataRow[rows.length + anotherDT.getRowCount()]; System.arraycopy(rows, 0, newRows, 0, srcPos); System.arraycopy(anotherDT.rows, 0, newRows, srcPos, anotherDT.getRowCount()); rows = null; rows = newRows; } public int getRowCount() { return this.rows.length; } public int getColCount() { return this.columns.length; } public DataColumn[] getDataColumns() { return columns; } public boolean isWebMode() { return isWebMode; } public void setWebMode(boolean isWebMode) { this.isWebMode = isWebMode; for (int i = 0; i < rows.length; i++) { this.rows[i].setWebMode(isWebMode); } } public String toString() { StringBuffer sb = new StringBuffer(); for (int i = 0; i < columns.length; i++) { if (i != 0) { sb.append("\t"); } sb.append(this.columns[i].getColumnName()); } sb.append("\n"); for (int i = 0; i < rows.length; i++) { if (i != 0) { sb.append("\n"); } for (int j = 0; j < columns.length; j++) { if (j != 0) { sb.append("\t"); } sb.append(this.get(i, j)); } } return sb.toString(); } public JSONArray toJSONArray() { JSONArray jsonArray = new JSONArray(); int rows = this.getRowCount(); for (int i = 0; i < rows; i++) { DataRow row = getDataRow(i); JSONObject json = new JSONObject(); int cols = row.getColumnCount(); for (int k = 0; k < cols; k++) { Object value = row.get(k); if (value instanceof Date) { value = DateUtil.formatDateTime((Date) value); } else if (value instanceof byte[]) {// blob value = new String((byte[]) value); } value = value == null ? "" : value; json.put(DBUtil.columnNameParser(columns[k].getColumnName()), value); } json.put("isTableColumn",true); json.put("isSelectColumn",false); // json.put("op","EQ"); jsonArray.add(json); } return jsonArray; } }