也是来自github的summer
package com.summer.simplekv.api;
/**
* KV数据库操作Client
*
* @author summer
* @version : SimpleKvClient.java, v 0.1 2022年05月05日 3:49 PM summer Exp $
*/
public interface SimpleKvClient {
/**
* 增加元素
*
* @param key k
* @param value v
*/
void put(String key, String value);
/**
* 获取指定key对于的值
*
* @param key k
* @return
*/
String get(String key);
/**
* 删除指定key
*
* @param key
*/
void del(String key);
}
package com.summer.simplekv.core;
import com.alibaba.fastjson.JSON;
import com.summer.simplekv.api.SimpleKvClient;
import com.summer.simplekv.enums.CommandTypeEnum;
import com.summer.simplekv.model.CommandRequestModel;
import lombok.extern.java.Log;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
/**
* 基于日志顺序写入的KV数据库实现
*
* @author summer
* @version : LogBasedKV.java, v 0.1 2022年05月05日 4:06 PM summer Exp $
*/
@Log
public class LogBasedKV implements SimpleKvClient {
/**
* 日志文件
*/
private File logFile;
/**
* 构造函数
*
* @param fileName 文件名
*/
public LogBasedKV(String fileName) {
logFile = new File(fileName);
}
@Override
public void put(String key, String value) {
BufferedWriter bufferedWriter = null;
try {
FileWriter fileWriter = new FileWriter(logFile, true);
bufferedWriter = new BufferedWriter(fileWriter);
//日志写入内容构造
CommandRequestModel commandRequestModel = new CommandRequestModel();
commandRequestModel.setCommandTypeEnum(CommandTypeEnum.SET);
commandRequestModel.setKey(key);
commandRequestModel.setValue(value);
//往日志文件中写入内容
bufferedWriter.write(JSON.toJSONString(commandRequestModel));
bufferedWriter.newLine();
} catch (Exception e) {
log.warning("put exception,[" + key + "," + value + "]");
} finally {
try {
bufferedWriter.close();
} catch (Exception e) {
log.warning("bufferedWriter close exception");
}
}
}
@Override
public String get(String key) {
try {
FileReader fileReader = new FileReader(logFile);
BufferedReader bufferedReader = new BufferedReader(fileReader);
//按行读取日志文件的内容,查找到最后一条修改类操作命令
CommandRequestModel lastUpdateCommand = null;
String line = bufferedReader.readLine();
while (line != null) {
CommandRequestModel commandRequestModel = JSON.parseObject(line, CommandRequestModel.class);
if ((CommandTypeEnum.SET == commandRequestModel.getCommandTypeEnum()
|| CommandTypeEnum.DEL == commandRequestModel.getCommandTypeEnum())
&& StringUtils.equals(key, commandRequestModel.getKey())) {
lastUpdateCommand = commandRequestModel;
}
line = bufferedReader.readLine();
}
if (lastUpdateCommand == null || CommandTypeEnum.DEL == lastUpdateCommand.getCommandTypeEnum()) {
return null;
}
return lastUpdateCommand.getValue();
} catch (Exception e) {
log.warning("get exception,[" + key + "]");
}
return null;
}
@Override
public void del(String key) {
BufferedWriter bufferedWriter = null;
try {
FileWriter fileWriter = new FileWriter(logFile, true);
bufferedWriter = new BufferedWriter(fileWriter);
//日志写入内容构造
CommandRequestModel commandRequestModel = new CommandRequestModel();
commandRequestModel.setCommandTypeEnum(CommandTypeEnum.DEL);
commandRequestModel.setKey(key);
//往日志文件中写入内容
bufferedWriter.write(JSON.toJSONString(commandRequestModel));
bufferedWriter.newLine();
} catch (Exception e) {
log.warning("del exception,[" + key + "]");
} finally {
try {
bufferedWriter.close();
} catch (Exception e) {
log.warning("bufferedWriter close exception");
}
}
}
}
package com.summer.simplekv.enums;
/**
* 命令类型
*
* @author summer
* @version : CommandTypeEnum.java, v 0.1 2022年05月05日 3:59 PM summer Exp $
*/
public enum CommandTypeEnum {
SET,//保存
GET,//查询
DEL,//删除
;
}
package com.summer.simplekv.model;
import com.summer.simplekv.enums.CommandTypeEnum;
import lombok.Data;
/**
* 命令请求模型
*
* @author summer
* @version : CommandRequestModel.java, v 0.1 2022年05月05日 4:02 PM summer Exp $
*/
@Data
public class CommandRequestModel {
/**
* 命令类型
*/
private CommandTypeEnum commandTypeEnum;
/**
* key
*/
private String key;
/**
* 值
*/
private String value;
}
package com.summer.simplekv;
import com.summer.simplekv.api.SimpleKvClient;
import com.summer.simplekv.core.LogBasedKV;
import lombok.extern.java.Log;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Log
@SpringBootApplication
public class SimplekvApplication {
public static void main(String[] args) {
String logFileName = "simplekv.log";
SimpleKvClient kvClient = new LogBasedKV(logFileName);
//写入数据
for (int index = 0; index < 5; ++index) {
kvClient.put("k-" + index, "v-" + index);
}
//查询数据
for (int index = 0; index < 5; ++index) {
String value = kvClient.get("k-" + index);
log.info("get [" + "k-" + index + " value is [" + value + "]");
}
//删除一行数据
kvClient.del("k-" + 3);
log.info("after del 3");
//再次查询已被删除的数据
String value = kvClient.get("k-" + 3);
log.info("get [" + "k-" + 3 + " value is [" + value + "]");
SpringApplication.run(SimplekvApplication.class, args);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.summer</groupId>
<artifactId>simplekv</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>simplekv</name>
<description>simplekv</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.22</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>