sharding实现数据库的读写分离
为了减少同一时刻大量的并发读操作和较少的写操作,可以将数据库拆分成主库和从库,主库主要用来进行数据的写入删除操作,从库用来进行数据的读操作,通常是一主多从的配置
sharding提供一主多从的数据机制,写入和删除数据会自动映射到主数据库,读的查询操作自动映射到从数据库,但是不支持主从数据库的数据同步操作,数据的同步是mysql自动支持的
对于mysql的数据同步设置参见:
mySQL的主从数据库同步设置
数据表结构:
studnet1
student2
1.pom依赖
<!--web启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.47</version>
</dependency>
<!--mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.16</version>
</dependency>
<!--sharding启动器-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>annotationProcessor</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
2.application配置
server.port=8080
spring.application.name=sharding
mybatis.configuration.map-underscore-to-camel-case=true
# 配置多数据源
spring.shardingsphere.datasource.names=m1,s0
# 主数据源
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=12345
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/temporary?characterEncoding=utf-8&useSSL=false
# 从数据源
spring.shardingsphere.datasource.s0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.username=root
spring.shardingsphere.datasource.s0.password=12345
spring.shardingsphere.datasource.s0.url=jdbc:mysql://localhost:3307/temporary?characterEncoding=utf-8&useSSL=false
#指定表主键生成策略及唯一性,主要用来进行生成id
spring.shardingsphere.sharding.tables.student.key-generator.column=id
spring.shardingsphere.sharding.tables.student.key-generator.type=SNOWFLAKE
#设置主从配置,都映射到ds0的名称上
#声明主数据源的配置是m1
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=m1
#声明从数据源的配置时s0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=s0
# 指定数据最终映射到哪些表上
# 配置从数据库的数据节点,次节点表示包含主从数据源的数据节点映射,需要注释掉原来主数据源的节点配置
spring.shardingsphere.sharding.tables.student.actual-data-nodes=ds0.student$->{1..2}
# 指定数据映射到不同表上的策略规则
# 指定逻辑插入方式分片策略,根据id映射到student1或student2表上,属于水平分表
spring.shardingsphere.sharding.tables.student.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.student.table-strategy.inline.algorithm-expression=student$->{id % 2 +1}
#打开日志
spring.shardingsphere.props.sql.show=true
# 允许bean覆盖,防止bean和springboot注入冲突
spring.main.allow-bean-definition-overriding=true
# 日志级别设置
logging.level.root=info
logging.level.org.springframework.web=info
logging.level.com.example.sharding=debug
logging.level.druid.sql=debug
3.实体类&dao开发
Student
@Data
public class Student {
private Integer id;
private String name;
private String sSex;
}
StudentDao
@Mapper
@Component
public interface StudentDao {
@Insert(" insert into student(name,s_sex) values (#{name},#{sSex}) ")
int insertStudent(@Param("name") String name, @Param("sSex") String sSex);
@Select(" select * from student where id = #{id}")
Student selectById(@Param("id") Integer id);
}
4. 测试类
ShardingApplicationTests
@SpringBootTest
class ShardingApplicationTests {
@Autowired
StudentDao studentDao;
@Test
void contextLoads() {
studentDao.insertStudent("马武","男");
}
@Test
void testGetById() {
Student student = studentDao.selectById(8);
System.out.println(student.getSSex());
}
}
5.运行结果: