当前位置: 首页 > news >正文

四川做网站的广州市官网网站建设公司

四川做网站的,广州市官网网站建设公司,网站建设技术方案怎么写,汉川建设局网站Sharding-JDBC系列 1、Sharding-JDBC分库分表的基本使用 2、Sharding-JDBC分库分表之SpringBoot分片策略 3、Sharding-JDBC分库分表之SpringBoot主从配置 4、SpringBoot集成Sharding-JDBC-5.3.0分库分表 5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表 6、【…

 Sharding-JDBC系列

1、Sharding-JDBC分库分表的基本使用

2、Sharding-JDBC分库分表之SpringBoot分片策略

3、Sharding-JDBC分库分表之SpringBoot主从配置

4、SpringBoot集成Sharding-JDBC-5.3.0分库分表

5、SpringBoot集成Sharding-JDBC-5.3.0实现按月动态建表分表

6、【源码】Sharding-JDBC源码分析之JDBC

前言

《Sharding-JDBC系列》的前5篇博文分析了Sharding-JDBC的使用,本篇带大家从源码的角度整体的熟悉Sharding-JDBC的实现原理。从Sharding-JDBC 5.1.2 版本开始,提供了原生JDBC驱动ShardingSphereDriver。

JDBC

2.1 JDBC概述

JDBC(Java DataBase Connectivity),是java连接数据库操作的原生接口API,为开发者访问数据库提供标准的接口。各数据库厂商依照JDBC规范,实现规范中的接口,实现数据库的连接。Java开发者使用同样的访问代码,配置不同的Driver、url以及账号,即可实现不同数据库厂家的数据库连接。

2.2 JDBC组成

JDBC是由一组用Java语言编写的类和接口,主要有DriverManager、Driver、Connection、Statement、ResultSet等。

使用JDBC连接数据库的步骤包含以下步骤:

1)加载JDBC驱动程序:使用Class.forName()方法加载特定数据库的JDBC驱动程序,即对应数据库插件中实现Driver接口的类;

如:

Mysql8之前为com.mysql.jdbc.Driver

Mysql8的com.mysql.cj.jdbc.Driver

Oracle的oracle.jdbc.driver.OracleDriver

2)创建Connection数据库连接:使用DriverManager.getConnection()方法返回一个Connection,创建一个数据库连接对象。该方法需要指定数据库的连接字符串、用户名和密码;

3)创建Statement对象:通过数据库连接对象Connection,创建一个Statement对象,用于执行SQL语句;

也可以通过数据库连接对象Connection,预编译SQL语句,获得一个PreparedStatement对象。该方式通常与动态SQL语句结合使用,获得PreparedStatement对象后,给动态SQL语句中的占位符赋值。使用该方式不会有SQL注入的风险。

4)执行SQL语句:使用Statement对象执行SQL语句,包括插入、查询、更新和删除等操作。如果是查询操作,返回ResultSet对象;

5)关闭数据库连接:使用数据库连接对象Connection的close()方法关闭数据库连接;

2.3 JDBC使用

以下以MySQL为例,讲解一下JDBC的使用。

2.3.1 使用创建Statement的方式

@SpringBootTest
public class Test {@org.junit.jupiter.api.Testpublic void mysqlTest() throws Exception {// 1、加载启动Class.forName("com.mysql.cj.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/test";String username = "root";String password = "123456";// 2、获取Connection对象Connection connection = DriverManager.getConnection(url, username, password);String sql = "select * from tb_user";// 3、创建Statement对象Statement statement = connection.createStatement();// 4、执行Sql。查询语句返回ResultSetResultSet resultSet = statement.executeQuery(sql);// 5、处理结果集while(resultSet.next()) {System.out.println("name : " + resultSet.getString("name"));}// 6、关闭数据库连接statement.close();connection.close();}}

2.3.2 使用PreparedStatement的方式

    @org.junit.jupiter.api.Testpublic void mysqlTest2() throws Exception {// 1、加载启动Class.forName("com.mysql.cj.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/test";String username = "root";String password = "123456";// 2、获取Connection对象Connection connection = DriverManager.getConnection(url, username, password);String sql = "insert into tb_user(name, state) values(?, ?)";// 3、预编译SQL语句,没有执行SQL// 此处传入两个参数值,第二个参数为Statement.RETURN_GENERATED_KEYS,指定返回数据库生成的主键PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);// 占位符赋值statement.setString(1, "王五");statement.setString(2, "1");// 4、执行Sql,此处不需要再传入SQL语句。执行更新操作,返回操作成功的记录数int rs = statement.executeUpdate();// 5、获取生成的主键ResultSet generatedKeys = statement.getGeneratedKeys();// 移到结果集的下一行generatedKeys.next();System.out.println("执行结果 : " + rs + ",记录主键:" + generatedKeys.getInt(1));// 6、关闭数据库连接statement.close();connection.close();}

1)通过Connection的prepareStatement()方法,可以在第二个参数中指定Statement.RRTURN_GENERATED_KEYS,获取数据库表中设置的自动生成的主键值;

2)可以通过PreparedStatement的addBatch()方法,实现对数据库的批量操作;

2.4 JDBC原理

2.4.1 JDBC的驱动程序

JDBC的驱动程序为实现了java.sql.Driver接口的类。如com.mysql.cj.jdbc.Driver。当使用Class.forName()将对应的驱动类加载到元空间后,会执行类的static静态代码段。源码如下:

package com.mysql.cj.jdbc;import java.sql.DriverManager;
import java.sql.SQLException;public class Driver extends NonRegisteringDriver implements java.sql.Driver {public Driver() throws SQLException {}static {try {DriverManager.registerDriver(new Driver());} catch (SQLException var1) {throw new RuntimeException("Can't register driver!");}}
}

在static静态代码段中,new一个Driver,并通过DriverManager.registerDriver(),将Driver注册到DriverManager中。DriverManager中使用一个静态的线程安全的List常量,保存进一步封装的Driver对象。

package java.sql;public class DriverManager {// 线程安全的静态集合常量,存放Driverprivate final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();public static synchronized void registerDriver(java.sql.Driver driver)throws SQLException {registerDriver(driver, null);}public static synchronized void registerDriver(java.sql.Driver driver,DriverAction da)throws SQLException {// 将driver封装成DriverInfo,保存到registeredDrivers集合中if(driver != null) {registeredDrivers.addIfAbsent(new DriverInfo(driver, da));} else {// This is for compatibility with the original DriverManagerthrow new NullPointerException();}println("registerDriver: " + driver);}
}class DriverInfo {final Driver driver;DriverAction da;DriverInfo(Driver driver, DriverAction action) {this.driver = driver;da = action;}@Overridepublic boolean equals(Object other) {return (other instanceof DriverInfo)&& this.driver == ((DriverInfo) other).driver;}@Overridepublic int hashCode() {return driver.hashCode();}@Overridepublic String toString() {return ("driver[className="  + driver + "]");}DriverAction action() {return da;}
}

Driver中的主要方法:

1)boolean acceptsURL(String url):查询驱动程序是否认为它可以打开到给定url的连接;

Driver制定自己能够连接的url的协议,只有符合自己协议形式的url,返回true;反之,返回false。

2)Connection connect(String url, Properties info):试图创建一个到给定url的数据库连接;

2.4.2 创建Connection数据库连接

通过DriverManager的getConnection()方法,获取一个Connection对象。源码如下:

package java.sql;public class DriverManager {// Driver集合private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();@CallerSensitivepublic static Connection getConnection(String url,String user, String password) throws SQLException {java.util.Properties info = new java.util.Properties();if (user != null) {info.put("user", user);}if (password != null) {info.put("password", password);}return (getConnection(url, info, Reflection.getCallerClass()));}/*** 公共的获取Connection的方法*/private static Connection getConnection(String url, java.util.Properties info, Class<?> caller) throws SQLException {/** 当callerCl为null时,我们应该检查应用程序的(间接调用此类的)类加载器,* 以便可以从这里加载rt.jar之外的JDBC驱动程序类*/ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;synchronized(DriverManager.class) {// synchronize loading of the correct classloader.if (callerCL == null) {callerCL = Thread.currentThread().getContextClassLoader();}}if(url == null) {throw new SQLException("The url cannot be null", "08001");}println("DriverManager.getConnection(\"" + url + "\")");// 浏览已加载的Driver,尝试建立连接。记录引发的第一个异常SQLException reason = null;// 遍历Driverfor(DriverInfo aDriver : registeredDrivers) {// 如果权限不足,跳过if(isDriverAllowed(aDriver.driver, callerCL)) {try {// 建立连接println("    trying " + aDriver.driver.getClass().getName());Connection con = aDriver.driver.connect(url, info);// 连接成功,则返回if (con != null) {// Success!println("getConnection returning " + aDriver.driver.getClass().getName());return (con);}} catch (SQLException ex) {if (reason == null) {reason = ex;}}} else {println("    skipping: " + aDriver.getClass().getName());}}// 如果异常,则抛出if (reason != null)    {println("getConnection failed: " + reason);throw reason;}println("getConnection: no suitable driver found for "+ url);throw new SQLException("No suitable driver found for "+ url, "08001");}}

使用注册的Driver,以及传入的url、用户信息,尝试连接数据库,获取一个Connection对象。

2.5 JDBC小结

JDBC通过DriverManager管理Driver,并提供了Driver、Connection、Statement、PreparedStatement、ResultSet等API接口,不同的数据库提供商实现对应接口,实现对数据库的连接、SQL语句的执行等。

ShardingSphereDriver

SpringBoot集成Sharding-JDBC-5.3.0分库分表-CSDN博客

在这篇博文介绍了Sharding-JDBC-5.3.0分库分表的基本使用。示例的application.yml配置信息为:

server:port: 8080
spring:main:# 处理连接池冲突allow-bean-definition-overriding: truedatasource:driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriverurl: jdbc:shardingsphere:classpath:sharding.yml

即对应的Driver为ShardingSphereDriver,url指向shardingsphere的配置文件sharding.yml。

ShardingSphereDriver的源码如下:

package org.apache.shardingsphere.driver;public final class ShardingSphereDriver implements Driver {private static final int MAJOR_DRIVER_VERSION = 5;private static final int MINOR_DRIVER_VERSION = 1;// 数据库连接缓存private final DriverDataSourceCache dataSourceCache = new DriverDataSourceCache();static {try {// 注册到DriverManagerDriverManager.registerDriver(new ShardingSphereDriver());} catch (final SQLException ex) {throw new DriverRegisterException(ex);}}/*** 在hikari的DriverDataSource或其他连接池中,会通过DriverManager.getDriver(url)获得该ShardingSphereDriver,* 然后调用ShardingSphereDriver.connect()获得数据库连接*/@Overridepublic Connection connect(final String url, final Properties info) throws SQLException {return acceptsURL(url) ? dataSourceCache.get(url).getConnection() : null;}/*** ShardingSphereDriver的url中必须是以jdbc:shardingsphere:开头* @param url* @return*/@Overridepublic boolean acceptsURL(final String url) {return null != url && url.startsWith("jdbc:shardingsphere:");}@Overridepublic DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) {return new DriverPropertyInfo[0];}@Overridepublic int getMajorVersion() {return MAJOR_DRIVER_VERSION;}@Overridepublic int getMinorVersion() {return MINOR_DRIVER_VERSION;}/*** 不符合JDBC标准* @return*/@Overridepublic boolean jdbcCompliant() {return false;}@Overridepublic Logger getParentLogger() {return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);}
}

1)在static静态代码段中,new一个ShardingSphereDriver,注册到DriverManager中;

