<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # Sharding-JDBC 讀寫分離 >>**導航** [TOC] ## 本節代碼地址 GitHub:[https://github.com/xuyisu/fw-shardingsphere-learning/tree/master/shardingsphere-learning-read-write](https://github.com/xuyisu/fw-shardingsphere-learning/tree/master/shardingsphere-learning-read-write) ***** 本節主要介紹Sharding-JDBC讀寫分離,并提供代碼樣例,在分布式項目架構中,讀寫分離也是常用的一種方案。 ## 項目技術棧 | 技術棧 | 版本 | | --- | --- | | jdk | 1.8.0_161 | | SpringBoot | 2.2.2.RELEASE | | Shardingsphere | 4.0.1 | | Mybatis-plus | 3.3.0 | | Hutool | 5.0.6 | | HikariCP | 2.7.9 | * SpringBoot 基于SpringBoot 2.2.2.RELEASE 構建我們的應用 * Shardingsphere 使用最新版的4.0.1來支撐讀寫分離 * Mybatis-plus來作為我們的持久層框架,介紹代碼的開發量 * Hutool作為java工具包 * HikariCP 項目中的連接池,性能要比Druid要高,目前SpringBoot 默認支持的數據連接池。 * lombok 使代碼簡介,介紹getter\setter\構造器的創建,需要在idea中安裝lombok插件 ## 1. 新建模塊shardingsphere-learning-common 為了減少代碼開發量,筆者統一封裝了一個`shardingsphere-learning-common`,用于將用戶表(分庫分表的功能全基于這張表演示)的增刪改查功能封裝。 ![](https://img.kancloud.cn/4a/3b/4a3b894920fd45d3d09999615816f985_455x248.png) ### 1.1 maven 配置 這里我們將需要的連接池、Mybatis-plus、Shardingsphere 等依賴包添加進來作為公共依賴。后面的模塊只需要依賴`shardingsphere-learning-common`包 ~~~ <dependencies> <!-- 數據連接池--> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <!-- mysql驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- for spring boot --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>${sharding-sphere.version}</version> </dependency> <!-- for spring namespace --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-namespace</artifactId> <version>${sharding-sphere.version}</version> </dependency> </dependencies> ~~~ ### 1.2 MybatisPlusConfig 配置 配置MybatisPlus,將mapper包的路徑用`@MapperScan`配置起來,如果需要分頁查詢的動作,可以配置MybatisPlus自帶的分頁插件。 ~~~ /** * @description MybatisPlusConfig * @author xuyisu * @date '2020-03-22' */ @Configuration @MapperScan(value = "com.yisu.shardingsphere.common.mapper") public class MybatisPlusConfig { /** * 分頁插件 * * @return PaginationInterceptor */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } } ~~~ ### 1.3 新建系統用戶表-實體SysUser ~~~ /** * @description 系統用戶表-實體 * @author xuyisu * @date '2020-03-22 10:04:27'. */ @Data @TableName("sys_user") @EqualsAndHashCode(callSuper=false) public class SysUser extends Model<SysUser> { /** * 主鍵 */ @TableId(value = "id", type = IdType.ID_WORKER) private Long id; /** * 創建時間 */ private Date createTime; /** * 更新時間 */ private Date updateTime; /** * 創建人編碼 */ private String createUser; /** * 修改人編碼 */ private String updateUser; /** * 刪除標記(1 刪除 0未刪除) */ @TableLogic private Integer deleteFlag; /** * 啟用標記(1 禁用 0啟用) */ private Integer disableFlag; /** * 職位編碼 */ private String posCode; /** * 頭像地址 */ private String avatar; /** * 郵箱 */ private String email; /** * 密碼 */ private String password; /** * 用戶名 */ private String userName; /** * 真實姓名 */ private String realName; /** * 部門編碼 */ private String deptCode; /** * 手機號 */ private String userPhone; } ~~~ ### 1.4 新建SysUserMapper 接口 并繼承BaseMapper接口,BaseMapper是MybatisPlus 提供的默認Mapper實現 ~~~ /** * @description 系統用戶表-Mapper * @author xuyisu * @date '2020-03-12' */ public interface SysUserMapper extends BaseMapper<SysUser> { } ~~~ 實現BaseMapper的好處就是基本的增刪改查不用自己寫了 ![](https://img.kancloud.cn/bc/f6/bcf69bcaf3b1aa6790c24d9616526112_457x375.png) ### 1.5 新建系統用戶表-業務接口 接口需要繼承IService,IService是MybatisPlus 針對service接口層的封裝 ~~~ /** * @description 系統用戶表-業務接口 * @author xuyisu * @date '2020-03-22' */ public interface SysUserService extends IService<SysUser> { } ~~~ 可以看到IService里包含了很多的默認接口 ![](https://img.kancloud.cn/c1/98/c198e326609022e2b69d3e4a2597b696_446x520.png) ### 1.6 新建系統用戶表-業務實現 并繼承`ServiceImpl<SysUserMapper, SysUser> `,ServiceImpl是MybatisPlus 提供的基本實現 ~~~ /** * @description 系統用戶表-業務實現 * @author xuyisu * @date '2020-03-22' */ @Service public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService { } ~~~ ServiceImpl提了上面IService的節本實現,這樣針對單表的增、刪、改、查、分頁查詢、批量操作等 ![](https://img.kancloud.cn/6c/f6/6cf6d76d29c276fc6363481ee4acd310_463x524.png) ## 2. 數據庫創建 ### 2.1 新建數據庫 mysql 數據庫的搭建可以**參考容器化章節**(docker run 一個) ### 2.2 執行腳本 執行以下腳本將創建數據庫ds_master和ds_slave,并分別在兩個庫里面創建`sys_user`表 ~~~ CREATE DATABASE ds_master; USE ds_master; DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '創建時間', `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新時間', `create_user` varchar(100) NOT NULL COMMENT '創建人編碼', `update_user` varchar(100) NOT NULL COMMENT '修改人編碼', `delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '刪除標記(1 刪除 0未刪除)', `pos_code` varchar(50) DEFAULT NULL COMMENT '職位編碼', `disable_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '啟用標記(1 禁用 0啟用)', `avatar` varchar(100) DEFAULT NULL COMMENT '頭像地址', `email` varchar(50) DEFAULT NULL COMMENT '郵箱', `password` varchar(100) DEFAULT NULL COMMENT '密碼', `user_name` varchar(50) DEFAULT NULL COMMENT '用戶名', `real_name` varchar(50) DEFAULT NULL COMMENT '真實姓名', `dept_code` varchar(50) DEFAULT NULL COMMENT '部門編碼', `user_phone` varchar(15) DEFAULT NULL COMMENT '手機號', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `idx_email` (`email`) USING BTREE COMMENT '郵箱索引', UNIQUE KEY `idx_user_name` (`user_name`) USING BTREE COMMENT '用戶名索引', KEY `idx_dept_code` (`dept_code`) USING BTREE COMMENT '部門編碼索引', KEY `idx_position_code` (`pos_code`) USING BTREE COMMENT '職位編碼索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系統用戶表'; CREATE DATABASE ds_slave; USE ds_slave; DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵', `create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '創建時間', `update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新時間', `create_user` varchar(100) NOT NULL COMMENT '創建人編碼', `update_user` varchar(100) NOT NULL COMMENT '修改人編碼', `delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '刪除標記(1 刪除 0未刪除)', `pos_code` varchar(50) DEFAULT NULL COMMENT '職位編碼', `disable_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '啟用標記(1 禁用 0啟用)', `avatar` varchar(100) DEFAULT NULL COMMENT '頭像地址', `email` varchar(50) DEFAULT NULL COMMENT '郵箱', `password` varchar(100) DEFAULT NULL COMMENT '密碼', `user_name` varchar(50) DEFAULT NULL COMMENT '用戶名', `real_name` varchar(50) DEFAULT NULL COMMENT '真實姓名', `dept_code` varchar(50) DEFAULT NULL COMMENT '部門編碼', `user_phone` varchar(15) DEFAULT NULL COMMENT '手機號', PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `idx_email` (`email`) USING BTREE COMMENT '郵箱索引', UNIQUE KEY `idx_user_name` (`user_name`) USING BTREE COMMENT '用戶名索引', KEY `idx_dept_code` (`dept_code`) USING BTREE COMMENT '部門編碼索引', KEY `idx_position_code` (`pos_code`) USING BTREE COMMENT '職位編碼索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系統用戶表'; ~~~ ## 3. 新建讀寫分離模塊shardingsphere-learning-read-write 上面我們已經配置了公共的針對用戶表的基本操作,這些暫時已經夠我們演示用了,如果不夠,可以自定義自己的實現 ### 3.1 添加依賴 這里我們將`shardingsphere-learning-common`的包依賴進來,方便我們操作用戶表的增刪改查 ~~~ <dependencies> <dependency> <groupId>com.yisu.fwcloud</groupId> <artifactId>shardingsphere-learning-common</artifactId> <version>${version}</version> </dependency> </dependencies> ~~~ ### 3.2 應用配置 >這里筆者將默認的端口修改為了8900,然后就是配置Sharding-JDBC的數據源,我們本節演示的Sharding-JDBC讀寫分離需要兩個庫(真實項目中需要兩個數據庫實例)。 1. 筆者在配置中先設置數據源的名稱 2. 分別配置主備數據庫連接信息,如`spring.shardingsphere.datasource.{數據源名稱}.type` 3. 對讀寫規則進行配置,查詢時的負載均衡算法(load-balance-algorithm-type)默認是輪詢、還可以選擇隨機,當然也可以實現MasterSlaveLoadBalanceAlgorithm接口自定義 4. 配置讀寫分離實例的名稱,并分別設置主從的實例名稱(別分對應1中設置的哪個名稱) 5. 將sql日志信息打印出來 ~~~ server.port=8900 #數據源定義 spring.shardingsphere.datasource.names=master,slave # 數據源 主庫 spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://${dbIp}:3306/ds_master?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false spring.shardingsphere.datasource.master.username=root spring.shardingsphere.datasource.master.password=123456 # 數據源 從庫 spring.shardingsphere.datasource.slave.type=com.zaxxer.hikari.HikariDataSource spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.slave.jdbc-url=jdbc:mysql://${dbIp}:3306/ds_slave?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=false spring.shardingsphere.datasource.slave.username=root spring.shardingsphere.datasource.slave.password=123456 # 讀寫分離 spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin spring.shardingsphere.masterslave.name=ms spring.shardingsphere.masterslave.master-data-source-name=master spring.shardingsphere.masterslave.slave-data-source-names=slave #打印sql spring.shardingsphere.props.sql.show=true spring.main.allow-bean-definition-overriding=true logging.level.com.yisu= debug ~~~ ### 3.3 新建啟動類 ~~~ /** * @description 啟動類 * @author xuyisu * @date '2020-03-22' */ @SpringBootApplication public class FwShardingsphereReadWrite { public static void main(String[] args) { SpringApplication.run(FwShardingsphereReadWrite.class, args); } } ~~~ ### 3.4 新建單元測試 新建單元測試,用于測試讀寫分離的功能 ~~~ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class UserinfoServiceImplReadWriteTest { @Autowired private SysUserService sysUserService; /** * 測試數量 */ @Test public void testSelect(){ int count = sysUserService.count(); System.out.println(count); } /** * 測試單個新增 */ @Test public void testInsert(){ SysUser sysUser=new SysUser(); sysUser.setAvatar("/home/avatar"); sysUser.setCreateTime(DateUtil.date()); sysUser.setCreateUser("sys"); sysUser.setDeleteFlag(0); sysUser.setDeptCode("depe"); sysUser.setDisableFlag(0); sysUser.setEmail("***@123.com"); sysUser.setPassword("123456"); sysUser.setPosCode("pos"); sysUser.setRealName("realname"); sysUser.setUpdateTime(DateUtil.date()); sysUser.setUserName("fwcloud"); sysUser.setUpdateUser("sys"); sysUser.setUserPhone("12345678912"); sysUserService.save(sysUser); } /** * 測試批量新增 */ @Test public void testBatch(){ List<SysUser> list=new ArrayList<>(); for (int i = 0; i <100 ; i++) { SysUser sysUser=new SysUser(); sysUser.setAvatar("/home/avatar"); sysUser.setCreateTime(DateUtil.date()); sysUser.setCreateUser("sys"+i); sysUser.setDeleteFlag(0); sysUser.setDeptCode("depe"+i); sysUser.setDisableFlag(0); sysUser.setEmail("***@123.com"+i); sysUser.setPassword("123456"); sysUser.setPosCode("pos"); sysUser.setRealName("realname"+i); sysUser.setUpdateTime(DateUtil.date()); sysUser.setUserName("fwcloud"+i); sysUser.setUpdateUser("sys"+i); sysUser.setUserPhone("12345678912"+i); list.add(sysUser); } boolean saveBatch = sysUserService.saveBatch(list); Assert.assertEquals(true,saveBatch); } } ~~~ #### 3.4.1 測試新增 先配置數據庫的ip地址,變量是dbIp,值是ip地址,也可以不用變量直接用真實的ip地址 ![](https://img.kancloud.cn/0a/bf/0abf49f0daa8acbf3a08cc4d5cc4387b_1049x620.png) 運行testInsert方法,可以看到控制臺的日志如下,可以看到走的實例是master ~~~ 2020-03-22 16:45:50 DEBUG main com.yisu.shardingsphere.common.mapper.SysUserMapper.insert ==> Preparing: INSERT INTO sys_user ( id, user_phone, update_user, update_time, avatar, user_name, delete_flag, real_name, password, create_time, disable_flag, pos_code, create_user, dept_code, email ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) 2020-03-22 16:45:50 INFO main ShardingSphere-SQL Rule Type: master-slave 2020-03-22 16:45:50 INFO main ShardingSphere-SQL SQL: INSERT INTO sys_user ( id, user_phone, update_user, update_time, avatar, user_name, delete_flag, real_name, password, create_time, disable_flag, pos_code, create_user, dept_code, email ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) ::: DataSources: master 2020-03-22 16:45:50 DEBUG main com.yisu.shardingsphere.common.mapper.SysUserMapper.insert ==> Parameters: 1241647261536813058(Long), 12345678912(String), sys(String), 2020-03-22 16:45:50.467(Timestamp), /home/avatar(String), fwcloud(String), 0(Integer), realname(String), 123456(String), 2020-03-22 16:45:50.467(Timestamp), 0(Integer), pos(String), sys(String), depe(String), ***@123.com(String) 2020-03-22 16:45:50 DEBUG main com.yisu.shardingsphere.common.mapper.SysUserMapper.insert <== Updates: 1 ~~~ #### 3.4.2 測試查詢 運行testSelect方法,可以看到控制臺的日志如下,可以看到走的實例是slave,查詢結果為0是因為讀庫沒有數據 ~~~ 2020-03-22 16:49:42 DEBUG main com.yisu.shardingsphere.common.mapper.SysUserMapper.selectCount ==> Preparing: SELECT COUNT( 1 ) FROM sys_user WHERE delete_flag=0 2020-03-22 16:49:43 INFO main ShardingSphere-SQL Rule Type: master-slave 2020-03-22 16:49:43 INFO main ShardingSphere-SQL SQL: SELECT COUNT( 1 ) FROM sys_user WHERE delete_flag=0 ::: DataSources: slave 2020-03-22 16:49:43 DEBUG main com.yisu.shardingsphere.common.mapper.SysUserMapper.selectCount ==> Parameters: 2020-03-22 16:49:43 DEBUG main com.yisu.shardingsphere.common.mapper.SysUserMapper.selectCount <== Total: 1 0 ~~~ 至此,讀寫分離已完成
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看