001/** 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.row; 017 018import com.mybatisflex.core.FlexConsts; 019import com.mybatisflex.core.javassist.ModifyAttrsRecord; 020import com.mybatisflex.core.query.QueryColumn; 021import com.mybatisflex.core.util.ArrayUtil; 022import com.mybatisflex.core.util.ConvertUtil; 023import com.mybatisflex.core.util.SqlUtil; 024import com.mybatisflex.core.util.StringUtil; 025 026import java.math.BigDecimal; 027import java.math.BigInteger; 028import java.sql.Time; 029import java.sql.Timestamp; 030import java.time.LocalDateTime; 031import java.util.*; 032 033public class Row extends LinkedHashMap<String, Object> implements ModifyAttrsRecord { 034 035 //主键,多个主键用英文逗号隔开 036 private RowKey[] primaryKeys; 037 038 public static Row of(String key, Object value) { 039 Row row = new Row(); 040 return row.set(key, value); 041 } 042 043 044 private final Set<String> modifyAttrs = new LinkedHashSet<>(); 045 046 @Override 047 public Set<String> getModifyAttrs() { 048 return modifyAttrs; 049 } 050 051 052 public static Row ofKey(String primaryKey, Object value) { 053 Row row = new Row(); 054 String[] primaryKeyStrings = primaryKey.split(","); 055 row.primaryKeys = new RowKey[primaryKeyStrings.length]; 056 057 for (int i = 0; i < primaryKeyStrings.length; i++) { 058 row.primaryKeys[i] = RowKey.of(primaryKeyStrings[i].trim()); 059 } 060 061 if (primaryKeyStrings.length > 1 && !value.getClass().isArray()) { 062 throw new IllegalArgumentException("The type of \"" + value + "\" must be an array."); 063 } 064 065 if (primaryKeyStrings.length == 1) { 066 row.put(primaryKey.trim(), value); 067 } else { 068 Object[] values = (Object[]) value; 069 for (int i = 0; i < primaryKeyStrings.length; i++) { 070 row.put(primaryKeyStrings[i].trim(), values[i]); 071 } 072 } 073 return row; 074 } 075 076 public static Row ofKey(RowKey... rowKeys) { 077 Row row = new Row(); 078 row.primaryKeys = rowKeys; 079 return row; 080 } 081 082 083 public static Row ofKey(RowKey rowKey, Object value) { 084 Row row = new Row(); 085 row.primaryKeys = new RowKey[]{rowKey}; 086 row.put(rowKey.keyColumn, value); 087 return row; 088 } 089 090 091 public static Row ofKey(RowKey[] rowKeys, Object[] value) { 092 Row row = new Row(); 093 row.primaryKeys = rowKeys; 094 for (int i = 0; i < rowKeys.length; i++) { 095 row.put(rowKeys[i].keyColumn, value[i]); 096 } 097 return row; 098 } 099 100 101 public Row set(String column, Object value) { 102 if (StringUtil.isBlank(column)) { 103 throw new IllegalArgumentException("key column not be null or empty."); 104 } 105 106 SqlUtil.keepColumnSafely(column); 107 108 //覆盖 put 109 super.put(column, value); 110 111 boolean isPrimaryKey = false; 112 if (this.primaryKeys != null) { 113 for (RowKey rowKey : primaryKeys) { 114 if (rowKey.getKeyColumn().equals(column)) { 115 isPrimaryKey = true; 116 break; 117 } 118 } 119 } 120 121 if (!isPrimaryKey) { 122 addModifyAttr(column); 123 } 124 125 return this; 126 } 127 128 public Row set(QueryColumn queryColumn, Object value) { 129 return set(queryColumn.getName(), value); 130 } 131 132 133 public Object get(String key, Object defaultValue) { 134 Object result = super.get(key); 135 return result != null ? result : defaultValue; 136 } 137 138 139 @Override 140 public Object put(String key, Object value) { 141 if (!containsKey(key)) { 142 return super.put(key, value); 143 } else { 144 for (int i = 1; i < 100; i++) { 145 String newKey = key + RowUtil.INDEX_SEPARATOR + 1; 146 if (!containsKey(newKey)) { 147 return super.put(newKey, value); 148 } 149 } 150 } 151 return super.put(key, value); 152 } 153 154 155 public String getString(String key) { 156 Object s = super.get(key); 157 return s != null ? s.toString() : null; 158 } 159 160 161 public String getString(String key, String defaultValue) { 162 Object s = super.get(key); 163 if (s == null) { 164 return defaultValue; 165 } 166 String r = s.toString(); 167 return r.trim().length() == 0 ? defaultValue : r; 168 } 169 170 public Integer getInt(String key) { 171 return ConvertUtil.toInt(super.get(key)); 172 } 173 174 public Integer getInt(String key, Integer defaultValue) { 175 Integer r = ConvertUtil.toInt(super.get(key)); 176 return r != null ? r : defaultValue; 177 } 178 179 public Long getLong(String key) { 180 return ConvertUtil.toLong(super.get(key)); 181 } 182 183 public Long getLong(String key, Long defaultValue) { 184 Long r = ConvertUtil.toLong(super.get(key)); 185 return r != null ? r : defaultValue; 186 } 187 188 public Double getDouble(String key) { 189 return ConvertUtil.toDouble(super.get(key)); 190 } 191 192 public Double getDouble(String key, Double defaultValue) { 193 Double r = ConvertUtil.toDouble(super.get(key)); 194 return r != null ? r : defaultValue; 195 } 196 197 198 public Float getFloat(String key, Float defaultValue) { 199 Float r = ConvertUtil.toFloat(super.get(key)); 200 return r != null ? r : defaultValue; 201 } 202 203 public Float getFloat(String key) { 204 return ConvertUtil.toFloat(super.get(key)); 205 } 206 207 208 public Short getShort(String key, Short defaultValue) { 209 Short r = ConvertUtil.toShort(super.get(key)); 210 return r != null ? r : defaultValue; 211 } 212 213 public Short getShort(String key) { 214 return ConvertUtil.toShort(super.get(key)); 215 } 216 217 public BigInteger getBigInteger(String key) { 218 return ConvertUtil.toBigInteger(super.get(key)); 219 } 220 221 public BigInteger getBigInteger(String key, BigInteger defaultValue) { 222 BigInteger r = ConvertUtil.toBigInteger(super.get(key)); 223 return r != null ? r : defaultValue; 224 } 225 226 public BigDecimal getBigDecimal(String key) { 227 return ConvertUtil.toBigDecimal(super.get(key)); 228 } 229 230 public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) { 231 BigDecimal r = ConvertUtil.toBigDecimal(super.get(key)); 232 return r != null ? r : defaultValue; 233 } 234 235 public Boolean getBoolean(String key) { 236 return ConvertUtil.toBoolean(super.get(key)); 237 } 238 239 public Boolean getBoolean(String key, Boolean defaultValue) { 240 Boolean r = ConvertUtil.toBoolean(super.get(key)); 241 return r != null ? r : defaultValue; 242 } 243 244 public Date getDate(String key) { 245 return ConvertUtil.toDate(super.get(key)); 246 } 247 248 public Date getDate(String key, Date defaultValue) { 249 Date r = ConvertUtil.toDate(super.get(key)); 250 return r != null ? r : defaultValue; 251 } 252 253 public LocalDateTime getLocalDateTime(String key) { 254 return ConvertUtil.toLocalDateTime(super.get(key)); 255 } 256 257 public LocalDateTime getLocalDateTime(String key, LocalDateTime defaultValue) { 258 LocalDateTime r = ConvertUtil.toLocalDateTime(super.get(key)); 259 return r != null ? r : defaultValue; 260 } 261 262 public Time getTime(String key) { 263 return (Time) super.get(key); 264 } 265 266 public Time getTime(String key, Time defaultValue) { 267 Time r = (Time) super.get(key); 268 return r != null ? r : defaultValue; 269 } 270 271 public Timestamp getTimestamp(String key) { 272 return (Timestamp) super.get(key); 273 } 274 275 public Timestamp getTimestamp(String key, Timestamp defaultValue) { 276 Timestamp r = (Timestamp) super.get(key); 277 return r != null ? r : defaultValue; 278 } 279 280 public Byte getByte(String key) { 281 return ConvertUtil.toByte(super.get(key)); 282 } 283 284 public byte[] getBytes(String key) { 285 return (byte[]) super.get(key); 286 } 287 288 @Override 289 public Object remove(Object key) { 290 removeModifyAttr(key.toString()); 291 return super.remove(key); 292 } 293 294 public <T> T toEntity(Class<T> entityClass) { 295 return RowUtil.toEntity(this, entityClass); 296 } 297 298 public <T> T toObject(Class<T> objectClass) { 299 return RowUtil.toObject(this, objectClass); 300 } 301 302 public Map<String, Object> toCamelKeysMap() { 303 Map<String, Object> ret = new HashMap<>(); 304 for (String key : keySet()) { 305 ret.put(StringUtil.underlineToCamel(key), get(key)); 306 } 307 return ret; 308 } 309 310 public Map<String, Object> toUnderlineKeysMap() { 311 Map<String, Object> ret = new HashMap<>(); 312 for (String key : keySet()) { 313 ret.put(StringUtil.camelToUnderline(key), get(key)); 314 } 315 return ret; 316 } 317 318 public void prepareAttrsByKeySet(){ 319 this.modifyAttrs.clear(); 320 this.modifyAttrs.addAll(keySet()); 321 322 if (this.primaryKeys != null){ 323 for (RowKey primaryKey : primaryKeys) { 324 this.modifyAttrs.removeIf(s -> s.equalsIgnoreCase(primaryKey.getKeyColumn())); 325 } 326 } 327 } 328 329 330 public void prepareAttrsByKeySet(RowKey ... primaryKeys){ 331 this.modifyAttrs.clear(); 332 this.modifyAttrs.addAll(keySet()); 333 this.primaryKeys = primaryKeys; 334 335 for (RowKey primaryKey : primaryKeys) { 336 this.modifyAttrs.removeIf(s -> s.equalsIgnoreCase(primaryKey.getKeyColumn())); 337 } 338 } 339 340 public void prepareAttrs(Collection<String> attrs) { 341 if (attrs == null) { 342 throw new NullPointerException("attrs is null."); 343 } 344 clearModifyFlag(); 345 modifyAttrs.addAll(attrs); 346 } 347 348 public RowKey[] getPrimaryKeys() { 349 return primaryKeys; 350 } 351 352 public void setPrimaryKeys(RowKey... primaryKeys) { 353 this.primaryKeys = primaryKeys; 354 for (RowKey primaryKey : primaryKeys) { 355 this.modifyAttrs.removeIf(s -> s.equalsIgnoreCase(primaryKey.getKeyColumn())); 356 } 357 } 358 359 /** 360 * 获取修改的值,值需要保持顺序,返回的内容不包含主键的值 361 */ 362 Object[] obtainModifyValues() { 363 Object[] values = new Object[modifyAttrs.size()]; 364 int index = 0; 365 for (String modifyAttr : modifyAttrs) { 366 values[index++] = get(modifyAttr); 367 } 368 return values; 369 } 370 371 372 String[] obtainsPrimaryKeyStrings() { 373 String[] returnKeys = new String[primaryKeys.length]; 374 for (int i = 0; i < primaryKeys.length; i++) { 375 returnKeys[i] = primaryKeys[i].keyColumn; 376 } 377 return returnKeys; 378 } 379 380 381 RowKey[] obtainsPrimaryKeys() { 382 return this.primaryKeys; 383 } 384 385 386 Object[] obtainsPrimaryValues() { 387 if (ArrayUtil.isEmpty(primaryKeys)) { 388 return FlexConsts.EMPTY_ARRAY; 389 } 390 Object[] values = new Object[primaryKeys.length]; 391 for (int i = 0; i < primaryKeys.length; i++) { 392 values[i] = get(primaryKeys[i].keyColumn); 393 } 394 return values; 395 } 396 397 398 Object[] obtainAllModifyValues() { 399 return ArrayUtil.concat(obtainModifyValues(), obtainsPrimaryValues()); 400 } 401 402 403 404}