2)在acceptsURL(String url)方法中,判断url是否以jdbc:shardingshpere:开头;

3)在connect()方法中,从dataSourceCache中,根据url,获取一个Connection对象;

ShardingSphere中的JDBC

在ShardingSphere框架中,对于JDBC中提供的Driver、Connection、Statement等API接口进行了实现,实现类分别为:

1)Driver:ShardingSphereDriver

2)DataSource:ShardingSphereDataSource

3)Connection:ShardingSphereConnection

4)Statement:ShardingSphereStatement

5)PreparedStatement:ShardingSpherePreparedStatement

小结

限于篇幅,本篇先分享到这里。

由于ShardingSphere采用了原生JDBC的驱动,所以本篇重点讲解了JDBC及其原理。在此基础上,结合ShardingSphereDriver的源码,可以很清晰的对ShardingSphere的框架有一个整体的认识。

ShardingSphere框架就是通过实现JDBC中的接口,在调用真实数据库的Statement执行SQL之前,对SQL语句进行拦截解析,结合分库分表规则,执行对应真实数据库的SQL操作。

关于本篇内容你有什么自己的想法或独到见解,欢迎在评论区一起交流探讨下吧。

http://www.sczhlp.com/news/63873/

相关文章:

  • 免费的室内设计网站wordpress 登陆后返回
  • 做网站费是多少网站建设挣钱 知乎
  • 网站ui设计方案赣州信息港房产网
  • 网站搜索引擎优化方法广州小程序设计
  • 企业站seo外包昆山网站建设kshuituo
  • 怎样查网站的注册地点衡阳seo快速排名
  • 设计师网站家装影视后期制作培训班价格
  • 新莱芜客户端seo查询系统源码
  • 网站的站点地图设计国际军事最新头条新闻
  • 给公司做一个网站流程旅游英文网站 建设需求
  • 2025最新权威榜单!5款主流公众号编辑器深度测评
  • 网站建设一点通精准营销的好处
  • 2 试列出网站开发建设的步骤神秘网站
  • 荥阳网站优化公司wordpress改页脚
  • 万网建网站济南网站
  • 韩国美容网站模板微信怎么建小程序
  • 亚马逊网站风格装修培训班大约多少钱一个月
  • 什么网站可以快速做3d效果图哪些企业必须用网站
  • 微网站建设制作dedecms网站后台管理
  • 织梦技术个人网站模板下载个人博客网页完整代码
  • PowerShell载荷添加出口暴力破解技术
  • 语音代理减少不必要澄清问题的新方法
  • 最简单的一个网站开发米拓建设网站
  • 常用网站开发技术和工具wordpress execl
  • 深圳那家做网站好怎么样把第一页PPT设为模板相关信息圆柱钢模板优势是什么?企业网站建设模板和定制化有什么区别呢?
  • 如何在搜索中找到自己做的网站小蚁人网站建设
  • 企业公司网站模版如何申请自己的网站空间
  • 石家庄网站建设维护上海普陀网站建设
  • Python做网站难不难郑州seo优化外包
  • 做数据分析的网站外贸wordpress收款插件