模拟数据库增删查改功能

1、 系统设计开发过程

数据库中有“表”的概念。“表”由若干“行”组成,每“行”由许多“列”组成。一般的数据库都提供了对SQL的支持。

我们可以模拟一个最简单版的SQL,只能实现简单的排序,简单的选择条件,列的显示顺序等功能。

输入help会打印出帮助信息。

可以使用下列命令序列测试它:

>load E:\\workspace\\data.txt
>add A 11 22 33 44
>delete A B
>update A length=11 weight=22
>update * A 22 33 44 55
>sort name
>select length weight
>select length weight where price>50
>select * where price>50 length<30
>exit

2、  主要功能模块的实现及调试过程

1.  创建信息类,信息包括名称(String)、长度(double)、重量(double)、威力(double)、price(double)。


class MyRow   
{   
   private String name;    // 名字   
   private double length;  // 长度   
   private double weight;  // 重量   
   private double power;   // 威力   
   private double price;   // 价格  
   public  MyRow(String x)   
   {   
       String[] ss = x.split("	"); 
       name = ss[0].trim();   
       length = Double.parseDouble(ss[1]);   
       weight = Double.parseDouble(ss[2]);   
       power = Double.parseDouble(ss[3]);   
       price = Double.parseDouble(ss[4]);
   }   
      
   public String toString()   
   {   
       return name+"	"+length+"	"+ weight+"	" + power + "	" + price;   
   } 
   public void SetName(String name){this.name=name;}
   public void SetLength(double length){this.length=length;}
   public void SetWeight(double weight){this.weight=weight;}
   public void SetPower(double power){this.power=power;}
   public void SetPrice(double price){this.price=price;}
   public String getName() { return name; }   
   public double getLength() { return length; }   
   public double getWeight() { return weight; }   
   public double getPower() { return power; }   
   public double getPrice() { return price; }   
}

2.主类,用来接收用户发送的命令,判断并把命令传给下一级处理类,得到返回值判断命令是否成功执行

public class Test   
{   
    private  static  BufferedReader  br_keyboard;      
    static   
{   
// 将它用于从键盘读入
        br_keyboard = new BufferedReader(new InputStreamReader(System.in));  
    }   
    public static void main(String[] args) throws Exception   
    {   
        MyData data = new MyData();   
        MyCommand cmd = new MyCommand(data);  // cmd 服务于 data      
        for(;;)//一直执行,只能用户用exit命令退出程序
{   
            System.out.print("请输入命令(输入help显示帮助信息):");   
            String s = br_keyboard.readLine(); 
            if(s.equals("exit")) break;  
            if(s.equals("help")){   
                System.out.println("----------------------------");   
                System.out.println("1.|load data.txt");   
                System.out.println("  |从当前目录装入文件data.txt,并显示");
                System.out.println("2.|add A 11 22 33 44");
                System.out.println("  |增加一条信息(名称A 长度11 重量22 威力33 价格44)到文件中,并显示");
                System.out.println("3.|delete A B");
                System.out.println("  |删除A和B的信息");
                System.out.println("4.|update A length=11 weight=22");
                System.out.println("  |把信息A的长度改为11,重量为22");
                System.out.println("5.|update * A 22 33 44 55");
                System.out.println("  |把信息A的长度、重量、威力、价格 改为22、33、44、55");
                System.out.println("6.|sort name");   
                System.out.println("  |按“名称”排序,并显示");   
                System.out.println("  |类似地,还可以是 sort length, sort price,sortweight,sort power等");   
                System.out.println("7.|select length weight");   
                System.out.println("  |只显示 长度,重量两列");   
                System.out.println("8.|select length weight where price>50");   
                System.out.println("  |只显示长度,重量两列, 只包含价格 >50的行");   
                System.out.println("9.|select * where price>50 length<30");   
                System.out.println("  |显示所有列, 只包含价格>50 且 长度<30 的行");   
                System.out.println("  |其它的组合,从上边类推");   
                System.out.println("0.|exit");   
                System.out.println("  |退出程序");   
                System.out.println("----------------------------");   
                continue;   
            }   
            if(!cmd.execute(s)){   //调用下一级类中的函数进行命令的解析
                System.out.println("无效的命令");   
            }   
        }     
    }   
} 

