关键词:
从文件查询开始
一. 前言
在前两章教程中,分别介绍了DOS环境搭建和Eclipse环境搭建。
本章将带大家实现用简单SQL语句查询文件。
注:
1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。
2.本文旨在达到抛砖引玉的效果,希望大家扩展本例子,以学到更多知识的精髓。
二. 写给初学Java的同学
在介绍本章内容之前,首先介绍一下Java的学习方法。
相信大家在看本文的时候已经已经拿到了各种Java学习路径,大体都是一样。
我想说的是,不要让知识的学习成为负担,Java技术种类繁多,是无论如何也学不完的。
正确的学习方法是兴趣驱动,实例驱动。
即通过一个简单的实例,不断加入所学知识进行扩展,最终扩展为一个大项目,达到系统学习,学以致用的效果。
三. 步入正题
话不多说,大家自己理解,下面步入正题:
练习1.
概要:本地有一个csv格式文件,用SQL语句查出结果。
前提:本地有一个csv格式文件
例:abc.csv放在c:/temp文件夹下,内容如下:
id,username,password
1,abc,aaa
2,def,bbb
3,xyz,ccc
输入:文件路径和sql语句
例:
GetFile gf = new GetFile("c:/temp/"); gf.queryFile("select * from abc.csv");
输出:查询结果
例:
1,abc,aaa
2,def,bbb
3,xyz,ccc
请先自己动手想办法实现,实在做不出来再往下看,否则失去了练习的意义。
四. 实现步骤
首先,我们需要解析SQL语句。是的,标准的写法是把SQL转化成语法树(AST),然后再解析这颗语法树。
但这篇文章面对的是初学者,我的目的是训练字符串的拆分,拼接,文件读取等基本操作,以及分析问题的方法。
所以,把问题简单化。
首先确认程序功能的边界:
下面是这个程序支持的最复杂的SQL语句(只支持单层的and条件):
select id,username from abc.csv where username=abc and password=aaa
所以,我们首先需要检查SQL的正确性:
?必须包含select,from
?可以包含where
?且循序必须为select,from,where
代码如下:
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 <= selectPos 13 || (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 }
解析的函数如下
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 }
(处理where后面的条件)接下来,对于读取的一行数据,我们需要检查该行数据是否符合查询条件,做个函数如下:
header为第一行数据用逗号分割后的数组(文件头)
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=aaa 10 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 }
做个辅助函数,根据列名,返回列名的位置
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 }
(处理select后面的列名)如果数据符合查询条件,则根据select关键字后面的列名(fields)过滤查询结果
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(" "); 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,aaa
2,def,bbb
3,xyz,ccc
Execute:select id from abc.csv
2
Execute:select id,username from abc.csv where id=2
2,def
Execute:select id,username from abc.csv where username=abc and password=aaa
1,abc
Execute:select id,username from abc.csv where username=abc and password=bbb
完整程序请大家从[这里]下载
五. 后续
本例为通过简单的SQL语句查询本地存在的文件,大家可以扩展此程序,让其支持更复杂的SQL,结果排序,索引等功能。
后续章节我将在此程序的基础上,把CSV文件放到另外一台电脑,然后让其支持JDBC接口。
最后换成数据库,并且一步一步实现ORM,Service,HTTP查询等功能。
如有问题,大家来我的网站进行提问。
https://www.java123.vip/qa
版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。
java学习不走弯路教程(4.用sql查询远程服务器的文件)
用SQL查询远程服务器的文件一.前言在前上一章教程中,介绍了用SQL查询本地文件。本章将在上一章的基础上,进一步扩展程序。实际的生产环境中,一般查询的文件都放在远程的文件或数据服务器上,下面我将带大家一步一步... 查看详情
java学习不走弯路教程(1.dos环境搭建)
DOS环境搭建在开始写第一个Java程序之前,我们需要做一些简单的准备工作。1.1还记得DOS吗我们可以通过图形界面来操作我们的电脑。但作为程序员,你首先需要学会用命令行的方式来操作电脑,因为不是所有的电脑都提供图形... 查看详情
java学习不走弯路教程(7orm框架(数据到对象映射))
ORM框架(数据到对象映射)一.前言在前上一章教程中,介绍了数据库查询的方法。本章将在上一章的基础上,进一步扩展程序。注:1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。2.本文旨在达到抛砖引玉的... 查看详情
java学习不走弯路教程(18web框架)
Web框架一.前言在前上一章教程中,我们实现了程序在Tomcat上的部署。本章将在上一章的基础上,进一步扩展程序。注:1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。2.本文旨在达到抛砖引玉的效果,希望大... 查看详情
java学习不走弯路教程(12container容器)
Container容器一.前言在前上一章教程中,介绍了单例模式。本章将在上一章的基础上,进一步扩展程序。注:1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。2.本文旨在达到抛砖引玉的效果,希望大家扩展本例... 查看详情
java学习不走弯路教程(14代码结构整理)
代码结构整理一.前言在前上一章教程中,介绍了和浏览器的通讯。本章将在上一章的基础上,进一步扩展程序。注:1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。2.本文旨在达到抛砖引玉的效果,希望大家... 查看详情
java学习不走弯路教程(2.eclipse环境搭建)
Eclipse环境搭建在前一章,我们熟悉了DOS环境下编译和运行Java程序,对于大规模的程序编写,开发工具是必不可少的。Java的开发工具比较常用的是Eclipse。在接下来的教程中,我们将基于Eclipse开发工具进行程序的编写,编译和运... 查看详情
java学习不走弯路教程(11单例模式2(单实例类))
单例模式2(单实例类)一.前言在前上一章教程中,介绍了静态方法的伪单例模式。本章将在上一章的基础上,进一步扩展程序。注:1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。2.本文旨在达到抛砖引玉... 查看详情
史上最简约的vi教程,10分钟包教会(代码片段)
...手”。本文的价值在于,我走了十几年的弯路,你可以少走弯路。每个人学习vi的目的不一样,学习过程和学习方法也比如不同。一般学习者分如下3种情况:新手级新手要求不高,会用基本操作即可。本文通过10分钟的学习,就... 查看详情
第二周java基础学习内容
本周学习了java的基础知识并完成了一些相关的,代码示例.1300个人围成一个圈,从某个指定的人开始报数,数到3的人退出继续开始数到3,求最后剩下的人的位置。packagej0413;publicclassMyTest4{publicstaticvoidmain(String[]args){ /* *300... 查看详情
自学java到底难不难?做好这几步,少走3年弯路
自学java到底难不难?其实学习java说难不难,说简单也不简单。如今互联网十分发达,各种学习资料,视频,文档都可以在网上找到。可以说如今是一个全民自学的时代,你要你有决心和时间,足不出户便能学习很多知识。特别... 查看详情
java开发从零开始!java游戏服务器开发教程
...握不牢,对于一个开发人员来说无疑是非常致命的。学习任何一个技术知识无疑不是从基础开始;在面试的时候,面试官无疑不是从基础开始拷问。内容包括:Java概述、Java基本语法、Java执行控制流程、面向对象... 查看详情
小白入门——如何从零开始学习python,过来人的一些学习经验,能让你少走弯路(代码片段)
应该怎么开始呢?别着急,我们需要先知道Python是什么。我可不太喜欢没有什么解释的大词。简单来说,Python就是一种你告诉电脑应该怎么做的方法。你也许会问,电脑怎么听得懂英语呢?Python有个编译器ÿ... 查看详情
python从入门到面试:超详细的学习路线,让你不走弯路
有很多自学的小伙伴都私信我说:想学习python做兼职,看我有没有相关的学习路线。经过一番聊天之后,发现他们会由于没有详细的学习路线,从而盲目找视频,找资料,导致浪费了很多时间。经过这几天... 查看详情
java学习之路:不走弯路,就是捷径
1.如何学习程序设计?Java是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于Java,对C++等其他程序设计语言也一样管用。有编程高手认为,JAVA也好C也好没什么分别,拿来就用。为什么他们能达到如此境界?... 查看详情
java学习之路:不走弯路,就是捷径
1.如何学习程序设计?Java是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于JAVA,对C++等其他程序设计语言也一样管用。有编程高手认为,JAVA也好C也好没什么分别,拿来就用。为什么他们能达到如此境界?... 查看详情
java学习之路:不走弯路,就是捷径
1.如何学习程序设计?Java是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于JAVA,对C++等其他程序设计语言也一样管用。有编程高手认为,JAVA也好C也好没什么分别,拿来就用。为什么他们能达到如此境界?... 查看详情
python从入门到面试:超详细的学习路线,让你不走弯路
有很多自学的小伙伴都私信我说:想学习python做兼职,看我有没有相关的学习路线。经过一番聊天之后,发现他们会由于没有详细的学习路线,从而盲目找视频,找资料,导致浪费了很多时间。经过这几天... 查看详情