SpringBoot集成uid-generator

uid-generator

uid-generator是百度开源的,基于雪花算法的一款唯一主键生成器(数据库表的主键要求全局唯一是相当重要的)。要求java8及以上版本。

官方介绍传送门:https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md

引入uid-generator

方式一:下载源码,本地引入

下载链接:https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md

下载后用maven导入,作为本地子项目引入主项目。

a、导入下载的项目

20200706215029264.png

b、引入

<dependency>
    <groupId>com.baidu.fsg</groupId>
	<artifactId>uid-generator</artifactId>
	<version>1.0.0-SNAPSHOT</version>
</dependency>

方式二:互联网jar包引入(本文用的是此方式)

在maven仓库只找到了一个jar包。

<dependency>
    <groupId>com.xfvape.uid</groupId>
    <artifactId>uid-generator</artifactId>
    <version>0.0.4-RELEASE</version>
</dependency>

配置

1、排除冲突的依赖

uid-generator中依赖了logback和mybatis。一般在项目搭建过程中,springboot中已经有了logback依赖,mybatis会作为单独的依赖引入。如果版本和uid-generator中的依赖不一致的话,就会导致冲突。为了防止出现这些问题,直接排除一劳永逸。(我这里用的是mybatis-plus,mybatis-plus官方要求的是,如果要使用mybatis-plus,就不能再单独引入mybatis了,所以我这里也是必须排除mybatis的)。排除jar包冲突问题参考另外一篇博文:https://blog.csdn.net/weixin_41381863/article/details/90042220

mybatis-plus和mybatis冲突的两个常见错误:

a、java.lang.NoClassDefFoundError: org/mybatis/logging/LoggerFactory

b、如下图

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTM4MTg2Mw==,size_16,color_FFFFFF,t_70

排除冲突的依赖如下:(使用本地项目引入的方式也需要排除以下依赖)

<dependency>
    <groupId>com.xfvape.uid</groupId>
    <artifactId>uid-generator</artifactId>
    <version>0.0.4-RELEASE</version>
    <exclusions>
		    	<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>log4j-over-slf4j</artifactId>
				</exclusion>
				<exclusion>
					<groupId>ch.qos.logback</groupId>
					<artifactId>logback-classic</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
				 <exclusion>
					<groupId>org.mybatis</groupId>
					<artifactId>mybatis-spring</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.mybatis</groupId>
					<artifactId>mybatis</artifactId>
				</exclusion>
    </exclusions>
</dependency>

2、配置项目。配置步骤全部参考官方介绍:https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md

a、配置数据库的连接和mybatis-plus。参考:https://blog.csdn.net/weixin_41381863/article/details/106533572

b、在使用的数据库中创建表WORKER_NODE。(如果数据库版本较低,需要将TIMESTAMP类型换成datetime(3),一劳永逸的做法就是直接将TIMESTAMP换成datetime(3))

DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID)
)
 COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;

c、将uid-generator核心对象装配为spring的bean。

uid-generator提供了两种生成器: DefaultUidGeneratorCachedUidGenerator。如对UID生成性能有要求, 请使用CachedUidGenerator。这里装配CachedUidGeneratorDefaultUidGenerator装配方式是一样的。

/**
 * <p> 百度  Uid-Generator配置
 * @author zepal
 * */
@Configuration
public class UidGeneratorConfig {

	@Bean("disposableWorkerIdAssigner")
	public DisposableWorkerIdAssigner initDisposableWorkerIdAssigner() {
		DisposableWorkerIdAssigner disposableWorkerIdAssigner = new DisposableWorkerIdAssigner();
		return disposableWorkerIdAssigner;
	}
	
	@Bean("cachedUidGenerator")
	public CachedUidGenerator initCachedUidGenerator(WorkerIdAssigner workerIdAssigner) {
		CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
		cachedUidGenerator.setWorkerIdAssigner(workerIdAssigner);
		// 属性参考链接  https://github.com/baidu/uid-generator/blob/master/README.zh_cn.md
        // 以下为可选配置, 如未指定将采用默认值
		// cachedUidGenerator.setTimeBits(28);
		// cachedUidGenerator.setWorkerBits(22);
		// cachedUidGenerator.setSeqBits(13);
		// cachedUidGenerator.setEpochStr("2016-09-20");
		cachedUidGenerator.setBoostPower(3);
		cachedUidGenerator.setPaddingFactor(50);
		cachedUidGenerator.setScheduleInterval(60L);
//		// 拒绝策略: 当环已满, 无法继续填充时
		// 默认无需指定, 将丢弃Put操作, 仅日志记录. 如有特殊需求, 请实现RejectedPutBufferHandler接口(支持Lambda表达式)
		// 拒绝策略: 当环已空, 无法继续获取时
		// 默认无需指定, 将记录日志, 并抛出UidGenerateException异常. 如有特殊需求, 请实现RejectedTakeBufferHandler接口(支持Lambda表达式)
		return cachedUidGenerator;
	}
}

 说明:默认的属性,是百度对雪花算法的组成部分作出的调整(所有位加起来要为64,标识位始终为1,即非标识位一共为63)。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTM4MTg2Mw==,size_16,color_FFFFFF,t_70

d、配置uid-generator依赖的mybatis配置

