存储、读取Json时get、set方法的拓展

经常有这样的需求:把对象转成json,存到数据库中/把json取出来,解析为对象。这些步骤一般都是手动完成的。

最近学到了一个技巧,通过改写get、set方法简化整个步骤,记录一下。

 

一、实现思路

使用mybatis(orm框架的原理都是差不多的,可以通用),使用mybatis generator生成代码。

1.一般实现思路

  1. 储存:把数据封装成HashMap,转成Json,存入数据库中
  2. 读取:把Json取出,解析为HashMap
  3. 修改:把Json取出,解析为HashMap,进行修改,再次封装成Json,存入数据库中

Status.java

很普通的一个pojo。

如果需要手动修改json,具体操作的方法为:

TestServiceImpl.java

逻辑还是比较直观的,但是我认为存在一个问题:service层最好只关注代码逻辑,“解析json”、“封装json”更像是“提供数据”,从代码结构上看,应该写在dao层。

2.我的实现思路

首先改写Status类:

Status.java

可以看到,我改写了status属性(本应该为String类型,为了方便转Json,改成HashMap),getStatus、setStatus的实现。

为什么要这样改?假如我把实现思路1中的Status.java中的get、set方法全都去掉,变成这样:

Status.java

mybatis还能正常工作吗?

显然不行啊,如果把get、set方法全都干掉,mybatis怎么能访问到id、status这两个私有属性呢?如果mybatis无法对这个status对象进行操作,怎么能解析这个对象然后入库呢?怎么从数据库取出数据然后映射成status对象呢?

“pojo要加上get、set方法”是mybatis的规范,是一种约定。mybatis的工作原理是:通过反射,可以找到类中的id、status属性,之后通过“拼接方法名称”的方式(比如status属性,先大写开头字母变成Status,set方法就加上set变成setStatus,get方法就加上get变成getStatus),得到属性的get、set方法名称。

(为什么不用反射的方式获取方法名称?这是因为,反射获取的是所有的方法名,获取的是一个Mothod数组。mybatis的目的是“调用”某个具体方法,要的是“具体方法名”,只能靠拼接)

得到方法名之后,mybatis只负责调用,不需要理会这个setStatus、getStatus具体做了什么。也就是说,我们可以改写这两个方法(只能改实现,不能改修饰符、方法名、返回值(即方法本身)),实现我们想要的骚操作。

mybatis什么时候会用到getStatus?当然是入库status对象时(insert、update),获取相应字段的数据时,才会用到get方法。

因此,可以这样改写:

最终效果为:mybatis储存status对象时,直接把(由HashMap转换得来的)json存入status字段。

mybatis什么时候会用到setStatus?当然是取出数据映射为status对象时(select),才会用到set方法。

因此,可以这样改写:

最终效果为:mybatis映射数据到status对象时,会自动把String类型的Json转化成HashMap,赋予status属性。

转换工作都由get、set方法做了,业务逻辑会变得很清爽:

TestServiceImpl.java

在service层,我们只需要专注代码逻辑的编写,不需要手动解析、封装json,结构更加合理。

二、总结

比较巧妙的技巧,把json封装、解析扔给pojo,可以优化代码的结构。

实际上,在dao自定义封装、解析的方法也可以,就是麻烦一点,没有这种方法方便。