optimize Row.java

This commit is contained in:
开源海哥 2023-04-07 17:27:39 +08:00
parent a3c43552c1
commit edeff55aba
10 changed files with 555 additions and 154 deletions

View File

@ -15,7 +15,7 @@
*/
package com.mybatisflex.core.datasource;
import com.mybatisflex.core.table.ConvertUtil;
import com.mybatisflex.core.util.ConvertUtil;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.reflection.invoker.Invoker;

View File

@ -19,6 +19,7 @@ import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.query.*;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowCPI;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.CollectionUtil;
@ -169,7 +170,7 @@ public class CommonsDialectImpl implements IDialect {
StringBuilder sql = new StringBuilder();
Set<String> modifyAttrs = row.obtainModifyAttrs();
String[] primaryKeys = row.obtainsPrimaryKeyStrings();
String[] primaryKeys = RowCPI.obtainsPrimaryKeyStrings(row);
sql.append("UPDATE ").append(wrap(tableName)).append(" SET ");
int index = 0;

View File

@ -15,9 +15,10 @@
*/
package com.mybatisflex.core.keygen;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowCPI;
import com.mybatisflex.core.row.RowKey;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.CollectionUtil;
@ -52,7 +53,7 @@ public class RowKeyGenerator implements KeyGenerator, IMultiKeyGenerator {
@Override
public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
Row row = (Row) ((Map) parameter).get(FlexConsts.ROW);
keyGenerators = buildRowKeyGenerators(row.obtainsPrimaryKeys());
keyGenerators = buildRowKeyGenerators(RowCPI.obtainsPrimaryKeys(row));
for (KeyGenerator keyGenerator : keyGenerators) {
keyGenerator.processBefore(executor, ms, stmt, parameter);
}

View File

@ -20,6 +20,7 @@ import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowCPI;
import com.mybatisflex.core.row.RowMapper;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.CollectionUtil;
@ -61,7 +62,7 @@ public class RowSqlProvider {
public static String insert(Map params) {
String tableName = ProviderUtil.getTableName(params);
Row row = ProviderUtil.getRow(params);
ProviderUtil.setSqlArgs(params, row.obtainModifyValues());
ProviderUtil.setSqlArgs(params, RowCPI.obtainModifyValues(row));
return DialectFactory.getDialect().forInsertRow(tableName, row);
}
@ -82,16 +83,15 @@ public class RowSqlProvider {
//让所有 row 的列顺序和值的数量与第条数据保持一致
//这个必须 new 一个 LinkedHashSet因为 keepModifyAttrs 会清除 row 所有的 modifyAttrs
Set<String> modifyAttrs = new LinkedHashSet<>(rows.get(0).obtainModifyAttrs());
rows.forEach(row -> row.keepModifyAttrs(modifyAttrs));
rows.forEach(row -> RowCPI.keepModifyAttrs(row, modifyAttrs));
Object[] values = new Object[]{};
for (Row row : rows) {
values = ArrayUtil.concat(values, row.obtainModifyValues());
values = ArrayUtil.concat(values, RowCPI.obtainModifyValues(row));
}
ProviderUtil.setSqlArgs(params, values);
//sql: INSERT INTO `tb_table`(`name`, `sex`) VALUES (?, ?),(?, ?),(?, ?)
return DialectFactory.getDialect().forInsertBatchWithFirstRowColumns(tableName, rows);
}
@ -144,7 +144,7 @@ public class RowSqlProvider {
public static String deleteByQuery(Map params) {
String tableName = ProviderUtil.getTableName(params);
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
CPI.setFromIfNecessary(queryWrapper,tableName);
CPI.setFromIfNecessary(queryWrapper, tableName);
Object[] valueArray = CPI.getValueArray(queryWrapper);
ProviderUtil.setSqlArgs(params, valueArray);
@ -162,7 +162,7 @@ public class RowSqlProvider {
public static String updateById(Map params) {
String tableName = ProviderUtil.getTableName(params);
Row row = ProviderUtil.getRow(params);
ProviderUtil.setSqlArgs(params, row.obtainAllModifyValues());
ProviderUtil.setSqlArgs(params, RowCPI.obtainAllModifyValues(row));
return DialectFactory.getDialect().forUpdateById(tableName, row);
}
@ -181,7 +181,7 @@ public class RowSqlProvider {
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
CPI.setFromIfNecessary(queryWrapper, tableName);
Object[] modifyValues = data.obtainModifyValues();
Object[] modifyValues = RowCPI.obtainModifyValues(data);
Object[] valueArray = CPI.getValueArray(queryWrapper);
ProviderUtil.setSqlArgs(params, ArrayUtil.concat(modifyValues, valueArray));
@ -207,7 +207,7 @@ public class RowSqlProvider {
Object[] values = new Object[0];
for (Row row : rows) {
values = ArrayUtil.concat(values, row.obtainAllModifyValues());
values = ArrayUtil.concat(values, RowCPI.obtainAllModifyValues(row));
}
ProviderUtil.setSqlArgs(params, values);
return DialectFactory.getDialect().forUpdateBatchById(tableName, rows);

View File

@ -20,12 +20,19 @@ import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.ConvertUtil;
import com.mybatisflex.core.util.SqlUtil;
import com.mybatisflex.core.util.StringUtil;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
private static final Object[] NULL_ARGS = new Object[0];
//主键多个主键用英文逗号隔开
@ -125,25 +132,156 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
}
public Object get(Object key, Object defaultValue) {
public Object get(String key, Object defaultValue) {
Object result = super.get(key);
return result != null ? result : defaultValue;
}
public String getString(String key) {
Object s = super.get(key);
return s != null ? s.toString() : null;
}
public String getString(String key, String defaultValue) {
Object s = super.get(key);
if (s == null) {
return defaultValue;
}
String r = s.toString();
return r.trim().length() == 0 ? defaultValue : r;
}
public Integer getInt(String key) {
return ConvertUtil.toInt(super.get(key));
}
public Integer getInt(String key, Integer defaultValue) {
Integer r = ConvertUtil.toInt(super.get(key));
return r != null ? r : defaultValue;
}
public Long getLong(String key) {
return ConvertUtil.toLong(super.get(key));
}
public Long getLong(String key, Long defaultValue) {
Long r = ConvertUtil.toLong(super.get(key));
return r != null ? r : defaultValue;
}
public Double getDouble(String key) {
return ConvertUtil.toDouble(super.get(key));
}
public Double getDouble(String key, Double defaultValue) {
Double r = ConvertUtil.toDouble(super.get(key));
return r != null ? r : defaultValue;
}
public Float getFloat(String key, Float defaultValue) {
Float r = ConvertUtil.toFloat(super.get(key));
return r != null ? r : defaultValue;
}
public Float getFloat(String key) {
return ConvertUtil.toFloat(super.get(key));
}
public Short getShort(String key, Short defaultValue) {
Short r = ConvertUtil.toShort(super.get(key));
return r != null ? r : defaultValue;
}
public Short getShort(String key) {
return ConvertUtil.toShort(super.get(key));
}
public BigInteger getBigInteger(String key) {
return ConvertUtil.toBigInteger(super.get(key));
}
public BigInteger getBigInteger(String key, BigInteger defaultValue) {
BigInteger r = ConvertUtil.toBigInteger(super.get(key));
return r != null ? r : defaultValue;
}
public BigDecimal getBigDecimal(String key) {
return ConvertUtil.toBigDecimal(super.get(key));
}
public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) {
BigDecimal r = ConvertUtil.toBigDecimal(super.get(key));
return r != null ? r : defaultValue;
}
public Boolean getBoolean(String key) {
return ConvertUtil.toBoolean(super.get(key));
}
public Boolean getBoolean(String key, Boolean defaultValue) {
Boolean r = ConvertUtil.toBoolean(super.get(key));
return r != null ? r : defaultValue;
}
public Date getDate(String key) {
return ConvertUtil.toDate(super.get(key));
}
public Date getDate(String key, Date defaultValue) {
Date r = ConvertUtil.toDate(super.get(key));
return r != null ? r : defaultValue;
}
public LocalDateTime getLocalDateTime(String key) {
return ConvertUtil.toLocalDateTime(super.get(key));
}
public LocalDateTime getLocalDateTime(String key, LocalDateTime defaultValue) {
LocalDateTime r = ConvertUtil.toLocalDateTime(super.get(key));
return r != null ? r : defaultValue;
}
public Time getTime(String key) {
return (Time) super.get(key);
}
public Time getTime(String key, Time defaultValue) {
Time r = (Time) super.get(key);
return r != null ? r : defaultValue;
}
public Timestamp getTimestamp(String key) {
return (Timestamp) super.get(key);
}
public Timestamp getTimestamp(String key, Timestamp defaultValue) {
Timestamp r = (Timestamp) super.get(key);
return r != null ? r : defaultValue;
}
public Byte getByte(String key) {
return ConvertUtil.toByte(super.get(key));
}
public byte[] getBytes(String key) {
return (byte[]) super.get(key);
}
@Override
public Object remove(Object key) {
removeModifyAttr(key.toString());
return super.remove(key);
}
public <T> T toEntity(Class<T> entityClass) {
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
return tableInfo.newInstanceByRow(this);
}
public Map<String, Object> toCamelKeysMap() {
Map<String, Object> ret = new HashMap<>();
for (String key : keySet()) {
@ -152,7 +290,6 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
return ret;
}
public Map<String, Object> toUnderlineKeysMap() {
Map<String, Object> ret = new HashMap<>();
for (String key : keySet()) {
@ -162,22 +299,18 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
}
public void keepModifyAttrs(Collection<String> attrs) {
void keepModifyAttrs(Collection<String> attrs) {
if (attrs == null) {
throw new NullPointerException("attrs is null.");
}
clearModifyFlag();
modifyAttrs.addAll(attrs);
}
/**
* 获取修改的值值需要保持顺序
* 返回的内容不包含主键的值
*
* @return values 数组
* 获取修改的值值需要保持顺序返回的内容不包含主键的值
*/
public Object[] obtainModifyValues() {
Object[] obtainModifyValues() {
Object[] values = new Object[modifyAttrs.size()];
int index = 0;
for (String modifyAttr : modifyAttrs) {
@ -187,7 +320,7 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
}
public String[] obtainsPrimaryKeyStrings() {
String[] obtainsPrimaryKeyStrings() {
String[] returnKeys = new String[primaryKeys.length];
for (int i = 0; i < primaryKeys.length; i++) {
returnKeys[i] = primaryKeys[i].keyColumn;
@ -196,12 +329,12 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
}
public RowKey[] obtainsPrimaryKeys() {
RowKey[] obtainsPrimaryKeys() {
return this.primaryKeys;
}
public Object[] obtainsPrimaryValues() {
Object[] obtainsPrimaryValues() {
if (ArrayUtil.isEmpty(primaryKeys)) {
return NULL_ARGS;
}
@ -213,7 +346,7 @@ public class Row extends HashMap<String, Object> implements ModifyAttrsRecord {
}
public Object[] obtainAllModifyValues() {
Object[] obtainAllModifyValues() {
return ArrayUtil.concat(obtainModifyValues(), obtainsPrimaryValues());
}

View File

@ -0,0 +1,49 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.row;
import java.util.Collection;
/**
* cross package invoker
*/
public class RowCPI {
public static void keepModifyAttrs(Row row, Collection<String> attrs) {
row.keepModifyAttrs(attrs);
}
public static Object[] obtainModifyValues(Row row) {
return row.obtainModifyValues();
}
public static String[] obtainsPrimaryKeyStrings(Row row) {
return row.obtainsPrimaryKeyStrings();
}
public static RowKey[] obtainsPrimaryKeys(Row row) {
return row.obtainsPrimaryKeys();
}
public static Object[] obtainsPrimaryValues(Row row) {
return row.obtainsPrimaryValues();
}
public static Object[] obtainAllModifyValues(Row row) {
return row.obtainAllModifyValues();
}
}

View File

@ -1,113 +0,0 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.table;
import com.mybatisflex.core.util.DateUtil;
import com.mybatisflex.core.util.StringUtil;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
public class ConvertUtil {
public static Object convert(Object value, Class<?> targetClass) {
if (value == null && targetClass.isPrimitive()){
return getPrimitiveDefaultValue(targetClass);
}
if (value == null || (targetClass != String.class && value.getClass() == String.class
&& StringUtil.isBlank((String) value))) {
return null;
}
if (value.getClass().isAssignableFrom(targetClass)) {
return value;
}
if (targetClass == String.class) {
return value.toString();
} else if (targetClass == Integer.class || targetClass == int.class) {
if (value instanceof Number) {
return ((Number) value).intValue();
}
return Integer.parseInt(value.toString());
} else if (targetClass == Long.class || targetClass == long.class) {
if (value instanceof Number) {
return ((Number) value).longValue();
}
return Long.parseLong(value.toString());
} else if (targetClass == Double.class || targetClass == double.class) {
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
return Double.parseDouble(value.toString());
} else if (targetClass == Float.class || targetClass == float.class) {
if (value instanceof Number) {
return ((Number) value).floatValue();
}
return Float.parseFloat(value.toString());
} else if (targetClass == Boolean.class || targetClass == boolean.class) {
String v = value.toString().toLowerCase();
if ("1".equals(v) || "true".equalsIgnoreCase(v)) {
return Boolean.TRUE;
} else if ("0".equals(v) || "false".equalsIgnoreCase(v)) {
return Boolean.FALSE;
} else {
throw new RuntimeException("Can not parse to boolean type of value: \"" + value + "\"");
}
} else if (targetClass == java.math.BigDecimal.class) {
return new java.math.BigDecimal(value.toString());
} else if (targetClass == java.math.BigInteger.class) {
return new java.math.BigInteger(value.toString());
} else if (targetClass == byte[].class) {
return value.toString().getBytes();
} else if (targetClass == Date.class) {
return DateUtil.parseDate(value);
} else if (targetClass == LocalDateTime.class) {
return DateUtil.toLocalDateTime(DateUtil.parseDate(value));
} else if (targetClass == LocalDate.class) {
return DateUtil.toLocalDate(DateUtil.parseDate(value));
} else if (targetClass == LocalTime.class) {
return DateUtil.toLocalTime(DateUtil.parseDate(value));
} else if (targetClass == Short.class || targetClass == short.class) {
if (value instanceof Number) {
return ((Number) value).shortValue();
}
return Short.parseShort(value.toString());
}
throw new IllegalArgumentException("\"" + targetClass.getName() + "\" can not be parsed.");
}
//Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE
public static Object getPrimitiveDefaultValue(Class<?> paraClass) {
if (paraClass == int.class || paraClass == long.class || paraClass == float.class || paraClass == double.class) {
return 0;
} else if (paraClass == boolean.class) {
return Boolean.FALSE;
} else if (paraClass == short.class) {
return (short) 0;
} else if (paraClass == byte.class) {
return (byte) 0;
} else if (paraClass == char.class) {
return '\u0000';
} else {
//不存在这种类型
return null;
}
}
}

View File

@ -23,10 +23,7 @@ import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.javassist.ModifyAttrsRecord;
import com.mybatisflex.core.mybatis.TypeHandlerObject;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.util.ArrayUtil;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.StringUtil;
import com.mybatisflex.core.util.*;
import org.apache.ibatis.mapping.ResultFlag;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
@ -406,9 +403,9 @@ public class TableInfo {
// ModifyAttrsRecord 忽略 ignoreNulls 的设置
// 当使用 ModifyAttrsRecord 可以理解为要对字段进行 null 值进行更新否则没必要使用 ModifyAttrsRecord
// if (ignoreNulls && value == null) {
// continue;
// }
// if (ignoreNulls && value == null) {
// continue;
// }
values.add(value);
}
}

View File

@ -0,0 +1,287 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.util;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.Temporal;
import java.util.Date;
public class ConvertUtil {
public static Object convert(Object value, Class<?> targetClass) {
if (value == null && targetClass.isPrimitive()) {
return getPrimitiveDefaultValue(targetClass);
}
if (value == null || (targetClass != String.class && value.getClass() == String.class
&& StringUtil.isBlank((String) value))) {
return null;
}
if (value.getClass().isAssignableFrom(targetClass)) {
return value;
}
if (targetClass == String.class) {
return value.toString();
} else if (targetClass == Integer.class || targetClass == int.class) {
if (value instanceof Number) {
return ((Number) value).intValue();
}
return Integer.parseInt(value.toString());
} else if (targetClass == Long.class || targetClass == long.class) {
if (value instanceof Number) {
return ((Number) value).longValue();
}
return Long.parseLong(value.toString());
} else if (targetClass == Double.class || targetClass == double.class) {
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
return Double.parseDouble(value.toString());
} else if (targetClass == Float.class || targetClass == float.class) {
if (value instanceof Number) {
return ((Number) value).floatValue();
}
return Float.parseFloat(value.toString());
} else if (targetClass == Boolean.class || targetClass == boolean.class) {
String v = value.toString().toLowerCase();
if ("1".equals(v) || "true".equalsIgnoreCase(v)) {
return Boolean.TRUE;
} else if ("0".equals(v) || "false".equalsIgnoreCase(v)) {
return Boolean.FALSE;
} else {
throw new RuntimeException("Can not parse to boolean type of value: \"" + value + "\"");
}
} else if (targetClass == java.math.BigDecimal.class) {
return new java.math.BigDecimal(value.toString());
} else if (targetClass == java.math.BigInteger.class) {
return new java.math.BigInteger(value.toString());
} else if (targetClass == byte[].class) {
return value.toString().getBytes();
} else if (targetClass == Date.class) {
return DateUtil.parseDate(value);
} else if (targetClass == LocalDateTime.class) {
return toLocalDateTime(value);
} else if (targetClass == LocalDate.class) {
return DateUtil.toLocalDate(DateUtil.parseDate(value));
} else if (targetClass == LocalTime.class) {
return DateUtil.toLocalTime(DateUtil.parseDate(value));
} else if (targetClass == Short.class || targetClass == short.class) {
if (value instanceof Number) {
return ((Number) value).shortValue();
}
return Short.parseShort(value.toString());
}
throw new IllegalArgumentException("\"" + targetClass.getName() + "\" can not be parsed.");
}
//Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE
public static Object getPrimitiveDefaultValue(Class<?> paraClass) {
if (paraClass == int.class || paraClass == long.class || paraClass == float.class || paraClass == double.class) {
return 0;
} else if (paraClass == boolean.class) {
return Boolean.FALSE;
} else if (paraClass == short.class) {
return (short) 0;
} else if (paraClass == byte.class) {
return (byte) 0;
} else if (paraClass == char.class) {
return '\u0000';
} else {
throw new IllegalArgumentException("Can not get primitive default value for type: " + paraClass);
}
}
public static Integer toInt(Object i) {
if (i instanceof Integer) {
return (Integer) i;
} else if (i instanceof Number) {
return ((Number) i).intValue();
}
return i != null ? Integer.parseInt(i.toString()) : null;
}
public static Long toLong(Object l) {
if (l instanceof Long) {
return (Long) l;
} else if (l instanceof Number) {
return ((Number) l).longValue();
}
return l != null ? Long.parseLong(l.toString()) : null;
}
public static Double toDouble(Object d) {
if (d instanceof Double) {
return (Double) d;
} else if (d instanceof Number) {
return ((Number) d).doubleValue();
}
return d != null ? Double.parseDouble(d.toString()) : null;
}
public static BigDecimal toBigDecimal(Object b) {
if (b instanceof BigDecimal) {
return (BigDecimal) b;
} else if (b != null) {
return new BigDecimal(b.toString());
} else {
return null;
}
}
public static BigInteger toBigInteger(Object b) {
if (b instanceof BigInteger) {
return (BigInteger)b;
}
// 数据类型 id(19 number) Oracle Jdbc 下对应的是 BigDecimal,
// 但是在 MySql 下对应的是 BigInteger这会导致在 MySql 下生成的代码无法在 Oracle 数据库中使用
if (b instanceof BigDecimal) {
return ((BigDecimal)b).toBigInteger();
} else if (b instanceof Number) {
return BigInteger.valueOf(((Number)b).longValue());
} else if (b instanceof String) {
return new BigInteger((String)b);
}
return (BigInteger)b;
}
public static Float toFloat(Object f) {
if (f instanceof Float) {
return (Float) f;
} else if (f instanceof Number) {
return ((Number) f).floatValue();
}
return f != null ? Float.parseFloat(f.toString()) : null;
}
public static Short toShort(Object s) {
if (s instanceof Short) {
return (Short) s;
} else if (s instanceof Number) {
return ((Number) s).shortValue();
}
return s != null ? Short.parseShort(s.toString()) : null;
}
public static Byte toByte(Object b) {
if (b instanceof Byte) {
return (Byte) b;
} else if (b instanceof Number) {
return ((Number) b).byteValue();
}
return b != null ? Byte.parseByte(b.toString()) : null;
}
public static Boolean toBoolean(Object b) {
if (b instanceof Boolean) {
return (Boolean) b;
} else if (b == null) {
return null;
}
// 支持 Number 之下的整数类型
if (b instanceof Number) {
int n = ((Number) b).intValue();
if (n == 1) {
return Boolean.TRUE;
} else if (n == 0) {
return Boolean.FALSE;
}
throw new IllegalArgumentException("Can not support convert: \"" + b + "\" to boolean.");
}
// 支持 String
if (b instanceof String) {
String s = b.toString();
if ("true".equalsIgnoreCase(s) || "1".equals(s)) {
return Boolean.TRUE;
} else if ("false".equalsIgnoreCase(s) || "0".equals(s)) {
return Boolean.FALSE;
}
}
return (Boolean) b;
}
public static Number toNumber(Object o) {
if (o instanceof Number) {
return (Number) o;
} else if (o == null) {
return null;
}
String s = o.toString();
return s.indexOf('.') != -1 ? Double.parseDouble(s) : Long.parseLong(s);
}
public static Date toDate(Object o) {
if (o instanceof Date) {
return (Date) o;
}
if (o instanceof Temporal) {
if (o instanceof LocalDateTime) {
return DateUtil.toDate((LocalDateTime) o);
}
if (o instanceof LocalDate) {
return DateUtil.toDate((LocalDate) o);
}
if (o instanceof LocalTime) {
return DateUtil.toDate((LocalTime) o);
}
}
if (o instanceof String) {
String s = (String) o;
return DateUtil.parseDate(s);
}
return (java.util.Date) o;
}
public static LocalDateTime toLocalDateTime(Object o) {
if (o instanceof LocalDateTime) {
return (LocalDateTime) o;
}
if (o instanceof java.util.Date) {
return DateUtil.toLocalDateTime((java.util.Date) o);
}
if (o instanceof LocalDate) {
return ((LocalDate) o).atStartOfDay();
}
if (o instanceof LocalTime) {
return LocalDateTime.of(LocalDate.now(), (LocalTime) o);
}
if (o instanceof String) {
String s = (String) o;
return DateUtil.parseLocalDateTime(s);
}
return (LocalDateTime) o;
}
}

View File

@ -20,13 +20,14 @@ import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author michael yang (fuhai999@gmail.com)
*/
public class DateUtil {
public static String datePatternWithoutDividing = "yyyyMMdd";
@ -39,6 +40,16 @@ public class DateUtil {
private static final ThreadLocal<HashMap<String, SimpleDateFormat>> TL = ThreadLocal.withInitial(() -> new HashMap<>());
private static final Map<String, DateTimeFormatter> dateTimeFormatters = new ConcurrentHashMap<>();
public static DateTimeFormatter getDateTimeFormatter(String pattern) {
DateTimeFormatter ret = dateTimeFormatters.get(pattern);
if (ret == null) {
ret = DateTimeFormatter.ofPattern(pattern);
dateTimeFormatters.put(pattern, ret);
}
return ret;
}
public static SimpleDateFormat getSimpleDateFormat(String pattern) {
SimpleDateFormat ret = TL.get().get(pattern);
@ -54,8 +65,6 @@ public class DateUtil {
}
public static Date parseDate(Object value) {
if (value instanceof Number) {
return new Date(((Number) value).longValue());
@ -122,6 +131,45 @@ public class DateUtil {
}
public static LocalDateTime parseLocalDateTime(String dateString) {
if (StringUtil.isBlank(dateString)) {
return null;
}
dateString = dateString.trim();
DateTimeFormatter dateTimeFormatter = getDateTimeFormatter(getPattern(dateString));
try {
return LocalDateTime.parse(dateString, dateTimeFormatter);
} catch (Exception ex) {
//2022-10-23 00:00:00.0
int lastIndexOf = dateString.lastIndexOf(".");
if (lastIndexOf == 19) {
return parseLocalDateTime(dateString.substring(0, lastIndexOf));
}
//2022-10-23 00:00:00,0
lastIndexOf = dateString.lastIndexOf(",");
if (lastIndexOf == 19) {
return parseLocalDateTime(dateString.substring(0, lastIndexOf));
}
//2022-10-23 00:00:00 000123
lastIndexOf = dateString.lastIndexOf(" ");
if (lastIndexOf == 19) {
return parseLocalDateTime(dateString.substring(0, lastIndexOf));
}
if (dateString.contains(".") || dateString.contains("/")) {
dateString = dateString.replace(".", "-").replace("/", "-");
dateTimeFormatter = getDateTimeFormatter(getPattern(dateString));
return LocalDateTime.parse(dateString, dateTimeFormatter);
} else {
throw ex;
}
}
}
private static String getPattern(String dateString) {
int length = dateString.length();
if (length == datetimePattern.length()) {
@ -145,7 +193,6 @@ public class DateUtil {
}
public static LocalDateTime toLocalDateTime(Date date) {
if (date == null) {
return null;
@ -177,7 +224,6 @@ public class DateUtil {
}
public static LocalTime toLocalTime(Date date) {
if (date == null) {
return null;