项目背景
首先我们有一套自己写的orm框架,使用上类似hibernate或spring(原理不一样,对hibernate和spring的原理也不是很清楚,总之是项目自创的),支持配置生成数据库表和table实体类,数据载入到逻辑层直接可通过实体类增删改查,table提供set get save delete方法可自动异步修改数据库,肥肠方便。
对于游戏业务,经常用到json格式,转成String存储到实体类字段中,每次读和写都要手动转化,这就比较烦了
项目需求
把json字符串的字段改成自定义结构实现Bean、BeanMap(extend HashMap implements Bean)、BeanList(extend ArrayList implements Bean),修改自定义对象的字段bean.setA(XXX)就可以自动更新到数据库,无需重新table.setB(bean)
遇到的问题
Bean的增删改查已经实现(实现方法与table实体类类似)没什么问题了
读过程String->Json->Bean 写过程Bean->Json->String,中间多了转Json操作,因为json比较好的支持String转换,key结构比较好的支持字段的增减
import com.alibaba.fastjson.JSONObject;
import com.kwai.clover.core.entity.EntityBase;
import com.kwai.clover.core.gen.JowGenFile;
import com.kwai.clover.core.gen.entity.Bean;
public final class BeanHumanInstDifficuty extends Bean {
/** 是否解锁 */
private boolean unlock;
/** 是否通关过 */
private boolean pass;
/** 通关数量 */
private int count;
public static final class K {
public static final String unlock = "u";
public static final String pass = "p";
public static final String count = "c";
}
public void setUnlock(boolean unlock) {
this.unlock = unlock;
modifyField();
}
public boolean isUnlock() {
return this.unlock;
}
public void setPass(boolean pass) {
this.pass = pass;
modifyField();
}
public boolean isPass() {
return this.pass;
}
public void setCount(int count) {
this.count = count;
modifyField();
}
public int getCount() {
return this.count;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof BeanHumanInstDifficuty) {
BeanHumanInstDifficuty p = (BeanHumanInstDifficuty)obj;
return unlock == p.unlock;
}
return false;
}
@Override
public void writeToJson(JSONObject jo) {
jo.put(K.unlock, unlock ? 1 : 0);
jo.put(K.pass, pass ? 1 : 0);
jo.put(K.count, count);
}
@Override
public void readFromJson(JSONObject jo) {
unlock = jo.getIntValue(K.unlock) == 1;
pass = jo.getIntValue(K.pass) == 1;
count = jo.getIntValue(K.count);
}
private String toBeanString() {
// TODO 不通过json转换成String
return null;
}
public static void main(String[] args) {
BeanHumanInstDifficuty bean = new BeanHumanInstDifficuty();
bean.setCount(1);
bean.setPass(true);
bean.setUnlock(true);
// 通过json转成String(下面三行在实际项目中会被封装,使用上无需手动new JSONObject())
JSONObject jo = new JSONObject();
bean.writeToJson(jo);
String result = jo.toJSONString();
// TODO 终极方法 未实现
result = bean.toBeanString();
}
}
目标是改成读过程String->Bean 写过程Bean->String,哪位大佬有什么比较好的方法吗
//--------------------------解决啦----------------------------------------
一切的打版都在fastjson里,这几天看了fastjson的源码,主要一下几点:
1.实测序列化和反序列类的速度比jsonObject要快,因为fastjson在第一次反射的时候把类信息保存到了
SerializeConfig.globalInstance中,所以不用担心反射问题,确实第一眼看上去感觉jsonObject会比类快
2.升级了到了1.2.58,只是想升级,发现最新版1.2.62的序列化和反序列化速度要比老版本和1.2.58慢很多,不知道为啥,咱也没问
3.fastjson提供了@JSONField和@JSONType辅助序列化反序列化,提供了一些过滤器和key重命名,肥肠方便。在实际项目中主要用JSONType的PropertyFilter过滤器过滤没赋值的字段,可以节省很大的空间;用JSONField的name重命名字段名,减少长度,但是耗时增长了一倍,可自行取舍。以下是注解的相关说明
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})//一般作用在字段上
public @interface JSONField {
int ordinal() default 0;//配置序列化和反序列化的顺序
String name() default "";//配置序列化和反序列化时字段的名字
String format() default "";//字段格式化,对日期很有用
boolean serialize() default true;//是否序列化
boolean deserialize() default true;//是否反序列化
SerializerFeature[] serialzeFeatures() default {};//控制序列化的一些规则,如NULL的处理
Feature[] parseFeatures() default {};//控制反序列化的一些规则
String label() default "";
boolean jsonDirect() default false;//当有一个字段是字符串类型,里面是json格式数据,希望直接输入,而不是经过转义之后再输出。
Class<?> serializeUsing() default Void.class;//对某一个类的某个属性定制序列化
Class<?> deserializeUsing() default Void.class;//对某一个类的某个属性定制反序列化
String[] alternateNames() default {};//反序列化时使用多个不同的字段名称
}
package com.alibaba.fastjson.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
@Retention(RetentionPolicy.RUNTIME)
//需要标注在类上
@Target({ ElementType.TYPE })
public @interface JSONType {
boolean asm() default true;
//这里可以定义输出json的字段顺序
String[] orders() default {};
//包含的字段
String[] includes() default {};
//不包含的字段
String[] ignores() default {};
//类级别的序列化特性定义
SerializerFeature[] serialzeFeatures() default {};
Feature[] parseFeatures() default {};
//按字母顺序进行输出
boolean alphabetic() default true;
Class<?> mappingTo() default Void.class;
Class<?> builder() default Void.class;
String typeName() default "";
String typeKey() default "";
Class<?>[] seeAlso() default{};
//序列化类
Class<?> serializer() default Void.class;
//反序列化类
Class<?> deserializer() default Void.class;
boolean serializeEnumAsJavaBean() default false;
PropertyNamingStrategy naming() default PropertyNamingStrategy.CamelCase;
Class<? extends SerializeFilter>[] serialzeFilters() default {};
}