http://www.cnblogs.com/yunai/p/7356628.html
1. 概述
本文前置阅读:
本文分享插入SQL解析的源码实现。
不考虑 INSERT SELECT 情况下,插入SQL解析比查询SQL解析复杂度低的多的多。不同数据库在插入SQL语法上也统一的多。本文分享 MySQL 插入SQL解析器 MySQLInsertParser。
MySQL INSERT 语法一共有 3 种 :
- 第一种:
INSERT
{VALUES | VALUES}
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
- 第二种:
INSERT
SET
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
- 第三种:
INSERT
SELECT
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
[PARTITION (partition_name,...)]
[(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
Sharding-JDBC 目前支持:
- 第一种:
INSERT
单条记录
{VALUES | VALUES} - 第二种:
INSERT SET
Sharding-JDBC 插入SQL解析主流程如下:
// AbstractInsertParser.java
public final InsertStatement parse() {
sqlParser.getLexer().nextToken(); // 跳过 INSERT 关键字
parseInto(); // 解析INTO
parseColumns(); // 解析表
if (sqlParser.equalAny(DefaultKeyword.SELECT, Symbol.LEFT_PAREN)) {
throw new UnsupportedOperationException("Cannot support subquery");
}
if (getValuesKeywords().contains(sqlParser.getLexer().getCurrentToken().getType())) { // 第一种插入SQL情况
parseValues();
} else if (getCustomizedInsertKeywords().contains(sqlParser.getLexer().getCurrentToken().getType())) { // 第二种插入SQL情况
parseCustomizedInsert();
}
appendGenerateKey(); // 自增主键
return insertStatement;
}
Sharding-JDBC 正在收集使用公司名单:传送门。