博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java学习不走弯路教程(3.从文件内容查询开始)
阅读量:4594 次
发布时间:2019-06-09

本文共 8744 字,大约阅读时间需要 29 分钟。

从文件查询开始

一. 前言

在前两章教程中,分别介绍了DOS环境搭建和Eclipse环境搭建。

本章我们讲开始Java的代码学习。

注:

1.本文针对初学Java的同学训练学习思路,点到为止,请不要太纠结于细节问题。
2.本文旨在达到抛砖引玉的效果,希望大家扩展本例子,以学到更多知识的精髓。

学习本章需要准备的知识:

1.读完本系列教程的前面章节。
2.理解变量定义,赋值,函数,分支,循环,数组,ArrayList,HashMap,类和对象的基本概念及SQL查询的写法。
3.理解文件的读取,字符串的常用操作。

二. 步入正题

话不多说,大家自己理解,下面步入正题:

对于如下需求,大家想一下实现的方法:

概要:本地有一个Csv格式文件,用SQL语句查出Csv文件的内容。
注:Csv文件可以理解为用逗号将字段分开的文件格式。

例:abc.csv放在c:/temp文件夹下,内容如下:

id,username,password1,abc,aaa2,def,bbb3,xyz,ccc

对于如下SQL格式的语句查询出结果,比如:

select id,username from abc.csv where id=1

输出:

1,abc

 

三. 实现方法

首先分析这个需求的输入和输出,如下图所示:

 

我们需要将输入的SQL和CSV文件转化为查询结果。

首先我们需要解析SQL,把其中的关键因素提炼出来。
标准的做法是把SQL转化成语法树(AST),然后再解析这颗语法树,如下图所示:

 

 

因为这篇文章的本意是通过这个例子熟悉字符串的操作,所以我用简单的方式来解析SQL。

首先定义程序功能的边界:
下面是这个程序支持的最复杂的SQL语句(只支持单层的and条件):

select id,username from abc.csv where username=abc and password=aaa

并且我定义了一个简单的规则来保证SQL的正确性:

・必须包含select,from
・可以包含where
・且循序必须为select,from,where

我们来写一个函数按照上述规则检查SQL的正确性

代码如下:

1 /** 2      * @author http://www.java123.vip 3      * @param sql 4      * @return 5      */ 6     private boolean checkSql(String sql) { 7         int selectPos = sql.indexOf("select"); 8         int fromPos = sql.indexOf("from"); 9         int wherePos = sql.indexOf("where");10         11         if(selectPos != 0 12                 || fromPos <= selectPos13                 || (wherePos != -1 && wherePos <= fromPos)) {14             return false;15         }else {16             return true;17         }18     }

 

然后,我们需要如下元素解析出来:

查询项目:id,username

查询文件:abc.csv
查询条件:username=abc,password=aaa

我们首先做一个类来存储上述元素:

1 package vip.java123.fileview; 2  3 /** 4  *  5  * @author http://www.java123.vip 6  * 7  */ 8 public class SqlParseResult { 9     public String[] fields;10     public String fileName;11     public String[] whereConditions;12     13     public void clearSpace() {14         for(int i = 0; i < fields.length; i ++) {15             fields[i] = fields[i].trim();16         }17         18         fileName = fileName.trim();19         20         for(int i = 0; i < whereConditions.length; i ++) {21             whereConditions[i] = whereConditions[i].trim();22         }23     }24 }

 

然后分别找到select,from,where的位置,并把它们之间的元素提取出来放入SqlParseResult中:

1 /** 2      * @author http://www.java123.vip 3      * @param sql 4      * @return 5      */ 6     private SqlParseResult parseSql(String sql) { 7         int selectPos = sql.indexOf("select"); 8         int fromPos = sql.indexOf("from"); 9         int wherePos = sql.indexOf("where");10         11         String columnStr = sql.substring(selectPos + "select".length(), fromPos).trim();12         String fileNameStr;13         String whereStr;14         if(wherePos == -1) {15             fileNameStr = sql.substring(fromPos + "from".length());16             whereStr = "";17         }else {18             fileNameStr = sql.substring(fromPos + "from".length(),wherePos);19             whereStr = sql.substring(wherePos + "where".length());20         }21         22         23         SqlParseResult spr = new SqlParseResult();24         spr.fields = columnStr.split(",");25         spr.fileName = fileNameStr;26         if(wherePos == -1) {27             spr.whereConditions = new String[] {};28         }else {29             spr.whereConditions = whereStr.split("and");30         }31         32         spr.clearSpace();33         34         return spr;35     }

因为select和where条件中包含数据的头信息(id,username,password),

所以我们需要在读取文件的时候,把这些头信息保存起来。
用一个字符串数组来存储头信息(String[]),在读取文件的第一行时,把头信息存下来:
String[] header = line.split(","); //line为一行数据

我们做一个函数来读取制定头信息所在的列,用来定位该列上的数据:

1     /** 2      * @author http://www.java123.vip 3      * @param header 4      * @param headerName 5      * @return 6      */ 7     private int getHeaderIndex(String[] header,String headerName) { 8         for(int i = 0; i < header.length; i ++) { 9             if(header[i].equals(headerName)) {10                 return i;11             }12         }13         14         return -1;15     }

接下来我们做一个函数来检查每一行数据(比如1,abc,aaa)是否符合where条件(比如id=1),

这个函数有三个参数,分别为:
String line:一条数据(1,abc,aaa)
String[] whereConditions:where条件(id=1)
String[] header:文件头信息(id,username,password)

