最近在学习数据库,做了一个数据源Druid,读写分离中间节ShardingJdbc对MySql读写分离的demo。
一、数据库
#主数据库:写入数据
Master_Host=192.168.10.197
Master_DB=qw_test
Master_user=root
Master_password=root
#从数据库:读取数据
Slave_Host=192.168.199.149
Slave_DB=qw_test
Slave_user=root
Slave_password=root
二、依赖包
<!-- MySql数据库驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<!-- Sharding-jdbc核心模块 -->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>1.4.2</version>
</dependency>
<!-- Druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.29</version>
</dependency>
三、源码
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.MasterSlaveDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.jdbc.ShardingDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 数据库读写分离简单demo
*/
public class ShardingJdbc {
/**
* 测试代码
* 测试代码中读和写如果在一次连接中执行的话,都操作的是主数据库的数据。如果分开不同连接执行的话,读会读取从数据库的数据
* 这是因为ShardingJdbc为了防止主从数据库同步延时导致的数据不一致。
*/
public static void main(String[] args) throws Exception {
testWrite();//测试写入
testRead();//测试读取
}
/**
* 具体的测试写代码
* 这里使用的JDBC原生的实现方式
*/
private static void testWrite() throws Exception {
String sql = "insert into param_area_tb (id, AreaName, ZipCode) values (90202, '11', '111')";
Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql);
int i = pstmt.executeUpdate();
System.out.println(i);
}
/**
* 具体的测试读代码
* 这里使用的JDBC原生的实现方式
*/
private static void testRead() throws Exception {
String sql = "SELECT * FROM param_code_tb";
Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet resultSet = pstmt.executeQuery();
while (resultSet.next()) {
System.out.print(resultSet.getInt(1));
System.out.print(resultSet.getString(2));
System.out.print(resultSet.getString(3));
System.out.println();
}
}
/**
* @title 获取数据库连接Connention
* @desc 通过Duird获取的数据连接源,通过ShardingJDBC,生成针对业务层的 Connention
* 此处的DataSource既可以使用Druid,也可以使用C3P0等ShardingJDBC支持的任何形式的数据源。
* 官方的Demo使用的是commons-dbcp
*/
private static Connection getConn() throws Exception {
DataSource masterSlaveDs0 = MasterSlaveDataSourceFactory
.createDataSource("ms_0", createDataSource("qw_test", "192.168.10.197"), createDataSource("qw_test", "192.168.199.149"));
Map<String, DataSource> dataSourceMap = new HashMap<>(2);
dataSourceMap.put("sharding_0", masterSlaveDs0);
DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap);
ShardingRule shardingRule = ShardingRule.builder()
.dataSourceRule(dataSourceRule)
.build();
DataSource dataSource = new ShardingDataSource(shardingRule);
return dataSource.getConnection();
}
/**
* @title 生成数据库连接源DataSource
* @desc 根据数据库url,用户名、密码,使用Druid获取数据库连洁源
*/
private static DataSource createDataSource(String dataSourceName, String url) throws Exception {
Properties props = new Properties();
props.put("driverClassName", com.mysql.jdbc.Driver.class.getName());
props.put("url", String.format("jdbc:mysql://%s:3306/%s", url, dataSourceName));
props.put("username", "root");
props.put("password", "root");
return DruidDataSourceFactory.createDataSource(props);
}
}
测试后显示正常。如果有时间,再单独写一个实现数据库分库分表的简单demo
四、传送门
ShardingJDBC官网http://shardingjdbc.io