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