數(shù)據(jù)結構主要有DataSet,DataRow兩種
分別對應數(shù)據(jù)庫的表與行
DataSet是DataRow的集合
DataSet通常由AnylineService.query()或AnylineService.cache()返回
DataRow通常由AnylineService.queryRow()或AnylineService.cacheRow()返回
數(shù)據(jù)結構:DataRow
DataRow對應數(shù)據(jù)庫中的一行數(shù)據(jù)內部是一個Map結構,Map的key對應了表的列名,一般通過anyline-config.IS_UPPER_KEY=true來設置返回值以大寫key存儲
DataRow提供了一些默認的數(shù)據(jù)操作方法
public Object get(String key) | 提取DataRow中的值 |
public boolean getBoolean(String key) | 提取DataRow中的值并轉換成Boolean值 |
public boolean getBoolean(String key, boolean def) | 提取DataRow中的值并轉換成Boolean值,如果沒有值則默認為def |
public Date getDate(String key, String def) | 提取DataRow中的值并轉換成Date類型,如果沒有值則默認為def |
public Date getDate(String key, Date def) | 提取DataRow中的值并轉換成Date類型,如果沒有值則默認為def |
public BigDecimal getDecimal(String key) | 提取DataRow中的值并轉換成BigDecimal類型 |
public BigDecimal getDecimal(String key, BigDecimal def) | 提取DataRow中的值并轉換成BigDecimal類型,如果沒有值則默認為def |
public BigDecimal getDecimal(String key, double def) | 提取DataRow中的值并轉換成BigDecimal類型,如果沒有值則默認為def |
public int getInt(String key) | 提取DataRow中的值并轉換成Int類型,如果沒有值則默認為0 |
public int getInt(String key, int def) | 提取DataRow中的值并轉換成int類型,如果沒有值則默認為def |
public long getLong(String key) | 提取DataRow中的值并轉換成long類型,如果沒有值則默認為0 |
public long getLong(String key, long def) | 提取DataRow中的值并轉換成long類型,如果沒有值則默認為def |
public DataRow getRow(String key) | 獲取DataRow中的值并轉換成DataRow,如果值不是DataRow類型則返回null |
public DataSet getSet(String key) | 獲取DataRow中的值并轉換成DataSet,如果值不是DataSet類型則返回null |
public String getPrimaryKey() | 獲取主鍵 |
public String getPrimaryKeys() | 攻取主鍵列表,復合主鍵時使用 |
public DataRow addPrimaryKey(String ... pks) | 添加主鍵,DataRow默認以ID作主鍵,調用以上方法可以在ID基礎上添加多個主鍵。 在AnylineService.save(DataRow)時會根據(jù)主鍵來判斷insert還是update applyContainer:設置主鍵時,是否同時應用到父級容器DataSet上 |
public DataRow addPrimaryKey(boolean applyContainer, Collection pks) |
public DataRow addPrimaryKey(boolean applyContainer, String ... pks) |
public DataRow addAllUpdateColumns() | 將所有列添加入保存范圍 AnylineService.save(DataRow)如果是update操作,則只會update值修改過和列 如果要強制upate所有列,需要調用以上方法 |
public DataRow clearUpdateColumns() | 清除所有需要更新的列(只是標記所有列不需要更新,并不清空值) |
public boolean checkRequired(String ... keys) | 檢測指定的列中是否有空值 |
public DataRow clearEmpty() | 刪除值為空的條目,相當于調用Map.remove(key) |
public DataRow clearNull() | 刪除值為null的條目 |
public boolean containsKey(String key) | 是否包含指定的key |
public DataRow copy(DataRow data, String ... keys) | 將data中對應的key的值存入當前對象,如果有重復的key以data中的值為準 |
public T entity(Class clazz) | 將普通的Java對象轉換成DataRow |
public DataRow formatDate(String format, String ... cols) | 格式化指定列的日期格式 |
public DataRow formatNumber(String format, String ... cols) | 格式化指定列的數(shù)字格式 |
public Object getPrimaryValue() | 獲取主鍵值 |
public Object getPrimaryValues() | 獲取主鍵值,復合主鍵時使用 |
public boolean hasValue(String key) | return get(key) != null; |
public boolean isEmpty(String key) | 指定列的值是否(不)為空(null) |
public boolean isNotEmpty(String key) |
public boolean isNull(String key) |
public boolean isNotNull(String key) |
public boolean isExpire() | 從創(chuàng)建對象到現(xiàn)在是否超過指定時間,配合setExpire(int millisecond)使用 |
public boolean isExpire(int millisecond) | 從創(chuàng)建對象到現(xiàn)在是否超過指定時間 |
public DataRow merge(DataRow row, boolean over) | 將row中的數(shù)據(jù)合并到當前DataRow over:key相同時是否覆蓋當前DataRow中的值 |
public DataRow merge(DataRow row |
public Object put(String key, Object value) | 類似于Map.put() pk:是否將當前key作為主鍵 override:如果當前DataRow中已存在key值是否覆蓋原來的值 |
public Object put(String key, Object value, boolean pk) |
public Object put(String key, Object value, boolean pk, boolean override) |
public void setUpdateEmptyColumn(boolean updateEmptyColumn) | 設置是否更新值為空的列 |
public void setUpdateNullColumn(boolean updateNullColumn) | 設置是否更新值為null的列 |
public String toJSON() | 轉換成json格式字符 |
public String toXML() | 轉換成xml格式字符 border:是否添加xml外層標簽包裹 order:是否需要排序后轉換 |
public String toXML(boolean border, boolean order) |
public DataRow toLowerKey(String ... keys) | 將指定的key轉換成小(大)寫,如果不指定則轉換全部key 轉換的是key而不是value |
public DataRow toUpperKey(String ... keys) |
public DataRow setExpires(int millisecond) | 設置過期時間,配合isExpires()使用 |
數(shù)據(jù)結構:DataSet
DataSet對應數(shù)據(jù)庫中的多行數(shù)據(jù),是一個DataRow集合,內部是一個Collection結構
DataSet提供了一些默認的數(shù)據(jù)操作方法
public boolean add(Object e) | 添加一行,并將e轉換成DataRow格式 |
public boolean addAll(Collection c) | 添加多行 |
public DataSet addRow(DataRow row) | 添加一行,只有當row != null時執(zhí)行添加 |
public DataSet addRow(int idx, DataRow row) | 在idx位置插入一行 |
public DataSet addPrimaryKey(boolean applyItem, Collection pks) | 添加主鍵,參考DataRow |
public DataSet addPrimaryKey(boolean applyItem, String ... pks) | applyItem:是否應用到集合中的DataRow 默認true |
public DataSet intersection(DataSet set, String ... keys) | 根據(jù)keys取set與當前DataSet的交集,返回結果為新生成的DataSet對象 |
public DataSet and(DataSet set, String ... keys) |
public DataSet difference(DataSet set, String ... keys) | 根據(jù)keys取set與當前DataSet的差集,返回結果為新生成的DataSet對象 |
public DataSet asc(final String ... keys) | 根據(jù)keys值排序 |
public DataSet order(final String ... keys) | 根據(jù)keys值排序(正序) |
public DataSet desc(final String ... keys) | 根據(jù)keys值排序 |
public BigDecimal avg(int top, String key) | 從第0行到top行,計算key列的平均值,空值不參與除法 |
public BigDecimal avg(String key) | 計算key列的平均值 |
public boolean checkRequired(String ... keys) | 集合中的DataRow是否keys值都不為空 |
public void clear() | 清空集合中的所有條目 |
public String concat(String key, String connector) | 提取集合中所有條目的key值,并以connector拼接 |
public String concat(String key) | 提取集合中所有條目的key值,并以","拼接 |
public String concatNvl(String key) | 提取集合中所有條目的key值,并以","拼接,如果有null值則以""代替 |
public String concatNvl(String key, String connector) | 提取集合中所有條目的key值,并以connector拼接,如果有null值則以""代替 |
public String concatWithoutEmpty(String key) | 提取集合中所有條目的key值,并以","拼接,如果值為空則略過 |
public String concatWithoutEmpty(String key, String connector) | 提取集合中所有條目的key值,并以connector拼接,如果值為空則略過 |
public String concatWithoutNull(String key) | 提取集合中所有條目的key值,并以","拼接,如果值為null則略過 |
public String concatWithoutNull(String key, String connector) | 提取集合中所有條目的key值,并以connector拼接,如果值為null則略過 |
public boolean contains(DataRow row, String ... keys) | 是否包含row,檢測指定keys的value值相同則認為包含 如果未指定keys,則只檢測主鍵值 |
public DataSet cut(int begin) | 截取begin到最后一行 |
public DataSet cut(int begin, int end) | 截取begin到end行 |
public DataSet dispatchItems(String field, boolean recursion, DataSet items, String ... keys) | 從items中按相應的key提取數(shù)據(jù) 存入集合中的DataRow recursion:是否遞歸執(zhí)行 dispatchItems("children",items, "PARENT_ID") dispatchItems("children",items, "ID:PARENT_ID") 參考經(jīng)典場景一節(jié)中的示例 |
public DataSet dispatchItems(String field,DataSet items, String ... keys) |
public DataSet dispatchItems(DataSet items, String ... keys) |
public DataSet dispatchItems(boolean recursion, String ... keys) |
public DataSet dispatchItems(String field, boolean recursion, String ... keys) |
public DataSet unique(String ... keys) | 根據(jù)keys值提取集合中不重復的子集,返回結果為新生成的DataSet |
public DataSet distinct(String... keys) | 根據(jù)keys值提取集合中不重復的子集,返回結果為新生成的DataSet |
public List getDistinctStrings(String key) | 提取指定列中不重復的值的集合 |
public List fetchDistinctValue(String key) | 提取指定列中不重復的值的集合 |
public List fetchValues(String key) | 提取key列的值,包含重復值 |
public DataSet filter(int begin, int end, String key, String value) | 取begin行到end行中,key值=value的子集 |
public DataSet formatDate(String format, String ... cols) | 將集合中DataRow的cols列格式化 |
public DataSet formatNumber(String format, String ... cols) | 將集合中DataRow的cols列格式化 |
public Object get(int index, String key) | 取第index個條目的key值 |
public BigDecimal getDecimal(int idx, String key) |
public BigDecimal getDecimal(int idx, String key, double def) |
public BigDecimal getDecimal(int idx, String key, BigDecimal def) |
public int getInt(int idx, String key) |
public int getInt(int idx, String key, int def) |
public double getDouble(int idx, String key, double def) |
public long getLong(int idx, String key) |
public long getLong(int idx, String key, long def) |
public Date getDate(int idx, String key) |
public Date getDate(int idx, String key, Date def) |
public Date getDate(int idx, String key, String def) |
public String getEscapeString(int index, String key) | 取第index行key值并進行escapse編碼 |
public String getDoubleEscapeString(int index, String key) { | 取第index行key值并進行兩次escapse編碼 |
public PageNavi getNavi() | 分頁信息,查詢方法有分頁時有效 |
public DataRow getRow(int index) | 提取第index行 |
public DataRow getRow(int begin, String... params) | 從第begin行開始 key=value的條目 getRow(0,"NAME","ZHANG"); |
public DataRow getRow(int begin, String... params) | 從第begin行開始 key=value的條目 getRow(0,"NAME","ZHANG","SEX","1"); |
public DataSet getRows(int fr, int to) | 提取從fr行到to行的子集 |
public DataSet getRows(int begin, int qty, String... params) | 根據(jù)條件從第begin行開始取最多qty行 getRows(0,10,key1,value1,key2:value2,key3,value3); |
public DataSet getRows(String... params) | 從第0開始 |
public DataSet getRows(int begin, String... params) |
public List getStringsWithoutEmpty(String key) |
public List getStringsWithoutNull(String key) |
public DataSet group(String ... keys) | 按keys分組,參與經(jīng)典場景中的示例 |
public boolean isEmpty() | 集合是否為空 |
public boolean isExpire(int millisecond) | 從創(chuàng)建到現(xiàn)在是否超過millisecond毫秒 |
public DataRow max(String key){ | key對應的value最大的一行 |
public DataRow min(String key) | key對應的value最小的一行 |
public BigDecimal maxDecimal(int top, String key) | 從第0行到top行中key列最大值 |
public BigDecimal maxDecimal(String key) | 集合中key列最大值 |
public BigDecimal minDecimal(int top, String key) | 從第0行到top行中key列最小值 |
public BigDecimal minDecimal(String key) | 集合中key列最小值 |
public double maxDouble(int top, String key) | 從第0行到top行中key列最大值 |
public double maxDouble(String key) | 集合中key列最大值 |
public double minDouble(int top, String key) | 從第0行到top行中key列最小值 |
public double minDouble(String key) | 集合中key列最小值 |
public int maxInt(int top, String key) | 從第0行到top行中key列最大值 |
public int maxInt(String key) | 集合中key列最大值 |
public int minInt(int top, String key) | 從第0行到top行中key列最小值 |
public int minInt(String key) | 集合中key列最小值 |
public DataSet or(DataSet set, String ... keys) | 合并set與當前DataSet,按keys去重,如果沒有指定keys,則按主鍵去重 |
public DataSet union(DataSet set, String ... keys) | 合并set與當前DataSet,按keys去重,如果沒有指定keys,則按主鍵去重 |
public DataSet unionAll(DataSet set) | 合并set與當前DataSet,不去重 |
public DataRow random() | 隨機取一行 |
public DataSet randoms(int qty) | 隨機取qty行 |
public DataSet regex(String key, String regex) | 匹配regex正則的子集 |
public DataSet regex(String key, String regex, Regular.MATCH_MODE mode) | org.anyline.util.regular.Regular.MATCH_MODE:匹配模式 |
public String toJSON() | 列表中的數(shù)據(jù)格式化成json格式 不同與toString |
類SQL操作
DataSet set = new DataSet();
DataSet result = set.select.equals("NAME","ZHANG");
public DataSet equals(String key, String value) | where key=value |
public DataSet equalsIgnoreCase(String key, String value) | where key=value,不區(qū)分大小寫 |
public DataSet notEquals(String key, String value) | where key != value |
public DataSet notEqualsIgnoreCase(String key, String value) | where key != value,不區(qū)分大小寫 |
public DataSet contains(String key, String value) | where key like ''%value%'' |
public DataSet like(String key, String pattern) | where key like pattern,與SQL通配符一致 |
public DataSet startWith(String key, String prefix) | where key like ''prefix%'' |
public DataSet endWith(String key, String suffix) | where key like ''%suffix'' |
public DataSet in(String key, String ... values) | where key in(values) |
public DataSet in(String key, Collection values) | where key in(values) |
public DataSet inIgnoreCase(String key, String ... values) | where key in(values),不區(qū)分大小寫 |
public DataSet inIgnoreCase(String key, Collection values) | where key in(values),不區(qū)分大小寫 |
public DataSet notIn(String key, String ... values) | where key not in(values) |
public DataSet notIn(String key, Collection values) | where key not in(values) |
public DataSet notInIgnoreCase(String key, String ... values) | where key not in(values),不區(qū)分大小寫 |
public DataSet notInIgnoreCase(String key, Collection values) | where key not in(values),不區(qū)分大小寫 |
public DataSet isNull(String key) | where key is null |
public DataSet isNull(String ... keys) | where key1 is null and key2 is null |
public DataSet isNotNull(String key) | where key is not null |
public DataSet isNotNull(String ... keys) | where key1 is not null and key2 is not null |
public DataSet isEmpty(String key) | where key is empty(null or '') |
public DataSet isEmpty(String ... keys) | where key1 is empty(null or '') ... |
public DataSet isNotEmpty(String key) | where key is not empty(null or '') |
public DataSet isNotEmpty(String ... keys) | where key1 is not empty(null or '') ... |
public DataSet less(String key, Object value) | where key < value(number,date,string) |
public DataSet lessEqual(String key, Object value) | where key <= value |
public DataSet greater(String key, Object value) | where key > value |
public DataSet greaterEqual(String key, Object value) | where key >= value |
public DataSet between(String key, Object min, Object max) | where key between min and max |
DataRow
DataRow繼承自HashMap, 除了HashMap之外的其他常用函數(shù)
public Object put(String key, Object value)
public String getString(String key)
public String getStringNvl(String key, String ... defs)
public int getInt(String key) throws Exception
public int getInt(String key, int def)
//基本類型類似
public DataSet getSet(String key)
public List<?> getList(String key)
/**
* 解析實體類對象
* @param obj obj
* @param keys 列名:obj屬性名 "ID:memberId"
* @return return
*/
public static DataRow parse(Object obj, String ... keys)
//JSON解析成DataRow
public static DataRow parseJson(String json)
//XML解析成DataRow
public static DataRow parseXml(String xml)
//key1,value1,key2,value2,key3:value3組合解析成DataRow
public static DataRow parseArray(String ... kvs)
/**
* 合并數(shù)據(jù)
* @param row row
* @param over key相同時是否覆蓋原數(shù)據(jù)
* @return return
*/
public DataRow merge(DataRow row, boolean over)
public DataRow merge(DataRow row)
/**
* key轉換成小寫
* @param keys keys(如果不傳值,默認轉換所有key)
* @return return
*/
public DataRow toLowerKey(String ... keys)
public DataRow toUpperKey(String ... keys)
/**
* 數(shù)字格式化
* @param format format
* @param cols cols
* @return return
*/
public DataRow formatNumber(String format, String ... cols)
/**
* 日期格式化
* @param format format
* @param cols cols
* @return return
*/
public DataRow formatDate(String format, String ... cols)
/**
* 指定列是否為空
* @param key key
* @return return
*/
public boolean isNull(String key)
public boolean isEmpty(String key)
/**
* 轉換成對象
* @param <T> T
* @param clazz clazz
* @return return
*/
public <T> T entity(Class<T> clazz)
public boolean hasValue(String key)
/**
* 轉換成json格式
* @return return
*/
public String toJSON()
/**
* 輪換成xml格式
* @return return
*/
public String toXML()
//清空值為null的列
public DataRow removeNull(String ... keys)
/**
* 抽取指定列,生成新的DataRow,新的DataRow只包括指定列的值,不包含其他附加信息(如來源表)
* @param keys keys
* @return DataRow
*/
public DataRow extract(String ... keys)
/**
* 替換所有空值
* @param value value
* @return return
*/
public DataRow replaceEmpty(String value)
/**
* 替換所有空值
* @param key key
* @param value value
* @return return
*/
public DataRow replaceEmpty(String value)
public DataRow replaceEmpty(String key, String value)
public DataRow replaceNull(String value)
public DataRow replaceNull(String key, String value)
/**
* 拼接value
* @param keys keys
* @return String
*/
public String join(String ... keys)
/**
* 在key列基礎上 +value,如果原來沒有key列則默認0并put
* @param key key
* @param value value
* @return this
*/
public DataRow add(String key, int value)
public DataRow subtract(String key, int value)
public DataRow multiply(String key, int value)
public DataRow divide(String key, int value)
//取第一個不為null的值
public Object nvl(String ... keys)
//取第一個不為空的值
public Object evl(String ... keys)
get(String key)與getString(String key)的區(qū)別
get(String key)與Map的get(String key)效果一樣
getString(String key)支持表達式getString("${ID}-${NAME}")
關于DataRow parse xml與parse json區(qū)別
**json結構相對簡單每一對key value可以直接存入DataRow **
{name:zhang,age:20}
對應:
row.put("name","zhang");
row.put("age",20);
但xml比json多了一個attribute,這個attribute不直接存入DataRow
<user id="1"><name>zhang</name></user>
對應:
user.attr("id","1");
user.put("name","zhang");
同樣取值時也通過user.attr("id");
關于DataRow中get與getString的區(qū)別
DataRow中get是覆蓋了父類Map的get
getString在get的基礎上增加了復合KEY的支持,如getString("{ID}/{CODE}")
替換DataSet,DataRow中所有空值(null,'')
將所有列中的空值替換成value
public DataSet replaceEmpty(String value)
一維數(shù)組轉成DataRow 二維數(shù)組轉成DataSet
通常情況下是把Bean或Map轉成DataRow,把Bean和Map的集合轉成DataSet
但有些情況下如從excel中讀取數(shù)據(jù),讀取出來的結果是List<List<String>>結構,并沒有列名或屬性名,只是按下標順序排列。
這時操作List就比較原始,如分組,排序等都需要重寫。
所以可以轉成DataSet,這樣可以利用DataSet的方法對結果集進行去重、分組等。因為沒有屬性名所以轉換成DataRow后以下標作為keyDataSet set = DataSet.parse(list);
DataRow根據(jù)表結構接收參數(shù)值
如果有實體類的話,可以根據(jù)實體類的屬性來接收url中的參數(shù)值。
而entity()函數(shù)則是根據(jù)表結果來接收
DataRow row = entity("{HR_USER}");
DataRow row = entity(TableBuilder.init("HR_USER"));
默認情況下列名與參數(shù)名一致。
實際開發(fā)中前端提交的數(shù)據(jù)經(jīng)常是小駝峰格式,可以在anyline-config.xml配置文件中添加配置camel
camel:表示小駝峰?Camel:表示大駝峰
如表結構ID,NAME,TYPE_CODE,ADDRESS
前端傳值id=1&name=zh&typeCode=101
entity()接收加密數(shù)據(jù)
如果前端提交的參數(shù)是加密后的值,需要這樣解密
DataRow row = entity("ID:id+");
與getParam("id", true)效果一樣
關于DataRow中key的大小寫
背景:JAVA從數(shù)據(jù)庫中查出來的數(shù)據(jù),封裝到DataRow中傳給前端顯示,顯示時需要根據(jù)屬性名來調用顯示內容。屬性中經(jīng)常會有各種不同的命名規(guī)則,如userName,UserName這類大小駝峰格式前端還可以分辨,但涉及到一些專用縮寫根據(jù)不同團體不同人的習慣會出現(xiàn)多種格式,如UserId,UserID,id,Id,ID,所以經(jīng)常需要統(tǒng)一成大寫以避免因大小寫造成的問。
所以調用DataRow.put(key,value)時會將key轉換成統(tǒng)一格式。在默認情況下key會轉換成全大寫。
轉換規(guī)則優(yōu)先級:
1.DataRow對象自身規(guī)則,DataRow 實例化時顯式指定。new DataRow(DataRow.KEY_CASE keyCase);KEY_CASE.CONFIG:根據(jù)配置類(默認值)KEY_CASE.SRC:原樣保存不轉換KEY_CASE.UPPER:轉大寫KEY_CASE.LOWER:轉小寫KEY_CASE.Camel:下/中劃線轉成大駝峰KEY_CASE.camel:下/中劃線轉成小駝峰
2.根據(jù)配置類ConfigTable
配置類先加載配置文件anyline-config.xml或統(tǒng)一配置(如nacos等)中的<property key="IS_UPPER_KEY">false</property><property key="IS_LOWER_KEY">false</property>如果沒有配置文件則根據(jù)默認屬性配置類中有兩個默認IS_UPPER_KEY = true;IS_LOWER_KEY = false;可以通過調用ConfigTable的靜態(tài)方式修改以上兩個屬性ConfigTable.setUpperKey(false);
需要注意的是配置類會定期加載配置文件,所以通過ConfigTable.setUpperKey(false);的效果會被覆蓋
在通過DataRow來解析json數(shù)據(jù)時,同樣按以上優(yōu)先級確認key的大小寫。如果要保持原樣可以解析時指定key規(guī)則
DataRow row = DataRow.parseJson(KEY_CASE.SRC,json);
DataRow key不區(qū)分大小寫設置
如果設置了keyCase = KEY_CASE.SRC,并且配置文件中設置true
在執(zhí)行get時不區(qū)分key大小寫并忽略-與_,但是DataRow中可以put多個key如(USER_ID,userId,UserId),取值是取最后put的值
其他情況在put和get時會強制轉換key,所以沒有大小寫之分
刪除空值
new DataSet().removeNull(String ... kyes)
new DataRow().removeNull(String ... kyes)
刪除值為null的列,如果不傳參數(shù)keys或keys.length=0,則檢測所有列
new DataSet().removeEmpty(String ... kyes)
new DataRow().removeEmpty(String ... kyes)
刪除值為空的列(null或""),如果不傳參數(shù)keys或keys.length=0,則檢測所有列
替換空值
new DataSet().replaceNull(String value)
new DataRow().replaceNull(String value)
new DataSet().replaceNull(String key, String value)
new DataRow().replaceNull(String key, String value)
如果key列的值為null,則替換成value,如果不傳參數(shù)key則檢查所有列
new DataSet().replaceEmpty(String value)
new DataRow().replaceEmpty(String value)
new DataSet().replaceEmpty(String key, String value)
new DataRow().replaceEmpty(String key, String value)
如果key列的值為空(null或""),則替換成value,如果不傳參數(shù)key則檢查所有列
關于DataRow的復合KEY
許多情況下需要從DataRow中取多個值合并顯示。如導出excel時地址列需要合并省市區(qū)詳細地址
DataRow可以取多個值拼接,但DataSet則需要遍歷,非常麻煩DataRow提供了復合KEY取值的函數(shù)如{ID:1,CODE:A01,NAME:張三}row.getString("{ID}-{CODE}")可以取出 1-A01row.getString("編號:{CODE};姓名:{NAME}")可以取出 編號:A01;姓名:張三
需要注意的是如果其中一個KEY取值為null 或 KEY不存在則以""代替,而不是"null"
類似的在導出EXCEL時指定需要導出的列時也可以使用復合KEY
DataSet
DataSet是DataRow的集合
提供了常用的集合操作以及針對集合中DataRow的操作
一般是由serivce.querys()返回的查詢結果集。
DataSet上附加了針對結果集數(shù)據(jù)二次操作的功能
DataSet構造多級樹型結構
表結構類似這樣
ID | BASE_ID | NAME |
1 | NULL | 中國 |
2 | 1 | 山東 |
3 | 2 | 濟南 |
4 | 2 | 青島 |
5 | 2 | 煙臺 |
6 | 3 | 歷下區(qū) |
7 | 3 | 天橋區(qū) |
8 | 4 | 市南區(qū) |
9 | 4 | 城陽區(qū) |
//先取出完整列表
DataSet set = service.querys("SYS_AREA");
//ID:主鍵 BASE_ID:表示上一級ID的列名
set.dispatchs(true,true, "ID:BASE_ID");
set.dispatchs("children",true,true, "ID:BASE_ID");
//執(zhí)行完成后會把每個DataRow中存入當前DataRow的下一級
//這里會生成多個樹型結構,一般需要根據(jù)ID取出最頂級的DataRow set.getRow("ID",1);
DataSet拆分
有些情況下需要對DataSet分組處理。如:查詢出2000個手機號,如果一短信平臺一次只能發(fā)500個
List<DataSet> list = set.split(set.size()/500);
for(DataSet items:list) {
List<String> mobiles = items.getDistinctStrings("mobile");
//發(fā)送短信
}
從列式數(shù)據(jù)庫中取出坐標數(shù)據(jù),格式化成地圖軌跡需要的數(shù)據(jù)
軌跡原始數(shù)據(jù)(保存在列式數(shù)據(jù)庫或thingsboard平臺上)
lng=[{"ts":1655007789001,"value":120.1}, {"ts":1655007759002,"value":120.2}],
lat=[{"ts":1655007789001,"value":36.1}, {"ts":1655007759002,"value":36.2}]
通過org.anyline.thingsboard.util.ThingsBoardClient.getTimeseries()取出列的DataSet結構:
[{"TS":1657707789001, "LNG":120.1, "LAT":36.1},
{"TS":1657707759002, "LNG":120.2, "LAT":36.2}]
DataSet轉換成地圖軌跡常用的格式:
{
//點位時間
time: [1657707789001, 1657707759002],
//點位坐標
path: [
[120.1, 36.1],
[120.2, 36.2],
]
}
取出時間 List<Long> times = set.getLongs("TS");
取出坐標 List<Double[]> points = set.getDoubleArrays("LNG", "LAT");
將所有列中的oldChar替換成newChar
將key列中的oldChar替換成newChar
public DataSet replace(String key, String oldChar, String newChar)
將所有列中的oldChar替換成newChar
public DataSet replace(String oldChar, String newChar)
DataSet清空集合中指定列為空的條目
DataSet set = service.querys("HR_USER");
清空set中DEPT_ID和SORT_ID都為空(包括null和"")的行
public DataSet removeEmptyRow(String... keys)
set.removeEmptyRow("DEPT_ID","SORT_ID");
清除指定列全為空的行,如果不指定keys,則清除所有列都為空(包括null和"")的行
任何一列不為空時,都不會被刪除
DataSet實現(xiàn)行轉列
DataSet set = service.querys("V_HR_SALARY","YYYY:"+ yyyy, "ORDER BY YM");
DataSet groups = set.pivot("EMPLOYEE_CODE,EMPLOYEE_NM","YM","TOTAL_PRICE");
//EMPLOYEE_CODE,EMPLOYEE_NM 作為主鍵,決定結果有多少行
//YM 轉換維度,決定結果有多少列,把月份作為列,有多少月份就有多少列
//TOTAL_PRICE 取值
原數(shù)據(jù)(240行-20個人12個月)
序號 | 工號 | 姓名 | 月份 | 底薪 | 獎金 | 合計 |
1 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
2 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
3 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
4 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
5 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
6 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
7 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
8 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
9 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
10 | 1005 | 練霓裳 | 2020-08 | 11000.00 | 200.00 | 10600.00 |
轉換結果(20行-20個人,12列-12個月)
工號 | 姓名 | 2020-01 | 2020-02 | 2020-03 | 2020-04 | 2020-05 | 2020-06 | 2020-07 | 2020-08 | 2020-09 | 2020-10 | 2020-11 | 2020-12 | 小計(人) |
1001 | 風清揚 | 19,400.00 | 22,600.00 | 17,100.00 | 29,000.00 | 15,900.00 | 22,700.00 | 14,900.00 | 17,500.00 | 27,000.00 | 20,100.00 | 28,100.00 | 20,900.00 | 255,200.00 |
1007 | 邀月 | 22,300.00 | 21,800.00 | 17,100.00 | 22,800.00 | 20,500.00 | 27,200.00 | 29,300.00 | 25,200.00 | 19,000.00 | 25,600.00 | 28,600.00 | 26,300.00 | 285,700.00 |
1011 | 黃藥師 | 23,800.00 | 26,900.00 | 16,500.00 | 26,300.00 | 16,400.00 | 29,000.00 | 14,400.00 | 22,400.00 | 21,400.00 | 20,600.00 | 20,100.00 | 28,300.00 | 266,100.00 |
1002 | 步驚云 | 15,800.00 | 18,800.00 | 23,000.00 | 13,700.00 | 20,500.00 | 24,600.00 | 12,100.00 | 27,200.00 | 31,300.00 | 13,800.00 | 12,000.00 | 13,500.00 | 226,300.00 |
1003 | 李尋歡 | 27,700.00 | 20,000.00 | 14,700.00 | 21,300.00 | 19,000.00 | 24,300.00 | 27,700.00 | 24,900.00 | 16,700.00 | 14,100.00 | 23,100.00 | 17,800.00 | 251,300.00 |
1015 | 燕十三 | 15,200.00 | 18,500.00 | 15,900.00 | 13,400.00 | 30,700.00 | 22,000.00 | 28,600.00 | 27,500.00 | 14,000.00 | 14,600.00 | 19,200.00 | 28,600.00 | 248,200.00 |
1008 | 王語嫣 | 14,800.00 | 28,400.00 | 27,400.00 | 27,800.00 | 19,000.00 | 24,400.00 | 29,700.00 | 24,500.00 | 19,700.00 | 14,300.00 | 27,700.00 | 23,300.00 | 281,000.00 |
1006 | 丁春秋 | 16,000.00 | 33,600.00 | 18,200.00 | 23,100.00 | 24,300.00 | 15,400.00 | 32,800.00 | 21,000.00 | 24,000.00 | 13,200.00 | 27,400.00 | 17,600.00 | 266,600.00 |
1013 | 任我行 | 22,600.00 | 30,800.00 | 27,700.00 | 11,700.00 | 33,400.00 | 10,200.00 | 10,800.00 | 18,800.00 | 19,600.00 | 15,600.00 | 21,400.00 | 31,700.00 | 254,300.00 |
1019 | 張無忌 | 17,400.00 | 12,900.00 | 13,100.00 | 19,600.00 | 16,300.00 | 30,200.00 | 16,300.00 | 18,600.00 | 15,600.00 | 26,300.00 | 22,100.00 | 26,200.00 | 234,600.00 |
1009 | 上官無極 | 30,200.00 | 29,300.00 | 11,500.00 | 29,900.00 | 28,400.00 | 22,700.00 | 30,800.00 | 19,500.00 | 15,100.00 | 31,100.00 | 21,900.00 | 26,200.00 | 296,600.00 |
1018 | 慕容復 | 24,700.00 | 18,500.00 | 15,900.00 | 26,800.00 | 14,600.00 | 15,400.00 | 19,800.00 | 9,800.00 | 19,600.00 | 29,600.00 | 14,700.00 | 24,300.00 | 233,700.00 |
1017 | 周芷若 | 30,900.00 | 15,700.00 | 13,500.00 | 14,500.00 | 30,100.00 | 27,700.00 | 26,500.00 | 15,400.00 | 29,700.00 | 14,900.00 | 31,500.00 | 19,800.00 | 270,200.00 |
1014 | 李莫愁 | 13,800.00 | 14,800.00 | 17,600.00 | 16,100.00 | 24,700.00 | 21,500.00 | 25,000.00 | 16,500.00 | 25,800.00 | 18,800.00 | 24,500.00 | 15,100.00 | 234,200.00 |
1004 | 西門吹雪 | 21,300.00 | 28,500.00 | 14,800.00 | 18,200.00 | 21,500.00 | 25,200.00 | 29,200.00 | 27,100.00 | 18,300.00 | 16,900.00 | 28,100.00 | 18,300.00 | 267,400.00 |
1016 | 燕南天 | 20,800.00 | 21,700.00 | 13,700.00 | 17,000.00 | 18,300.00 | 11,900.00 | 27,300.00 | 29,400.00 | 11,000.00 | 24,500.00 | 32,800.00 | 28,800.00 | 257,200.00 |
1005 | 練霓裳 | 23,000.00 | 19,500.00 | 15,000.00 | 27,200.00 | 33,700.00 | 32,100.00 | 13,600.00 | 17,700.00 | 19,600.00 | 33,000.00 | 24,600.00 | 19,300.00 | 278,300.00 |
1012 | 令狐沖 | 13,500.00 | 22,100.00 | 22,900.00 | 20,200.00 | 22,500.00 | 12,600.00 | 33,200.00 | 15,700.00 | 12,300.00 | 24,200.00 | 23,100.00 | 21,000.00 | 243,300.00 |
1010 | 歐陽鋒 | 18,700.00 | 15,900.00 | 27,400.00 | 26,500.00 | 31,200.00 | 14,500.00 | 31,400.00 | 14,700.00 | 27,200.00 | 27,800.00 | 20,000.00 | 22,000.00 | 277,300.00 |
1020 | 小龍女 | 31,000.00 | 18,500.00 | 16,900.00 | 17,900.00 | 14,800.00 | 28,300.00 | 21,400.00 | 26,200.00 | 22,800.00 | 26,800.00 | 26,800.00 | 21,000.00 | 272,400.00 |
小計(月) | 422,900.00 | 438,800.00 | 359,900.00 | 423,000.00 | 455,800.00 | 441,900.00 | 474,800.00 | 419,600.00 | 409,700.00 | 425,800.00 | 477,700.00 | 450,000.00 | 5,199,900.00 |
顏色尺寸二維數(shù)組交叉表格(DataSet實現(xiàn)垂直水平分組合計)

<table>
<tr class="stat">
<td>尺寸</td>
<c:forEach var="size" items="${sizes}">
<td class="number-cell">${size.NM}</td>
</c:forEach>
<td class="number-cell">合計</td>
</tr>
<c:forEach var="color" items="${colors}">
<tr>
<td class="stat">${color.NM_CN}</td>
<c:forEach var="size" items="${sizes}">
<td class="number-cell">
<al:text data="${all}" var="q" selector="SUIT_ID:${suit.ID},COLOR_ID:${color.ID},SIZE_ID:${size.ID}" property="${col}"></al:text>
${q}
</td>
</c:forEach>
<td class="color-stat stat number-cell" data-suit="${suit.ID}" data-color="${color.ID}">
<span><al:sum data="${all}" var="sumColorQ" selector="SUIT_ID:${suit.ID},COLOR_ID:${color.ID}" property="${col}"></al:sum></span>
${sumColorQ}
</td>
</tr>
</c:forEach>
<tr>
<td class="stat">合計</td>
<c:forEach var="size" items="${sizes}">
<td class="stat size-stat number-cell" data-suit="${suit.ID}" data-size="${size.ID}">
<span><al:sum data="${all}" selector="SUIT_ID:${suit.ID},SIZE_ID:${size.ID}" property="${col}"></al:sum></span>
</td>
</c:forEach>
<td class="stat all-stat number-cell" data-suit="${suit.ID}">
<span><al:sum property="${col}" data="${all}" selector="SUIT_ID:${suit.ID}"></al:sum></span>
</td>
</tr>
</table>
DataSet實現(xiàn)垂直水平分組合計
| M | L | S | 合計 |
純白 | 20 | 20 | 200 | 240 |
天藍 | 30 | 60 | 120 | 210 |
藏青 | 100 | 150 | 500 | 750 |
合計 | 150 | 230 | 820 | 1200 |
DataSet按條件過濾
查詢DataSet中SORT=1 AND AGE =20 的子集
DataSet result = set.getRows("SORT","1","AGE","20");或set.getRows("SORT:1","AGE:20");
執(zhí)行后set集合沒有改變,會生成一個新集合
DataSet移除每個條目中指定的key
移除DataSet中ID與PASSWORD屬性
set.remove("ID","PASSWORD");
DataSet計算總和
計算一列的總和
BigDecimal result = set.sum("PRICE");
計算多列總和DataRow row = set.sums("PRICE","QTY");
DataSet計算平均值
計算一列的平均值
BigDecimal result = set.avg("PRICE");
計算多列平均值DataRow row = set.avgs("PRICE","QTY");
DataSet取最大值最小值
BigDecimalresult = set.maxDecimal("PRICE");
int result = set.maxInt("AGE");
doubleresult = set.maxDouble("RATE");
取金額最大的一個條目
DataRow result = set.max("PRICE");
DataSet提取集合中一列并拼接成String
取集合中所有CODE值并以逗號拼接
String result = set.concat("CODE")
返回001,002,003
以|分隔
String result = set.concat("CODE","|")
返回001|002|003
concatNvl
concatWithoutNull
concatWithoutEmpty
DataSet抽取指定列生成新的DataSet
抽取指定列生成新的DataSet 新的DataSet只包括指定列的值與分頁信息,不包含其他附加信息(如來源表)
set.extract("ID","CODE")
新集合中只有ID,CODE兩列
DataSet合并兩個集合
set1與set2合并生成新的集合
DataSet set = set1.unionAll(set2)
合并不重復的集合,根據(jù)ID,CODE判斷是否重復
DataSet set = set1.union(set2,"ID","CODE")
查詢DataSet中AGE在20到30之間的子集
set.select.between('AGE',20,30)
查詢DataSet中CODE in(1,2,3)的子集
set.select.in("CODE",1,2,3)
查詢DataSet中PRICE>100的子集
set.select.greater("PRICE",100) // 大于100
set.select.greaterEqual("PRICE",100) // 大于等于100
移除set中指定條件的子集
先通過set.select過濾出符合移除條件的子集,再通過set與子集取差集
DataSet src
DataSet removes = src.select.between("AGE",20,30)
DataSet result = src.difference(removes,"ID"); //從當前集合中刪除set中存在的row,生成新的DataSet并不修改當前對象
或
result = src.removeAll(removes);
查詢DataSet中NAME以‘張’開頭的子集
set.select.like('NAME','張%')
set.select.startWith('NAME','張')
DataSet交集
計算兩個DataSet的交集(根據(jù)每個條目keys的屬性值判斷條目是否相同)
set1.intersection(DataSet set2, String ... keys)
如果是多個DataSet可以通過DataSet提供的的靜態(tài)方法
DataSet.intersection(List<DataSet> sets, String ... keys)
DataSet.select選擇器
DataSet.select可以實現(xiàn)類似SQL的查詢功能
//設置是否忽略大小寫
DataSet.select.setIgnoreCase(boolean bol);
/**
* 是否忽略NULL 如果設置成true 在執(zhí)行equal notEqual like contains進 null與null比較返回false
* 左右出現(xiàn)NULL時直接返回false
* true會導致一行數(shù)據(jù) equal notEqual都篩選不到
*/
DataSet.select.setIgnoreNull(boolean bol);
DataSet set = new DataSet();
//查詢key=value的子集
public DataSet set.select.equals(String key, String value);
//查詢key!=value的子集
public DataSet set.select.notEquals(String key, String value);
//篩選key列的值是否包含value的子集
public DataSet set.select.contains(String key, String value);
//篩選key列的值like pattern的子集,pattern遵循sql通配符的規(guī)則,%表示任意個字符,_表示一個字符
public DataSet like(String key, String pattern)
public DataSet notLike(String key, String pattern)
//key列以值以prefix開頭的子集
public DataSet startWith(String key, String prefix)
public DataSet endWith(String key, String suffix)
public <T> DataSet in(String key, T ... values)
public<T> DataSet in(String key, Collection<T> values)
public <T> DataSet notIn(String key, T ... values)
public<T> DataSet notIn(String key, Collection<T> values)
//keys列都為NULL的子集
public DataSet isNull(String ... keys)
//keys列都不為NULL的子集
public DataSet isNotNull(String ... keys)
//keys列都為空(null|"")的子集
public DataSet isEmpty(String ... keys)
//keys列都不為空(null|"")的子集
public DataSet isNotEmpty(String ... keys)
public <T> DataSet less(String key, T value)
public <T> DataSet lessEqual(String key, T value)
public <T> DataSet greater(String key, T value)
public <T> DataSet greaterEqual(String key, T value)
public <T> DataSet between(String key, Object min, T max)
DataSet中cut與truncate區(qū)別
cut與truncate都是根據(jù)條件截取
區(qū)別是cut會生成新的DataSet集合不影響DataSet本身
而truncate將直接在源集合上操作,改變源集合的長度
把部門=D的所有用戶,分組設置成G
new DataSet().select.equals("DEPT","D").set("GROUP","G");
DataSet實現(xiàn)分組,合并
數(shù)據(jù)庫中有以下數(shù)據(jù)
ID | USER_NM | SUBJECT | SCORE |
1 | 張三 | 語文 | 90 |
2 | 小明 | 語文 | 89 |
3 | 李四 | 語文
| 99 |
4 | 小明 | 數(shù)學 | 87 |
5 | 張三 | 數(shù)學
| 67 |
6 | 李四 | 數(shù)字
| 89 |
7 | 張三 | 英語 | 87 |
8 | 小明 | 英語
| 89 |
9 | 李四 | 英語
| 77 |
需要實現(xiàn)以下效果
1.合并單元格
序號
| 姓名
| 學科 | 成績 |
1
| 張三 | 語文 | 90 |
數(shù)學 | 67 |
英語 | 87 |
2
| 李四
| 語文
| 88 |
數(shù)學
| 99 |
英語
| 66 |
3 | 小明 | 語文
| 89 |
數(shù)學
| 76 |
英語
| 89 |
不可取的是:先查出所有用戶,再遍歷用戶列表,根據(jù)用戶查詢成績,需要4次查詢
利用DataSet可以實現(xiàn)一次查詢
DataSet set = service.query("成績表");
DataSet groups = set.group("USER_NM");
執(zhí)行后groups中有3行用戶信息,每行用戶信息中包括一個成績集合
實際環(huán)境中通常是用戶有單獨的一個表,并且查詢時需要分組,這時需要兩次查詢實現(xiàn)
1.分頁查詢用戶
DataSet users = service.query("用戶表", config(true));
2.根據(jù)用戶ID區(qū)間查詢成績
DataSet scores = service.query("成績表", "USER_ID:>="+users.getMinId("USER_ID"), "USER_ID:<="+users.getMaxId("USER_ID"));
3.將成績分配到對應的用戶
users.dispatchItem(scores,"ID:USER_ID"); //類似于SQL關聯(lián)條件中的WHERE USER.ID = SCORE.USER_ID
執(zhí)行后,每行用戶信息中包含一個成績集合
從人員列表中,查出所有不重復的部門名稱
DataSet set = service.query("HR_USER");
set.distinct("DEPARTMENT_NM"); //這里返回的還是人員列表,但一個部門只返回一個.concat("DEPARTMENT_NM"); //這里返回String并以逗號分隔:部門A,部門BList<String> departments = set.getDistinctStrings("DEPARTMENT_NM"); //這里返回一個不重復的部門名稱List
DataSet篩選不重復的數(shù)據(jù)
DataSet result = set.distinct("SORT_CODE","SORT_NM")
DataSet查詢
DataSet類似sql的查詢
DataSet set = new DataSet();
以DataSet result = set.select.equals("AGE","20")的方式調用
/**
* 是否忽略NULL 如果設置成true 在執(zhí)行equal notEqual like contains進 null與null比較返回false
* 左右出現(xiàn)NULL時直接返回false
* true會導致一行數(shù)據(jù) equal notEqual都篩選不到
*/
private boolean ignoreNull = true;
public DataSet setIgnoreCase(boolean bol)
public DataSet setIgnoreNull(boolean bol)
/**
* 篩選key=value的子集
*
* @param key key
* @param value value
* @return DataSet
*/
public DataSet equals(String key, String value)
/**
* 篩選key != value的子集
*
* @param key key
* @param value value
* @return DataSet
*/
public DataSet notEquals(String key, String value)
/**
* 篩選key列的值是否包含value的子集
*
* @param key key
* @param value value
* @return DataSet
*/
public DataSet contains(String key, String value)
/**
* 篩選key列的值like pattern的子集,pattern遵循sql通配符的規(guī)則,%表示任意個字符,_表示一個字符
*
* @param key 列
* @param pattern 表達式
* @return DataSet
*/
public DataSet like(String key, String pattern)
public DataSet notLike(String key, String pattern)
public DataSet startWith(String key, String prefix)
public DataSet endWith(String key, String suffix)
public <T> DataSet in(String key, T... values)
public <T> DataSet in(String key, Collection<T> values)
public <T> DataSet notIn(String key, T... values)
public <T> DataSet notIn(String key, Collection<T> values)
public DataSet isNull(String... keys)
public DataSet null(String... keys)
public DataSet isNotNull(String... keys)
public DataSet isEmpty(String... keys)
public DataSet empty(String... keys)
public DataSet isNotEmpty(String... keys)
public DataSet notEmpty(String... keys)
public <T> DataSet less(String key, T value)
public <T> DataSet lessEqual(String key, T value)
public <T> DataSet greater(String key, T value)
public <T> DataSet greaterEqual(String key, T value)
public <T> DataSet between(String key, T min, T max)
EntitySet
與DataSet類似,一般都是由service.querys()返回的查詢結果集
DataSet是一個DataRow的集合
EntitySet是一個Entity的集合
數(shù)據(jù)集操作
DataSet截斷
從下標0開始截斷到10,方法執(zhí)行將改變原DataSet長度
DataSet result = set.truncates(0,10)
從begin開始截斷到最后一個,如果輸入負數(shù)則取后n個,如果造成數(shù)量不足,則取全部
DataSet result = set.truncates(10);
從begin開始截斷到end位置并返回其中第一個DataRow
DataRow result = set.truncate(0,10)
truncates將修改原集合長度,如果不想修改原集合長度可以調用cuts或cut函數(shù),參數(shù)與truncates一致
更多建議: