博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库分库分表中间件 Sharding-JDBC 源码分析 —— SQL 解析(五)之更新SQL
阅读量:6572 次
发布时间:2019-06-24

本文共 3306 字,大约阅读时间需要 11 分钟。

hot3.png

???关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

本文主要基于 Sharding-JDBC 1.5.0 正式版


1. 概述

本文前置阅读:

本文分享更新SQL解析的源码实现。

更新SQL解析比查询SQL解析复杂度低的多的多。不同数据库在插入SQL语法上也统一的多。本文分享 MySQL 更新SQL解析器 MySQLUpdateParser

MySQL UPDATE 语法一共有 2 种 :

  • 第一种:Single-table syntax
UPDATE [LOW_PRIORITY] [IGNORE] table_reference    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...    [WHERE where_condition]    [ORDER BY ...]    [LIMIT row_count]
  • 第二种:Multiple-table syntax
UPDATE [LOW_PRIORITY] [IGNORE] table_references    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...    [WHERE where_condition]

Sharding-JDBC 目前仅支持第一种。业务场景上使用第二种的很少很少。

Sharding-JDBC 更新SQL解析主流程如下:

// AbstractUpdateParser.java@Overridepublic UpdateStatement parse() {   sqlParser.getLexer().nextToken(); // 跳过 UPDATE   skipBetweenUpdateAndTable(); // 跳过关键字,例如:MYSQL 里的 LOW_PRIORITY、IGNORE   sqlParser.parseSingleTable(updateStatement); // 解析表   parseSetItems(); // 解析 SET   sqlParser.skipUntil(DefaultKeyword.WHERE);   sqlParser.setParametersIndex(parametersIndex);   sqlParser.parseWhere(updateStatement);   return updateStatement; // 解析 WHERE}

Sharding-JDBC 正在收集使用公司名单:。

? 你的登记,会让更多人参与和使用 Sharding-JDBC。
Sharding-JDBC 也会因此,能够覆盖更多的业务场景。
登记吧,骚年!

2. UpdateStatement

更新SQL 解析结果。

public final class UpdateStatement extends AbstractSQLStatement {}

? 对,没有其他属性。

我们来看下 UPDATE t_user SET nickname = ?, age = ? WHERE user_id = ?解析结果

3. #parse()

3.1 #skipBetweenUpdateAndTable()

UPDATE 和 表名 之间有些词法,对 SQL 路由和改写无影响,进行跳过。

// MySQLUpdateParser.java@Overrideprotected void skipBetweenUpdateAndTable() {   getSqlParser().skipAll(MySQLKeyword.LOW_PRIORITY, MySQLKeyword.IGNORE);}// OracleUpdateParser.java@Overrideprotected void skipBetweenUpdateAndTable() {   getSqlParser().skipIfEqual(OracleKeyword.ONLY);}

3.2 #parseSingleTable()

解析,请看。

3.3 #parseSetItems()

解析SET后语句。

// AbstractUpdateParser.java/*** 解析多个 SET 项*/private void parseSetItems() {   sqlParser.accept(DefaultKeyword.SET);   do {       parseSetItem();   } while (sqlParser.skipIfEqual(Symbol.COMMA)); // 以 "," 分隔}/*** 解析单个 SET 项*/private void parseSetItem() {   parseSetColumn();   sqlParser.skipIfEqual(Symbol.EQ, Symbol.COLON_EQ);   parseSetValue();}/*** 解析单个 SET 项*/private void parseSetColumn() {   if (sqlParser.equalAny(Symbol.LEFT_PAREN)) {       sqlParser.skipParentheses();       return;   }   int beginPosition = sqlParser.getLexer().getCurrentToken().getEndPosition();   String literals = sqlParser.getLexer().getCurrentToken().getLiterals();   sqlParser.getLexer().nextToken();   if (sqlParser.skipIfEqual(Symbol.DOT)) { // 字段有别名       // TableToken       if (updateStatement.getTables().getSingleTableName().equalsIgnoreCase(SQLUtil.getExactlyValue(literals))) {           updateStatement.getSqlTokens().add(new TableToken(beginPosition - literals.length(), literals));       }       sqlParser.getLexer().nextToken();   }}/*** 解析单个 SET 值*/private void parseSetValue() {   sqlParser.parseExpression(updateStatement);   parametersIndex = sqlParser.getParametersIndex();}

3.4 #parseWhere()

解析 WHERE 条件。解析代码:。

666. 彩蛋

? 比更新SQL解析是不是简单,更不用对比查询SQL解析。?有一种在水更的感觉。嘿嘿,下一篇()会更加容易。

道友,帮我分享一波怎么样?

转载于:https://my.oschina.net/sword4j/blog/1523219

你可能感兴趣的文章
解决:laravel出现Please provide a valid cache path.
查看>>
兼容IE浏览器样式的html上传文件控件
查看>>
直接插入排序
查看>>
SQLServer的Top功能
查看>>
CentOS之crontab
查看>>
【在线研讨-现场文字】《敏捷开发用户故事分类与组织结构(二期-3)》2012-07-03...
查看>>
Hyper-V 2012 R2 配置存储QoS
查看>>
易语言 --什么情况下 用许可证
查看>>
项目总结:凡事预则立,不预则废!
查看>>
ORA-32004: obsolete and/or deprecated parameter(s)
查看>>
建属于自己的网站
查看>>
[linux] ubuntu 切换默认的/bin/sh
查看>>
Web Bench (网站压力测试工具)
查看>>
boost库之智能指针
查看>>
linux c/c++ GDB教程详解(转载)
查看>>
华为HCIE 面试战报
查看>>
C++ 一些知名的库
查看>>
用busybox创建一个不足50M的Linux
查看>>
在redhat server 6 安装gcc-4.5.2
查看>>
我的友情链接
查看>>