Java实现ADO.NET DataTable的SQL查询
Java 没有 DataTable(有吗?这个应该有,这个真没有)
Code
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Date;
import java.sql.Timestamp;
public class DataTableTest
{
static DataTable selectFromDB()
{
DataTable dTable = new DataTable();
HashMap row1 = new HashMap();
row1.put("id",1);
row1.put("name","zhangsan");
row1.put("is_student",1);
row1.put("age",25);
row1.put("desc","");
dTable.add(row1);
HashMap row2 = new HashMap();
row2.put("id",2);
row2.put("name","lishi");
row2.put("is_student",1);
row2.put("age",28);
row2.put("desc","");
dTable.add(row2);
HashMap row3 = new HashMap();
row3.put("id",3);
row3.put("name","qianduo");
row3.put("is_student",1);
row3.put("age",31);
row3.put("desc","leader's son");
dTable.add(row3);
HashMap row4 = new HashMap();
row4.put("id",4);
row4.put("name","zhaoliu");
row4.put("is_student",1);
row4.put("age",22);
row4.put("desc","");
dTable.add(row4);
HashMap row5 = new HashMap();
row5.put("id",5);
row5.put("name","sunqi");
row5.put("is_student",0);
row5.put("age",27);
row5.put("desc","");
dTable.add(row5);
return dTable;
}
public static void main(String[] args)
{
DataTable dTable = selectFromDB();
DataTable table = dTable.select("(is_student==1 and age <= 25) or (is_student==0 and age < 30) or desc like 'leader%'");
for(Map dr : table)
{
System.out.println(String.format("%s\t%s",dr.get("id"),dr.get("name")));
}
}
}
class DataTable extends ArrayList<Map>
{
public DataTable select(String expression)
{
SQLExpression e = new SQLExpression(expression);
DataTable newTable = new DataTable();
for(Map row : this)
if(e.eval(row))
newTable.add(row);
return newTable;
}
}
//<editor-fold defaultstate="collapsed" desc="SQLExpression">
class SQLExpression
{
private String SQLExpression;
private int exp_len;
private char[] exp_array;
private ArrayList<String> token_list;
private boolean is_flushed;
private char c;
private StringBuffer sb;
private int cur_token_index;
private int token_count;
public SQLExpression(String SQLExpression)
{
this.SQLExpression = SQLExpression;
this.exp_len = SQLExpression.length();
this.exp_array = SQLExpression.toCharArray();
this.token_list = new ArrayList<String>();
this.is_flushed = true;
this.cur_token_index = -1;
this.sb = new StringBuffer();
this.initTokenList();
this.token_count = this.token_list.size();
}
private void flush()
{
if(this.is_flushed)
return;
this.token_list.add(this.sb.toString());
this.sb = new StringBuffer();
this.is_flushed = true;
}
private void collect()
{
this.sb.append(c);
this.is_flushed = false;
}
private boolean nextToken()
{
if(this.cur_token_index<this.token_count-1)
{
this.cur_token_index++;
return true;
}
return false;
}
private String currentToken()
{
return this.token_list.get(this.cur_token_index);
}
private void initTokenList()
{
for(int i=0;i<this.exp_len;i++)
{
c = exp_array[i];
if(Character.isWhitespace(c))
{
this.flush();
continue;
}
switch(c)
{
case '<' :
this.flush();
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.token_list.add("<=");
i++;
}
else
{
this.token_list.add("<");
}
break;
case '>' :
this.flush();
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.token_list.add(">=");
i++;
}
else
{
this.token_list.add(">");
}
break;
case '(' :
this.flush();
this.token_list.add("(");
break;
case ')' :
this.flush();
this.token_list.add(")");
break;
case '=' :
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.flush();
this.token_list.add("==");
i++;
}
else
{
this.collect();
}
break;
case '!' :
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.flush();
this.token_list.add("!=");
i++;
}
else
{
this.collect();
}
break;
default:
this.collect();
break;
}
}
this.flush();
}
public boolean eval(Map dr)
{
this.nextToken();
boolean result = this.doAndOr(dr);
this.cur_token_index = -1;
return result;
}
private boolean doAndOr(Map dr)
{
boolean result = this.doNot(dr);
String op = "";
boolean result_right;
while((op=this.currentToken()).equals("and") || op.equals("or"))
{
this.nextToken();
if(op.equals("and"))
{
result_right = this.doNot(dr);
result = result && result_right;
}
else
{
result_right = this.doNot(dr);
result = result || result_right;
}
}
return result;
}
private boolean doNot(Map dr)
{
String op="";
if((op=this.currentToken()).equals("not"))
this.nextToken();
boolean result = this.doBrackets(dr);
if(op.equals("not"))
return !result;
return result;
}
private boolean doBrackets(Map dr)
{
boolean result;
if(this.currentToken().equals("("))
{
this.nextToken();
result = this.doAndOr(dr);
this.nextToken();
}
else
{
result = this.doCompare(dr);
}
return result;
}
private boolean doCompare(Map dr)
{
Object field = dr.get(this.currentToken());
this.nextToken();
String opt = this.currentToken();
this.nextToken();
String value = this.currentToken();
this.nextToken();
if(opt.equals("like"))
{
return isLike(field,value);
}
else if(opt.equals(">"))
{
return isGreat(field,value);
}
else if(opt.equals("<"))
{
return isLess(field,value);
}
else if(opt.equals("=="))
{
return isEquals(field,value);
}
else if(opt.equals(">="))
{
return isGreatEquals(field,value);
}
else if(opt.equals("<="))
{
return isLessEquals(field,value);
}
else if(opt.equals("!="))
{
return isNotEquals(field,value);
}
return false;
}
//<editor-fold defaultstate="collapsed" desc="tool method">
private static boolean isLike(Object field,String value)
{
int len = value.length();
if(value.startsWith("'%") && value.endsWith("%'"))
return Convert.toString(field).contains(value.substring(2,len-2));
else if(value.startsWith("'%"))
return Convert.toString(field).endsWith(value.substring(2,len-1));
else if(value.endsWith("%'"))
return Convert.toString(field).startsWith(value.substring(1,len-2));
else
return Convert.toString(field).equals(value.substring(1,len-1));
}
private static boolean isLess(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)<Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))<0;
}
private static boolean isGreat(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)>Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))>0;
}
private static boolean isEquals(Object field,String value)
{
if(value.equals("null"))
return field==null;
if(field instanceof Number)
return Convert.toFloat(field)==Convert.toFloat(value);
if(field instanceof Boolean)
return Convert.toBool(field)==Convert.toBool(value);
return Convert.toString(field).equals(value.substring(1,value.length()-1));
}
private static boolean isNotEquals(Object field,String value)
{
if(value.equals("null"))
return field!=null;
if(field instanceof Number)
return Convert.toFloat(field)!=Convert.toFloat(value);
if(field instanceof Boolean)
return Convert.toBool(field)==Convert.toBool(value);
return !Convert.toString(field).equals(value.substring(1,value.length()-1));
}
private static boolean isLessEquals(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)<=Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))<=0;
}
private static boolean isGreatEquals(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)>=Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))>=0;
}
}
class Convert
{
public static String toString(Object o)
{
return toString(o, "");
}
public static String toString(Object o, String defValue)
{
if (o == null)
return defValue;
return o.toString();
}
public static int toInt(Object o)
{
return toInt(o, 0);
}
public static int toInt(Object o, int defValue)
{
if(o==null)
return defValue;
if (o instanceof Integer)
return ((Integer) o).intValue();
try
{
return (int)Float.parseFloat(o.toString());
}
catch (Exception e)
{
return defValue;
}
}
public static long toLong(Object o)
{
if(o==null)
return 0L;
if (o instanceof Long)
return ((Long) o).longValue();
try
{
return Long.parseLong(o.toString());
}
catch (Exception e)
{
return 0L;
}
}
public static float toFloat(Object o)
{
if(o==null)
return 0F;
if (o instanceof Float)
return ((Float) o).floatValue();
try
{
return Float.parseFloat(o.toString());
}
catch (Exception e)
{
return 0F;
}
}
public static boolean toBool(Object o)
{
if(o==null)
return false;
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
try
{
return Boolean.parseBoolean(o.toString());
}
catch(Exception e)
{
return false;
}
}
public static Date toDate(Object o)
{
return toDate(o, new Date(System.currentTimeMillis()));
}
public static Date toDate(Object o, Date defValue)
{
if(o==null)
return defValue;
if (o instanceof java.util.Date)
return (Date) o;
try
{
return Timestamp.valueOf(o.toString());
}
catch (Exception e)
{
return defValue;
}
}
}
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Date;
import java.sql.Timestamp;
public class DataTableTest
{
static DataTable selectFromDB()
{
DataTable dTable = new DataTable();
HashMap row1 = new HashMap();
row1.put("id",1);
row1.put("name","zhangsan");
row1.put("is_student",1);
row1.put("age",25);
row1.put("desc","");
dTable.add(row1);
HashMap row2 = new HashMap();
row2.put("id",2);
row2.put("name","lishi");
row2.put("is_student",1);
row2.put("age",28);
row2.put("desc","");
dTable.add(row2);
HashMap row3 = new HashMap();
row3.put("id",3);
row3.put("name","qianduo");
row3.put("is_student",1);
row3.put("age",31);
row3.put("desc","leader's son");
dTable.add(row3);
HashMap row4 = new HashMap();
row4.put("id",4);
row4.put("name","zhaoliu");
row4.put("is_student",1);
row4.put("age",22);
row4.put("desc","");
dTable.add(row4);
HashMap row5 = new HashMap();
row5.put("id",5);
row5.put("name","sunqi");
row5.put("is_student",0);
row5.put("age",27);
row5.put("desc","");
dTable.add(row5);
return dTable;
}
public static void main(String[] args)
{
DataTable dTable = selectFromDB();
DataTable table = dTable.select("(is_student==1 and age <= 25) or (is_student==0 and age < 30) or desc like 'leader%'");
for(Map dr : table)
{
System.out.println(String.format("%s\t%s",dr.get("id"),dr.get("name")));
}
}
}
class DataTable extends ArrayList<Map>
{
public DataTable select(String expression)
{
SQLExpression e = new SQLExpression(expression);
DataTable newTable = new DataTable();
for(Map row : this)
if(e.eval(row))
newTable.add(row);
return newTable;
}
}
//<editor-fold defaultstate="collapsed" desc="SQLExpression">
class SQLExpression
{
private String SQLExpression;
private int exp_len;
private char[] exp_array;
private ArrayList<String> token_list;
private boolean is_flushed;
private char c;
private StringBuffer sb;
private int cur_token_index;
private int token_count;
public SQLExpression(String SQLExpression)
{
this.SQLExpression = SQLExpression;
this.exp_len = SQLExpression.length();
this.exp_array = SQLExpression.toCharArray();
this.token_list = new ArrayList<String>();
this.is_flushed = true;
this.cur_token_index = -1;
this.sb = new StringBuffer();
this.initTokenList();
this.token_count = this.token_list.size();
}
private void flush()
{
if(this.is_flushed)
return;
this.token_list.add(this.sb.toString());
this.sb = new StringBuffer();
this.is_flushed = true;
}
private void collect()
{
this.sb.append(c);
this.is_flushed = false;
}
private boolean nextToken()
{
if(this.cur_token_index<this.token_count-1)
{
this.cur_token_index++;
return true;
}
return false;
}
private String currentToken()
{
return this.token_list.get(this.cur_token_index);
}
private void initTokenList()
{
for(int i=0;i<this.exp_len;i++)
{
c = exp_array[i];
if(Character.isWhitespace(c))
{
this.flush();
continue;
}
switch(c)
{
case '<' :
this.flush();
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.token_list.add("<=");
i++;
}
else
{
this.token_list.add("<");
}
break;
case '>' :
this.flush();
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.token_list.add(">=");
i++;
}
else
{
this.token_list.add(">");
}
break;
case '(' :
this.flush();
this.token_list.add("(");
break;
case ')' :
this.flush();
this.token_list.add(")");
break;
case '=' :
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.flush();
this.token_list.add("==");
i++;
}
else
{
this.collect();
}
break;
case '!' :
if(i+1<this.exp_len && exp_array[i+1]=='=')
{
this.flush();
this.token_list.add("!=");
i++;
}
else
{
this.collect();
}
break;
default:
this.collect();
break;
}
}
this.flush();
}
public boolean eval(Map dr)
{
this.nextToken();
boolean result = this.doAndOr(dr);
this.cur_token_index = -1;
return result;
}
private boolean doAndOr(Map dr)
{
boolean result = this.doNot(dr);
String op = "";
boolean result_right;
while((op=this.currentToken()).equals("and") || op.equals("or"))
{
this.nextToken();
if(op.equals("and"))
{
result_right = this.doNot(dr);
result = result && result_right;
}
else
{
result_right = this.doNot(dr);
result = result || result_right;
}
}
return result;
}
private boolean doNot(Map dr)
{
String op="";
if((op=this.currentToken()).equals("not"))
this.nextToken();
boolean result = this.doBrackets(dr);
if(op.equals("not"))
return !result;
return result;
}
private boolean doBrackets(Map dr)
{
boolean result;
if(this.currentToken().equals("("))
{
this.nextToken();
result = this.doAndOr(dr);
this.nextToken();
}
else
{
result = this.doCompare(dr);
}
return result;
}
private boolean doCompare(Map dr)
{
Object field = dr.get(this.currentToken());
this.nextToken();
String opt = this.currentToken();
this.nextToken();
String value = this.currentToken();
this.nextToken();
if(opt.equals("like"))
{
return isLike(field,value);
}
else if(opt.equals(">"))
{
return isGreat(field,value);
}
else if(opt.equals("<"))
{
return isLess(field,value);
}
else if(opt.equals("=="))
{
return isEquals(field,value);
}
else if(opt.equals(">="))
{
return isGreatEquals(field,value);
}
else if(opt.equals("<="))
{
return isLessEquals(field,value);
}
else if(opt.equals("!="))
{
return isNotEquals(field,value);
}
return false;
}
//<editor-fold defaultstate="collapsed" desc="tool method">
private static boolean isLike(Object field,String value)
{
int len = value.length();
if(value.startsWith("'%") && value.endsWith("%'"))
return Convert.toString(field).contains(value.substring(2,len-2));
else if(value.startsWith("'%"))
return Convert.toString(field).endsWith(value.substring(2,len-1));
else if(value.endsWith("%'"))
return Convert.toString(field).startsWith(value.substring(1,len-2));
else
return Convert.toString(field).equals(value.substring(1,len-1));
}
private static boolean isLess(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)<Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))<0;
}
private static boolean isGreat(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)>Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))>0;
}
private static boolean isEquals(Object field,String value)
{
if(value.equals("null"))
return field==null;
if(field instanceof Number)
return Convert.toFloat(field)==Convert.toFloat(value);
if(field instanceof Boolean)
return Convert.toBool(field)==Convert.toBool(value);
return Convert.toString(field).equals(value.substring(1,value.length()-1));
}
private static boolean isNotEquals(Object field,String value)
{
if(value.equals("null"))
return field!=null;
if(field instanceof Number)
return Convert.toFloat(field)!=Convert.toFloat(value);
if(field instanceof Boolean)
return Convert.toBool(field)==Convert.toBool(value);
return !Convert.toString(field).equals(value.substring(1,value.length()-1));
}
private static boolean isLessEquals(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)<=Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))<=0;
}
private static boolean isGreatEquals(Object field,String value)
{
if(field instanceof Number)
return Convert.toFloat(field)>=Convert.toFloat(value);
return Convert.toString(field).compareTo(value.substring(1,value.length()-1))>=0;
}
}
class Convert
{
public static String toString(Object o)
{
return toString(o, "");
}
public static String toString(Object o, String defValue)
{
if (o == null)
return defValue;
return o.toString();
}
public static int toInt(Object o)
{
return toInt(o, 0);
}
public static int toInt(Object o, int defValue)
{
if(o==null)
return defValue;
if (o instanceof Integer)
return ((Integer) o).intValue();
try
{
return (int)Float.parseFloat(o.toString());
}
catch (Exception e)
{
return defValue;
}
}
public static long toLong(Object o)
{
if(o==null)
return 0L;
if (o instanceof Long)
return ((Long) o).longValue();
try
{
return Long.parseLong(o.toString());
}
catch (Exception e)
{
return 0L;
}
}
public static float toFloat(Object o)
{
if(o==null)
return 0F;
if (o instanceof Float)
return ((Float) o).floatValue();
try
{
return Float.parseFloat(o.toString());
}
catch (Exception e)
{
return 0F;
}
}
public static boolean toBool(Object o)
{
if(o==null)
return false;
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
try
{
return Boolean.parseBoolean(o.toString());
}
catch(Exception e)
{
return false;
}
}
public static Date toDate(Object o)
{
return toDate(o, new Date(System.currentTimeMillis()));
}
public static Date toDate(Object o, Date defValue)
{
if(o==null)
return defValue;
if (o instanceof java.util.Date)
return (Date) o;
try
{
return Timestamp.valueOf(o.toString());
}
catch (Exception e)
{
return defValue;
}
}
}