> Empty open or the right side is blocked, no elegant way
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
JDBC Starting point Overall idea: Implement the interface analysis of JDBC Specification COM.DANGDANG.DDFRAME.RDB.SHARDING.JDBC package Implement Javax.sql.DataSource interface Shardingdatasource Implement Java.sql.Connection interface shardingconnection implement Java.sql.Statement Shardingstatement Implement Java.sql.PreparedStatement shardingpreparedstatement implement Java.sql.ResultSet Abstractshardingresultset The way to re-implement ABSTRACTUNSUPPORTEDOPERATIONXXXX describes an unsupported interface implementation this series of classes shows what operations Abstractxxxxadapter is not supported. Wrapperadapter Specific implementation analysis Shardingdatasource preparing DatabaseMetaData instances based on Shardingrule instances Process for building shardingconnection instances preparing DatabaseMetaData instances: To obtain information about a database product based on the original datasource all data sources that are prepared at one time must be the same database product Can not have both MySQL and DB2 shardingconnection main completion of createstatement, preparestatement interface implementation The main process for implementing Createstatement, Preparestatement interfaces is to create shardingstatement, shardingpreparedstatement instances Creating the above two instances requires the Sqlrouteengine instance sqlrouteengine instance to complete the connection construction when the creation requires Shardingrule, DatabaseType What do sqlrouteengine do with it? For Sub-Access points for rule logic for library tables Shardingstatement implementation of java.sql.Statement interfaces Unsupported operations See abstractunsupportedoperationstatement currentresultset = Resultsetfactory.getresultset ( Generateexecutor (SQL). ExecuteQuery (), mergecontext); shardingpreparedstatement Abstractshardingresultset Executor statementexecutor based on sqlrouteengine and SQL Route out Sqlrouteresult Sqlrouteresult gets the execution unit Sqlexecutionunit Execution Unit wraps the SQL and its corresponding datasource key name Get Mergecontext statementexecutor essence lies in packaging a number of statement and the corresponding SQL in the code with the statemententity to do that the SQL is already a physical table name replaced by the logical table name of SQL Here the statement is already the corresponding JDBC driver corresponding to the native statement Sqlrouteengine 1. Route is the core of its externally exposed interface Parsesql interface with Sqlparseengine parse out Sqlparsedresult based on the parse out of the Sqlparsedresult result instance of the Conditioncontext, logical table name, sqlbuilder instance and Shardingrule (sqlrouteengine instance variable) processed Sqlexecutionunit instance List 1.1 parsesql 1. Sqlparserfactory creation of Sqlparseengine 1.1 based on logical SQL (SQL that does not yet have an actual physical table name), shard column name, database type, query condition parameters sqlparseengine The main process is: a. Use Ali's Druid to parse out the syntax tree Com.alibaba.Druid.sql.ast.SQLStatement B. Based on the SQL statement is deleted and modified to determine which visitor instance (for post processing) 1.2 parse process relies on visitor special handling with or conditions Specific visitor TODO or condition special handling 1.2 route Required features: Shardingrule (sqlrouteengine instance variable), Conditioncontext, logical table name, sqlbuilder instance Three kinds: singletablerouter--route-->singleroutingresult//single table (logical table) operation Bindingtablesrouter--route-->bindingroutingresult Mixedtablesrouter--route-->routingresult ( Cartesiantablesrouter) Singletablerouter routedatasources shardingvalue Databaseshardingstrategy.dosharding routetables shardingvalue tableshardingstrategy.dosharding Bindingtablesrouter bindingroutingresult.bind Bindingroutingdatasource.bind Bindingroutingtablefactor Visitor five kinds. Understanding the visitor premise is to understand the compiler common visitors this design pattern Com.dangdang.ddframe.rdb.sharding.parser.visitor.basic.mysql Mysqlinsertvisitor mysqldeletevisitor mysqlselectvisitor mysqlupdatevisitor OrVisitor Visitor through the Parsecontex did Mergecurrentconditioncontext, Getparsedresult, Visitor also Getsqlbuilder Abstractmysqlvisitor additions and deletions are used to re-implement visit the following types of AST node logic: sqlvariantrefexpr,sqlexprtablesource,sqlpropertyexpr, sqlbinaryopexpr,sqlinlistexpr,sqlbetweenexpr SQLVARIANTREFEXPR The question mark placeholder in sql: This named parameter xxx, @max_order_id: = this Select @max_order_id: =max (order_id) from order where id=? and User_id=:userid parent class is not only replaced with @@ 替换 but also replaced with actual parameter values. placeholder SHARDING-JDBC replace the placeholder with a true parameter value Action handed to shardingpreparedstatement finish Sqlexprtablesource select * from Order o where o.id=1 The order from the back is the Sqlexprtablesource select * FROM (the SELECT * from Order o where o.id=1) Order_alias from after the order is Sqlexprtables Ource, but Order_alias not Order_alias is Sqlsubquerytablesource Sqlsubquerytablesource and Sqlexprtablesource It's all Sqltablesourceimpl. Subclass Insert Parsecontext.addtable (x) Logic: 1. Handles special characters in table names and their aliases---[] ' \ 2. Join the table name and its alias routecontext SQLPROPERTYEXPR Select o.name from order o where o.id=1 name and ID are sqlpropertyexpr after the table alias point number Face ofis sqlpropertyexpr for the "select * from T_order where t_order.order_id=1002 this type of SQL to re-implement the visitor process of this kind of node: t_ order.order_id to alias t_order.order_id the rest of Sqlpropertyexpr inherits the parent class logic SQLBINARYOPEXPR SELECT * from Order o where o.id=1 lvalue o The. ID right value of 1 is the 1 that describes the operation of SELECT. When an OR operation is found, the presence or condition flag in the Parsecontext is set to true to facilitate the special handling of 2 later. When a = (equals comparison) operation is found, it is added to Parsecontext's conditioncontext sqlinlistexpr select * from the user U where u.id in (1,3,4,5) target The list is in the following listing expr is in front of the expression in operation is the same as the above = action sqlbetweenexpr SELECT * from T_order_0 where order_id Betwe En 1004 and 1008 between the same as above = Operation Mysqlselectvisitor Re-implement/update visit the following types of AST node logic: Mysqlselectqueryblock, Sqlselectitem,sqlaggregateexpr sqlorderby,mysqlselectgroupbyexpr, Mysqlselectqueryblock.limit, EndVisit (final Sqlselectstatement x) Mysqlselectqueryblock insert logic: tells the program which table is currently being processed by sub-query Sqlselectitem Insert logic: Update ItemIndex to process sqlaggregateexpr using sqlaggregateexpr aggregation: string[] aggregate_functions = {"AVG "," COUNT "," MAX "," MIN "," STDDEV "," SUM "} aggregation insertion logic for the Sub-Library table is mainly to analyze what kind of aggregation aggregation of which column and then throw into the Parsecontext mergeconte XT when querying with logical table names, aggregation calculations are non-sharding when querying with a physical table name, the aggregation calculation is an error, sharding does not know the physical table name Sqlorderby Similar to sqlaggregateexpr processing the order by insert logical processing of the sub-database table is mainly to analyze what sort form is which column (support multiple columns) and then throw into Parsecontext mergecontext mysqlselectgroupbyexpr treatments like sqlaggregateexpr, Sqlorderby mysqlselectqueryblock.limit Dealing with Parsecontext's mergecontext is similar to sqlaggregateexpr, Sqlorderby's handling of offset and rowcount in the context is the original SQL value One logic: The SQL to the actual physical table query is rewritten here, offset starting from 0, rowcount is the original SQL offset plus the original SQL rowcount of course support (compatible)? Placeholder status Log more intuitive: Logic sql:select * from T_order o order by o.order_id limit, route SQL to DB: [db0] sql: [select * FROM T_order_0 o ORDER by o.order_id LIMIT 0, 3] route SQL to DB: [db0] sql: [SELECT * from t_order_1 o ORDER by o.order_id LIM IT 0, 3] endvisit (final sqlselectstatement x) get agg from Mergecontext when a query endsRegationcolumns for processing, for example, the main logic is as follows: Select AVG (order_id) from T_order processed into select AVG (order_id) [Token (, COUNT (order_id) as Sha rding_gen_1, SUM (order_id) as Sharding_gen_2)] from [Token (T_order)] mostly complements SUM and Count Mysqldeletevisitor Update mysqldeletestatement processing logic adds the current table name and its alias to Routecontext feel and abstractmysqlvisitor the Sqlexprtablesource processing logic has a repeating part Mysqlinsertvisitor Adding the current table name and its alias to Routecontext with the delete inserted column also needs to be included in Parsecontext Conditioncontext management To make sure to insert into the correct table! Mysqlupdatevisitor Add the current table name and its alias Routecontext with delete No other processing logic then the Sharding key will not be updated correctly to the corresponding physical table. Shard Key Value Update The Sharding key also acts as the Where condition for the update t_order_0 set order_id=1011 where order_id=1002
Sharding-jdbc-how2work when the Sharding-jdbc anatomy