Java DB loadBalance 设计

1 JDBC

简单介绍下JDBC的定义,如下(摘自百度百科):

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。1 平时我们在实际开发中一般都是直接使用连接池来做DB相关操作的,很少会直接使用JDBC进行编程。但是连接池底层连接DB的时候也是使用的JDBC,比如c3p0。2

下面通过代码介绍下通过JDBC操作DB的过程。如下所示:

//1. 注册DriverManager,DriverManager中的静态List registeredDrivers 保存了所有的Driver引用

Class.forName("com.mysql.jdbc.Driver");

//2.拼接连接信息,协议/子协议/数据源标识,连接信息
String url = "jdbc:mysql://localhost:3306/csc?user=root&password=xxxx"; //3. DriverManager 负责从注册的驱动中挑选合适的连接
Connection connection = DriverManager.getConnection(url); //4. 建立陈述式语句 (Statement,PrepareStatement(安全性[防止sql注入]和性能),CallableStatement(存储过程)) //4.1 Statement
Statement statement = connection.createStatement();
//execute query
ResultSet resultSet = statement.executeQuery("SELECT * FROM test ORDER by ID limit 10");
//4.2 PrepareStatement,在一个提交中设置了多个陈述式语句。
connection.setAutoCommit(false);
PreparedStatement preparedStatementInsert = connection.prepareStatement("INSERT into test(name,sex) VALUES (?,?)");
preparedStatementInsert.setString(, "csophys");
preparedStatementInsert.setInt(, );
preparedStatementInsert.execute();
Statement getLastIdStatement = connection.createStatement();
ResultSet set = getLastIdStatement.executeQuery("SELECT LAST_INSERT_ID()");
connection.commit(); //4.3 statement 的batch的功能以及CallableStatement平时用的不多 //5. 处理返回结果ResultSet
while (resultSet.next()) {
System.out.println(resultSet.getString());
System.out.println(resultSet.getString("id"));
}
while(set.next()){
System.out.println(set.getString());
System.out.println(set.getString("LAST_INSERT_ID()"));
}

通过上面的代码,比较清楚的能够看到通过JDBC进行DB操作的几个步骤。如下图所示:

其中 建立陈述式语句 Statement时可以有三类,,Statement,PrepareStatement,CallableStatement。CallableStatement一般用于存储过程, 而Statement和PrepareStatement一般用PrepareStatement比较多,PrepareStatement 可以预编译SQL预计,然后通过sql参数传递执行sql语句, 而Statement执行的时候是完整的执行一个sql,不会预编译,所以需要多次执行一个sql的时候。PrepareStatement比Statement的效果要好,而且PrepareStatement还可以预防SQL注入。3

2 DATASOURCE

Datasource 的功能和DriverManager 比较类似,都是向外输出Connection,只是DataSource一般不直接和DB交互,而是会从连接池中获取DB连接

不要混淆DataSource,DriverManager还有连接池的概念。我的理解是,DriverManager封装了各个DB厂商数据库驱动的差异,能直接和DB操作并且向
外提供数据库连接。而连接池保存了多个DB连接,减少新建DB连接所需要的时间开销。Datasource是更高层次的封装,向外提供Connection,底层一般会
使用连接池技术。

比如采用Spring和Mybatis进行集成开发的时候,会需要配置一个DataSource。一般从采用比较有名的c3p0等。如下:

<!--c3p0数据源-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/csc" />
<property name="user" value="root" />
<property name="password" value="xxxx" />
</bean>

为了强化记忆,我们可以自己来实现一个简单的DataSource,来给Mybatis使用。如下:

<!--MyDatasource-->
<bean id="myDataSource" class="base.jdbc.MyDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/csc" />
<property name="user" value="root" />
<property name="password" value="xxxx" />
</bean>

MyDataSource中来接收DB的连接信息,并且直接通过DriverManager来获取DB连接。MyDataSource只要集成javax.sql.DataSource,
并且实现里面的getConnection方法就可以了。如下所示:

