MyCat 是一个开源的,面向企业应用开发的大数据库集群,支持事务、ACID、可以替代 MySQL 的加强版数据库,一个新颖的数据库中间件产品。MyCat 天生是与 MySQL 完美结合,支持前端作为 MySQL 通用代理,后端 JDBC 方式支持 Oracle 等数据库。此处我们与 DM 数据库进行适配使用,利用 MyCat 对 DM 数据库进行分库分表。
开发环境搭建
软件
版本
DM 数据库
DM 8.0 及以上版本
Mycat 中间件
Mycat-server-1.6-release
MyCat 中间件下载 可从官网下载 Mycat 安装包。
DM 数据库连接 MyCat 配置 数据库端准备 由于适配 MyCat 分库分表功能,我们预先在数据库端准备好两个用户对应两个模式,分别在模式里创建同一张表,注意除模式不同,表结构须完全一致。
建用户 SQL 语句如下所示:
以 SYSDBA/SYSDBA 用户登录达梦数据库,创建用户 mydb1 mydb2,此时会自动生成用户名同名的模式。 create user "mydb1" identified by "a123456789" ;grant VTI to mydb1;create user "mydb2" identified by "a123456789" ;grant VTI to mydb2;分别在两个用户的模式下创建表 PRODUCT_CATEGORY 此表就是等会利用 MyCat 进行分库分表操作的表。 create table mydb1.PRODUCT_CATEGORY( ID INT PRIMARY KEY , NAME VARCHAR (50 ) NOT NULL ) ; create table mydb2.PRODUCT_CATEGORY( ID INT PRIMARY KEY , NAME VARCHAR (50 ) NOT NULL ) ;
创建完成后如下图所示:
MyCat 配置
将 DM 数据库的 JDBC 驱动包 复制到 MyCat 安装路径下 lib 文件夹内。
配置 conf/server.xml 和 conf/schema.xml 两个配置文件。
server.xml 配置 说明:
主要是配置 MyCat 服务启动后,对外提供数据库访问的用户信息,如下图所示:
<user name="root"><!--此处配置为连接 MyCat 的用户名密码--> <property name="password">123456</property> <property name="schemas">PRODUCTION</property> <!-- 表级 DML 权限设置 --> <!-- <privileges check="false"> <schema name="TESTDB" dml="0110" > <table name="tb01" dml="0000"></table> <table name="tb02" dml="1111"></table> </schema> </privileges> --> </user> <!-- 定于 MyCat 用户,只读:user/user --> <user name="user"> <property name="password">user</property> <property name="schemas">PRODUCTION</property> <property name="readOnly">true</property> </user>
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!-- 定义一个 MyCat 的模式,此处定义了一个逻辑数据库名称 PRODUCTION --> <!-- “checkSQLschema”:描述的是当前的连接是否需要检测数据库的模式 --> <!-- “sqlMaxLimit”:表示返回的最大的数据量的行数 --> <!-- “dataNode="dn1,dn2"”:该操作使用的数据节点是 dn1 的逻辑名称,这里 dn1 dn2 分别对应刚刚数据库里的两个模式 --> <!--rule="mod-long" 这里指的是数据库分库分表的柜子,可以在 rule.xml 文件里配置规则,此处 mod-long 指的是,交替插入 dn1 dn2 等各个节点--> <schema name="PRODUCTION" checkSQLschema="true" sqlMaxLimit="100" > <table name="PRODUCT_CATEGORY" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long"/> </schema> <!-- 定义个数据的操作节点,以后这个节点会进行一些库表分离使用 --> <!-- “dataHost="localhost1"”:定义数据节点的逻辑名称 --> <!-- “database="mydb1"”:定义数据节点要使用的数据库名称,针对达梦数据库来说,对应的是模式名。 --> <dataNode name="dn1" dataHost="localhost1" database="mydb1" /> <dataNode name="dn2" dataHost="localhost2" database="mydb2" /> <!-- 定义数据节点,包括各种逻辑项的配置 --> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="oracle" dbDriver="jdbc" switchType="1" slaveThreshold="100"> <!-- 配置真实数据库与 MyCat 的心跳 --> <heartbeat>select user()</heartbeat> <!-- 配置真实的 MySQL 的连接信息 这里由于我们借用 Oracle 连接通道,通过达梦配置对 Oracle 数据库的兼容参数--> <writeHost host="hostM1" url="jdbc:dm://localhost:5236?comOra=true" user="MYDB1" password="a123456789"></writeHost> </dataHost> <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="oracle" dbDriver="jdbc" switchType="1" slaveThreshold="100"> <!-- 配置真实 MySQL 与 MyCat 的心跳 --> <heartbeat>select user()</heartbeat> <!-- 配置真实的 MySQL 的连接信息 --> <writeHost host="hostM1" url="jdbc:dm://localhost:5236?comOra=true" user="MYDB2" password="a123456789"></writeHost> </dataHost> </mycat:schema>
配置完成后,双击 bin/startup_nowrap.bat 即可启动 MyCat 中间件服务。
使用 JDBC 连接 MyCat 中间件服务操作数据库 导入所需 jar 包 由于 MyCat 完全适配 MySQL,所以无论是什么数据库,都要使用 mysql-connect-java 的 JDBC 驱动包,可从mysql-connector-java包下载 指定 jar 包。
新建项目 JAVA_Mycat,并导入项目所需 jar 包,如下图所示:
注意 复制 jar 包到 lib 文件夹后,要选择所有 jar 包,鼠标右键,Build path–>Add to Build path。
基础操作示例 编写 TetsDemo.java 文件。
package com.mycat; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TestDemo { // 定义 DM JDBC 驱动串 static String jdbcString = "com.mysql.jdbc.Driver"; // 定义 DM URL 连接串 static String urlString = "jdbc:mysql://localhost:8066/PRODUCTION"; // 定义连接用户名 static String userName = "root"; // 定义连接用户口令 static String password = "123456"; // 定义连接对象 static Connection conn = null; // 定义 SQL 语句执行对象 static Statement state = null; // 定义结果集对象 static ResultSet rs = null; public static void main(String[] args) { try { //1.加载 JDBC 驱动程序 System.out.println("Loading JDBC Driver..."); Class.forName(jdbcString); //2.连接 DM 数据库 System.out.println("Connecting to DM Server..."); conn = DriverManager.getConnection(urlString, userName, password); //3.通过连接对象创建 java.sql.Statement 对象 state = conn.createStatement(); //-------------------------------------------------------------------------------------------------- //基础操作:此处操作对应的数据库,为示例库中的 PRODUCTION 模式中的 PRODUCT_CATEGORY 表 //增加 //定义增加的 SQL--这里由于此表中的结构为主键,自增,只需插入 name 列的值 String sql_insert = "insert into PRODUCTION.PRODUCT_CATEGORY (id,name)values(1,'小说'),"+ "(2,'文学'),(3,'计算机'),(4,'英语'),(5,'管理'),(6,'少儿'),(7,'金融')"; //执行添加的 SQL 语句 state.executeUpdate(sql_insert); //删除 //定义删除的 SQL 语句 String sql_delete = "delete from PRODUCTION.PRODUCT_CATEGORY where name = '厨艺'"; //执行删除的 SQL 语句 state.execute(sql_delete); //修改 String sql_update = "update PRODUCTION.PRODUCT_CATEGORY set name = '国学' where name = '文学'"; state.executeUpdate(sql_update); //查询表中数据 //定义查询 SQL String sql_selectAll = "select * from PRODUCTION.PRODUCT_CATEGORY"; //执行查询的 SQL 语句 rs = state.executeQuery(sql_selectAll); displayResultSet(rs); //--------------------------------------------------------------------------------------------------- } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { //关闭资源 rs.close(); state.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } //显示结果集 public static void displayResultSet(ResultSet rs) throws SQLException{ while (rs.next()) { int i=1; Object id = rs.getObject(i++); Object name = rs.getObject(i++); System.out.println(id+" "+name); } } }
运行前数据库截图如下所示:
运行后控制台截图如下所示:
运行后数据库表截图,可以看到数据分别插入两张表中,如下图所示:
绑定变量示例 绑定参数示例代码 package java_jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;public class jdbc_prepareStatement { static String jdbcString = "com.mysql.jdbc.Driver" ; static String urlString = "jdbc:mysql://localhost:8066/PRODUCTION" ; static String userName = "root" ; static String password = "123456" ; static Connection conn = null ; static PreparedStatement pstate = null ; public static void main (String[] args) { try { System.out.println("Loading JDBC Driver..." ); Class.forName(jdbcString); System.out.println("Connecting to DM Server..." ); conn = DriverManager.getConnection(urlString, userName, password); String sql_updateNameById = "update PRODUCTION.PRODUCT_CATEGORY " + "set name = ? where ID = ? " ; pstate = conn.prepareStatement(sql_updateNameById); pstate.setString(1 , "魔幻" ); pstate.setInt(2 , 3 ); pstate.executeUpdate(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { try { pstate.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
运行示例截图 运行后数据库截图如下图所示: