instructions

1. The function of infra module is the core engine, including: parsing, routing, rewriting, execution, merging and so on. However, in our daily work, we cannot directly use the functions of infra module, but through sharding JDBC module. Sharding JDBC provides support for distributed database scenarios through the encapsulation of JDBC, so that we can not care about the underlying implementation, directly with the operation of JDBC to deal with sharding, read and write separation and other problems.

Java Database Connectivity (JDBC) is designed to provide a unified standard for all kinds of databases, and different Database vendors comply with this standard, and provide their own implementation solutions to provide program calls. As a unified standard, the JDBC specification has a complete architecture, as shown in the following figure:

The Driver Manager in the JDBC architecture is responsible for loading various drivers and returning the corresponding database Connection to the caller based on the request. The application invokes the JDBC API to operate on the database. For developers, the JDBC API is our primary access to the database and the entry point for ShardingSphere to rewrite the JDBC specification and add sharding capabilities. If we use JDBC to develop a process for accessing a database, the common code style is as follows:

Final String HOST = "127.0.0.1"; final int PORT = 3306; final String USER_NAME = "root"; final String PASSWORD = "123456"; HikariDataSource result = new HikariDataSource(); result.setDriverClassName("com.mysql.jdbc.Driver"); result.setJdbcUrl(String.format("jdbc:mysql://%s:%s/%s? serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8", HOST, PORT, dataSourceName)); result.setUsername(USER_NAME); result.setPassword(PASSWORD); try (Connection connection = result.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement("select * from user"); ResultSet set = preparedStatement.executeQuery();) { while (set.next()) { String name = set.getString(1); } } catch (SQLException throwables) { throwables.printStackTrace(); }Copy the code

This code contains the core interfaces in the JDBC API, which are the basic way we do jDBC-based data access, and which you’ll find doing your daily development in the ShardingSphere.

DataSource

DataSource represents a DataSource in the JDBC specification, and its core function is to obtain a database Connection object. In the JDBC specification, you can actually get a Connection directly from DriverManager. We know that the process of obtaining a Connection requires the establishment of a Connection with the database, and this process incurs significant system overhead.

To improve performance, an intermediate layer is usually created that stores the Connection generated by DriverManager into a Connection pool and then retrits the Connection from the pool. In daily development, we usually get a Connection based on a DataSource. In the ShardingSphere, business developers are exposed to an enhanced DataSource object as well. The DataSource interface is defined as follows:

public interface DataSource  extends CommonDataSource, Wrapper {

  Connection getConnection() throws SQLException;

  Connection getConnection(String username, String password)
    throws SQLException;
}
Copy the code

Note that the DataSource interface also inherits a Wrapper interface. The naming of the interface suggests that it should act as a Wrapper. In fact, since many database vendors offer extensions beyond the standard JDBC API, the Wrapper interface can wrap a non-JDBC standard interface provided by a third-party vendor as a standard interface. Taking the DataSource interface as an example, if we want to implement our DataSource MyDataSource, we can provide a Wrapper class MyDataSourceWrapper that implements the Wrapper interface.

In the JDBC specification, in addition to DataSource, Connection, Statement, ResultSet and other core objects also inherit this interface. Obviously, ShardingSphere provides a non-JDBC standard interface, so the Wrapper interface should also be used and provides a similar implementation.

The following figure shows the development flow chart of database access with JDBC specification

ShardingSphere provides an API that is fully compliant with the JDBC specification. That is, developers can perform sharding engines, data desensitization, and so on, based on this development process and the core interfaces in JDBC. Let’s take a look.

JDBC rewrite implementation scheme based on adapter pattern

In ShardingSphere, the basic strategy to achieve compatibility with the JDBC specification is to adopt the Adapter Pattern in the design Pattern. The adapter pattern is often used as a bridge between two incompatible interfaces and involves adding separate or incompatible functionality to an interface.

As a set of implementation scheme adapted to JDBC specification, ShardingSphere needs to rewrite the DataSource, Connection, Statement, ResultSet and other core objects in JDBC API. Although these objects carry different functions, the override mechanism should be common, otherwise we would need to implement custom development for different objects, which is obviously not in line with our design principles. Therefore, ShardingSphere abstracts and develops a set of implementation schemes based on adapter patterns. The overall structure is as follows. I take Connection as an example, as shown in the figure below:

First, we see that there is a Connection interface. As mentioned earlier, these interfaces inherit from the Wrapper interface. ShardingSphere provides an implementation class WrapperAdapter for the Wrapper interface, as shown in the figure. In ShardingSphere sharding code project – JDBC – the core of the org. Apache. ShardingSphere. Shardingjdbc. JDBC. Adapter package contains all adapter related implementation class:

At the bottom of ShardingSphere’s adapter-pattern-based implementation diagram, there is a ShardingSphereConnection implementation class.

Finally found ShardingSphereConnection inherited from a AbstractConnectionAdapter, And AbstractConnectionAdapter inherited from AbstractUnsupportedOperationConnection, these two classes are abstract classes, but also refers to a set of classes. The difference between the two is that AbstractConnectionAdapter is only provided for the Connection part of the interface implementation method, these methods is that we complete the shard operation need. Realizes, and for those who we don’t need all to AbstractUnsupportedOperationConnection for implementation, these two classes of all methods of collection, is the original Connection interface all methods of definition.

This gives us an overview of ShardingSphere’s rewriting mechanism for core interfaces in the JDBC specification. This rewriting mechanism is very important and widely used in the ShardingSphere, and can be further understood through examples.

ShardingSphereConnection is an adaptation and wrapper for Connection in JDBC, so it needs to provide the methods defined in the Connection interface, This includes createConnection, getMetaData, prepareStatement and createStatement of various overloads, and setAutoCommit, COMMIT, and rollback methods for transactions. ShardingSphereConnection overwrites these methods.

conclusion

The JDBC specification is fundamental to understanding and applying ShardingSphere, which rewrites the JDBC specification and provides a fully compatible set of interfaces.