最近在做数据同步的时候,发现同步过来的数据全是String类型,但是又不想MySQL数据库全部用varchar存储,所以写了该工具类,该工具类用于将List里全部字段为String的对象,转换成指定类型的对象。
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class StringToTargetObjConverter {
/**
* 将stringObjs中的字符串值转换为targetClass类型,并存储到新创建的对象中
* 如果转换失败,则在目标对象字段存储null值
*
* @param stringObjs 包含字符串值的对象列表
* @param targetClass 目标对象的类
* @param <T> 目标对象的类型
* @param <S> 包含字符串值的对象的类型
* @return 转换后的目标对象列表
*/
public static <T, S> List<T> convert(List<S> stringObjs, Class<T> targetClass) {
List<T> targetObjs = new ArrayList<>();
for (S stringObj : stringObjs) {
T targetObj;
try {
targetObj = targetClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Failed to create target object: " + e.getMessage());
}
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
Object value = getValueFromString(field.getType(), getStringValueFromObj(stringObj, field.getName()));
field.set(targetObj, value);
} catch (Exception e) {
try {
field.set(targetObj, null);
} catch (Exception ignored) {
}
}
}
targetObjs.add(targetObj);
}
return targetObjs;
}
/**
* 从对象中获取指定字段的字符串值
*
* @param obj 包含要获取字符串值的字段的对象
* @param fieldName 要获取值的字段名称
* @param <T> 对象的类型
* @return 字符串值
*/
private static <T> String getStringValueFromObj(T obj, String fieldName) {
try {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(obj);
if (value == null) {
return null;
}
return value.toString();
} catch (Exception e) {
return null;
}
}
/**
* 将字符串值转换为指定的类型
*
* @param clazz 目标类型
* @param valueString 要转换的字符串值
* @return 转换后的值
*/
private static Object getValueFromString(Class<?> clazz, String valueString) {
if (clazz == String.class) {
return valueString;
} else if (clazz == Integer.class || clazz == int.class) {
try {
return Integer.parseInt(valueString);
} catch (NumberFormatException e) {
return null;
}
} else if (clazz == Double.class || clazz == double.class) {
try {
return Double.parseDouble(valueString);
} catch (NumberFormatException e) {
return null;
}
} else if (clazz == Boolean.class || clazz == boolean.class) {
return Boolean.parseBoolean(valueString);
} else if (clazz == Long.class || clazz == long.class) {
try {
return Long.parseLong(valueString);
} catch (NumberFormatException e) {
return null;
}
} else if (clazz == Float.class || clazz == float.class) {
try {
return Float.parseFloat(valueString);
} catch (NumberFormatException e) {
return null;
}
} else if (clazz == LocalDateTime.class) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.parse(valueString, formatter);
} catch (Exception e) {
return null;
}
} else {
return null;
}
}
}
我们准备两个实体类做测试
StringObj
public class StringObj {
private String stringField;
private String intField;
private String doubleField;
private String booleanField;
private String dateTimeField;
public StringObj(String stringField, String intField, String doubleField, String booleanField, String dateTimeField) {
this.stringField = stringField;
this.intField = intField;
this.doubleField = doubleField;
this.booleanField = booleanField;
this.dateTimeField = dateTimeField;
}
public String getStringField() {
return stringField;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
public String getIntField() {
return intField;
}
public void setIntField(String intField) {
this.intField = intField;
}
public String getBooleanField() {
return booleanField;
}
public void setBooleanField(String booleanField) {
this.booleanField = booleanField;
}
public String getDateTimeField() {
return dateTimeField;
}
public void setDateTimeField(String dateTimeField) {
this.dateTimeField = dateTimeField;
}
public String getDoubleField() {
return doubleField;
}
public void setDoubleField(String doubleField) {
this.doubleField = doubleField;
}
}
TargetObj
import java.time.LocalDateTime;
public class TargetObj {
private String stringField;
private Integer intField;
private Double doubleField;
private Boolean booleanField;
private Long longField;
private Float floatField;
private LocalDateTime dateTimeField;
public TargetObj() {
}
public String getStringField() {
return stringField;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
public Integer getIntField() {
return intField;
}
public void setIntField(Integer intField) {
this.intField = intField;
}
public Double getDoubleField() {
return doubleField;
}
public void setDoubleField(Double doubleField) {
this.doubleField = doubleField;
}
public Boolean isBooleanField() {
return booleanField;
}
public void setBooleanField(Boolean booleanField) {
this.booleanField = booleanField;
}
public Long getLongField() {
return longField;
}
public void setLongField(Long longField) {
this.longField = longField;
}
public Float getFloatField() {
return floatField;
}
public void setFloatField(Float floatField) {
this.floatField = floatField;
}
public LocalDateTime getDateTimeField() {
return dateTimeField;
}
public void setDateTimeField(LocalDateTime dateTimeField) {
this.dateTimeField = dateTimeField;
}
}
测试方法
import com.chovy.transition.utils.StringToTargetObjConverter;
import com.chovy.transition.vo.StringObj;
import com.chovy.transition.vo.TargetObj;
import java.util.ArrayList;
import java.util.List;
public class MainTest {
public static void main(String[] args) {
List<StringObj> stringObjs = new ArrayList<>();
stringObjs.add(new StringObj("hello", "123", "12.3", "true", "2022-04-14 12:34:56"));
stringObjs.add(new StringObj("world", "456", "45.6", "false", "2022-04-15 01:23:45"));
List<TargetObj> targetObjs = StringToTargetObjConverter.convert(stringObjs, TargetObj.class);
for (TargetObj targetObj : targetObjs) {
System.out.println(targetObj.getStringField());
System.out.println(targetObj.getIntField());
System.out.println(targetObj.getDoubleField());
System.out.println(targetObj.isBooleanField());
System.out.println(targetObj.getLongField());
System.out.println(targetObj.getFloatField());
System.out.println(targetObj.getDateTimeField());
System.out.println("===========");
}
}
}
结果输出
hello
123
12.3
true
null
null
2022-04-14T12:34:56
===========
world
456
45.6
false
null
null
2022-04-15T01:23:45
===========
Process finished with exit code 0