实体类和Map类型相互转换

我们将对象数据存入redis中的hash结构时,需要将实体类的对象字段转换为hash结构的字段,不论是jedis客户端提供的hset方法还是redisTemplate提供的putAll方法,都可以通过map数据结构直接将键值对存入redis的hash中,所以有必要研究一下如何将实体类转换为map对象以及将map对象转换为实体类。
可以使用json工具类实现该功能,先将java对象序列化为json字符串,再反序列化为Map对象,这里有一个问题就是要两步才能达到目的,整体性能可想而知不会太好,如果小项目可以使用这种方式实现,主要是简单。
上面的处理方式并不好,涉及到数据的多次处理,下面介绍使用java的反射技术实现java对象向Map转换,直接上代码:

public Map<String, String> buildRedisHashData(Object obj) {
    SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    Map<String, String> data = new HashMap<>();
    Field[] fields = obj.getClass().getDeclaredFields();
    for(Field field : fields) {
        field.setAccessible(true);
        String name = field.getName();
        Object val = null;
        try {
            val = field.get(obj);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if(val == null) {
            continue;
        }
        String value = null;
        String fieldType = field.getType().getName();
        if(fieldType.equals("java.util.Date")) {
            value = dateTimeFormat.format((Date) val);
        } else {
            value = val.toString();
        }
        data.put(name, value);
    }
    return data;
}

上面的代码展示了如何将java对象转换为map,map的键为java实体类的字段名,值为字段对应的值,这里把时间类型的数据按照格式序列化为字符串。
当从redis的hash中取出数据也是一个map,这时就需要将map对象转换为java的实体类,同样可以使用反射来实现该功能:

public <T> T redisHashToObject(Map<Object, Object> data, Class<T> clazz) {
    SimpleDateFormat dateTimeFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat dateTimeFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    if(data == null) {
        return null;
    }

    try {
        T obj = clazz.getDeclaredConstructor().newInstance();
        Field[] fields = obj.getClass().getDeclaredFields();
        for(Field field : fields) {
            String name = field.getName();
            Object val = data.get(name);
            if(val == null) {
                continue;
            }
            int mod = field.getModifiers();
            // 有final、static修饰符
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            field.setAccessible(true);

            String fieldType = field.getType().getName();
            String strVal = (String) val;
            if(fieldType.equals("java.lang.String")) {
                field.set(obj, val);
            } else if(fieldType.equals("java.lang.Byte") || fieldType.equals("byte")) {
                field.set(obj, Byte.valueOf(strVal));
            } else if(fieldType.equals("java.lang.Integer") || fieldType.equals("int")) {
                field.set(obj, Integer.valueOf(strVal));
            } else if(fieldType.equals("java.lang.Double") || fieldType.equals("double")) {
                field.set(obj, Double.valueOf(strVal));
            } else if(fieldType.equals("java.lang.Float") || fieldType.equals("float")) {
                field.set(obj, Float.valueOf(strVal));
            } else if(fieldType.equals("java.lang.Long") || fieldType.equals("long")) {
                field.set(obj, Long.valueOf(strVal));
            } else if(fieldType.equals("java.lang.Short") || fieldType.equals("short")) {
                field.set(obj, Short.valueOf(strVal));
            } else if(fieldType.equals("java.lang.Boolean") || fieldType.equals("boolean")) {
                field.set(obj, Boolean.valueOf(strVal));
            } else if (fieldType.equals("java.util.Date")) {
                if(strVal.length() == 19) {
                    field.set(obj, dateTimeFormat1.parse(strVal));
                } else {
                    field.set(obj, dateTimeFormat2.parse(strVal));
                }
            } else if(fieldType.equals("java.sql.Timestamp")) {
                if(strVal.length() == 19) {
                    field.set(obj, new Timestamp(dateTimeFormat1.parse(strVal).getTime()));
                } else {
                    field.set(obj, new Timestamp(dateTimeFormat2.parse(strVal).getTime()));
                }
            } else {
                field.set(obj, val);
            }
        }

        return obj;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

上面转换时涉及到具体数据类型的处理,使用比较low的处理方式每个字段都判断数据类型,然后根据具体的数据类型进行强制类型转换。

你可能感兴趣的:(java,redis)