利用jsqlparser解析SQL语句
来源:互联网 发布:万户网络官网 编辑:程序博客网 时间:2024/06/09 23:55
时常会遇到很多情况,我们需要对SQL语句进行替换或者拼接。以往我们可能会用StringBuild来进行拼接。
StringBuilder sql = new StringBuilder();sql.append("select * from");sql.append(schema);sql.append(".");sql.append(table);sql.append("where id = '"+id+"'");
但是这样的操作不仅看起来不优雅,也不简洁。面对复杂的sql,有很多子循环的情况下,并不适用。
因此我们需要借助一些工具来实现这个功能。这里我们使用jsqlparser这个sql解析工具。
SqlParser - github地址:https://github.com/JSQLParser/JSqlParser
SqlParser最新版jar下载:http://search.maven.org/remotecontent?filepath=com/github/jsqlparser/jsqlparser/0.9.1/jsqlparser-0.9.1.jar
maven依赖为
<dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> </dependency>
在GitHub中有很详细的介绍,我们对常用的CRUD方法做一个总结。
首先建立一个DBSelectDeParser继承SelectDeParser
public class DBSelectDeParser extends SelectDeParser { public DBSelectDeParser(ExpressionVisitor expressionVisitor, StringBuilder buffer){ super(expressionVisitor, buffer); } @Override public void visit(Table tableName) { String schema = tableName.getSchemaName(); String table = tableName.getName(); if (fullTableName ==null){ throw new SqlvpException("table is null"); } tableName.setSchemaName("user"); tableName.setName("age"); StringBuilder buffer = getBuffer(); buffer.append(tableName.getFullyQualifiedName()); Pivot pivot = tableName.getPivot(); if (pivot != null) { pivot.accept(this); } Alias alias = tableName.getAlias(); if (alias != null) { buffer.append(alias); } }}
现在来定义一个接口,每次只要调用这个接口就可以了
public interface TablePicker { /** * 从sql文中挑选出所有的库表 * * @param sql sql文 * @param mode 错误的策略模式 * @param params * @return 库表列表 */ String pickTable(String sql, ErrorMode mode, Map<String, Object> params);}
实现类:TablePickerImpl
public class TablePickerImpl implements TablePicker { private static Logger logger = LoggerFactory.getLogger(TablePickerImpl.class); @Override public String pickTable(String sql, ErrorMode mode, Map<String, Object> params) { CCJSqlParserManager parser = new CCJSqlParserManager(); StringBuilder buffer = new StringBuilder(); try { Statement stmt = parser.parse(new StringReader(sql)); // 查询语句处理 if (stmt instanceof Select) { Select Statement = (Select) stmt; logger.debug("解析sql的语句: {} ",Statement.toString()); //Start of value modification ExpressionDeParser expressionDeParser = new ExpressionDeParser(); SelectDeParser deparser = new DBSelectDeParser(expressionDeParser, buffer, mode, params); expressionDeParser.setSelectVisitor(deparser); expressionDeParser.setBuffer(buffer); Statement.getSelectBody().accept(deparser); logger.debug("替换成功,文本为: {} ",buffer.toString()); return buffer.toString(); } // 插入语句处理 if (stmt instanceof Insert) { Insert Statement = (Insert) stmt; logger.debug("解析sql的语句: {} ",Statement.toString()); Table t = new Table(); t.setSchemaName("user"); t.setName("age"); Statement.setTable(t); // 获取insert语句中的查询语句,如果没有则不替换select Select select = Statement.getSelect(); if (select != null) { ExpressionDeParser expressionDeParser = new ExpressionDeParser(); SelectDeParser deparser = new DBSelectDeParser(expressionDeParser, buffer, mode, params); expressionDeParser.setSelectVisitor(deparser); expressionDeParser.setBuffer(buffer); select.getSelectBody().accept(deparser); } logger.debug("替换成功,文本为: {} ",Statement.toString()); return Statement.toString(); } } catch (JSQLParserException e) { logger.error(e.getMessage()); } // 如果四种条件都不匹配则抛出异常。 throw new SqlvpException("error sql can not be parse!check your sql!"); }}
通过以上操作我们就完成了对查询和插入语句的解析替换,查询和插入是两个不同的操作,所以语句解析也不相同。
官方支持各种SQL语句,可以查看源码包。
同样还支持对where语句的解析,大家可自行测试。
阅读全文
1 0
- 利用jsqlparser解析SQL语句
- Java SQL语句解析——Jsqlparser开源项目
- java 使用JSqlParser 解析sql语句中的表字段
- JAVA - Sql解析工具jsqlparser简单使用
- JAVA - Sql解析工具jsqlparser简单使用
- org.tinygroup.jsqlparser-SQL解析器
- org.tinygroup.jsqlparser-SQL解析器
- JSQLParser
- SQL 语法解释器jsqlparser
- java SQL语法解释器jsqlparser
- SQL语句解析
- SQL语句全解析
- SQL语句全解析
- SQL语句解析
- SQL语句解析
- SQL语句优化解析
- sql语句解析实现
- sql 左外连语句解析
- xdebug Debug session was finished without being paused
- 仿斗鱼滑动拼图验证码控件
- FreeRadioGroup一一淡出、自由拖动、自动贴边
- 2016年终总结,新的里程和新的开始
- Android多进程使用场景
- 利用jsqlparser解析SQL语句
- web-前端开发之栅格系统的简单应用
- CycleRotationView:自定义控件之轮播图
- 直播写代码,今晚8点见!
- ThreadLocal使用案例
- Android RxJava+Retrofit完美封装
- Android自定义ViewGroup之浪漫求婚
- LED_1_0(单灯闪烁)
- 通信协议之Protocol buffer(Java篇)