用SQL查询对象(200行Java代码)

用SQL查询对象(200行Java代码)

本文主要讲解SQL对象查询的实现过程。SQL4ObjQuery 实现了基本Sql查询功能:多条件过滤,分页,排序。

第三方组件使用

1. druid SQL字符串的解析
2. spring-expression  对象值读取及方法调用,表达式的

核心实现思路

  • 用druid解析SQL字符串,获得SQL的结构化对象表征.
  • 把SQL的条件过滤逻辑转为Stream.filter方法所需要的Predicate对象,需递归。

主要代码

/**
 * execute query
 * @param sql  format:select * from T t where t.xx=XXX
 * @param dataList data which query on
 * @return T's Stream
 * @throws Throwable sometime not support SQL eg:parse error,join clause,group clause will ignore
 */
public   Stream<T> execute(String sql,Collection<T>  dataList) throws Throwable {
	System.out.println("query Collection size="+dataList.size());
    // parse
    List<SQLStatement> statements = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
    // only support one select statement
    SQLStatement statement = statements.get(0);
    SQLSelectStatement sqlSelectStatement = (SQLSelectStatement) statement;
    SQLSelectQuery sqlSelectQuery     = sqlSelectStatement.getSelect().getQuery();
    // not union select statement
    if (sqlSelectQuery instanceof SQLSelectQueryBlock) {
        this.sqlSelectQueryBlock = (SQLSelectQueryBlock) sqlSelectQuery;
        //get table info 
        SQLTableSource from = sqlSelectQueryBlock.getFrom();
        if (!(from instanceof SQLExprTableSource)) {
        	throw new Throwable("Sql not support! only one table");
        }
        this.parser = new SpelExpressionParser();
        this.table=(SQLExprTableSource)from;
        this.where = sqlSelectQueryBlock.getWhere();
        this.stream=dataList.stream();
        
    	// See if we have any expressions that are to be executed on   the Stream<T>.
        this.evalWhereClause();
    	// Now perform the order by.
        this.evalOrderByClause (sqlSelectQueryBlock.getOrderBy());
    	// Finally, if we have a limit clause, restrict the size of Stream<T> returned...
        this.evalLimitClause ();
    } 
    return this.stream;
}

运行:执行查询在File对象上

public static void main(String[] args) throws Throwable {
	// Get a list of java.io.File objects.
	File dir =new File("/Users/xx/Desktop/db/sql4object/src/main/java/fencer911/sql4object");
	List<File> files = Arrays.asList(dir.listFiles());
	String sql="SELECT * FROM File f WHERE f.name like '%p%.java' order by f.name ";
	sql="SELECT * FROM java.io.File  WHERE name like '%p%.java' and length()>1241 order by name desc  ";
	Stream<File> stream=new SQL4ObjQuery<File>().execute(sql,files);
	
    System.out.println("stream.forEach");
    List<File> list=stream.collect(Collectors.toList());
    list.forEach(f->{
	    System.out.println(f.getName()+","+f.length());
    });
}

项目源码地址

https://github.com/fencer911/SQL4ObjQuery

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值