这一篇说说一个简单的写入实现,首先创建对应的KDB Server Connection,这里给出一个类似singleton的实现,加入了connection挂掉了重连的功能,没有考虑短时间重连太多被封的可能性,原因是因为我们的系统中由单一线程每五秒钟往kdb写数一次,ip在kdb的白名单中,所以没可能会被封。
/**
*
*/
package kx;
import java.io.IOException;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import kx.C.KException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
/**
* @author cloudlu
*
*/
@Log4j2
@Getter
@Setter
public class KDBConnectionManager {
@NotNull
@Size(min = 2, max = 30)
private String host;
@NotNull
private int port;
@NotNull
@Size(min = 2, max = 30)
private String username;
@NotNull
@Size(min = 2, max = 30)
private String password;
private C c;
private boolean isValid(final C conn) {
if (null == conn)
return false;
if (null == conn.s || conn.s.isClosed() || !conn.s.isConnected())
return false;
try {
conn.k("");
} catch (final Exception e) {
return false;
}
return true;
}
public final C get() {
if (isValid(c))
return c;
synchronized (this) {
// double check
if (isValid(c))
return c;
try {
c = new C(host, port, username + ":" + password);
} catch (KException | IOException e) {
LOG.error("fail to create connection to host {} port {}", host,
port, e);
}
}
return c;
}
public void release(final C con) {
}
}
接下来编写KDBData类,负责把业务对象映射到KDB表。不同KDB表应该有不同的KDBData类。以KDB自带的例子为例:
package kx;
import java.sql.Time;
import lombok.Data;
@Data
public class KDBData {
public static final String TABLE_NAME = "test";
public static final String[] COL_NAMES = new String[] { "time", "sym",
"price", "size", "stop", "cond", "ex" };
private Time time;
private String sym;
private double price;
private int size;
private boolean stop;
private char cond;
private char ex;
}
/**
*
*/
package kx;
import java.io.IOException;
import java.util.Collection;
import kx.C.KException;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
* @author cloudlu
*
*/
@Log4j2
@Service
public class KDBService {
@Autowired
@Qualifier("ticketPlant")
private KDBConnectionManager manager;
/**
* insert data to specified table
*
* @param data
* : data with key - value from external system
* @return
*/
public boolean insertKDBData(final Collection data) {
final C con = manager.get();
final Object[] tab = convertData(data);
final Object[] updStatement = { ".u.upd", KDBData.TABLE_NAME, tab };
try {
final Object result = con.k(updStatement);
if (null == result)
return true;
} catch (KException | IOException e) {
LOG.error(e);
} finally {
manager.release(con);
}
return false;
}
/**
* need to convert object to data for column based storage
*
* @param cols
* @param data
* @return
*/
private Object[] convertData(final Collection data) {
final Object[] cols = KDBData.COL_NAMES;
final Object[][] result = new Object[cols.length][data.size()];
int i = 0;
for (final KDBData singleData : data) {
result[0][i] = singleData.getTime();
result[1][i] = singleData.getSym();
result[2][i] = singleData.getPrice();
result[3][i] = singleData.getSize();
result[4][i] = singleData.isStop();
result[5][i] = singleData.getCond();
result[6][i] = singleData.getEx();
i++;
}
return result;
}
}