3.命令解析类,把从主类传递过来的命令进行解析,判断命令对应的处理函数,把命令传给对应的函数。接收返回值并返回给Text类。

 class MyCommand   
{   
    private MyData data;     
    public MyCommand(MyData x)   
    {   
        data = x;   
    }   
    public boolean execute(String x) throws IOException   
    {   
        int d = x.indexOf(" ");  // 找第一个空格的位置   
        if(d<0) return false;      
        String x1 = x.substring(0,d);     
        String x2 = x.substring(d+1);      
        if(x1.equals("load")){   
            if(!data.load(x2.trim()))   
                System.out.println("装入文件出错!");   
            return true;   
        }   
        if(x1.equals("add"))
        	 return data.add(x2); 
        if(x1.equals("delete"))
        	 return data.delete(x2);
        if(x1.equals("update"))
        	 return data.update(x2);
        if(x1.equals("sort"))   
           return data.sort(x2.trim());   
        if(x1.equals("select"))   
            return data.select(x2);
        return false;   
    }   
}

4.处理类,处理各种命令,返回处理结果

class MyData   
{   
    // 内部类,“裁判”类,用于裁决Vector中的对象的比较大小问题     
    class Bijiao implements Comparator<MyRow>   
    {   
        private int type;    //保存需要比较的信息的序号。例如:1,表示name;2,表示length……
        public Bijiao(int type)   
        {   
            this.type = type;   
        }   
        public int compare(MyRow o1,MyRow o2)    //比较的规则   
        {   
            if(!(o1 instanceof MyRow)) return 0;   //判断传递过来的信息是否是MyRow类
            if(!(o2 instanceof MyRow)) return 0; 
  
            MyRow r1 = (MyRow)o1;   
            MyRow r2 = (MyRow)o2;   

            switch(type){ 
            case 1:
            	if(r1.equals(r2))
            		return 0;
            	else if(r1.getName().compareTo(r2.getName())<0)    //name大小排列,小->大
            		return -1;
            	else 
            		return 1;
            case 2:
            	if(r1.equals(r2))
            		return 0;
            	else if(r1.getLength()<r2.getLength())        //length大小排列,小->大
            		return -1;
            	else 
            		return 1;
            case 3:
            	if(r1.equals(r2))
            		return 0;
            	else if(r1.getWeight()<r2.getWeight())      //weight大小排列,小->大
            		return -1;
            	else 
            		return 1;	
            case 4:
            	if(r1.equals(r2))
            		return 0;
            	else if(r1.getPower()<r2.getPower())     //power大小排列,小->大
            		return -1;
            	else 
            		return 1;	
            case 5:
            	if(r1.equals(r2))
            		return 0;
            	else if(r1.getPrice()<r2.getPrice())       //price大小排列,小->大
            		return -1;
            	else 
            		return 1;
            default:
            	return 0;
            }   
        }   
    }   
    private List<MyRow> _v = new Vector<MyRow>();   //保存所有的信息
       
    //在屏幕上显示信息
    public void show()   
    {   
        System.out.println("....................................");   
        System.out.println("名称	长度	重量	威力	价格");   
        for(int i=0; i<_v.size(); i++){   
            System.out.println(_v.get(i));   
        }   
        System.out.println("....................................");   
    }     
    
File file=null;            		//全局变量保存路径

    //加载文件信息,读取->保存->show()
    public boolean load(String x)   //x为一个路径 
    {   
        try{ 
       	    if(!x.equals("syh"))    //判断加载时否是用户主用命令加载
       	    {
        	       this.file=new File(x);
       	    }
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));   
            _v.clear(); 			//清空_v,防止二次加载时_v中有之前保存的数据
            br.readLine();  		// 第一行不要   
            String s="";
            while((s = br.readLine())!=null){    
                _v.add(new MyRow(s));
            }   
            br.close();
            show();    				//显示到屏幕
            return true;       
        }   
        catch(Exception e){    
            return false;   
        }   
    }   
    
    //添加信息,先在链表中添加,然后写入文件然后加载
    public boolean add(String x) 	//x:A 11 22 33 44
    {
    	try{
    	     String[] ss = x.split(" "); 
    	     String name = ss[0].trim(); 
    	     x=ss[0]+"	"+ss[1]+"	"+ss[2]+"	"+ss[3]+"	"+ss[4];//把数组x改为MyRow()可以分解的数组
    	     if((check(name))==0)    		//判断添加的信息是否已经存在
    		{
    			 _v.add(new MyRow(x));
    		}else{
    			System.out.println("您增加的信息重复");
    			return true;
    		}
        	Write();
        	load("syh");   			//非用户主动用命令加载信息,读取路径为用户用命令时的路径
        	return true;
    	 }catch(Exception e){
    		return false;
    	}
}

    //按name查找某条信息,返回该信息下标+1
    public int  check(String s)
    {
    	for(int i=0;i<_v.size();i++)
     {
        	MyRow row = (MyRow)_v.get(i);
         if(s.equals(row.getName()))
        	   return (i+1);    	 	//返回该信息的位置+1是因为防止该信息为下标为0
     }
     return 0;						//信息不存在直接返回0
}

