Java学习不走弯路教程(3.从文件内容查询开始)
2021-06-17 16:05
标签:ring from htm www. 形式 row 效果 print 字符串 一. 前言 二. 写给初学Java的同学 练习1. 输入:文件路径和sql语句 例: 输出:查询结果 例: 请先自己动手想办法实现,实在做不出来再往下看,否则失去了练习的意义。 四. 实现步骤 首先,我们需要解析SQL语句。是的,标准的写法是把SQL转化成语法树(AST),然后再解析这颗语法树。 所以,我们首先需要检查SQL的正确性: 然后,我们需要把上述语句的如下元素解析出来: 查询项目:id,username 解析的函数如下 (处理where后面的条件)接下来,对于读取的一行数据,我们需要检查该行数据是否符合查询条件,做个函数如下: (处理select后面的列名)如果数据符合查询条件,则根据select关键字后面的列名(fields)过滤查询结果 把上面的函数拼接在一起,主函数如下: 最后,测试我们的程序: 输出结果如下: 完整程序请大家从[这里]下载 五. 后续 如有问题,大家来我的网站进行提问。 版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。 原帖发表于:https://www.cnblogs.com/java123vip/p/9719828.html Java学习不走弯路教程(3.从文件内容查询开始) 标签:ring from htm www. 形式 row 效果 print 字符串 原文地址:https://www.cnblogs.com/java123vip/p/9719828.html
在前两章教程中,分别介绍了DOS环境搭建和Eclipse环境搭建。
本章将带大家实现用简单SQL语句查询文件。
注:
1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。
2.本文旨在达到抛砖引玉的效果,希望大家扩展本例子,以学到更多知识的精髓。
在介绍本章内容之前,首先介绍一下Java的学习方法。
相信大家在看本文的时候已经已经拿到了各种Java学习路径,大体都是一样。
我想说的是,不要让知识的学习成为负担,Java技术种类繁多,是无论如何也学不完的。
正确的学习方法是兴趣驱动,实例驱动。
即通过一个简单的实例,不断加入所学知识进行扩展,最终扩展为一个大项目,达到系统学习,学以致用的效果。
三. 步入正题
话不多说,大家自己理解,下面步入正题:
概要:本地有一个csv格式文件,用SQL语句查出结果。
前提:本地有一个csv格式文件
例:abc.csv放在c:/temp文件夹下,内容如下:id,username,password
1,abc,aaa
2,def,bbb
3,xyz,ccc
GetFile gf = new GetFile("c:/temp/");
gf.queryFile("select * from abc.csv");
1,abc,aaa
2,def,bbb
3,xyz,ccc
但这篇文章面对的是初学者,我的目的是训练字符串的拆分,拼接,文件读取等基本操作,以及分析问题的方法。
所以,把问题简单化。
首先确认程序功能的边界:
下面是这个程序支持的最复杂的SQL语句(只支持单层的and条件):select id,username from abc.csv where username=abc and password=aaa
?必须包含select,from
?可以包含where
?且循序必须为select,from,where
代码如下: /**
* @author http://www.java123.vip
* @param sql
* @return
*/
private boolean checkSql(String sql) {
int selectPos = sql.indexOf("select");
int fromPos = sql.indexOf("from");
int wherePos = sql.indexOf("where");
if(selectPos != 0
|| fromPos selectPos
|| (wherePos != -1 && wherePos fromPos)) {
return false;
}else {
return true;
}
}
查询文件:abc.csv
查询条件:username=abc,password=aaa
做一个类来存储解析结果:package vip.java123.fileview;
/**
*
* @author http://www.java123.vip
*
*/
public class SqlParseResult {
public String[] fields;
public String fileName;
public String[] whereConditions;
public void clearSpace() {
for(int i = 0; i ) {
fields[i] = fields[i].trim();
}
fileName = fileName.trim();
for(int i = 0; i ) {
whereConditions[i] = whereConditions[i].trim();
}
}
}
/**
* @author http://www.java123.vip
* @param sql
* @return
*/
private SqlParseResult parseSql(String sql) {
int selectPos = sql.indexOf("select");
int fromPos = sql.indexOf("from");
int wherePos = sql.indexOf("where");
String columnStr = sql.substring(selectPos + "select".length(), fromPos).trim();
String fileNameStr;
String whereStr;
if(wherePos == -1) {
fileNameStr = sql.substring(fromPos + "from".length());
whereStr = "";
}else {
fileNameStr = sql.substring(fromPos + "from".length(),wherePos);
whereStr = sql.substring(wherePos + "where".length());
}
SqlParseResult spr = new SqlParseResult();
spr.fields = columnStr.split(",");
spr.fileName = fileNameStr;
if(wherePos == -1) {
spr.whereConditions = new String[] {};
}else {
spr.whereConditions = whereStr.split("and");
}
spr.clearSpace();
return spr;
}
header为第一行数据用逗号分割后的数组(文件头) /**
* @author http://www.java123.vip
* @param line
* @param whereConditions
* @param header
* @return
*/
private boolean checkRow(String line, String[] whereConditions, String[] header) {
// username=abc password=aaa
String[] lineColumns = line.split(",");
for(int i = 0; i ) {
String key = whereConditions[i].split("=")[0];
String value = whereConditions[i].split("=")[1];
String checkValue = lineColumns[getHeaderIndex(header,key)];
if(!value.equals(checkValue)) {
return false;
}
}
return true;
}
做个辅助函数,根据列名,返回列名的位置 /**
* @author http://www.java123.vip
* @param header
* @param headerName
* @return
*/
private int getHeaderIndex(String[] header,String headerName) {
for(int i = 0; i ) {
if(header[i].equals(headerName)) {
return i;
}
}
return -1;
}
/**
* @author http://www.java123.vip
* @param line
* @param fields
* @param header
* @return
*/
private String selectLine(String line, String[] fields, String[] header) {
if(fields[0].equals("*")) {
return line;
}
StringBuffer result = new StringBuffer();
String[] lineColumns = line.split(",");
for(int i = 0; i ) {
int columnIndex = this.getHeaderIndex(header, fields[i]);
result.append(lineColumns[columnIndex]);
if(i != fields.length -1) {
result.append(",");
}
}
return result.toString();
}
/**
* @author http://www.java123.vip
* @param sql
* @return
* @throws Exception
*/
public String queryFile(String sql) throws Exception{
sql = sql.toLowerCase().trim();
if(!checkSql(sql)) {
return null;
}
SqlParseResult spr = parseSql(sql);
File f = new File(basePath + spr.fileName);
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
boolean readHeader = true;
String[] header = null;
StringBuffer result = new StringBuffer();
String line = null;
while((line = br.readLine()) != null) {
if(readHeader) {
header = line.split(",");
readHeader = false;
}else {
if(checkRow(line,spr.whereConditions,header)) {
result.append(selectLine(line,spr.fields,header));
result.append("\n");
}
}
}
br.close();
isr.close();
fis.close();
return result.toString();
}
/**
* @author http://www.java123.vip
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
GetFile gf = new GetFile("c:/temp/");
String sql1 = "select * from abc.csv ";
String sql2 = "select id from abc.csv ";
String sql3 = "select id,username from abc.csv where id=2 ";
String sql4 = "select id,username from abc.csv where username=abc and password=aaa ";
String sql5 = "select id,username from abc.csv where username=abc and password=bbb ";
System.out.println("Execute:"+sql1);
System.out.println(gf.queryFile(sql1));
System.out.println("Execute:"+sql2);
System.out.println(gf.queryFile(sql2));
System.out.println("Execute:"+sql3);
System.out.println(gf.queryFile(sql3));
System.out.println("Execute:"+sql4);
System.out.println(gf.queryFile(sql4));
System.out.println("Execute:"+sql5);
System.out.println(gf.queryFile(sql5));
}
Execute:select * from abc.csv
1,abc,aaa
2,def,bbb
3,xyz,ccc
Execute:select id from abc.csv
1
2
3
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