一、后台配置文件
# 連接地址 url: jdbc:mysql://127.0.0.1:8066/CHUNK?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true # 用戶名 username: root # 密碼 password: bluetooth@wy2019
8066:mycat默認端口
root:mycat配置文件設置、
password:mycat配置文件配置
二、mycat配置
2.1 schema.xml配置
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!-- <schema>:表示的是在mycat中的邏輯庫配置,邏輯庫名稱為:CHUNK --> <schema name="CHUNK" checkSQLschema="false" sqlMaxLimit="10000"> <!-- <table>:表示在mycat中的邏輯表配置,邏輯表名稱為:cn_chunk,映射到兩個數據庫節點dataNode中,設置幾個幾點代表要分片幾個庫,切分規則為:rule1(在rule.xml配置) --> <table name="cn_chunk" primaryKey="id" autoIncrement="true" dataNode="dn01,dn02,dn03" rule="rule1"> <childTable name="cn_chunk_lockset" primaryKey="id" joinKey="chunkId" parentKey="id" /></table> </schema> <!-- 設置dataNode 對應的數據庫,及 mycat 連接的地址dataHost --> <!-- <dataNode>:表示數據庫節點,這個節點不一定是單節點,可以配置成讀寫分離. --> <!-- <dataHost>:真實的數據庫的地址配置.在下面進行配置 --> <!-- <heartbeat>:用戶心跳檢測 --> <!-- <writeHost>:寫庫的配置 --> <dataNode name="dn01" dataHost="localhost" database="chunk001" /> <dataNode name="dn02" dataHost="localhost" database="chunk002" /> <dataNode name="dn03" dataHost="localhost" database="chunk003" /> <!-- mycat 邏輯主機dataHost對應的物理主機.其中也設置對應的mysql登陸信息 --> <dataHost name="localhost" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native"> <heartbeat>select user()</heartbeat> <!-- 連接到本地數據庫服務的配置 --> <writeHost host="server1" url="127.0.0.1:3306" user="root" password="root"/> </dataHost> </mycat:schema>
2.2 rule.xml配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:rule SYSTEM "rule.dtd"> <mycat:rule xmlns:mycat="http://io.mycat/"> <tableRule name="rule1"> <rule> <!-- 是按照id列進行切分,切分規則是采取取模的方式, --> <columns>id</columns> <algorithm>mod-long</algorithm> </rule> </tableRule> <function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <!-- <property name="count">2</property>:這里配置了我們有拆分了多個庫(表),需要和前面配置 <table name="user" primaryKey="id" dataNode="dn01,dn02,dn03" rule="rule1" /> 中的dataNode個數一致,否則會出錯. --> <property name="count">3</property> </function> </mycat:rule>
2.3 server.xml配置
<?xml version="1.0" encoding="UTF-8"?> <!-- - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. --> <!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://io.mycat/"> <system> <property name="useSqlStat">0</property> <!-- 1為開啟實時統計、0為關閉 --> <property name="useGlobleTableCheck">0</property> <!-- 1為開啟全加班一致性檢測、0為關閉 --> <property name="sequnceHandlerType">1</property> <!-- <property name="sequnceHandlerType">2</property>--> <!-- <property name="useCompression">1</property>--> <!--1為開啟mysql壓縮協議--> <!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--設置模擬的MySQL版本號--> <!-- <property name="processorBufferChunk">40960</property> --> <!-- <property name="processors">1</property> <property name="processorExecutor">32</property> --> <!--默認為type 0: DirectByteBufferPool | type 1 ByteBufferArena--> <property name="processorBufferPoolType">0</property> <!--默認是65535 64K 用於sql解析時最大文本長度 --> <!--<property name="maxStringLiteralLength">65535</property>--> <!--<property name="sequnceHandlerType">0</property>--> <!--<property name="backSocketNoDelay">1</property>--> <!--<property name="frontSocketNoDelay">1</property>--> <!--<property name="processorExecutor">16</property>--> <!-- <property name="serverPort">8066</property> <property name="managerPort">9066</property> <property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property> <property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> --> <!--分布式事務開關,0為不過濾分布式事務,1為過濾分布式事務(如果分布式事務內只涉及全局表,則不過濾),2為不過濾分布式事務,但是記錄分布式事務日志--> <property name="handleDistributedTransactions">0</property> <!-- off heap for merge/order/group/limit 1開啟 0關閉 --> <property name="useOffHeapForMerge">1</property> <!-- 單位為m --> <property name="memoryPageSize">1m</property> <!-- 單位為k --> <property name="spillsFileBufferSize">1k</property> <property name="useStreamOutput">0</property> <!-- 單位為m --> <property name="systemReserveMemorySize">384m</property> <!--是否采用zookeeper協調切換 --> <property name="useZKSwitch">true</property> </system> <!-- 全局SQL防火牆設置 --> <!-- <firewall> <whitehost> <host host="127.0.0.1" user="mycat"/> <host host="127.0.0.2" user="mycat"/> </whitehost> <blacklist check="false"> </blacklist> </firewall> --> <user name="root"> <!-- java項目配置文件連接的密碼 --> <property name="password">bluetooth@wy2019</property> <!-- schema.xml下的邏輯庫,要一致 --> <property name="schemas">CHUNK</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> <user name="user"> <property name="password">user</property> <!-- schema.xml下的邏輯庫,要一致 --> <property name="schemas">CHUNK</property> <property name="readOnly">true</property> </user> </mycat:server>
2.4 sequence_db_conf.properties配置
#sequence stored in datanode
GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1
#邏輯庫的分片函數在對應個庫下
CN_CHUNK=dn01
三、建表語句
#創建表語句區塊與子表區塊鎖
#添加表 區塊
DROP TABLE IF EXISTS `cn_chunk`;
CREATE TABLE `cn_chunk` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`createdAt` datetime DEFAULT NULL COMMENT '創建時間',
`modifiedAt` datetime DEFAULT NULL COMMENT '更新時間',
`createdBy` varchar(36) DEFAULT NULL COMMENT '創建人',
`modifiedBy` varchar(36) DEFAULT NULL COMMENT '更新人',
`version` int(11) DEFAULT NULL COMMENT '版本號',
`isDelete` int(11) DEFAULT NULL COMMENT '是否刪除',
`keyInfoId` varchar(36) DEFAULT NULL COMMENT '鑰匙id',
`chunkOne` int(11) DEFAULT NULL COMMENT '區塊1',
`chunkTwo` int(11) DEFAULT NULL COMMENT '區塊2',
`chunkThree` int(11) DEFAULT NULL COMMENT '區塊3',
`chunkFour` int(11) DEFAULT NULL COMMENT '區塊4',
`chunkFive` int(11) DEFAULT NULL COMMENT '區塊5',
`chunkSix` int(11) DEFAULT NULL COMMENT '區塊6',
`chunkSeven` int(11) DEFAULT NULL COMMENT '區塊7',
`chunkEight` int(11) DEFAULT NULL COMMENT '區塊8',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#添加表 區塊鎖
DROP TABLE IF EXISTS `cn_chunk_lockset`;
CREATE TABLE `cn_chunk_lockset` (
`id` varchar(36) NOT NULL,
`createdAt` datetime DEFAULT NULL COMMENT '創建時間',
`modifiedAt` datetime DEFAULT NULL COMMENT '更新時間',
`createdBy` varchar(36) DEFAULT NULL COMMENT '創建人',
`modifiedBy` varchar(36) DEFAULT NULL COMMENT '更新人',
`version` int(11) DEFAULT NULL COMMENT '版本號',
`isDelete` int(11) DEFAULT NULL COMMENT '是否刪除',
`taskId` varchar(36) DEFAULT NULL COMMENT '任務id',
`keyInfoId` varchar(36) DEFAULT NULL COMMENT '鑰匙id',
`startTime` datetime DEFAULT NULL COMMENT '起始時間',
`endTime` datetime DEFAULT NULL COMMENT '截止時間',
`chunkLocation` int(11) DEFAULT NULL COMMENT '對應區塊(1-8)',
`lockSetId` varchar(36) DEFAULT NULL COMMENT '鎖具信息id',
`lockId` varchar(50) DEFAULT NULL COMMENT '鎖具Id',
`lockSetName` varchar(50) DEFAULT NULL COMMENT '鎖具名稱',
`principalId` varchar(36) DEFAULT NULL COMMENT '執行人id',
`lockIdDecimal` int(11) DEFAULT NULL COMMENT '鎖具Id十進制',
`chunkId` bigint(20) DEFAULT NULL COMMENT '區塊id',
`thisUpdate` int(11) DEFAULT NULL COMMENT '本次更新(0:否,1:是)',
`sequence` int(11) DEFAULT NULL COMMENT '區塊鎖序列號',
PRIMARY KEY (`id`),
KEY `fk_cn_chunk_lockset_cn_chunk` (`chunkId`),
CONSTRAINT `cn_chunk_lockset_ibfk_1` FOREIGN KEY (`chunkId`) REFERENCES `cn_chunk` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
四、對應實體類
@Getter @Setter @Entity @Table(name = "cn_chunk") public class Chunk extends ChunkBaseEntity { /** 鑰匙id*/ @ApiModelProperty(value = "鑰匙id") private String keyInfoId; /** 區塊1*/ @ApiModelProperty(value = "區塊1") private Integer chunkOne = 0; /** 區塊2*/ @ApiModelProperty(value = "區塊2") private Integer chunkTwo = 0; /** 區塊3*/ @ApiModelProperty(value = "區塊3") private Integer chunkThree = 0; /** 區塊4*/ @ApiModelProperty(value = "區塊4") private Integer chunkFour = 0; /** 區塊5*/ @ApiModelProperty(value = "區塊5") private Integer chunkFive = 0; /** 區塊6*/ @ApiModelProperty(value = "區塊6") private Integer chunkSix = 0; /** 區塊7*/ @ApiModelProperty(value = "區塊7") private Integer chunkSeven = 0; /** 區塊8*/ @ApiModelProperty(value = "區塊8") private Integer chunkEight = 0; }
@Getter @Setter @Entity @Table(name = "cn_chunk_lockset") public class ChunkLockSet extends BaseEntity { /** 任務id*/ @ApiModelProperty(value = "任務id") @Column(length = 36) private String taskId; /** 鑰匙id*/ @ApiModelProperty(value = "鑰匙id") private String keyInfoId; /** 起始時間*/ @ApiModelProperty(value = "起始時間") private LocalDateTime startTime; /** 截止時間*/ @ApiModelProperty(value = "截止時間") private LocalDateTime endTime; /** 區塊*/ @ApiModelProperty(value = "區塊") @ManyToOne @JoinColumn(name = "chunkId", updatable = false, insertable = false) @JsonIgnore private Chunk chunk; /** 區塊id*/ @ApiModelProperty(value = "區塊id") @Column(name = "chunkId", updatable = false, length = 36) private Long chunkId; /** 對應區塊(1-8)*/ @ApiModelProperty(value = "對應區塊(1-8)") private Integer chunkLocation; /** 鎖具信息id*/ @ApiModelProperty(value = "鎖具信息id") @Column(name = "lockSetId", length = 36) private String lockSetId; /** 鎖具Id*/ @ApiModelProperty(value = "鎖具Id") @Column(length = 50) private String lockId; /** 鎖具Id十進制*/ @ApiModelProperty(value = "鎖具Id十進制") private Integer lockIdDecimal; /** 鎖具名稱*/ @ApiModelProperty(value = "鎖具名稱") @Column(length = 50) private String lockSetName; /** 執行人id*/ @ApiModelProperty(value = "執行人id") @Column(name = "principalId", length = 36) private String principalId; /** 是否已上傳(0:否,1:是)*/ @ApiModelProperty(value = "是否已上傳(0:否,1:是)") private Integer thisUpdate = BooleanEnum.FALSE.ordinal(); /** 區塊鎖序列號*/ @ApiModelProperty(value = "區塊鎖序列號") private Integer sequence; }
@Getter @Setter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) @Slf4j public abstract class ChunkBaseEntity implements Serializable { /** * 主鍵id * GenericGenerator 注解 strategy 參數設置參考如下 * @see org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory * 參考網站:https://blog.csdn.net/mafian/article/details/53968878 */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false) @ApiModelProperty(value = "主鍵id", position = 1) private Long id; /** 創建時間*/ @CreatedDate @ApiModelProperty(value = "創建時間", position = 2) @JsonFormat @DateTimeFormat private LocalDateTime createdAt; /** 更新時間*/ @LastModifiedDate @ApiModelProperty(value = "更新時間", position = 3) @JsonFormat @DateTimeFormat private LocalDateTime modifiedAt; /** 創建人*/ @Column(length = 36) @CreatedBy @ApiModelProperty(value = "創建人", position = 4) private String createdBy; /** 更新人*/ @Column(length = 36) @LastModifiedBy @ApiModelProperty(value = "更新人", position = 5) private String modifiedBy; /** 版本(樂觀鎖)*/ @Version @ApiModelProperty(value = "版本(樂觀鎖)", position = 6) private Integer version; /** 邏輯刪除*/ @ApiModelProperty(value = "邏輯刪除", position = 7) private Integer isDelete = BooleanEnum.FALSE.ordinal(); }
五、mycat分片函數
配置文件:sequence_db_conf.properties
設置節點:CN_CHUNK=dn01
該參數設置在哪個節點,則就在對應的數據庫內執行
#函數自增 實現新增數據自增長以1開始 #添加表 DROP TABLE IF EXISTS MYCAT_SEQUENCE; CREATE TABLE MYCAT_SEQUENCE ( NAME VARCHAR (50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 100, PRIMARY KEY (NAME) ) ENGINE = INNODB ; INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL', 10000000, 100); DROP FUNCTION IF EXISTS `mycat_seq_currval`; DELIMITER ;; CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8 DETERMINISTIC BEGIN DECLARE retval VARCHAR(64); SET retval="-999999999,null"; SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval FROM MYCAT_SEQUENCE WHERE name = seq_name; RETURN retval ; END ;; DELIMITER ; DROP FUNCTION IF EXISTS `mycat_seq_nextval`; DELIMITER ;; CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf8 DETERMINISTIC BEGIN UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment WHERE name = seq_name; RETURN mycat_seq_currval(seq_name); END ;; DELIMITER ; DROP FUNCTION IF EXISTS `mycat_seq_setval`; DELIMITER ;; CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), value INTEGER) RETURNS varchar(64) CHARSET utf8 DETERMINISTIC BEGIN UPDATE MYCAT_SEQUENCE SET current_value = value WHERE name = seq_name; RETURN mycat_seq_currval(seq_name); END ;; DELIMITER ; #插入一條數據,這條數據是我們這個表所需要的。 #必須是大寫的字符,不然就會報錯 #插入需要自增張的表的策略 #其中cn_chunk代表哪張表實現自增 insert into MYCAT_SEQUENCE (name,current_value,increment) values ('cn_chunk',0,1);
六、關閉默認事務
import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; /** * 關閉jpamor默認事務 * @author lixin.shao */ @EnableJpaRepositories(basePackages = "com.hs.lock.bluetooth.chunk", enableDefaultTransactions = false) @Configuration public class JpaTransactionConfig { }
