自定义的数据库缓存层支持字段结构化——项目

项目自创ORM框架,类似Hibernate或Spring,支持自动数据库操作。面对游戏业务中JSON字段存储的需求,将JSON字符串字段改为自定义Bean结构,以实现自动更新数据库。在实现Bean的增删改查后,优化读写过程,减少Json转换。通过深入研究Fastjson源码,利用其注解如@JSONField和@JSONType进行序列化和反序列化的加速及字段过滤,提升效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目背景

    首先我们有一套自己写的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 {};
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值