搜索
写经验 领红包
 > 职场

SQL解析利器JSqlParser

导语:

JSqlParser是一个与RDBMS无关的SQL语句解析器,支持多种方言,例如Oracle、SQL Server、MySQL、MariaDB、PostgreSQL、H2等。

JSqlParser将SQL语句转换为Java类的可遍历层次结构,还可以用于通过API从Java代码创建SQL语句。现在普遍使用的mybatis-plus以及分页插件PageHelper都是借助JSqlParser实现SQL解析的。

JSqlParser源码主要包括以下几类对象:

expression:SQL构建相关类,比如Function、EqualsTo、AndExpression、InExpression等表达式用于构建SQL。parser:SQL解析相关类,比如CCJSqlParserUtil、CCJSqlParserManager、抽象语法树对象等。schema:主要存放数据库schema相关的类 ,比如Database、Table、Column等。statement:封装了数据库操作对象,create、insert、delete、select、drop、alter、truncate等。util:各种工具类、不同DB版本、SQL标准等处理类,如SelectUtils、DatabaseType等。

解析SQL

对于下列SQL语句:

SELECT name, age, score FROM user WHERE id=1;

转换为Java对象层次结构为:

SQL解析利器JSqlParser

解析SQL代码实例:

public static void parseSQL() {    //Select语句样本    String sql1 = &39;10&39;12&34;;    //Insert语句样本    String sql2 = &34;;    //Create语句样本    String sql3 = &34; +        &39;编号&34; +        &39;&39;名称&34; +        &39;年龄&34; +        &39;&39;创建者&34; +        &39;创建时间&34; +        &39;&39;更新者&34; +        &39;更新时间&34; +        &39;备注&34; +        &34; +        &39;用户表&34;;    try {        //处理Select语句        Select select = (Select) CCJSqlParserUtil.parse(sql1);        TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();        List<String> tableList = tablesNamesFinder.getTableList(select);        // 获取到查询sql中的所有表名        System.out.println(&34; + tableList);                   //处理Insert语句        Insert insert = (Insert) CCJSqlParserUtil.parse(sql2);        System.out.println(&34; + insert.getTable());        System.out.println(&34; + insert.getColumns());        System.out.println(&34; + insert.getItemsList());                   //处理Create Table语句        Statement statement = CCJSqlParserUtil.parse(sql3);        if (statement instanceof CreateTable) {            CreateTable createTable = ((CreateTable) statement);            Table table = createTable.getTable();            //通过columnDefinition进而可以获取列名、数据类型等            List<ColumnDefinition> columnDefinitions = createTable.getColumnDefinitions();            System.out.println(table);            System.out.println(columnDefinitions);        }    } catch (Exception e) {        e.printStackTrace();    }}

输出如下:

表名:[table1, table2, table3]插入的表table插入的列[f1, f2]插入的值(1, 2)`sys_user`[`id` bigint (20) NOT NULL AUTO_INCREMENT COMMENT &39;, `username` varchar (200) DEFAULT &39; COMMENT &39;, `age` tinyint (4) DEFAULT NULL COMMENT &39;, `create_by` varchar (64) DEFAULT &39; COMMENT &39;, `create_time` datetime DEFAULT NULL COMMENT &39;, `update_by` varchar (64) DEFAULT &39; COMMENT &39;, `update_time` datetime DEFAULT NULL COMMENT &39;, `remark` varchar (500) DEFAULT NULL COMMENT &39;]

创建SQL
/** * 创建SQL查询语句 * * @throws JSQLParserException */public static void createSQL() throws JSQLParserException {  // 单表全量  Table table = new Table(&34;);  //查询所有列  Select select = SelectUtils.buildSelectFromTable(table);  // SELECT * FROM sys_user  System.out.println(select);    // 指定列查询    Select buildSelectFromTableAndExpressions = SelectUtils.buildSelectFromTableAndExpressions(new Table(&34;), new Column(&34;), new Column(&34;));    // SELECT col1, col2 FROM sys_user    System.out.println(buildSelectFromTableAndExpressions);    // WHERE =    EqualsTo equalsTo = new EqualsTo(); // 等于表达式    // 设置表达式左边值    equalsTo.setLeftExpression(new Column(table, &34;));     // 设置表达式右边值    equalsTo.setRightExpression(new StringValue(&34;));    // 转换为更细化的Select对象    PlainSelect plainSelect = (PlainSelect) select.getSelectBody();    plainSelect.setWhere(equalsTo);    // SELECT * FROM sys_user WHERE sys_user.user_id = &39;    System.out.println(plainSelect);    // WHERE  != <>    NotEqualsTo notEqualsTo = new NotEqualsTo();    notEqualsTo.setLeftExpression(new Column(table, &34;)); // 设置表达式左边值    notEqualsTo.setRightExpression(new StringValue(&34;));// 设置表达式右边值    PlainSelect plainSelectNot = (PlainSelect) select.getSelectBody();    plainSelectNot.setWhere(notEqualsTo);    System.out.println(plainSelectNot);//  SELECT * FROM sys_user WHERE sys_user.user_id <> &39;    // 其他运算符, 参考上面代码添加表达式即可    GreaterThan gt = new GreaterThan(); // &34;    GreaterThanEquals geq = new GreaterThanEquals(); // &34;    MinorThan mt = new MinorThan(); // &34;    MinorThanEquals leq = new MinorThanEquals();// &34;    IsNullExpression isNull = new IsNullExpression(); // &34;    isNull.setNot(true);// &34;    LikeExpression nlike = new LikeExpression();    nlike.setNot(true); // &34;    Between bt = new Between();    bt.setNot(true);// &34;    // WHERE LIKE    LikeExpression likeExpression = new LikeExpression(); // 创建Like表达式对象    likeExpression.setLeftExpression(new Column(&34;)); // 表达式左边    likeExpression.setRightExpression(new StringValue(&34;)); // 右边表达式    PlainSelect plainSelectLike = (PlainSelect) select.getSelectBody();    plainSelectLike.setWhere(likeExpression);    System.out.println(plainSelectLike); // SELECT * FROM sys_user WHERE username LIKE &39;    // WHERE IN    Set<String> deptIds = Sets.newLinkedHashSet(); // 创建IN范围的元素集合    deptIds.add(&34;);    deptIds.add(&34;);    ItemsList itemsList = new ExpressionList(deptIds.stream().map(StringValue::new).collect(Collectors.toList())); // 把集合转变为JSQLParser需要的元素列表    InExpression inExpression = new InExpression(new Column(&34;), itemsList); // 创建IN表达式对象,传入列名及IN范围列表    PlainSelect plainSelectIn = (PlainSelect) select.getSelectBody();    plainSelectIn.setWhere(inExpression);    System.out.println(plainSelectIn); // SELECT * FROM sys_user WHERE dept_id  IN (&39;, &39;)    // WHERE BETWEEN AND    Between between = new Between();    between.setBetweenExpressionStart(new LongValue(18)); // 设置起点值    between.setBetweenExpressionEnd(new LongValue(30)); // 设置终点值    between.setLeftExpression(new Column(&34;)); // 设置左边的表达式,一般为列    PlainSelect plainSelectBetween = (PlainSelect) select.getSelectBody();    plainSelectBetween.setWhere(between);    System.out.println(plainSelectBetween); // SELECT * FROM sys_user WHERE age BETWEEN 18 AND 30    //  WHERE AND 多个条件结合,都需要成立    AndExpression andExpression = new AndExpression(); // AND 表达式    andExpression.setLeftExpression(equalsTo); // AND 左边表达式    andExpression.setRightExpression(between);  // AND 右边表达式    PlainSelect plainSelectAnd = (PlainSelect) select.getSelectBody();    plainSelectAnd.setWhere(andExpression);    System.out.println(plainSelectAnd); //  SELECT * FROM sys_user WHERE sys_user.user_id = &39; AND age BETWEEN 18 AND 30    //  WHERE OR 多个条件满足一个条件成立返回    OrExpression orExpression = new OrExpression();// OR 表达式    orExpression.setLeftExpression(equalsTo); // OR 左边表达式    orExpression.setRightExpression(between);  // OR 右边表达式    PlainSelect plainSelectOr = (PlainSelect) select.getSelectBody();    plainSelectOr.setWhere(orExpression);    System.out.println(plainSelectOr); // SELECT * FROM sys_user WHERE sys_user.user_id = &39; OR age BETWEEN 18 AND 30    // ORDER BY 排序    OrderByElement orderByElement = new OrderByElement(); // 创建排序对象    orderByElement.isAsc(); //  设置升序排列 从小到大    orderByElement.setExpression(new Column(&34;)); // 设置排序字段    PlainSelect plainSelectOrderBy = (PlainSelect) select.getSelectBody();    plainSelectOrderBy.addOrderByElements(orderByElement);    // SELECT * FROM sys_user WHERE sys_user.user_id = &39; OR age BETWEEN 18 AND 30 ORDER BY col01    System.out.println(plainSelectOrderBy); }

输出如下:

SELECT * FROM sys_userSELECT col1, col2 FROM sys_userSELECT * FROM sys_user WHERE sys_user.user_id = &39;SELECT * FROM sys_user WHERE sys_user.user_id <> &39;SELECT * FROM sys_user WHERE username LIKE &39;SELECT * FROM sys_user WHERE dept_id  IN (&39;, &39;)SELECT * FROM sys_user WHERE age BETWEEN 18 AND 30SELECT * FROM sys_user WHERE sys_user.user_id = &39; AND age BETWEEN 18 AND 30SELECT * FROM sys_user WHERE sys_user.user_id = &39; OR age BETWEEN 18 AND 30SELECT * FROM sys_user WHERE sys_user.user_id = &39; OR age BETWEEN 18 AND 30 ORDER BY col01