介绍:
从库可以有多个,主库进行增删改,从库进行查。
准备工作:两台Linux虚拟机 安装了MySQL并启动服务(可以参考的之前的博客,有详细教程!!!)
主库:192.168.58.100
从库:192.168.58.101
配置主库:
第一步:修改MySQL数据库的配置文件/etc/my.cnf
[root@192 /]# vim /etc/my.cnf 在 [mysqld] 下加入: log-bin=mysql-bin #启动二进制日志 server-id=100 #服务器唯一ID
第二步:重启服务
systemctl restart mysqld
第三步:登录MySQL,执行下面sql
GRANT REPLICATION SLAVE ON *.* to 'xiaoming'@'%' identified by 'Root@123456';
第四步:登录MySQL数据库([root@192 etc]# mysql -uroot -proot
),执行下面sql,记录结果中File和position的值mysql> show master status;
注意:此时不要再执行任何sql,否则position的值会改变!!!
配置从库:
第一步:修改MySQL数据库的配置文件/etc/my.cnf
[root@192 /]# vim /etc/my.cnf 在 [mysqld] 下加入: server-id=101 #服务器唯一ID
第二步:重启服务
systemctl restart mysqld
第三步:登录到Mysql,执行以下sql(修改file和pos的值)
启动slave
mysql> start slave;
第四步:查看状态
mysql> show slave status;
复制结果到notepad++中打开
测试:
在Navicat中分别对主从数据库建立连接
在主数据库中创建一个数据库abc,刷新从数据库,也会出现一个abc的数据库
创建表跟添加数据类似。
案例实现:
如何做到主库进行增删改,从库进行查呢?
这里要用到一个java轻量级框架——Sharding-JDBC
(ORM框架:对象关系映射Object-Relational-Mapping)
准备:在主库中创建一个vm数据库,并创建一个user表
一个很基础的springboot项目
导入坐标:
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
在配置文件中配置读写分离规则,以下是整个application.yml
server:
port: 8080
mybatis-plus:
configuration:
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: ASSIGN_ID
spring:
shardingsphere:
datasource:
names:
master,slave
# 主数据源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.58.100:3306/rw?characterEncoding=utf-8
username: root
password: root
# 从数据源
slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.58.101:3306/rw?characterEncoding=utf-8
username: root
password: root
masterslave:
# 读写分离配置
load-balance-algorithm-type: round_robin #轮循(负载均衡)
# 最终的数据源名称
name: dataSource
# 主库数据源名称
master-data-source-name: master
# 从库数据源名称列表,多个逗号分隔
slave-data-source-names: slave
props:
sql:
show: true #开启SQL显示(控制台),默认false
此时如果启动项目,会报错
The bean 'dataSource', defined in class path resource [org/apache/shardingsphere/shardingjdbc/spring/boot/SpringBootConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/alibaba/druid/spring/boot/autoconfigure/DruidDataSourceAutoConfigure.class] and overriding is disabled.
两个地方都想创建数据源对象!!!
解决:
允许bean定义覆盖
再次启动项目。
(如果报错:com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
解决:
修改
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
并将驱动类中的cj去掉)
启动成功!
此时创建了两个数据源对象:
从结果可以看到增和查是操作不同的数据库
我的controller:
package com.itheima.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.entity.User;
import com.itheima.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.sql.DataSource;
import java.util.List;
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Autowired
private DataSource dataSource;
@Autowired
private UserService userService;
@PostMapping
public User save(User user){
userService.save(user);
return user;
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id){
userService.removeById(id);
}
@PutMapping
public User update(User user){
userService.updateById(user);
return user;
}
@GetMapping("/{id}")
public User getById(@PathVariable Long id){
User user = userService.getById(id);
return user;
}
@GetMapping("/list")
public List<User> list(User user){
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(user.getId() != null,User::getId,user.getId());
queryWrapper.eq(user.getName() != null,User::getName,user.getName());
List<User> list = userService.list(queryWrapper);
return list;
}
}
跟着黑马学技术!!!yyds