SelectBody接口
SelectBody 对象
在之前的案例中,我们尝试解析了各种SQL语句,比如以下代码,将一个查询语句解析为了Select对象:
String SQL002 = "SELECT t1.a , t1.b FROM tab1 AS t1 JOIN tab2 t2 ON t1.user_id = t2.user_id"; // 多表SQL
Select select = (Select) CCJSqlParserUtil.parse(SQL002);
而Select对象有两个重要的属性 SelectBody 和 WithItem集合:
public class Select implements Statement {
private SelectBody selectBody;
private List<WithItem> withItemsList;
}
那个这两个属性,具体是什么呢,接下来我们解析一个使用了WITH 关键字的查询语句:
String SQL003="WITH t AS ( SELECT * FROM user WHERE user.user_name = 'test' ) SELECT t.* FROM t";
Debug发现,原来SelectBody 就是Select 语句(这里为PlainSelect类型),withItemsList就是WITH 关键字后的SQL语句(WITH语句用于定义一个或者多个子查询,每个子查询定义一个临时表,类似于视图的定义)。
SelectBody接口
SelectBody中文意思就是select体,可以理解为Select语句对象,在JSqlParser中,是一个接口:
public interface SelectBody extends Model {
void accept(SelectVisitor selectVisitor);
}
SelectBody继承了Model接口,Model是JSqlParser中模型类的标记接口,sql语法由Model组成树结构表示。
SelectBody的实现类
SelectBody有四个实现类,每个对应了常用的几种SELECT操作,如下所示:
- PlainSelect:普通查询
- WithItem:WITH语句
- SetOperationList:INTERSECT、EXCEPT、MINUS、UNION语句
- ValuesStatement:VALUES语句
使用JSqlParser进行解析SQL,如果是查询操作,则会根据语句,解析为以上四种查询对象中的一种。
PlainSelect
PlainSelect是最常见的SELECT 查询对象,可以理解为普通查询语句对象,所有属性如下所示:
// 查询语句:SELECT t1.a, t1.b FROM tab1 AS t1 JOIN tab2 t2 ON t1.user_id = t2.user_id
// DISTINCT 语句
private Distinct distinct = null;
// 查询元素集合: t1.a 、t1.b
private List<SelectItem> selectItems;
// SELECT INTO 的表
private List<Table> intoTables;
// From :tab1 AS t1
private FromItem fromItem;
// JOIN 语句: JOIN tab2 t2 ON t1.user_id = t2.user_id
private List<Join> joins;
// WHERE 语句:
private Expression where;
// GroupBy 语句
private GroupByElement groupBy;
// GroupBy 语句的多个元素
private List<OrderByElement> orderByElements;
// having表达式
private Expression having;
// 分页Limit 语句内容
private Limit limit;
// 分页 offset
private Offset offset;
// 游标 Fetch
private Fetch fetch;
// 限制返回的行数 OPTIMIZE FOR xx ROWS
private OptimizeFor optimizeFor;
// SKIP
private Skip skip;
// 是否MYSQL HintStraightJoin
private boolean mySqlHintStraightJoin;
//
private First first;
// TOP 子句
private Top top;
// Oracle Hierarchical
private OracleHierarchicalExpression oracleHierarchical = null;
// OracleHint
private OracleHint oracleHint = null;
// 是否oracle siblings
private boolean oracleSiblings = false;
// 是否forUpdate 语句(手工加锁语句)
private boolean forUpdate = false;
// 手工加锁的表
private Table forUpdateTable = null;
// 是否使用括号
private boolean useBrackets = false;
// Wait 语句 多少MS
private Wait wait;
// MYSQL 中的SQL_CALC_FOUND_ROWS
private boolean mySqlSqlCalcFoundRows = false;
// 是否开启 SQL_NO_CACHE
private boolean sqlNoCacheFlag = false;
// XML 路径
private String forXmlPath;
//
private KSQLWindow ksqlWindow = null;
// 是否不是Wait
private boolean noWait = false;
Debug如下:
WithItem
WithItem是处理With语句的对象,比如下图所示中的的WITH 语句,就被解析为一个Select对象,包含PlainSelect和一个WithItem集合。
WithItem的属性说明如下:
// Whith 临时表的名称 t
private String name;
// SelectItem 集合
private List<SelectItem> withItemList;
// Whith 语句后面的查询语句
private SelectBody selectBody;
// 是否递归
private boolean recursive;
SetOperationList
当我们使用INTERSECT、EXCEPT、MINUS、UNION这些交并集查询时,就会转换为SetOperationList对象。
其属性说明如下:
// 每个SELECT 语句:SELECT Txn_Date FROM Store_Information
private List<SelectBody> selects;
// 是否包含括号
private List<Boolean> brackets;
// 操作关键字=》INTERSECT
private List<SetOperation> operations;
// 排序元素
private List<OrderByElement> orderByElements;
// 分页关键字
private Limit limit;
private Offset offset;
private Fetch fetch;
Debug如下:
ValuesStatement
貌似是处理VALUES的,但是没整明白。。。有知道的可以告知下
private List<Expression> expressions;