mapper文件:(注意:<mapper>中namespace属性要修改为引入的uid-generator,WorkerNodeDAO的绝对路径。<resultMap>的type属性和<insert>中的parameterType属性,要修改为引入的uid-generator,WorkerNodeEntity的绝对路径。不然mybatis怎么取映射路径)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xfvape.uid.worker.dao.WorkerNodeDAO">
	<resultMap id="workerNodeRes"
			   type="com.xfvape.uid.worker.entity.WorkerNodeEntity">
		<id column="ID" jdbcType="BIGINT" property="id" />
		<result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" />
		<result column="PORT" jdbcType="VARCHAR" property="port" />
		<result column="TYPE" jdbcType="INTEGER" property="type" />
		<result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" />
		<result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" />
		<result column="CREATED" jdbcType="TIMESTAMP" property="created" />
	</resultMap>

	<insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id"
		parameterType="com.xfvape.uid.worker.entity.WorkerNodeEntity">
		INSERT INTO WORKER_NODE
		(HOST_NAME,
		PORT,
		TYPE,
		LAUNCH_DATE,
		MODIFIED,
		CREATED)
		VALUES (
		#{hostName},
		#{port},
		#{type},
		#{launchDate},
		NOW(),
		NOW())
	</insert>

	<select id="getWorkerNodeByHostPort" resultMap="workerNodeRes">
		SELECT
		ID,
		HOST_NAME,
		PORT,
		TYPE,
		LAUNCH_DATE,
		MODIFIED,
		CREATED
		FROM
		WORKER_NODE
		WHERE
		HOST_NAME = #{host} AND PORT = #{port}
	</select>
</mapper>

@MapperScan的dao层接口扫描:

@MapperScan({"com.zgn.mp.dao", "com.xfvape.uid.worker.dao"})

说明:com.xfvape.uid.worker.dao是引入的uid-generator,WorkerNodeDAO所在的包。(前面的路径请忽略,是我本地demo的dao层接口路径)

application.properties配置:

mybatis-plus.mapper-locations=classpath:mapper/*.xml,classpath:mapper/uid/WORKER_NODE.xml

说明:classpath:mapper/uid/WORKER_NODE.xml是创建上述mapper文件所在的路径。(classpath:mapper/*.xml是我本地demo的mapper文件路径,忽略或改成自己项目中的路径)

测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)
public class UidGeneratorTest {

	@Autowired
	private UidGenerator uidGenerator;
	
	@Test
	public void testSerialGenerate() {
		
		long uid = uidGenerator.getUID();
		System.out.println("生成的id = " + uid);
		
		// 生成当前唯一id所用的元素
		System.out.println(uidGenerator.parseUID(uid));
	}
}

输出结果:

20200706220540473.png

扩展

1、如果是通过本地项目引入,参考上述步骤配置进主项目即可(注意各个类的路径)。

2、如果是分布式项目,将官方开源的项目下载下来后,参考它的配置修改,放进tomcat运行。也可以重新创建springboot项目,参考上述步骤配置运行即可(注意各个类的路径)。

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,下面是 SpringBoot 集成 sharding-jdbc-spring-boot-starter 并使用 yml 配置多数据源的方式 进行 分表配置的步骤: 1. 首先,在 pom.xml 文件中添加 sharding-jdbc-spring-boot-starter 依赖,如下所示: ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>${shardingsphere.version}</version> </dependency> ``` 2. 在 application.yml 配置文件中添加数据源配置,如下所示: ```yml spring: datasource: # 主数据源 master: url: jdbc:mysql://localhost:3306/db_master?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 username: root password: root # 从数据源 slave: url: jdbc:mysql://localhost:3306/db_slave?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 username: root password: root # sharding-jdbc 配置 sharding: jdbc: #配置主从数据源名称 data-sources: # 配置主数据源 master: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver jdbc-url: ${spring.datasource.master.url} username: ${spring.datasource.master.username} password: ${spring.datasource.master.password} hikari: minimum-idle: 5 maximum-pool-size: 20 auto-commit: true idle-timeout: 30000 pool-name: master # 配置从数据源 slave: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver jdbc-url: ${spring.datasource.slave.url} username: ${spring.datasource.slave.username} password: ${spring.datasource.slave.password} hikari: minimum-idle: 5 maximum-pool-size: 20 auto-commit: true idle-timeout: 30000 pool-name: slave # 配置表规则 sharding: tables: # 配置分表规则 user: actual-data-nodes: master.user_${0..2} table-strategy: inline: sharding-column: id algorithm-expression: user_${id % 3} key-generator: type: SNOWFLAKE column: id props: worker-id: 123 # 配置读写分离规则 master-slave-rules: - name: ms master-data-source-name: master slave-data-source-names: slave ``` 3. 在代码中使用数据源,如下所示: ```java @Service public class UserServiceImpl implements UserService { @Autowired private JdbcTemplate jdbcTemplate; @Override public void addUser(User user) { String sql = "insert into user(id, name, age) values(?, ?, ?)"; Object[] params = new Object[]{user.getId(), user.getName(), user.getAge()}; jdbcTemplate.update(sql, params); } @Override public List<User> getUsers() { String sql = "select * from user"; List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class)); return userList; } } ``` 希望这些步骤能够帮助你集成 sharding-jdbc-spring-boot-starter 并使用 yml 配置多数据源的方式进行分表配置。如果你有更多的问题,欢迎随时向我提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值