public class MyDataSource implements DataSource {
private String driverClass;
private String jdbcUrl;
private String user;
private String password; public Connection getConnection() throws SQLException {
try {
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return DriverManager.getConnection(jdbcUrl+"?user="+user+"&password="+password);
}
....

然后用自己的DataSource替换c3p0后用单元测试可以正常工作。

3 读写分离及分库分表设计

首先读写分离肯定会有多个数据源,所以需要先获取到主从库的配置信息比如,w,r1,r2.w为主库,r1,r2为从库,并且建立了3个数据源wds,rds1,rds2。 为了方便DBA修改,主从库的配置信息可以配置在远程,然后程序动态获取。

接下来可以对于多个数据源做一个封装,根据SQL类型、事务是否自动提交来决定具体走哪一个数据源。封装的类图如下所示(取名参考大众点评的架构组件zebra):

GroupPrepareStatement执行的时候,会根据SQL的类型以及配置类型会选择GroupConnection中的Datasource引用,然后获取真实的connection后进行数据库操作。

然后分库分表设计的原理也和上面类似,只是主库一般会有多个,会根据某个维度进行水平切分。执行的时候需要根据sql中的维度的值来确定具体需要选择的DataSource。

Footnotes:

2

com.mchange.v2.c3p0.DriverManagerDataSource

    private synchronized Driver driver() throws SQLException
{
//System.err.println( "driver() <-- " + this );
if (driver == null)
driver = DriverManager.getDriver( jdbcUrl );
return driver;
}

Author: 陈胜 csophys

Created: 2017-01-15 Sun 21:45

Validate





















Java DB loadBalance 设计的更多相关文章

  1. Java SE 6 新特性: Java DB 和 JDBC 4.0

    http://www.ibm.com/developerworks/cn/java/j-lo-jse65/index.html 长久以来,由于大量(甚至几乎所有)的 Java 应用都依赖于数据库,如何 ...

  2. 解决NetBeans运行web项目时出现的“未能正确设置java DB”问题

    1.在NetBeans导航器中,点击"服务"选项卡: 2.展开"数据库"菜单: 3.在"Java DB"上右键 –> 选择" ...

  3. Java异常处理和设计【转】

    Java异常处理和设计 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常 ...

  4. Java语言课程设计——博客作业教学数据分析系统(201521123107 张翔)

    #Java语言课程设计--博客作业教学数据分析系统(个人博客) 1.团队课程设计博客链接 [博客作业教学数据分析系统(From:网络五条狗)](http://www.cnblogs.com/fanta ...

  5. 201521123118《java程序与设计》第4周作业总结

    1.本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点 1.2 使用常规方法总结其他上课内容. 为了不必要写重复的代码,可以运用继承,用关键字extends来定义一个类,被继承的类叫做父类,继 ...

  6. Java程序算法设计视频分享,需要的来

    每年都会有人说,IT行业饱和了,根本就找不到工作,其实,我想说的是,不是工作难找,而是你自己不够好! 前几天看到一CEO在微博上吐槽: 前几天招一算法工程师我们给了8万月薪*14+奖金,人家去阿里拿5 ...

  7. Java面向对象课程设计——购物车

    Java面向对象课程设计——购物车 小组成员:余景胜.刘格铭.陈国雄.达瓦次仁 一.前期调查 流程 客人(Buyer)先在商城(Mall)中浏览商品(Commidity),将浏览的商品加入购物车(Sh ...

  8. Java秒杀简单设计二:数据库表和Dao层设计

    Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表  https://www.cnblogs.com/taiguyiba/p/9791431.html ...

  9. 使用 Java DB (Derby) 数据库

    使用 Java DB (Derby) 数据库 https://netbeans.org/kb/docs/ide/java-db_zh_CN.html 本文档说明了如何在 NetBeans IDE 中设 ...

随机推荐

  1. ANDROID定义自己的观点——模仿瀑布布局(源代码)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 在自己定义view的时候,事实上非常easy,仅仅须要知道3步骤: 1.測量- ...

  2. UC编程:输入输出重定向(系统调用)

    在Unix下,系统重定向是使用dup和dup2函数完成的 在学习使用这两个函数之前,必须要搞懂一个概念就是文件描述符 摘自:<文件描述符和文件指针的区别> 文件描述符就是open文件时产生 ...

  3. POI操作Excel详细解释,HSSF和XSSF两种方式

    HSSF道路: package com.tools.poi.lesson1; import java.io.FileInputStream; import java.io.FileNotFoundEx ...

  4. [翻译]初识SQL Server 2005 Reporting Services Part 1

    原文:[翻译]初识SQL Server 2005 Reporting Services Part 1 构建和部署基本报表 如果曾经存在一项工作使得“真正的”开发者给他的上司泡蘑菇,那就是构建报表.毕竟 ...

  5. [转]【Android】9-patch图片以及例子说明

    1.何为9-patch? NinePatch图片以*.9.png结尾,和普通图片(png图片)的区别是四周多了一个边框(如下图所示): 采用NinePatch图片做背景,可使背景随着内容的拉伸(缩小) ...

  6. ASP.NET MVC应用程序使用axd格式文件

    ASP.NET MVC应用程序使用axd格式文件 axd格式文件,不管是在asp.net还是现在开发asp.net MVC应用程序,都是Insus.NET较喜欢使用的. 因为我们可以虚拟一个在应用程序 ...

  7. MINIGUI 编译 helloworld

    MiniGui 编译hello.c 文件成功!记载一下! MiniGui 版本v3.0 和 2 编译 差异 是极其的大!   源文件代码 :   #include <stdio.h>#in ...

  8. Linux 宿主机安装 MiniGUI

    去MiniGUI官方网站看的时候,很兴奋,安装竟然这么容易. 上帝总是在给你一个苹果之后,赏你一巴掌.我的确是高兴太早了. 首先看一下官网文档的说明步骤: (截取于官方文档) Installing r ...

  9. Coursera台大机器学习基础课程1

    Coursera台大机器学习基础课程学习笔记 -- 1 最近在跟台大的这个课程,觉得不错,想把学习笔记发出来跟大家分享下,有错误希望大家指正. 一 机器学习是什么? 感觉和 Tom M. Mitche ...

  10. SSL协议的握手过程

    SSL握手的目的 第一,客户端与服务器需要就一组用于保护数据的算法达成一致. 第二,它们需要确立一组由那些算法所使用的加密密钥. 第三,握手还可以选择对客户端进行认证. SSL 握手概述 SSL 握手 ...