当前位置: 首页 > 工具软件 > KV.JS > 使用案例 >

玩具kv数据库

高宇定
2023-12-01

介绍

用java写一个简陋的kv数据库(俩小时的货),用来复习一下java流知识、线程、socket等知识。

客户端:
	很简单的写了一下
	功能:就是发送用户的命令,还有接收数据显示出来
服务端:
	redis类:读写和操作数据库(就是封装了一堆map)
	socket类:接收命令,发送数据

打开这两个,然后在客户端打命令即可。

使用规范:
***************************************
create tableName//创建表(最多一百个,可以改)
例:create stu//创建名为stu的表
***************************************
use tableName//操作表
例:use stu//操作名字为stu的表
***************************************
showall//打印所有表名
***************************************
增:add key value
删:delete key
改:change key
查:get key
是否存在:contains key
***************************************
end//结束

redis.java:

大概思路:

属性:

    private Map<String, String>[] r // 存储所有表
    private String[] tableName//存储所有表名
    private int num = 0;// 表数量
    private int target;// 当前操作的表

方法:

    增删改查

    更换操作的表

    打印

    写入硬盘

    从硬盘读出数据

    接受命令并执行,给反馈

package redisDemo01;

import java.io.*;
import java.util.*;

public class redis {
	Scanner in = new Scanner(System.in);
	private Map<String, String>[] r = new Map[100];// 最多创建100个表
	private String[] tableName = new String[100];
	private int num = 0;// 表数量
	private int target;// 当前操作的表
	// 创建表
	public void create(String name) {
		r[num] = new HashMap<String, String>();
		tableName[num] = name;
		target = num;
		num++;
	}
	
	// 操作表
	public void use(int target) {
		this.target = target;
	}

	public void use(String name) {
		for (int i = 0; i < num; i++) {
			if (tableName[i].equals(name)) {
				target = i;
				break;
			}
		}
	}

	// 判断是否存在
	public boolean contains(String key) {
		return r[target].containsKey(key);
	}

	// 增
	public void add(String key, String value) {
		r[target].put(key, value);
	}

	// 删
	public void delete(String key) {
		r[target].remove(key);
	}

	// 改
	public void change(String key, String value) {
		r[target].put(key, value);
	}

	// 查
	public String get(String key) {
		return r[target].get(key);
	}

	// 打印表
	public String show() {
		String ans = "";
		for (String key : r[target].keySet()) {
			ans = ans + key + " " + r[target].get(key) + " ";
		}
		return ans;
	}
	public String showAllTableName() {
		String anString="";
		for(int i=0;i<num;i++)
			anString=anString+i+":"+tableName[i];
		return anString;
	}
	//写入硬盘
	public void write() {
		try {
			Writer writer = new FileWriter(new File("member.txt"));
			int i=0;//表的下标
			while (i<num) {
				writer.write("table " + tableName[i] + "\r\n");//表名
				for (String key : r[i].keySet()) {
					writer.write(key + " " + r[i].get(key) + "\r\n");//数据
				}
				i++;
			}
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	//读数据
	public void read() {
		try {

			FileReader fileReader = new FileReader("member.txt");
			BufferedReader bufferedReader = new BufferedReader(fileReader);
			String str;

			while ((str = bufferedReader.readLine()) != null) {
				String[] a = str.split(" ");
				if (a[0].equals("table")) {
					create(a[1]);//新表
				} else {
					add(a[0], a[1]);//表里的数据
				}
			}
			bufferedReader.close();
			fileReader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 接收命令
	public String command(String aString) {
		String ans = "success";
		String[] cmd = aString.split(" ");

		for (int i = 0; i < cmd.length; i++) {
			cmd[i] = cmd[i].replaceAll(" ", "");
		}

		String command = cmd[0];
		if (command.equals("create")) {
			create(cmd[1]);
		} else if (command.equals("use")) {
			use(cmd[1]);
		} else if (command.equals("add")) {
			add(cmd[1], cmd[2]);
		} else if (command.equals("contains")) {
			if (contains(cmd[1]))
				ans = "This key exists";
			else
				ans = "This key does not exists";
		} else if (command.equals("get")) {
			ans = "key:" + cmd[1] + "  value:" + get(cmd[1]);
		} else if (command.equals("delete")) {
			delete(cmd[1]);
		} else if (command.equals("show")) {
			ans = show();
		} else if (command.equals("showall")) {
			ans = showAllTableName();
		} else if (command.equals("end")) {
			write();
			return "end";
		}else {
			return "false,tryAgain";
		}
		return ans;
	}
}

socket.java

属性:

    String cmd;// 命令
    redis r0 // 数据库
    String returnText // 给客户看的信息

方法:

    主要任务是和客户端通信,接受命令,发出客户看到的界面数据。

package redisDemo01;

import java.io.*;
import java.net.*;

public class socket implements Runnable {
	String cmd;// 命令
	redis r0 = new redis();// 数据库
	String returnText = "success";// 给客户看的信息

	public void run() {
		try {
			r0.read();
			ServerSocket serverSocket = new ServerSocket(12016);
			do {
				Socket socket = serverSocket.accept();
				InputStream is = socket.getInputStream();
				OutputStream os = socket.getOutputStream();
				byte[] cache = new byte[1024];

				is.read(cache);
				cmd = new String(cache);
				cmd = cmd.trim();// 去掉多余空格,这个bug调了半天
				System.out.println("redis  >  " + cmd);

				returnText = r0.command(cmd);//操作数据库
				os.write(returnText.getBytes());// 给客户打印的数据

				os.flush();
				is.close();
				os.close();
			} while (!returnText.equals("end"));
			// serverSocket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

然后你run一下socket,服务端这边就完事了。

ClientThread.java

接受客户命令然后发给服务端

接受服务端处理完的数据

用自己的方式呈现给客户(惭愧惭愧)

package Demo;

import java.io.*;
import java.net.*;
import java.util.*;

public class ClientThread implements Runnable {
	@Override
	public void run() {
		try {
			while (true) {
				Scanner s = new Scanner(System.in);
				String temp = s.nextLine();
				Socket socket = new Socket("127.0.0.1", 12016);
				// 获取输入输出流
				InputStream is = socket.getInputStream();
				OutputStream os = socket.getOutputStream();
				// 发送
				os.write(temp.getBytes());
				os.flush();
				// 接收
				byte[] cache = new byte[1024];
				is.read(cache);
				String a = new String(cache);
				if (temp.equals("show")) {//打印所有k——v
					a = a.trim();//去空格
					String[] c = a.split(" ");
					for (int i = 0; i < c.length; i++) {
						c[i] = c[i].replaceAll(" ", "");
					}
					for (int i = 0; i < c.length - 1; i += 2)//依次打印k——v
						System.out.printf("key:%10s  value:%10s\n", c[i], c[i + 1]);
				} else
					System.out.println(a);
				os.close();
				socket.close();
				if (temp.equals("end"))
					break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

界面贼丑但是就是随便练个手啦。。。

 类似资料: