吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2071|回复: 10
收起左侧

[Java 转载] 利用ArrayList写一个简单的模拟数据库操作

[复制链接]
AItechnology 发表于 2020-8-12 23:13
这是纯技术交流的目的,欢迎各位点进来的大佬提出改进意见
首先,其实所有数据的存储不过就是转为字符串或者二进制形式存储,不外乎加一些加密,压缩,采用特殊编码格式等来存储,加密则是为了数据安全,压缩,特殊编码格式等则是为了节省存储空间,这里我就写一个简单的以字符串形式明文存储的仿数据库,优点就是实现简单,不需要学习sql语言操作数据库,适合存储临时,或者不需要保密的数据,当然,想安全的话,请各位大佬提一点字符串加密解密的思路,我会后续加进去,谢谢大家。缺点就是没有做过优化,肯能数据太多,比如几千万条,同时加载进入ArrayList,不知道内存吃紧不。所以后续想加一点加载超多一定数量的数据后进行优化的代码,希望各位大佬提点意见和思路。
废话不多说,我们都知道数据库基本功能就是增删查改,利用已经封装好的ArrayLsit可以很方便的实现数据库的基本功能,下面上代码:
[Asm] 纯文本查看 复制代码
public class MyOwnDateBase {
	//这是自定义数据库的底层实现,核心原理就是存储文本到这个文件中去
//下面是读取文本
private static ArrayList<String> getInfoFromTextfile(String filePath) {		
		ArrayList<String> list = new ArrayList<String>();
		String[] res=getFileName(filePath);
	    try
	    {
	        String encoding = "UTF-8";	      
	        File file1 = new File(res[0]);
	        File file2 = new File(res[1]);
	        if(!file1.exists()) {
	        	file1.mkdirs();
	        }
	        if (file2.isFile() && file2.exists())
	        { // 判断文件是否存在
InputStreamReader read = new InputStreamReader(
	                    new FileInputStream(file2), encoding);// 考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
	            String lineTxt = null;
	            while ((lineTxt = bufferedReader.readLine()) != null)
	            {
	                list.add(lineTxt);
	            }
	            bufferedReader.close();
	            read.close();
	        }
	        else
	        {
	            file2.createNewFile();
	            System.out.println("初次使用,创建新的数据库,路经为:"+filePath);	           	           
	        }
	    }
	    catch (Exception e)
	    {
	        System.out.println("读取文件内容出错");
e.printStackTrace();
	    }

	    return list;

	}
	//下面是写入文本
private static void saveInfo2TextFile(String filePath,ArrayList<String> info) {
        FileWriter fw ;
		BufferedWriter bw;
		String[] res=getFileName(filePath);
		File file1 = new File(res[0]);
        File file2 = new File(res[1]);
        if(!file1.exists()) {
        	file1.mkdirs();
        }
        try {
        	if (file2.isFile() && file2.exists()) {

            }else {
            	file2.createNewFile();
            	System.out.println("初次使用,创建新的数据库,路经为:"+filePath);
            }

        	if (file2.isFile() && file2.exists()) {
        		fw =new FileWriter(file2,false);
        		bw =new BufferedWriter(fw);
        		bw =new BufferedWriter(fw);
        		int num=info.size();
        		for(int i=0;i<num;i++) {
        			bw.write(info.get(i)+"\r\n");
        		}	
        		bw.flush();
        		bw.close();
        		fw.close();
        	}else {
    			System.out.println("无法写入文件,数据库更新失败,可能是系统无此盘符");
    		}	
        }catch (Exception e) {
        	e.printStackTrace();
		}finally {

		}

	}
	//由文本读取数据的进一步封装
static ArrayList<String> getDateFromDB(String pathOfDate) {
		ArrayList<String> reStrings=getInfoFromTextfile(pathOfDate);
		if(reStrings.isEmpty()) {
			System.out.println("数据库为空");
		}
return reStrings;
	}
	//由文本写入的进一步封装
static void saveDate2DB(String pathOfDate,ArrayList<String> list) {
		saveInfo2TextFile(pathOfDate,list);
	}
	//处理文件路径的问题,路径请统一使用"/"来分隔,该函数自会处理
private static String[] getFileName(String str) {
		String[] tmpStrings=StringTools.seperateString(str, "/");
		String[] res=new String[2];
		str="test";
		String reString=tmpStrings[0];
		for(int i=1;i<tmpStrings.length-1;i++) {
			reString=reString+File.separator+tmpStrings[i];
		}
		res[0]=reString;
		String filename=reString+File.separator+tmpStrings[tmpStrings.length-1];
		res[1]=filename;
		return res;
	}
}

下面是一个工具类中字符串处理方法
[Asm] 纯文本查看 复制代码
public class StringTools {
	//parameter : str
	//the string you need to process
	//parameter : fenggefu
	//the seperate code in string, such as the "," in the string"Type=neme, Date=20200725"
	//for example: str="haha=haha,didi=didi"
	//res=StringTools.seperateString(str,",") will return an array res[0]="haha=haha",res[1]="didi=didi"
	public static String[] seperateString(String str,String fenggefu) {
		char fengefu=fenggefu.charAt(0);
		int len=str.length();
		char ss[]=str.toCharArray();
		int numberofCode=1;
		for(int i=0;i<len;i++) {
			if(ss[i]==fengefu) {numberofCode=numberofCode+1;}
		}
		String properties[];
		if(numberofCode>0) {
			int tmpnum=0;
			properties = new String[numberofCode];
			for(int i=0;i<numberofCode;i++) {
				properties[i]="";
			}
			for(int i=0;i<len;i++) {
				if(ss[i]!=fengefu) {
					properties[tmpnum]=properties[tmpnum]+ss[i];
					}
				if(ss[i]==fengefu) {
					tmpnum=tmpnum+1;
					}
			}
		}else {
			properties = new String[1];
			properties[0]=str;
		}
		return properties;
	}
}

最后就是封装数据库的增删查改功能了:
[Asm] 纯文本查看 复制代码

import java.util.ArrayList;

import system.test.lvb.utils.StringTools;

public class SqlUtils {
	private static ArrayList<String> dateDBList;
	private static String PATHDB;
	private static Boolean isInitDB=false;
	//初始化数据库
public static void initSqlDB(String path) {
		PATHDB=path;
		dateDBList=MyOwnDateBase.getDateFromDB(PATHDB);
		isInitDB=true;
	}
	//插入数据
public static void insetDate(String info,int position) {
		if(isInitDB) {
			if(position>=dateDBList.size()) {
				dateDBList.add(info);
			}else {
				dateDBList.add(position, info);
			}
			commitDBInfo();
		}else {
			System.out.println("未初始化数据库,编辑失败");
		}
	}
	//修改数据
public static void editDate(String info,int position) {
		if(isInitDB) {
			if(position>=dateDBList.size()) {
				System.out.println("索引越界,编辑失败");
			}else {
				dateDBList.remove(position);
				dateDBList.add(position, info);
			}
			commitDBInfo();
		}else {
			System.out.println("未初始化数据库,编辑失败");
		}
	}
	//添加数据
public static void addDate(String info) {
		if(isInitDB) {
			dateDBList.add(info);
			commitDBInfo();
		}
		else {
			System.out.println("未初始化数据库,编辑失败");
		}
	}
	//保存数据
private static void commitDBInfo() {
		if(isInitDB)	
		MyOwnDateBase.saveDate2DB(PATHDB, dateDBList);
	}
	//删除数据
public static void delDate(int position) {
		if(isInitDB)
		if(dateDBList.size()<position) {
			System.out.println("索引越界,删除失败");
		}else {
			dateDBList.remove(position);
			commitDBInfo();
		}
	}
	//清空数据
public static void clearDate() {
		if(isInitDB)
		if(dateDBList.size()>0) {
			dateDBList.clear();
			commitDBInfo();
		}
	}
	//获取记录
public static String getDate(int postion) {
		if(isInitDB)
		if(dateDBList.size()>0&&dateDBList.size()>postion) {
			return dateDBList.get(postion);
		}else {
			return "null";
		}
		return "null";
	}
	//获取记录数目
public static int getSize() {
		if(isInitDB)
		return dateDBList.size();
		return 0;
}
	//获取整个数据库
public static void getAllDate(ArrayList<String> info) {
		for(int i=0;i<dateDBList.size();i++) {
			info.add(dateDBList.get(i));
		}
	}
	//保存所有数据
public static void saveAllDate(ArrayList<String> info) {
		ArrayList<String> tmpArrayList=new ArrayList<String>();
		ArrayList<String> finalArrayList=new ArrayList<String>();
getAllDate(tmpArrayList);
		for(int i=0;i<info.size();i++) {
			tmpArrayList.add(info.get(i));//新旧数据合并
}
finalArrayList=StringTools.getSingle(tmpArrayList);//清除冗余重复数据,如果不用管数据库中数据是否重复,这句代码可以删了
clearDate();//清空数据库
for(int i=0;i<finalArrayList.size();i++) {
			addDate(finalArrayList.get(i));//重新存储数据
}
	}
}

最后,再加上前面那个工具类StringTools中另一个方法的实现:
[Asm] 纯文本查看 复制代码
public static ArrayList<String> getSingle(ArrayList<String> list){
        ArrayList<String> newList = new ArrayList<String>();    //1.创建新集合
Iterator<String> it = list.iterator();          //2.根据传入的集合(老集合)获取迭代器
while(it.hasNext()){                    //3.遍历老集合
String obj = it.next();             //记录住每一个元素
if(!(newList.contains(obj))){       //如果新集合中不包含老集合中的元素
newList.add(obj); //将该元素进行添加
}
        }
return newList;
    }

至此,完成模拟数据库基本功能的增删查改等功能。最后就是贴具体调用的方式(只是我的工程中一段代码调用):
[Asm] 纯文本查看 复制代码
//提取网址头	
ArrayList<String> finalReStrings=new ArrayList<String>();
		ArrayList<String> singleReStrings=new ArrayList<String>();
		for(int i=0;i<filePath.size();i++) {
			String[] strings=StringTools.seperateString(filePath.get(i), "/");
			finalReStrings.add(strings[0]+"//"+strings[2]);
			System.out.println(filePath.get(i));
		}
		//保存在数据库
singleReStrings=StringTools.getSingle(finalReStrings);
		SqlUtils.initSqlDB("C:/test/website1.txt");
		SqlUtils.saveAllDate(singleReStrings);

最后的最后,将打包的jar包分享给大家,大家就可以直接引入工程使用了.
由于论坛不支持jar文件,所以我改后缀为rar,大家到时候直接把后缀改为jar就可以了。

DBJava.rar

6.9 KB, 下载次数: 8, 下载积分: 吾爱币 -1 CB

把文件后缀名改为jar就行了

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

zguozzao 发表于 2020-8-13 08:01
牛。好东西
EnterpriseSolu 发表于 2020-8-13 09:01
"大佬提一点字符串加密解密的思路"

加盐是最简单的,其次要看密码学的东西,自己想的算法漏洞百出,不如直接学书里专家研究的成果
狂龙@ 发表于 2020-8-13 09:45
c03xp 发表于 2020-8-13 10:14
增删改查的“查”,参数postion如何获取?
 楼主| AItechnology 发表于 2020-8-13 12:13
c03xp 发表于 2020-8-13 10:14
增删改查的“查”,参数postion如何获取?

这个很容易实现,后续我会实现搜索功能
 楼主| AItechnology 发表于 2020-8-13 13:06
EnterpriseSolu 发表于 2020-8-13 09:01
"大佬提一点字符串加密解密的思路"

加盐是最简单的,其次要看密码学的东西,自己想的算法漏洞百出,不如 ...

好的,谢谢
zyfhyc 发表于 2020-8-22 23:22
最后的最后,将打包的jar包分享给大家,大家就可以直接引入工程使用
zyfhyc 发表于 2020-8-22 23:23
最后的最后,将打包的jar包分享给大家,大家就可以直接引入工程使用
bookaccount 发表于 2020-8-23 03:21
楼主可以研究一下开源数据库 HSQLDB 的代码,如果要简化一下,不支持sql,那么sql解析器的部分可以跳过,但是物理存储部分的代码可以参考
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 02:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表