Redis序列



import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;


import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;


public class RedisSequenceUtil 
{

public static String SEQUENCE_PUBLIC_KEY ="SEQUENCE_PUBLIC_KEY";

public static String SEQUENCE_PICTRUE_KEY ="SEQUENCE_PICTRUE";

public static String SEQUENCE_TABLENO_KEY ="SEQUENCE_TABLENO";

public static String SEQUENCE_ORDER_KEY ="SEQUENCE_ORDER";

public static String SEQUENCE_BILL_KEY ="SEQUENCE_BILL";

public static String SEQUENCE_ACCOUNTNO_KEY ="SEQUENCE_ACCOUNTNO";

public static String SEQUENCE_TRANSCODE_KEY ="SEQUENCE_TRANSCODE";

//用户注册
public static String SEQUENCE_REGIST_KEY ="SEQUENCE_REGIST";
//需求管理
public static String SEQUENCE_DEMAND_KEY ="SEQUENCE_DEMAND";
//报价
public static String SEQUENCE_QUOTE_KEY ="SEQUENCE_QUOTE";
//上传文件
public static String UPLOAD_FILE_KEY ="UPLOAD_FILE";
//投诉
public static String COMPLAINT_KEY ="COMPLAINT";
//平台分发地接序列ID
public static String RECEPTION_DEMAND_KEY ="RECEPTION_DEMAND";
//产品
public static String PRODUCT_KEY ="PRODUCT_KEY";
//子产品
public static String SUBPRODUCT_KEY ="SUBPRODUCT_KEY";
//产品行程
public static String PRODUCT_TRIP_KEY ="PRODUCT_TRIP_KEY";
// //子产品行程
// public static String SUBPRODUCT_TRIP_KEY ="SUBPRODUCT_TRIP_KEY";
//子产品价格
public static String SUBPRODUCT_PRICE_KEY ="SUBPRODUCT_PRICE_KEY";

//交通方式
public static String TRAFFIC_KEY = "TRAFFIC_KEY";

//大交通产品订单预定关联表
public static String ORDER_RELATIVE_BIGTRAFFICE = "ORDER_RELATIVE_BIGTRAFFICE_KEY";
//大交通产品订单预定价格明细
public static String ORDER_PRICE = "ORDER_PRICE_KEY";



//图片库
//public static String PRODUCT_LIBRARY_KEY ="PRODUCT_LIBRARY";
//产品库存
public static String PRODUCT_INVENTORY_KEY ="PRODUCT_INVENTORY_KEY";
//产品库存价格
public static String PRODUCT_INVENTORY_PRICE_KEY ="PRODUCT_INVENTORY_PRICE";
//产品库存价格
public static String PRODUCT_INVENTORY_NUMBER_KEY ="PRODUCT_INVENTORY_NUMBER";
//主产品价格
public static String PRODUCT_PRICE_KEY = "PRODUCT_PRICE_KEY";
//订单日志
public static String SEQUENCE_ORDERLOGS_KEY ="SEQUENCE_ORDERLOGS";
//订单修改
public static String SEQUENCE_ORDERCHANGE_KEY ="SEQUENCE_ORDERCHANGE";
//导游信息
public static String SEQUENCE_GUIDEINFO_KEY ="SEQUENCE_GUIDEINFO";
//酒店 信息
public static String SEQUENCE_HOTELINFO_KEY ="SEQUENCE_HOTELINFO";
//购物流水信息
public static String SEQUENCE_SHOPWATERINFO_KEY ="SEQUENCE_SHOPWATERINFOINFO";
//航班信息
public static String SEQUENCE_FLIGHT_KEY ="SEQUENCE_FLIGHT";
//人员信息
public static String SEQUENCE_CUSTOMER_KEY ="SEQUENCE_CUSTOMER";
//游轮信息
public static String SEQUENCE_SHIP_KEY ="SEQUENCE_SHIP";
//订单实时结算收款
public static String SEQUENCE_RECEIVERECORD_KEY = "SEQUENCE_RECEIVERECORD";
//订单实时结算流水
public static String SEQUENCE_RECEIPTWATER_KEY = "SEQUENCE_RECEIPTWATER";
//组团社行程主表序列
public static String SEQUENCE_TRIP_KEY = "SEQUENCE_TRIP_KEY";
//组团社行程其他信息表序列
public static String SEQUENCE_TRIPITEM_KEY = "SEQUENCE_TRIPITEM_KEY";
//组团社行程图片表序列
public static String SEQUENCE_TRIPIMAGE_KEY = "SEQUENCE_TRIPIMAGE_KEY";
//平台订单审核(mge_order_check)
public static String SEQUENCE_ORDER_CHECK_KEY = "SEQUENCE_ORDER_CHECK";
//质保金及账户余额日志信息(mge_retention_log)
    public static String SEQUENCE_RETENTIONLOG_KEY ="SEQUENCE_RETENTIONLOG";