//把信息重新写到文件中
    public void Write()
    {
    	try {
    		Writer out=new FileWriter(file);
    		out.write("名称	长度	重量	威力	价格");
        	for(int i=0;i<_v.size();i++)
            {
            	MyRow row = (MyRow)_v.get(i);
        	    out.write("\r\n"+row.getName()+"	"+row.getLength()+"	"+row.getWeight()+"	"+row.getPower()+"	"+row.getPrice()); 
            }	
        	out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
}

    //删除某几条信息,先删除链表中的信息,然后再文件中写入,然后再加载
    public boolean delete(String x)		//x:A B
    {
    	try{
    		String[] ss = x.split(" ");
    		int j;			 
            for(int i=0;i<ss.length;i++)
            	if((j=check(ss[i]))!=0)
            	{
            	    _v.remove(j-1);
            	}            			
            Write();
            load("syh");
        	return true;
    	}catch(Exception e){
    		return false;
    	}
}

    //更新信息,先更新链表中的信息->把全部信息写入文件->加载
    public boolean update(String x)  //x:A length=11 weight=33或者* A 11 22 33 44
    {
    	try {
    		  String ss[]=x.split(" ");
            boolean flag=true;      //判断更新的信息是否更新,如没更新,则说明该信息不存在
            for(int i=1;i<ss.length;i++)
            {
           	  String[]  ssa=ss[i].split("=");
           	  int j=0;
           	  if((j=check(ss[0]))!=0)  //当x为A length=11 weight=33,即部分更新的情况
           	  {
           		 flag=false;
           		 if(ssa[0].equals("length"))
           			_v.get(j-1).SetLength(Double.parseDouble(ssa[1]));
           		 if(ssa[0].equals("weight"))
           			_v.get(j-1).SetWeight(Double.parseDouble(ssa[1]));
           		 if(ssa[0].equals("power"))
           			_v.get(j-1).SetPower(Double.parseDouble(ssa[1]));
           		 if(ssa[0].equals("price"))
           			_v.get(j-1).SetPrice(Double.parseDouble(ssa[1]));
              }
            }
            if(ss[0].equals("*"))      //当x为* A 11 22 33 44,即全部更新情况
        	{ 
              int j;
        		if((j=check(ss[1]))!=0)
        		{
        			flag=false;
        			_v.get(j-1).SetLength(Double.parseDouble(ss[2]));
        			_v.get(j-1).SetWeight(Double.parseDouble(ss[3]));
        			_v.get(j-1).SetPower(Double.parseDouble(ss[4]));
        		    _v.get(j-1).SetPrice(Double.parseDouble(ss[5]));
        		}	
        	}
            if(flag)
            {
           	 System.out.println("不存在您要更新的内容");
           	 return true;
            }
            Write();
            load("syh");
       	    return true;
	   }catch (Exception e) {
		    return false;    
	   } 
}

    //排序
    public boolean sort(String x)   //x可为name或者lengt或者weight……   
    {   
    	if(x.equals("name")){
    		Collections.sort(_v, new Bijiao(1)); //1表示名称,类似2为长度……  
            show();   
            return true; 
    	}
        if(x.equals("length")){   
            Collections.sort(_v, new Bijiao(2)); 
            show();   
            return true;   
        }   
        if(x.equals("weight")){   
            Collections.sort(_v, new Bijiao(3));   
            show();   
            return true;   
        }   
        if(x.equals("power")){   
            Collections.sort(_v, new Bijiao(4));   
            show();   
            return true;   
        }   
        if(x.equals("price")){   
            Collections.sort(_v, new Bijiao(5));   
            show();   
            return true;   
        }   
        return false;   
    }   
       
    // 筛选需要显示的信息,把筛选命令分解
    public boolean select(String x)      //x:select weight length或者select weight length where price>50或者 select * where price>50 length<30 
    {   
        Vector<String> sort = new Vector<String>();  // 保存需要显示的信息  
        Vector<String> where = new Vector<String>();  // 保存过滤的条件即where后面的字符   
        String[] ss = x.split(" ");  
        Vector<String > t = sort;   
        for(int i=0; i<ss.length; i++){   
            if(ss[i].length()==0) continue;  // 防止多个空格   
            if(ss[i].equals("where")){   
                t = where;   
                continue;   
            }   
            t.add(ss[i]);   
        }   
           
        if(sort.size()==0) return false;  // 字段必须指定   
        if(sort.size()>5) return false;  // 字段太多   
        return select(sort, where);    
    }      
       
    // 执行select任务   
    public boolean select(Vector<String> sort,Vector<String> where)   
    {   
      try{   
        System.out.println("....................................");   
        //输出标题   
        System.out.print("名称	"); 
        for(int k=0; k<sort.size(); k++){   // 枚举sort    
            if(sort.get(k).equals("length"))   
                System.out.print("长度	");   
            else if(sort.get(k).equals("weight"))   
                System.out.print("重量	");   
            else if(sort.get(k).equals("power"))   
                System.out.print("威力	");   
            else if(sort.get(k).equals("price"))   
                System.out.print("价格	");   
            else if(sort.get(k).equals("*"))   
                System.out.print("长度	重量	威力	价格	");   
            else   
                return false;   
        }
        System.out.println("");       
        for(int i=0; i<_v.size(); i++){    //输出内容
            MyRow row = (MyRow)_v.get(i);   
            if(checkWhere(row, where)){  
            	System.out.print(row.getName() + "	"); 
                for(int k=0; k<sort.size(); k++){        
                    if(sort.get(k).equals("length"))   
                        System.out.print(row.getLength() + "	");   
                    else if(sort.get(k).equals("weight"))   
                        System.out.print(row.getWeight() + "	");   
                    else if(sort.get(k).equals("power"))   
                        System.out.print(row.getPower() + "	");   
                    else if(sort.get(k).equals("price"))   
                        System.out.print(row.getPrice() + "	");   
                    else if(sort.get(k).equals("*"))   
                       System.out.print(row.getLength()+"	"+row.getWeight()+"	"+row.getPower()+"	"+row.getPrice());   
                    else   
                        return false;   
                }
                System.out.println("");   
            }     
        } 
        System.out.println("....................................");   
        return true;   
    }   
    catch(Exception e){   
        //e.printStackTrace();   
        return false;   
    }   
    }   
      
    // 返回true 则该行记录显示,返回false,则不显示   
    public boolean checkWhere(MyRow row, Vector<String > where) throws Exception   
    {   
        boolean op=true;  // true: 表示比较符号为 > , 否则为 <   
        String field = "";  // 过滤条件的字段   
        String value = "";  // 过滤值   
       
        // 对每一个条件处理    
        for(int i=0; i<where.size(); i++){   
            String s = (String)where.get(i);   
            String[] ss = s.split(">");   
            if(ss.length==2){   
                field = ss[0];   
                op = true;   
                value = ss[1];   
            }   
            else{   
                ss = s.split("<");   
                if(ss.length==2){   
                    field = ss[0];   
                    op = false;   
                    value = ss[1];   
                }   
                else   
                    return false;  // 既没有"<"也没有">"的情况   
            }   
               
            double d_value = Double.parseDouble(value);   
               
            if(field.equals("length")){   
                if(op){   
                    if(row.getLength() <= d_value)   return false;   
                }          
                else{   
                    if(row.getLength() >= d_value) return false;   
                }   
            }   
            else if(field.equals("weight")){   
                if(op){   
                    if(row.getWeight() <= d_value) return false;   
                }   
                else{   
                    if(row.getWeight() >= d_value) return false;   
                }   
            }   
            else if(field.equals("power")){   
                if(op){   
                    if(row.getPower() <= d_value) return false;   
                }   
                else{   
                    if(row.getPower() >= d_value) return false;   
                }   
            }   
            else if(field.equals("price")){   
                if(op){   
                    if(row.getPrice() <= d_value) return false;   
                }   
                else{    
                    if(row.getPrice() >= d_value) return false;   
                }   
            }   
            else   
                throw new Exception("valid field name!");  // 无法识别的 field,则算错表达式错   
        }  
        return true;   
    }   
}

3、  系统存在的不足

在对数据进行增(add)、删(delete)、改(update)时,先对从文件读取的数据进行修改,然后重新写入文件然后再读取显示到屏幕中。这种操作在数据量较小时处理的时间比较短,但随着数据量的增加处理的时间就会急剧增加,假如修改一个数据需要时间为x,往文件中写入一个数据需要时间为y,从文件中读取一个数据时间为z,则增加一条数据则用时为:(x+(n+1)*y+(n+1)*z)。若直接在文件中进行增加一条数据则用时为:(y+(n+1)*z)。这样比较就显示出程序的效率太低,需要改进。还有就是只能对特定的表进行操作,比如如果表的属性不是 名称(String)、长度(double)、重量(double)、威力(double)、price(double),则功能就不能实现,但是该缺点易改进,使用Map进行匹配就可以实现对任意表进行操作。

源码  下载地址



  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值