我们根据这三个参数,返回一个检查结果(true或false)

1 /** 2      * @author http://www.java123.vip 3      * @param line 4      * @param whereConditions 5      * @param header 6      * @return 7      */ 8     private boolean checkRow(String line, String[] whereConditions, String[] header) { 9         // username=abc  password=aaa10         String[] lineColumns = line.split(",");11         for(int i = 0; i < whereConditions.length; i ++) {12             String key = whereConditions[i].split("=")[0];13             String value = whereConditions[i].split("=")[1];14             15             String checkValue = lineColumns[getHeaderIndex(header,key)];16             if(!value.equals(checkValue)) {17                 return false;18             }19         }20         return true;21     }

对于符合条件的数据,我们需要根据select的列名,返回制定列名的数据:

比如数据为1,abc,aaa,select语句为select id,username
则返回1,abc
函数代码如下:

1 /** 2      * @author http://www.java123.vip 3      * @param line 4      * @param fields 5      * @param header 6      * @return 7      */ 8     private String selectLine(String line, String[] fields, String[] header) { 9         10         if(fields[0].equals("*")) {11             return line;12         }13         14         StringBuffer result = new StringBuffer();15         16         String[] lineColumns = line.split(",");17         for(int i = 0; i < fields.length; i ++) {18             int columnIndex = this.getHeaderIndex(header, fields[i]);19             result.append(lineColumns[columnIndex]);20             21             if(i != fields.length -1) {22                 result.append(",");23             }24         }25         return result.toString();26     }

最后,我们做一个主函数,把上面的函数拼起来,

代码如下:

1 /** 2      * @author http://www.java123.vip 3      * @param sql 4      * @return 5      * @throws Exception 6      */ 7     public String queryFile(String sql) throws Exception{ 8         sql = sql.toLowerCase().trim(); 9         10         if(!checkSql(sql)) {11             return null;12         }13         SqlParseResult spr = parseSql(sql);14         15         File f = new File(basePath + spr.fileName);16         17         FileInputStream fis = new FileInputStream(f);18         InputStreamReader isr = new InputStreamReader(fis);19         BufferedReader br = new BufferedReader(isr);20         21         boolean readHeader = true;22         String[] header = null;23         24         StringBuffer result = new StringBuffer();25         String line = null;26         while((line = br.readLine()) != null) {27             if(readHeader) {28                 header = line.split(",");29                 readHeader = false;30             }else {31                 if(checkRow(line,spr.whereConditions,header)) {32                     33                     result.append(selectLine(line,spr.fields,header));34                     result.append("\n");35                 }36             }37             38         }39         40         br.close();41         isr.close();42         fis.close();43         44         return result.toString();45     }

 

四. 测试程序

最后,测试我们的程序:

1 /** 2      * @author http://www.java123.vip 3      * @param args 4      * @throws Exception 5      */ 6     public static void main(String[] args) throws Exception { 7          8         GetFile gf = new GetFile("c:/temp/"); 9         10         String sql1 = "select * from abc.csv ";11         String sql2 = "select id from abc.csv ";12         String sql3 = "select id,username from abc.csv where id=2 ";13         String sql4 = "select id,username from abc.csv where username=abc and password=aaa ";14         String sql5 = "select id,username from abc.csv where username=abc and password=bbb ";15         16         System.out.println("Execute:"+sql1);17         System.out.println(gf.queryFile(sql1));18         19         System.out.println("Execute:"+sql2);20         System.out.println(gf.queryFile(sql2));21         22         System.out.println("Execute:"+sql3);23         System.out.println(gf.queryFile(sql3));24         25         System.out.println("Execute:"+sql4);26         System.out.println(gf.queryFile(sql4));27         28         System.out.println("Execute:"+sql5);29         System.out.println(gf.queryFile(sql5));30         31     }

 

输出结果如下:

Execute:select * from abc.csv 1,abc,aaa2,def,bbb3,xyz,cccExecute:select id from abc.csv 2Execute:select id,username from abc.csv where id=2 2,defExecute:select id,username from abc.csv where username=abc and password=aaa 1,abcExecute:select id,username from abc.csv where username=abc and password=bbb

 

完整程序请大家从[]下载

如有问题,大家来我的网站进行提问。

版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。

转载于:https://www.cnblogs.com/java123-vip/p/9740186.html

你可能感兴趣的文章
S3C2440的LCD虚拟显示测试
查看>>
大小端格式
查看>>
阅读书籍电技术
查看>>
互联网时代的报纸收费与读者细分
查看>>
mysql优化
查看>>
vs2012中怎样设为起始页,怎样取消
查看>>
CSS3中的box-shadow
查看>>
Collections
查看>>
php面试题之二——Javascript(基础部分)
查看>>
Java常用函数式接口--Supplier接口使用案例
查看>>
【常识】常见外国计量单位
查看>>
MySQL索引
查看>>
新版本读取老版本文件崩溃BUG
查看>>
高可用Hadoop平台-应用JAR部署
查看>>
【随感】不要以为自己不足轻重而放任自己做一些事或一些话。你的不在意,才会影响到别人也不在意你。...
查看>>
集美大学网络15软工个人作业4分数统计
查看>>
奇怪吸引子---四涡卷超混沌吸引子
查看>>
微信第三方登陆
查看>>
Android中的WebView进行直接加载网页(要注意解决权限问题)
查看>>
嵌套事务及分类1
查看>>