1.数据库设计
1.1 表设计
create table variables
(
id bigint not null comment '主键',
business_key varchar(128) null comment '业务key',
data_key varchar(128) null comment 'Map中的key',
data_value varchar(255) null comment 'Map中的value',
data_type varchar(32) null comment '数据类型',
created datetime null comment '创建时间',
modified datetime null comment '修改时间',
yn int null comment '数据是否有效,1:有效,0:无效'
)
comment '自定义变量表';
2.程序逻辑
2.0 原始要保存数据saveMap(仅仅支持所有的基本类型):
char[] charArray = "2".toCharArray();
Character c = new Character(charArray[0]);
boolean bool = Boolean.TRUE;
Byte byte2 = new Byte("9");
byte byt = 8;
Short aShort = new Short("12");
short st = 56;
long l = 22;
Long l2 = new Long("23");
Map<String, Object> saveMap = new HashMap<String, Object>();
saveMap.put("int", 12);
saveMap.put("Integer", new Integer(180));
saveMap.put("double", 12.0);
saveMap.put("Double", new Double(180));
saveMap.put("char", charArray[0]);
saveMap.put("Character", c);
saveMap.put("boolean", bool);
saveMap.put("Boolean", Boolean.FALSE);
saveMap.put("byt", byt);
saveMap.put("Byte", byte2);
saveMap.put("short", st);
saveMap.put("Short", aShort);
saveMap.put("long", l);
saveMap.put("Long", l2);
saveMap.put("float", 36.12);
saveMap.put("Float", new Float("35.64"));
saveMap.put("String", "NIKE");
Map map1 = new HashMap<>();
map1.put(1, 12);
saveMap.put("map1", map1);
List<Long> list1 = new ArrayList();
list1.add(2000L);
saveMap.put("list1", list1);
Date date = new Date();
saveMap.put("Date", date);
LocalDate localDate = LocalDate.now();
saveMap.put("localDate", localDate);
TestPersons testPerson = new TestPersons();
saveMap.put("testPerson", testPerson);
saveMap.put("BigDecimal", new BigDecimal("12.36"));
内部类
@Data
static class TestPersons {
private String name = "Nike";
private Integer age = 26;
}
public static boolean mapIsEqual(Map<?, ?> map1, Map<?, ?> map2) {
if (map1 == null || map2 == null) {
return map1 == map2;
}
if (map1.size() != map2.size()) {
return false;
}
for (Map.Entry<?, ?> entry : map1.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
if (!map2.containsKey(key) || !map2.get(key).equals(value)) {
return false;
}
}
return true;
}
2.1 第一步:模拟保存到数据库,将value与key、数据类型保存到数据库
// 模拟保存数据库
Map<String, String> dbJsonMap = new HashMap<String, String>();
for (Map.Entry<String, Object> entry : saveMap.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
String dataType = getPackagingPrimitiveType(value);
dbJsonMap.put(key, JSON.toJSONString(entry.getValue()));
// 保存到数据库....省略,要保持的值为key、value、dataType
}
2.2 第二步:从数据库取回数据并转换,假定转换后的数据为 returnMap
// 从数据库查询数据并转换,假定从数据库查询回来的数据为 dbJsonMap
Map<String, Object> returnMap = new HashMap<String, Object>();
// 模拟从数据库取回数据,并转换得到returnMap。如果程序运行正常returnMap与原石的saveMap应该完全一致
for (Map.Entry<String, String> entry : dbJsonMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
String dataType = getPackagingPrimitiveType(saveMap.get(key));
// 假设key、value、dataType是从数据库取回的
Object originTypeValue = getObjectByDataType(dataType, value);
returnMap.put(key, originTypeValue);
}
2.3 第三步:对比原始的saveMap是否与returnMap完全一致
boolean equal = mapIsEqual(saveMap, returnMap);
if (equal) {
System.out.println("保存到数据库中的saveMap与从数据库查取回并转换后的returnMap完全一致");
}
public static boolean mapIsEqual(Map<?, ?> map1, Map<?, ?> map2) {
if (map1 == null || map2 == null) {
return map1 == map2;
}
if (map1.size() != map2.size()) {
return false;
}
for (Map.Entry<?, ?> entry : map1.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
if (!map2.containsKey(key) || !map2.get(key).equals(value)) {
return false;
}
}
return true;
}
2.4 用到的工具类
/**
* 将JSON字符串转换为对应实例类型
* @param dataType dataType
* @param value value
* @return 转换后的类型
*/
static Object getObjectByDataType(String dataType, String value) {
if (StringUtils.isBlank(dataType) || StringUtils.isBlank(value)) {
return null;
}
return JSON.parseObject(value, getInitialTypeClass(dataType));
}
/**
* 数据类型判断
* @param obj obj
* @return 数据类型
*/
static String getPackagingPrimitiveType(Object obj) {
if (obj == null) {
return null;
}
// 初始类型
if (obj == int.class) {
return "int";
} else if (obj == double.class) {
return "double";
} else if (obj == char.class) {
return "char";
} else if (obj == boolean.class) {
return "boolean";
} else if (obj == byte.class) {
return "byte";
} else if (obj == short.class) {
return "short";
} else if (obj == long.class) {
return "long";
} else if (obj == float.class) {
return "float";
// 包装类型
} else if (obj instanceof Integer) {
return "Integer";
} else if (obj instanceof Double) {
return "Double";
} else if (obj instanceof Character) {
return "Character";
} else if (obj instanceof Boolean) {
return "Boolean";
} else if (obj instanceof Byte) {
return "Byte";
} else if (obj instanceof Short) {
return "Short";
} else if (obj instanceof Long) {
return "Long";
} else if (obj instanceof Float) {
return "Float";
} else if (obj instanceof String) {
return "String";
} else if (obj instanceof BigDecimal) {
return "BigDecimal";
} else if (obj instanceof Map) {
return "Map";
} else if (obj instanceof List) {
return "List";
} else if (obj instanceof Date) {
return "Date";
} else if (obj instanceof LocalDate) {
return "LocalDate";
} else if (obj instanceof Object) {
return "Object";
} else {
throw new RuntimeException("数据类型判断-参数不是基本包装数据类型");
}
}
/**
* 获取实例类型
* @param dataType dataType
* @return 实例类型
*/
static Class<?> getInitialTypeClass(String dataType) {
if (dataType == null) {
return null;
}
if ("int".equals(dataType)) {
return int.class;
} else if ("double".equals(dataType)) {
return double.class;
} else if ("char".equals(dataType)) {
return char.class;
} else if ("boolean".equals(dataType)) {
return boolean.class;
} else if ("byte".equals(dataType)) {
return byte.class;
} else if ("short".equals(dataType)) {
return short.class;
} else if ("long".equals(dataType)) {
return long.class;
} else if ("float".equals(dataType)) {
return float.class;
} else if ("Integer".equals(dataType)) {
return Integer.class;
} else if ("Double".equals(dataType)) {
return Double.class;
} else if ("Character".equals(dataType)) {
return Character.class;
} else if ("Boolean".equals(dataType)) {
return Boolean.class;
} else if ("Byte".equals(dataType)) {
return Byte.class;
} else if ("Short".equals(dataType)) {
return Short.class;
} else if ("Long".equals(dataType)) {
return Long.class;
} else if ("Float".equals(dataType)) {
return Float.class;
} else if ("String".equals(dataType)) {
return String.class;
} else if ("BigDecimal".equals(dataType)) {
return BigDecimal.class;
} else if ("Map".equals(dataType)) {
return Map.class;
} else if ("List".equals(dataType)) {
return List.class;
} else if ("Date".equals(dataType)) {
return Date.class;
} else if ("LocalDate".equals(dataType)) {
return LocalDate.class;
} else if ("Object".equals(dataType)) {
return Object.class;
} else {
throw new RuntimeException("获取实例类型-参数不是基本包装数据类型");
}
}
3.完整代码
public static void main(String[] args) {
char[] charArray = "2".toCharArray();
Character c = new Character(charArray[0]);
boolean bool = Boolean.TRUE;
Byte byte2 = new Byte("9");
byte byt = 8;
Short aShort = new Short("12");
short st = 56;
long l = 22;
Long l2 = new Long("23");
Map<String, Object> saveMap = new HashMap<String, Object>();
saveMap.put("int", 12);
saveMap.put("Integer", new Integer(180));
saveMap.put("double", 12.0);
saveMap.put("Double", new Double(180));
saveMap.put("char", charArray[0]);
saveMap.put("Character", c);
saveMap.put("boolean", bool);
saveMap.put("Boolean", Boolean.FALSE);
saveMap.put("byt", byt);
saveMap.put("Byte", byte2);
saveMap.put("short", st);
saveMap.put("Short", aShort);
saveMap.put("long", l);
saveMap.put("Long", l2);
saveMap.put("float", 36.12);
saveMap.put("Float", new Float("35.64"));
saveMap.put("String", "NIKE");
Map map1 = new HashMap<>();
map1.put(1, 12);
saveMap.put("map1", map1);
List<Long> list1 = new ArrayList();
list1.add(2000L);
saveMap.put("list1", list1);
Date date = new Date();
saveMap.put("Date", date);
LocalDate localDate = LocalDate.now();
saveMap.put("localDate", localDate);
TestPersons testPerson = new TestPersons();
saveMap.put("testPerson", testPerson);
saveMap.put("BigDecimal", new BigDecimal("12.36"));
// 模拟保存数据库
Map<String, String> dbJsonMap = new HashMap<String, String>();
for (Map.Entry<String, Object> entry : saveMap.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
String dataType = getPackagingPrimitiveType(value);
dbJsonMap.put(key, JSON.toJSONString(entry.getValue()));
// 保存到数据库....省略,要保持的值为key、value、dataType
}
// 从数据库查询数据并转换,假定从数据库查询回来的数据为 dbJsonMap
Map<String, Object> returnMap = new HashMap<String, Object>();
// 模拟从数据库取回数据,并转换得到returnMap。如果程序运行正常returnMap与原石的saveMap应该完全一致
for (Map.Entry<String, String> entry : dbJsonMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
String dataType = getPackagingPrimitiveType(saveMap.get(key));
// 假设key、value、dataType是从数据库取回的
Object originTypeValue = getObjectByDataType(dataType, value);
returnMap.put(key, originTypeValue);
}
boolean equal = mapIsEqual(saveMap, returnMap);
if (equal) {
System.out.println("保存到数据库中的saveMap与从数据库查取回并转换后的returnMap完全一致");
}
}
@Data
static class TestPersons {
private String name = "Nike";
private Integer age = 26;
}
public static boolean mapIsEqual(Map<?, ?> map1, Map<?, ?> map2) {
if (map1 == null || map2 == null) {
return map1 == map2;
}
if (map1.size() != map2.size()) {
return false;
}
for (Map.Entry<?, ?> entry : map1.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
if (!map2.containsKey(key) || !map2.get(key).equals(value)) {
return false;
}
}
return true;
}
/**
* 将JSON字符串转换为对应实例类型
* @param dataType dataType
* @param value value
* @return 转换后的类型
*/
static Object getObjectByDataType(String dataType, String value) {
if (StringUtils.isBlank(dataType) || StringUtils.isBlank(value)) {
return null;
}
return JSON.parseObject(value, getInitialTypeClass(dataType));
}
/**
* 数据类型判断
* @param obj obj
* @return 数据类型
*/
static String getPackagingPrimitiveType(Object obj) {
if (obj == null) {
return null;
}
// 初始类型
if (obj == int.class) {
return "int";
} else if (obj == double.class) {
return "double";
} else if (obj == char.class) {
return "char";
} else if (obj == boolean.class) {
return "boolean";
} else if (obj == byte.class) {
return "byte";
} else if (obj == short.class) {
return "short";
} else if (obj == long.class) {
return "long";
} else if (obj == float.class) {
return "float";
// 包装类型
} else if (obj instanceof Integer) {
return "Integer";
} else if (obj instanceof Double) {
return "Double";
} else if (obj instanceof Character) {
return "Character";
} else if (obj instanceof Boolean) {
return "Boolean";
} else if (obj instanceof Byte) {
return "Byte";
} else if (obj instanceof Short) {
return "Short";
} else if (obj instanceof Long) {
return "Long";
} else if (obj instanceof Float) {
return "Float";
} else if (obj instanceof String) {
return "String";
} else if (obj instanceof BigDecimal) {
return "BigDecimal";
} else if (obj instanceof Map) {
return "Map";
} else if (obj instanceof List) {
return "List";
} else if (obj instanceof Date) {
return "Date";
} else if (obj instanceof LocalDate) {
return "LocalDate";
} else if (obj instanceof Object) {
return "Object";
} else {
throw new RuntimeException("数据类型判断-参数不是基本包装数据类型");
}
}
/**
* 获取实例类型
* @param dataType dataType
* @return 实例类型
*/
static Class<?> getInitialTypeClass(String dataType) {
if (dataType == null) {
return null;
}
if ("int".equals(dataType)) {
return int.class;
} else if ("double".equals(dataType)) {
return double.class;
} else if ("char".equals(dataType)) {
return char.class;
} else if ("boolean".equals(dataType)) {
return boolean.class;
} else if ("byte".equals(dataType)) {
return byte.class;
} else if ("short".equals(dataType)) {
return short.class;
} else if ("long".equals(dataType)) {
return long.class;
} else if ("float".equals(dataType)) {
return float.class;
} else if ("Integer".equals(dataType)) {
return Integer.class;
} else if ("Double".equals(dataType)) {
return Double.class;
} else if ("Character".equals(dataType)) {
return Character.class;
} else if ("Boolean".equals(dataType)) {
return Boolean.class;
} else if ("Byte".equals(dataType)) {
return Byte.class;
} else if ("Short".equals(dataType)) {
return Short.class;
} else if ("Long".equals(dataType)) {
return Long.class;
} else if ("Float".equals(dataType)) {
return Float.class;
} else if ("String".equals(dataType)) {
return String.class;
} else if ("BigDecimal".equals(dataType)) {
return BigDecimal.class;
} else if ("Map".equals(dataType)) {
return Map.class;
} else if ("List".equals(dataType)) {
return List.class;
} else if ("Date".equals(dataType)) {
return Date.class;
} else if ("LocalDate".equals(dataType)) {
return LocalDate.class;
} else if ("Object".equals(dataType)) {
return Object.class;
} else {
throw new RuntimeException("获取实例类型-参数不是基本包装数据类型");
}
}