ProtoBuf是一種序列化和解析速度遠高于JSON和XML的資料格式,項目中使用了CouchBase作為緩存伺服器,從資料庫中拿到資料後通過protobuf序列化後放入CouchBase作為緩存,查詢資料的時候解壓并反序列化成資料對象,下面是ProtoBuf的具體使用方法
1、pom.xml引入相關依賴
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>io.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.4.0</version>
</dependency>
2、建立序列化工具類ProtoBufUtil.java
package com.xrq.demo.utils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.objenesis.Objenesis;
import org.springframework.objenesis.ObjenesisStd;
import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;
/**
* ProtoBufUtil 轉換工具類
*
* @author XRQ
*
*/
public class ProtoBufUtil {
private static Logger log = LoggerFactory.getLogger(ProtoBufUtil.class);
private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<Class<?>, Schema<?>>();
private static Objenesis objenesis = new ObjenesisStd(true);
@SuppressWarnings("unchecked")
private static <T> Schema<T> getSchema(Class<T> cls) {
Schema<T> schema = (Schema<T>) cachedSchema.get(cls);
if (schema == null) {
schema = RuntimeSchema.createFrom(cls);
if (schema != null) {
cachedSchema.put(cls, schema);
}
}
return schema;
}
public ProtoBufUtil() {
}
@SuppressWarnings({ "unchecked" })
public static <T> byte[] serializer(T obj) {
Class<T> cls = (Class<T>) obj.getClass();
LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
try {
Schema<T> schema = getSchema(cls);
return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
} catch (Exception e) {
log.error("protobuf序列化失敗");
throw new IllegalStateException(e.getMessage(), e);
} finally {
buffer.clear();
}
}
public static <T> T deserializer(byte[] bytes, Class<T> clazz) {
try {
T message = (T) objenesis.newInstance(clazz);
Schema<T> schema = getSchema(clazz);
ProtostuffIOUtil.mergeFrom(bytes, message, schema);
return message;
} catch (Exception e) {
log.error("protobuf反序列化失敗");
throw new IllegalStateException(e.getMessage(), e);
}
}
}
3、建立實體類User.java(注:重點是@Tag标簽需要按照順序往下排,如果需要新增字段,隻能接着往下排,不能改變已存在的标簽序号)
package com.xrq.demo.bo;
import java.io.Serializable;
import java.util.Date;
import io.protostuff.Tag;
/**
* 使用者資訊類
*
* @ClassName: User
* @author XRQ
* @date 2019年4月30日
*/
public class User implements Serializable
{
private static final long serialVersionUID = 1L;
// 使用者ID
@Tag(1)
private int userId;
// 使用者類型
@Tag(2)
private int userTypeId;
// 使用者名
@Tag(3)
private String userName;
// 建立時間
@Tag(4)
private Date createDateTime;
public int getUserId()
{
return userId;
}
public void setUserId(int userId)
{
this.userId = userId;
}
public int getUserTypeId()
{
return userTypeId;
}
public void setUserTypeId(int userTypeId)
{
this.userTypeId = userTypeId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public Date getCreateDateTime()
{
return createDateTime;
}
public void setCreateDateTime(Date createDateTime)
{
this.createDateTime = createDateTime;
}
}
4、使用方式:
User user = new User();
user.setUserId(1);
user.setUserTypeId(1);
user.setUserName("XRQ");
user.setCreateDateTime(new Date());
//序列化成ProtoBuf資料結構
byte[] userProtoObj= ProtoBufUtil.serializer(userInfo)
//ProtoBuf資料結構反序列化成User對象
User newUserObj = ProtoBufUtil.deserializer(userProtoObj, User.class))