    //产品出发城市价格
public static String SEQUENCE_CITYPRICE_KEY ="SEQUENCE_CITYPRICE";

//产品分发信息
public static String SEQUENCE_DISTRIBUTE_KEY ="SEQUENCE_DISTRIBUTE";

//游客类型地接社关联
public static String SEQUENCE_TRAVELERRECEPTION_KEY ="SEQUENCE_TRAVELERRECEPTION";

    //游客类型价格设置
  public static String SEQUENCE_PRICE_KEY ="SEQUENCE_PRICE";
 
  //产品出发城市设置时间
  public static String SEQUENCE_SETTIME_KEY ="SEQUENCE_SETTIME";
 
//本地序列缓存组集合
private static Map<String, ConcurrentLinkedQueue<String> > squenceQueueMap = Collections.synchronizedMap(new HashMap<String, ConcurrentLinkedQueue<String>>());

    //redis序列缓存数
private final static  long redisSequenceSize = 100;

private static  JedisSentinelPool jedisSentinelPool;

/**
* 获取序列的值(String类型)
* @param sequenceKey
* @return
* @throws Exception 
*/
public synchronized static String getSequenceValue(String sequenceKey) throws Exception
{
String returnSeq = null;
//从本地缓存中获取序列集合

ConcurrentLinkedQueue<String> queue = squenceQueueMap.get(sequenceKey);
//如果集合对象存在
if(queue != null)
{
if(queue.isEmpty())
{
//从redis获取新的序列组,放到本地缓存
getMutiSequenceFromJedis(sequenceKey, queue);
}

}
else//集合对象不存在,说明有是一个新的序列,重新初始一个缓存序列
{
queue = new ConcurrentLinkedQueue<String>();
squenceQueueMap.put(sequenceKey, queue);
//从redis获取新的序列组,放到本地缓存
getMutiSequenceFromJedis(sequenceKey, queue);
}
returnSeq = queue.poll();
return returnSeq;
}


/**
* 获取序列的值(Long类型)
* @param sequenceKey
* @return
* @throws Exception 
* @throws NumberFormatException 
*/
public  static Long getSequenceValueToLong(String sequenceKey) throws  Exception{
return Long.parseLong(getSequenceValue(sequenceKey));
}



/**
* 从redis获取新的序列组,放到本地缓存
* @param sequenceKey
* @param vector
* @throws Exception 
*/
private static void getMutiSequenceFromJedis(String sequenceKey,ConcurrentLinkedQueue<String> queue) throws Exception
{

Jedis jedis  = getJedis();
try
{
String luaScript = "local firstNum=redis.call('INCR',KEYS[1]);local endNum=firstNum+("+String.valueOf(redisSequenceSize)+"-1);redis.call('SET',KEYS[1],endNum);return firstNum..'-'..endNum;";
//获得的值格式为 1-100  
Object mutiSeq = jedis.eval(luaScript.toString(),1,sequenceKey);
//System.out.println("sequenceNo"+ String.valueOf(mutiSeq));
String [] sequenceNo = String.valueOf(mutiSeq).split("-");
for(Long m = Long.valueOf(sequenceNo[0]);m<=Long.valueOf(sequenceNo[1]);m++)
{
queue.add(String.valueOf(m));
}
}
catch(Exception e)
{
e.printStackTrace();
throw e;
}
finally
{
releaseJedis(jedis);
}
}





/**
* 从redis获取单个序列
* @param sequenceKey
* @throws Exception 
*/
public  static Long getSingleSequenceFromJedis(String sequenceKey) throws Exception
{

Jedis jedis  = getJedis();

Long lreturnSequence = 0l;
try
{
//获得的值格式为 1-100  
lreturnSequence = jedis.incr(sequenceKey);


}
catch(Exception e)
{
e.printStackTrace();
throw e;
}
finally
{
releaseJedis(jedis);
}

return lreturnSequence;
}




/**
* 获取jedis对象
* @return
*/
    private static Jedis getJedis()
    {
    Jedis jedis=null;
    try{
    if(jedisSentinelPool==null){
       jedisSentinelPool = getJedisSentinelPool();
    }
    jedis = jedisSentinelPool.getResource();
    jedis.select(RedisDistributedUtil.SELECTDB_SEQUENCE);
    }
    catch(Exception ex){
    ex.printStackTrace();
    }
        return jedis;
    }
    
    
    /**
* 获取redis

* @param key
* @param jedisGroup
* @return
*/
private static  JedisSentinelPool getJedisSentinelPool() throws Exception{
JedisSentinelPool jedisSentinelPool = null;
List<RedisCluster> clustersList = null;
try {
clustersList = RedisConfig.redisGroupList;
    if(clustersList!=null && clustersList.size()>0){
jedisSentinelPool = RedisDistributedFactory.redisPoolMap.get(0);
    }
    else{
    throw new Exception("没有在xml文件找到有用的redis服务配置");
    }


} catch (Exception e) {
e.printStackTrace();
throw e;
}
return jedisSentinelPool;
}


    
    /**
     * 释放jedis
     * @param jedisPool
     * @return
     */
    private static void releaseJedis(Jedis jedis)
    {
    jedisSentinelPool.returnResourceObject(jedis);
    }  





}
### Redis 序列化方法及配置 #### Jackson 和 Redis 的集成 为了使 Spring Boot 项目中的 Redis 能够正确处理 Java 对象的存储与读取,Jackson 是一种常用的 JSON 处理库。通过自定义 `ObjectMapper` 并设置默认类型信息的方式可以确保对象及其子类型的完整序列化[^1]。 当使用如下代码片段时: ```java objectMapper.activateDefaultTyping( LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); ``` 这段代码的作用在于激活默认类型识别机制,并指定以数组形式包裹整个 JSON 字符串来保存类名信息。这使得即使是从 Redis 取回的数据也能被准确无误地映射回原始的对象结构而不是简单的 `LinkedHashMap` 实例。 对于最终用户来说,这意味着任何继承自非 final 基础类的具体实现都可以安全地存入并取出而不会丢失其实际类型的信息。然而需要注意的是,final 类型属性并不会参与此过程;因此这些字段将按照常规方式进行序列化/反序列化操作而不附加额外元数据。 #### 配置方式的选择 在决定采用哪种序列化策略之前,应该考虑应用程序的需求以及性能因素。例如,虽然上述提到的方法能够很好地支持多态性场景下的对象持久化需求,但它可能会增加一些开销因为每条记录都需要携带完整的类型描述信息。相比之下,其他更轻量级或者特定于应用领域模型的设计也可能更加合适取决于具体的应用环境和业务逻辑复杂度。 另外值得注意的一点是,如果选择了不同的封装风格如 `WRAPPER_OBJECT` 来代替 `WRAPPER_ARRAY`,那么所得到的结果将会是以大括号包围的形式而非方括号[]。这种差异可能会影响到后续解析阶段的行为模式,所以在做决策前应当充分评估各种选项带来的影响。 #### 如何实现正确的序列化配置 要实现在 Spring Boot 中利用 Jackson 完成对 Redis 数据源的有效管理,可以通过扩展 `RedisTemplate` 或者创建自己的序列化工厂来完成定制工作。下面是一个简单例子展示了如何注册一个带有特殊配置项(即上面讨论过的)的 `ObjectMapper` 给到模板实例上: ```java @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); // 设置序列化器 Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.activateDefaultTyping( LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY ); serializer.setObjectMapper(objectMapper); template.setValueSerializer(serializer); template.afterPropertiesSet(); return template; } ``` 以上代码段实现了为 Redis 模板指定了基于 Jackson 的 JSON 序列化工具链,并启用了必要的类型保留特性以便更好地兼容复杂的对象图谱结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值