可信赖的企业网站开发,个人音乐网站免费建设,企业展厅策划方案,东莞大岭山楼盘一.基础数据回显说明
微服务项目中由于从服务独立的角度考虑#xff0c;对数据库做了分库的处理。对于基础数据表来说#xff0c;各个服务都是需要的。项目中在使用基础数据时#xff0c;往往是在sql中写连接然后获取基础数据的名称。例#xff1a;
select wi.name,bc.ci…一.基础数据回显说明
微服务项目中由于从服务独立的角度考虑对数据库做了分库的处理。对于基础数据表来说各个服务都是需要的。项目中在使用基础数据时往往是在sql中写连接然后获取基础数据的名称。例
select wi.name,bc.city_namefrom wms_info wileft join bas_city bc on wi.city_code bc.city_codewhere wi.id#{id}
由于做了分库处理要保证各个业务库中都存一份基础数据表并且保证基础数据一致是很难做到的。这里我们用另外一种方式替换sql中的连接处理实现基础数据回显功能。
实现思路:将基础数据缓存到redis中数据发送给第三方或者web前端页面时在做序列化的时间节点将基础数据代码替换为基础数名称。
二.序列化和反序列化
当两个进程进行远程通信时可以相互发送各种类型的数据包括文本、图片、音频、视频等 而这些数据都会以二进制序列的形式在网络上传送。而 java 是面向对象的开发方式一切都是 java 对象想要实现 java 对象的网络传输就可以使用序列化和反序列化来实现。发送方将需要发送的 Java 对象序列化转换为字节序列然后在网络上传送接收方接收到字符序列后使用反序列化从字节序列中恢复出 Java 对象。在网络中数据的传输必须是序列化形式来进行的。
序列化执行时间节点。
响应处理Response Handling当一个Spring Boot应用的控制器方法处理完请求后返回的对象会被自动序列化为JSON如果使用了Spring MVC的默认配置。使用RestTemplate或WebClient在使用这些Spring提供的REST客户端发送请求时对象会在发送前被序列化为JSON或其他格式。
三.代码实现
1.基础数据回显类型枚举
package infosky.dmsp.util.redisBas;import lombok.AllArgsConstructor;
import lombok.Getter;/*** 基础数据回显类型枚举*/
Getter
AllArgsConstructor
public enum RedisBasTypeEnum {/*** 承运人*/DMSP_BAS_CARRIER(dmsp_bas_carrier),/*** 城市*/DMSP_BAS_CITY(dmsp_bas_city);private final String key;
}
2.自定义基础数据回显注解
package infosky.dmsp.util.redisBas;import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 基础数据回显注解* -将基础数据保存到redis中业务数据中存基础数据主键通过本注解将主键转换为表示值*/
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
JacksonAnnotationsInside
JsonSerialize(using RedisBasSerializer.class)
public interface RedisBas {//缓存的数据类型RedisBasTypeEnum type();
}
3.自定义序列化 用于将基础数据key转换成显示值
package infosky.dmsp.util.redisBas;import java.io.IOException;
import java.util.Objects;
import org.springframework.data.redis.core.RedisTemplate;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import infosky.dmsp.util.SpringContextUtils;/*** 自定义序列化 用于将基础数据key转换成显示值* ※springboot默认使用JsonSerializer作为序列化处理器* StdSerializer继承自JsonSerializer*/
public class RedisBasSerializer extends StdSerializerObject implements ContextualSerializer {private static final long serialVersionUID 1L;private RedisBasTypeEnum type;public RedisBasSerializer() {super(Object.class);}public RedisBasSerializer(RedisBasTypeEnum type) {super(Object.class);this.type type;}Overridepublic void serialize(Object value, JsonGenerator jg, SerializerProvider sp) throws IOException {if(Objects.isNull(value)) {jg.writeObject(value);return;}RedisTemplate rt (RedisTemplate)SpringContextUtils.getBean(redisTemplate);Object bas rt.boundHashOps(type.getKey()).get(value);if(bas ! null) {jg.writeObject(bas);}else {jg.writeObject(value);}}/*** 获取属性上的注解属性*/Overridepublic JsonSerializer? createContextual(SerializerProvider sp, BeanProperty bp) throws JsonMappingException {if (bp ! null) {if (Objects.equals(bp.getType().getRawClass(), String.class)) {RedisBas de bp.getAnnotation(RedisBas.class);if (de null) {de bp.getContextAnnotation(RedisBas.class);}if (de ! null) {return new RedisBasSerializer(de.type());}}return sp.findValueSerializer(bp.getType(), bp);}return sp.findNullValueSerializer(null);}
}
4.项目启动后将基础数据缓存到redis中
package infosky.dmsp.init;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import infosky.dmsp.common.CommonConstants;
import infosky.dmsp.dao.BasCarrierMapper;
import infosky.dmsp.entity.BasCarrier;
import infosky.dmsp.entity.BasCarrierExample;/*** 初始化时将基础数据保存到redis中* ※实现ApplicationRunner接口项目启动后就会直接这些run方法*/
Component
public class InitBas implements ApplicationRunner{private Logger logger LoggerFactory.getLogger(this.getClass());Autowiredprivate RedisTemplate redisTemplate;Autowiredprivate BasCarrierMapper basCarrierMapper;/*** 加载权限数据*/Overridepublic void run(ApplicationArguments args) throws Exception {//■1.删除redis中旧全部航司基础数据 ※dmsp_bas_carrierredisTemplate.delete(dmsp_bas_carrier);//■2.加载全部航司基础数据到redissaveAllBasCarrier2Redis();}/*** 加载全部航司基础数据到redis*/private void saveAllBasCarrier2Redis(){//获取全部航司基础数据//构造查询条件BasCarrierExample bce new BasCarrierExample();BasCarrierExample.Criteria ca bce.createCriteria();ListBasCarrier lstBc basCarrierMapper.selectByExample(bce);//构造redis中需要航司基础数据的map ※CA:Air China:中国国际航空公司MapString,String basCarrierMap new HashMap();for(BasCarrier bc : lstBc){basCarrierMap.put(bc.getCarrierId(), bc.getCarrierNameCn());}redisTemplate.boundHashOps(dmsp_bas_carrier).putAll(basCarrierMap);}
}
以下为测试代码
5.测试实体
package infosky.dmsp.util.redisBas;import lombok.Data;
import lombok.ToString;/*** 测试实体*/
Data
ToString
public class ExampleRedisBasEntity {//基础数据缓存注解这个type值要和缓存key对应上RedisBas(typeRedisBasTypeEnum.DMSP_BAS_CARRIER)private String carrier;private String msg;
}
6.测试controller类
package infosky.dmsp.util.redisBas;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 测试接口* -基础数据表示值从缓存中读出* -在前端页面 or postman中可确认脱敏数据*/
RestController
RequestMapping(/redisBas)
public class ExampleRedisBasController {RequestMapping(/example)public ExampleRedisBasEntity example() {ExampleRedisBasEntity ee new ExampleRedisBasEntity();ee.setCarrier(CA);ee.setMsg(测试从缓存中读取基础数据);System.out.println(ee);return ee;}
}
四.测试结果
1.后端日志 2.页面传输结果