百度UID generator
一, 创建表: worker_node(在项目启动时初始化生成workId)
java
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 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'modified time',
`CREATED` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'created time',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb3 COMMENT='DB WorkerID Assigner for UID Generator';
二, 创建Model及Exmple、Dao
Model: WorkerNode
java
package org.com.spi.model;
import java.util.Date;
public class WorkerNode {
private Long id;
private String hostName;
private String port;
private Integer type;
private Date launchDate;
private Date modified;
private Date created;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getHostName() {
return hostName;
}
public void setHostName(String hostName) {
this.hostName = hostName == null ? null : hostName.trim();
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port == null ? null : port.trim();
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public Date getLaunchDate() {
return launchDate;
}
public void setLaunchDate(Date launchDate) {
this.launchDate = launchDate;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
}
Example: WorkerNodeExample
java
package org.com.spi.model;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
public class WorkerNodeExample {
protected String orderByClause;
protected boolean distinct;
protected List<Criteria> oredCriteria;
public WorkerNodeExample() {
oredCriteria = new ArrayList<Criteria>();
}
public void setOrderByClause(String orderByClause) {
this.orderByClause = orderByClause;
}
public String getOrderByClause() {
return orderByClause;
}
public void setDistinct(boolean distinct) {
this.distinct = distinct;
}
public boolean isDistinct() {
return distinct;
}
public List<Criteria> getOredCriteria() {
return oredCriteria;
}
public void or(Criteria criteria) {
oredCriteria.add(criteria);
}
public Criteria or() {
Criteria criteria = createCriteriaInternal();
oredCriteria.add(criteria);
return criteria;
}
public Criteria createCriteria() {
Criteria criteria = createCriteriaInternal();
if (oredCriteria.size() == 0) {
oredCriteria.add(criteria);
}
return criteria;
}
protected Criteria createCriteriaInternal() {
Criteria criteria = new Criteria();
return criteria;
}
public void clear() {
oredCriteria.clear();
orderByClause = null;
distinct = false;
}
protected abstract static class GeneratedCriteria {
protected List<Criterion> criteria;
protected GeneratedCriteria() {
super();
criteria = new ArrayList<Criterion>();
}
public boolean isValid() {
return criteria.size() > 0;
}
public List<Criterion> getAllCriteria() {
return criteria;
}
public List<Criterion> getCriteria() {
return criteria;
}
protected void addCriterion(String condition) {
if (condition == null) {
throw new RuntimeException("Value for condition cannot be null");
}
criteria.add(new Criterion(condition));
}
protected void addCriterion(String condition, Object value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value));
}
protected void addCriterion(String condition, Object value1, Object value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
criteria.add(new Criterion(condition, value1, value2));
}
protected void addCriterionForJDBCDate(String condition, Date value, String property) {
if (value == null) {
throw new RuntimeException("Value for " + property + " cannot be null");
}
addCriterion(condition, new java.sql.Date(value.getTime()), property);
}
protected void addCriterionForJDBCDate(String condition, List<Date> values, String property) {
if (values == null || values.size() == 0) {
throw new RuntimeException("Value list for " + property + " cannot be null or empty");
}
List<java.sql.Date> dateList = new ArrayList<java.sql.Date>();
Iterator<Date> iter = values.iterator();
while (iter.hasNext()) {
dateList.add(new java.sql.Date(iter.next().getTime()));
}
addCriterion(condition, dateList, property);
}
protected void addCriterionForJDBCDate(String condition, Date value1, Date value2, String property) {
if (value1 == null || value2 == null) {
throw new RuntimeException("Between values for " + property + " cannot be null");
}
addCriterion(condition, new java.sql.Date(value1.getTime()), new java.sql.Date(value2.getTime()), property);
}
public Criteria andIdIsNull() {
addCriterion("ID is null");
return (Criteria) this;
}
public Criteria andIdIsNotNull() {
addCriterion("ID is not null");
return (Criteria) this;
}
public Criteria andIdEqualTo(Long value) {
addCriterion("ID =", value, "id");
return (Criteria) this;
}
public Criteria andIdNotEqualTo(Long value) {
addCriterion("ID <>", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThan(Long value) {
addCriterion("ID >", value, "id");
return (Criteria) this;
}
public Criteria andIdGreaterThanOrEqualTo(Long value) {
addCriterion("ID >=", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThan(Long value) {
addCriterion("ID <", value, "id");
return (Criteria) this;
}
public Criteria andIdLessThanOrEqualTo(Long value) {
addCriterion("ID <=", value, "id");
return (Criteria) this;
}
public Criteria andIdIn(List<Long> values) {
addCriterion("ID in", values, "id");
return (Criteria) this;
}
public Criteria andIdNotIn(List<Long> values) {
addCriterion("ID not in", values, "id");
return (Criteria) this;
}
public Criteria andIdBetween(Long value1, Long value2) {
addCriterion("ID between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andIdNotBetween(Long value1, Long value2) {
addCriterion("ID not between", value1, value2, "id");
return (Criteria) this;
}
public Criteria andHostNameIsNull() {
addCriterion("HOST_NAME is null");
return (Criteria) this;
}
public Criteria andHostNameIsNotNull() {
addCriterion("HOST_NAME is not null");
return (Criteria) this;
}
public Criteria andHostNameEqualTo(String value) {
addCriterion("HOST_NAME =", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameNotEqualTo(String value) {
addCriterion("HOST_NAME <>", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameGreaterThan(String value) {
addCriterion("HOST_NAME >", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameGreaterThanOrEqualTo(String value) {
addCriterion("HOST_NAME >=", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameLessThan(String value) {
addCriterion("HOST_NAME <", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameLessThanOrEqualTo(String value) {
addCriterion("HOST_NAME <=", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameLike(String value) {
addCriterion("HOST_NAME like", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameNotLike(String value) {
addCriterion("HOST_NAME not like", value, "hostName");
return (Criteria) this;
}
public Criteria andHostNameIn(List<String> values) {
addCriterion("HOST_NAME in", values, "hostName");
return (Criteria) this;
}
public Criteria andHostNameNotIn(List<String> values) {
addCriterion("HOST_NAME not in", values, "hostName");
return (Criteria) this;
}
public Criteria andHostNameBetween(String value1, String value2) {
addCriterion("HOST_NAME between", value1, value2, "hostName");
return (Criteria) this;
}
public Criteria andHostNameNotBetween(String value1, String value2) {
addCriterion("HOST_NAME not between", value1, value2, "hostName");
return (Criteria) this;
}
public Criteria andPortIsNull() {
addCriterion("PORT is null");
return (Criteria) this;
}
public Criteria andPortIsNotNull() {
addCriterion("PORT is not null");
return (Criteria) this;
}
public Criteria andPortEqualTo(String value) {
addCriterion("PORT =", value, "port");
return (Criteria) this;
}
public Criteria andPortNotEqualTo(String value) {
addCriterion("PORT <>", value, "port");
return (Criteria) this;
}
public Criteria andPortGreaterThan(String value) {
addCriterion("PORT >", value, "port");
return (Criteria) this;
}
public Criteria andPortGreaterThanOrEqualTo(String value) {
addCriterion("PORT >=", value, "port");
return (Criteria) this;
}
public Criteria andPortLessThan(String value) {
addCriterion("PORT <", value, "port");
return (Criteria) this;
}
public Criteria andPortLessThanOrEqualTo(String value) {
addCriterion("PORT <=", value, "port");
return (Criteria) this;
}
public Criteria andPortLike(String value) {
addCriterion("PORT like", value, "port");
return (Criteria) this;
}
public Criteria andPortNotLike(String value) {
addCriterion("PORT not like", value, "port");
return (Criteria) this;
}
public Criteria andPortIn(List<String> values) {
addCriterion("PORT in", values, "port");
return (Criteria) this;
}
public Criteria andPortNotIn(List<String> values) {
addCriterion("PORT not in", values, "port");
return (Criteria) this;
}
public Criteria andPortBetween(String value1, String value2) {
addCriterion("PORT between", value1, value2, "port");
return (Criteria) this;
}
public Criteria andPortNotBetween(String value1, String value2) {
addCriterion("PORT not between", value1, value2, "port");
return (Criteria) this;
}
public Criteria andTypeIsNull() {
addCriterion("TYPE is null");
return (Criteria) this;
}
public Criteria andTypeIsNotNull() {
addCriterion("TYPE is not null");
return (Criteria) this;
}
public Criteria andTypeEqualTo(Integer value) {
addCriterion("TYPE =", value, "type");
return (Criteria) this;
}
public Criteria andTypeNotEqualTo(Integer value) {
addCriterion("TYPE <>", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThan(Integer value) {
addCriterion("TYPE >", value, "type");
return (Criteria) this;
}
public Criteria andTypeGreaterThanOrEqualTo(Integer value) {
addCriterion("TYPE >=", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThan(Integer value) {
addCriterion("TYPE <", value, "type");
return (Criteria) this;
}
public Criteria andTypeLessThanOrEqualTo(Integer value) {
addCriterion("TYPE <=", value, "type");
return (Criteria) this;
}
public Criteria andTypeIn(List<Integer> values) {
addCriterion("TYPE in", values, "type");
return (Criteria) this;
}
public Criteria andTypeNotIn(List<Integer> values) {
addCriterion("TYPE not in", values, "type");
return (Criteria) this;
}
public Criteria andTypeBetween(Integer value1, Integer value2) {
addCriterion("TYPE between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andTypeNotBetween(Integer value1, Integer value2) {
addCriterion("TYPE not between", value1, value2, "type");
return (Criteria) this;
}
public Criteria andLaunchDateIsNull() {
addCriterion("LAUNCH_DATE is null");
return (Criteria) this;
}
public Criteria andLaunchDateIsNotNull() {
addCriterion("LAUNCH_DATE is not null");
return (Criteria) this;
}
public Criteria andLaunchDateEqualTo(Date value) {
addCriterionForJDBCDate("LAUNCH_DATE =", value, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateNotEqualTo(Date value) {
addCriterionForJDBCDate("LAUNCH_DATE <>", value, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateGreaterThan(Date value) {
addCriterionForJDBCDate("LAUNCH_DATE >", value, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateGreaterThanOrEqualTo(Date value) {
addCriterionForJDBCDate("LAUNCH_DATE >=", value, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateLessThan(Date value) {
addCriterionForJDBCDate("LAUNCH_DATE <", value, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateLessThanOrEqualTo(Date value) {
addCriterionForJDBCDate("LAUNCH_DATE <=", value, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateIn(List<Date> values) {
addCriterionForJDBCDate("LAUNCH_DATE in", values, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateNotIn(List<Date> values) {
addCriterionForJDBCDate("LAUNCH_DATE not in", values, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateBetween(Date value1, Date value2) {
addCriterionForJDBCDate("LAUNCH_DATE between", value1, value2, "launchDate");
return (Criteria) this;
}
public Criteria andLaunchDateNotBetween(Date value1, Date value2) {
addCriterionForJDBCDate("LAUNCH_DATE not between", value1, value2, "launchDate");
return (Criteria) this;
}
public Criteria andModifiedIsNull() {
addCriterion("MODIFIED is null");
return (Criteria) this;
}
public Criteria andModifiedIsNotNull() {
addCriterion("MODIFIED is not null");
return (Criteria) this;
}
public Criteria andModifiedEqualTo(Date value) {
addCriterion("MODIFIED =", value, "modified");
return (Criteria) this;
}
public Criteria andModifiedNotEqualTo(Date value) {
addCriterion("MODIFIED <>", value, "modified");
return (Criteria) this;
}
public Criteria andModifiedGreaterThan(Date value) {
addCriterion("MODIFIED >", value, "modified");
return (Criteria) this;
}
public Criteria andModifiedGreaterThanOrEqualTo(Date value) {
addCriterion("MODIFIED >=", value, "modified");
return (Criteria) this;
}
public Criteria andModifiedLessThan(Date value) {
addCriterion("MODIFIED <", value, "modified");
return (Criteria) this;
}
public Criteria andModifiedLessThanOrEqualTo(Date value) {
addCriterion("MODIFIED <=", value, "modified");
return (Criteria) this;
}
public Criteria andModifiedIn(List<Date> values) {
addCriterion("MODIFIED in", values, "modified");
return (Criteria) this;
}
public Criteria andModifiedNotIn(List<Date> values) {
addCriterion("MODIFIED not in", values, "modified");
return (Criteria) this;
}
public Criteria andModifiedBetween(Date value1, Date value2) {
addCriterion("MODIFIED between", value1, value2, "modified");
return (Criteria) this;
}
public Criteria andModifiedNotBetween(Date value1, Date value2) {
addCriterion("MODIFIED not between", value1, value2, "modified");
return (Criteria) this;
}
public Criteria andCreatedIsNull() {
addCriterion("CREATED is null");
return (Criteria) this;
}
public Criteria andCreatedIsNotNull() {
addCriterion("CREATED is not null");
return (Criteria) this;
}
public Criteria andCreatedEqualTo(Date value) {
addCriterion("CREATED =", value, "created");
return (Criteria) this;
}
public Criteria andCreatedNotEqualTo(Date value) {
addCriterion("CREATED <>", value, "created");
return (Criteria) this;
}
public Criteria andCreatedGreaterThan(Date value) {
addCriterion("CREATED >", value, "created");
return (Criteria) this;
}
public Criteria andCreatedGreaterThanOrEqualTo(Date value) {
addCriterion("CREATED >=", value, "created");
return (Criteria) this;
}
public Criteria andCreatedLessThan(Date value) {
addCriterion("CREATED <", value, "created");
return (Criteria) this;
}
public Criteria andCreatedLessThanOrEqualTo(Date value) {
addCriterion("CREATED <=", value, "created");
return (Criteria) this;
}
public Criteria andCreatedIn(List<Date> values) {
addCriterion("CREATED in", values, "created");
return (Criteria) this;
}
public Criteria andCreatedNotIn(List<Date> values) {
addCriterion("CREATED not in", values, "created");
return (Criteria) this;
}
public Criteria andCreatedBetween(Date value1, Date value2) {
addCriterion("CREATED between", value1, value2, "created");
return (Criteria) this;
}
public Criteria andCreatedNotBetween(Date value1, Date value2) {
addCriterion("CREATED not between", value1, value2, "created");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {
protected Criteria() {
super();
}
}
public static class Criterion {
private String condition;
private Object value;
private Object secondValue;
private boolean noValue;
private boolean singleValue;
private boolean betweenValue;
private boolean listValue;
private String typeHandler;
public String getCondition() {
return condition;
}
public Object getValue() {
return value;
}
public Object getSecondValue() {
return secondValue;
}
public boolean isNoValue() {
return noValue;
}
public boolean isSingleValue() {
return singleValue;
}
public boolean isBetweenValue() {
return betweenValue;
}
public boolean isListValue() {
return listValue;
}
public String getTypeHandler() {
return typeHandler;
}
protected Criterion(String condition) {
super();
this.condition = condition;
this.typeHandler = null;
this.noValue = true;
}
protected Criterion(String condition, Object value, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.typeHandler = typeHandler;
if (value instanceof List<?>) {
this.listValue = true;
} else {
this.singleValue = true;
}
}
protected Criterion(String condition, Object value) {
this(condition, value, null);
}
protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
super();
this.condition = condition;
this.value = value;
this.secondValue = secondValue;
this.typeHandler = typeHandler;
this.betweenValue = true;
}
protected Criterion(String condition, Object value, Object secondValue) {
this(condition, value, secondValue, null);
}
}
}
Dao: WorkerNodeMapper
java
package org.com.spi.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.com.spi.model.WorkerNode;
import org.com.spi.model.WorkerNodeExample;
@Mapper
public interface WorkerNodeMapper {
int countByExample(WorkerNodeExample example);
int deleteByExample(WorkerNodeExample example);
int deleteByPrimaryKey(Long id);
int insert(WorkerNode record);
int insertSelective(WorkerNode record);
List<WorkerNode> selectByExample(WorkerNodeExample example);
WorkerNode selectByPrimaryKey(Long id);
int updateByExampleSelective(@Param("record") WorkerNode record, @Param("example") WorkerNodeExample example);
int updateByExample(@Param("record") WorkerNode record, @Param("example") WorkerNodeExample example);
int updateByPrimaryKeySelective(WorkerNode record);
int updateByPrimaryKey(WorkerNode record);
}
三, 配置文件 及 xml
配置文件内容:
java
spring.datasource.url=jdbc:mysql://localhost:3306/generate_id?characterEncoding=utf8&serverTimezone=UTC
# ??????
spring.datasource.username=root
# ?????
spring.datasource.password=root
# ?????
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
###################################### MyBatis ??######################################
# ?? mapper.xml ???
mybatis.mapper-locations=classpath:mybatis/*.xml
#????????,?????????????? mapper.xml ??????????????
mybatis.type-aliases-package=net.biancheng.www.bean
#???????????????????
mybatis.configuration.map-underscore-to-camel-case=true
在resources/mybatis目录下创建WorkerNodeMapper.xml
java
<?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="org.com.spi.dao.WorkerNodeMapper" >
<resultMap id="BaseResultMap" type="org.com.spi.model.WorkerNode" >
<id column="ID" property="id" jdbcType="BIGINT" />
<result column="HOST_NAME" property="hostName" jdbcType="VARCHAR" />
<result column="PORT" property="port" jdbcType="VARCHAR" />
<result column="TYPE" property="type" jdbcType="INTEGER" />
<result column="LAUNCH_DATE" property="launchDate" jdbcType="DATE" />
<result column="MODIFIED" property="modified" jdbcType="TIMESTAMP" />
<result column="CREATED" property="created" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Example_Where_Clause" >
<where >
<foreach collection="oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause" >
<where >
<foreach collection="example.oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List" >
ID, HOST_NAME, PORT, TYPE, LAUNCH_DATE, MODIFIED, CREATED
</sql>
<select id="selectByExample" resultMap="BaseResultMap" parameterType="org.com.spi.model.WorkerNodeExample" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from worker_node
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select
<include refid="Base_Column_List" />
from worker_node
where ID = #{id,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
delete from worker_node
where ID = #{id,jdbcType=BIGINT}
</delete>
<delete id="deleteByExample" parameterType="org.com.spi.model.WorkerNodeExample" >
delete from worker_node
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="org.com.spi.model.WorkerNode" >
insert into worker_node (ID, HOST_NAME, PORT,
TYPE, LAUNCH_DATE, MODIFIED,
CREATED)
values (#{id,jdbcType=BIGINT}, #{hostName,jdbcType=VARCHAR}, #{port,jdbcType=VARCHAR},
#{type,jdbcType=INTEGER}, #{launchDate,jdbcType=DATE}, #{modified,jdbcType=TIMESTAMP},
#{created,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="org.com.spi.model.WorkerNode" >
insert into worker_node
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
ID,
</if>
<if test="hostName != null" >
HOST_NAME,
</if>
<if test="port != null" >
PORT,
</if>
<if test="type != null" >
TYPE,
</if>
<if test="launchDate != null" >
LAUNCH_DATE,
</if>
<if test="modified != null" >
MODIFIED,
</if>
<if test="created != null" >
CREATED,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=BIGINT},
</if>
<if test="hostName != null" >
#{hostName,jdbcType=VARCHAR},
</if>
<if test="port != null" >
#{port,jdbcType=VARCHAR},
</if>
<if test="type != null" >
#{type,jdbcType=INTEGER},
</if>
<if test="launchDate != null" >
#{launchDate,jdbcType=DATE},
</if>
<if test="modified != null" >
#{modified,jdbcType=TIMESTAMP},
</if>
<if test="created != null" >
#{created,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="org.com.spi.model.WorkerNodeExample" resultType="java.lang.Integer" >
select count(*) from worker_node
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map" >
update worker_node
<set >
<if test="record.id != null" >
ID = #{record.id,jdbcType=BIGINT},
</if>
<if test="record.hostName != null" >
HOST_NAME = #{record.hostName,jdbcType=VARCHAR},
</if>
<if test="record.port != null" >
PORT = #{record.port,jdbcType=VARCHAR},
</if>
<if test="record.type != null" >
TYPE = #{record.type,jdbcType=INTEGER},
</if>
<if test="record.launchDate != null" >
LAUNCH_DATE = #{record.launchDate,jdbcType=DATE},
</if>
<if test="record.modified != null" >
MODIFIED = #{record.modified,jdbcType=TIMESTAMP},
</if>
<if test="record.created != null" >
CREATED = #{record.created,jdbcType=TIMESTAMP},
</if>
</set>
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map" >
update worker_node
set ID = #{record.id,jdbcType=BIGINT},
HOST_NAME = #{record.hostName,jdbcType=VARCHAR},
PORT = #{record.port,jdbcType=VARCHAR},
TYPE = #{record.type,jdbcType=INTEGER},
LAUNCH_DATE = #{record.launchDate,jdbcType=DATE},
MODIFIED = #{record.modified,jdbcType=TIMESTAMP},
CREATED = #{record.created,jdbcType=TIMESTAMP}
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="org.com.spi.model.WorkerNode" >
update worker_node
<set >
<if test="hostName != null" >
HOST_NAME = #{hostName,jdbcType=VARCHAR},
</if>
<if test="port != null" >
PORT = #{port,jdbcType=VARCHAR},
</if>
<if test="type != null" >
TYPE = #{type,jdbcType=INTEGER},
</if>
<if test="launchDate != null" >
LAUNCH_DATE = #{launchDate,jdbcType=DATE},
</if>
<if test="modified != null" >
MODIFIED = #{modified,jdbcType=TIMESTAMP},
</if>
<if test="created != null" >
CREATED = #{created,jdbcType=TIMESTAMP},
</if>
</set>
where ID = #{id,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="org.com.spi.model.WorkerNode" >
update worker_node
set HOST_NAME = #{hostName,jdbcType=VARCHAR},
PORT = #{port,jdbcType=VARCHAR},
TYPE = #{type,jdbcType=INTEGER},
LAUNCH_DATE = #{launchDate,jdbcType=DATE},
MODIFIED = #{modified,jdbcType=TIMESTAMP},
CREATED = #{created,jdbcType=TIMESTAMP}
where ID = #{id,jdbcType=BIGINT}
</update>
</mapper>
四, 编写相关类
入口类: DefaultUidGenerator
java
package org.com.spi.utils.baidu;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class DefaultUidGenerator implements UidGenerator, InitializingBean {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultUidGenerator.class);
/** Bits allocate */
protected int timeBits = 28;
protected int workerBits = 22;
protected int seqBits = 13;
/** Customer epoch, unit as second. For example 2016-05-20 (ms: 1463673600000)*/
protected String epochStr = "2016-05-20";
protected long epochSeconds = TimeUnit.MILLISECONDS.toSeconds(1463673600000L);
/** Stable fields after spring bean initializing */
protected BitsAllocator bitsAllocator;
protected long workerId;
/** Volatile fields caused by nextId() */
protected long sequence = 0L;
protected long lastSecond = -1L;
// /** Spring property */
// protected WorkerIdAssigner workerIdAssigner;
public long getWorkerId() {
return workerId;
}
public void setWorkerId(long workerId) {
this.workerId = workerId;
}
@Override
public void afterPropertiesSet() throws Exception {
// initialize bits allocator
bitsAllocator = new BitsAllocator(timeBits, workerBits, seqBits);
// // initialize worker id
// workerId = workerIdAssigner.assignWorkerId();
if (workerId > bitsAllocator.getMaxWorkerId()) {
throw new RuntimeException("Worker id " + workerId + " exceeds the max " + bitsAllocator.getMaxWorkerId());
}
LOGGER.info("Initialized bits(1, {}, {}, {}) for workerID:{}", timeBits, workerBits, seqBits, workerId);
}
@Override
public long getUID() throws UidGenerateException {
try {
return nextId();
} catch (Exception e) {
LOGGER.error("Generate unique id exception. ", e);
throw new UidGenerateException(e);
}
}
@Override
public String parseUID(long uid) {
long totalBits = BitsAllocator.TOTAL_BITS;
long signBits = bitsAllocator.getSignBits();
long timestampBits = bitsAllocator.getTimestampBits();
long workerIdBits = bitsAllocator.getWorkerIdBits();
long sequenceBits = bitsAllocator.getSequenceBits();
// parse UID
long sequence = (uid << (totalBits - sequenceBits)) >>> (totalBits - sequenceBits);
long workerId = (uid << (timestampBits + signBits)) >>> (totalBits - workerIdBits);
long deltaSeconds = uid >>> (workerIdBits + sequenceBits);
Date thatTime = new Date(TimeUnit.SECONDS.toMillis(epochSeconds + deltaSeconds));
String thatTimeStr = DateUtils.formatByDateTimePattern(thatTime);
// format as string
return String.format("{\"UID\":\"%d\",\"timestamp\":\"%s\",\"workerId\":\"%d\",\"sequence\":\"%d\"}",
uid, thatTimeStr, workerId, sequence);
}
/**
* Get UID
*
* @return UID
* @throws UidGenerateException in the case: Clock moved backwards; Exceeds the max timestamp
*/
protected synchronized long nextId() {
long currentSecond = getCurrentSecond();
// Clock moved backwards, refuse to generate uid
if (currentSecond < lastSecond) {
long refusedSeconds = lastSecond - currentSecond;
throw new UidGenerateException("Clock moved backwards. Refusing for %d seconds", refusedSeconds);
}
// At the same second, increase sequence
if (currentSecond == lastSecond) {
sequence = (sequence + 1) & bitsAllocator.getMaxSequence();
// Exceed the max sequence, we wait the next second to generate uid
if (sequence == 0) {
currentSecond = getNextSecond(lastSecond);
}
// At the different second, sequence restart from zero
} else {
sequence = 0L;
}
lastSecond = currentSecond;
// Allocate bits for UID
return bitsAllocator.allocate(currentSecond - epochSeconds, workerId, sequence);
}
/**
* Get next millisecond
*/
private long getNextSecond(long lastTimestamp) {
long timestamp = getCurrentSecond();
while (timestamp <= lastTimestamp) {
timestamp = getCurrentSecond();
}
return timestamp;
}
/**
* Get current second
*/
private long getCurrentSecond() {
long currentSecond = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
if (currentSecond - epochSeconds > bitsAllocator.getMaxDeltaSeconds()) {
throw new UidGenerateException("Timestamp bits is exhausted. Refusing UID generate. Now: " + currentSecond);
}
return currentSecond;
}
/**
* Setters for spring property
*/
// public void setWorkerIdAssigner(WorkerIdAssigner workerIdAssigner) {
// this.workerIdAssigner = workerIdAssigner;
// }
public void setTimeBits(int timeBits) {
if (timeBits > 0) {
this.timeBits = timeBits;
}
}
public void setWorkerBits(int workerBits) {
if (workerBits > 0) {
this.workerBits = workerBits;
}
}
public void setSeqBits(int seqBits) {
if (seqBits > 0) {
this.seqBits = seqBits;
}
}
public void setEpochStr(String epochStr) {
if (StringUtils.hasLength(epochStr)) {
this.epochStr = epochStr;
this.epochSeconds = TimeUnit.MILLISECONDS.toSeconds(DateUtils.parseByDayPattern(epochStr).getTime());
}
}
public String getPodIp(){
try {
InetAddress localHost = InetAddress.getLocalHost();
return localHost.getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return "127.0.0.1";
}
}
接口: UidGenerator
java
package org.com.spi.utils.baidu;
public interface UidGenerator {
/**
* Get a unique ID
*
* @return UID
* @throws UidGenerateException
*/
long getUID() throws UidGenerateException;
/**
* Parse the UID into elements which are used to generate the UID. <br>
* Such as timestamp & workerId & sequence...
*
* @param uid
* @return Parsed info
*/
String parseUID(long uid);
}
接口WorkerIdAssigner:
java
package org.com.spi.utils.baidu;
public interface WorkerIdAssigner {
/**
* @return assigned worker id
*/
long assignWorkerId();
}
BitsAllocator类:
java
package org.com.spi.utils.baidu;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.util.Assert;
public class BitsAllocator {
/**
* Total 64 bits
*/
public static final int TOTAL_BITS = 1 << 6;
/**
* Bits for [sign-> second-> workId-> sequence]
*/
private int signBits = 1;
private final int timestampBits;
private final int workerIdBits;
private final int sequenceBits;
/**
* Max value for workId & sequence
*/
private final long maxDeltaSeconds;
private final long maxWorkerId;
private final long maxSequence;
/**
* Shift for timestamp & workerId
*/
private final int timestampShift;
private final int workerIdShift;
/**
* Constructor with timestampBits, workerIdBits, sequenceBits<br>
* The highest bit used for sign, so <code>63</code> bits for timestampBits, workerIdBits, sequenceBits
*/
public BitsAllocator(int timestampBits, int workerIdBits, int sequenceBits) {
// make sure allocated 64 bits
int allocateTotalBits = signBits + timestampBits + workerIdBits + sequenceBits;
Assert.isTrue(allocateTotalBits == TOTAL_BITS, "allocate not enough 64 bits");
// initialize bits
this.timestampBits = timestampBits;
this.workerIdBits = workerIdBits;
this.sequenceBits = sequenceBits;
// initialize max value
this.maxDeltaSeconds = ~(-1L << timestampBits);
this.maxWorkerId = ~(-1L << workerIdBits);
this.maxSequence = ~(-1L << sequenceBits);
// initialize shift
this.timestampShift = workerIdBits + sequenceBits;
this.workerIdShift = sequenceBits;
}
/**
* Allocate bits for UID according to delta seconds & workerId & sequence<br>
* <b>Note that: </b>The highest bit will always be 0 for sign
*
* @param deltaSeconds
* @param workerId
* @param sequence
* @return
*/
public long allocate(long deltaSeconds, long workerId, long sequence) {
return (deltaSeconds << timestampShift) | (workerId << workerIdShift) | sequence;
}
/**
* Getters
*/
public int getSignBits() {
return signBits;
}
public int getTimestampBits() {
return timestampBits;
}
public int getWorkerIdBits() {
return workerIdBits;
}
public int getSequenceBits() {
return sequenceBits;
}
public long getMaxDeltaSeconds() {
return maxDeltaSeconds;
}
public long getMaxWorkerId() {
return maxWorkerId;
}
public long getMaxSequence() {
return maxSequence;
}
public int getTimestampShift() {
return timestampShift;
}
public int getWorkerIdShift() {
return workerIdShift;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
异常类UidGenerateException:
java
package org.com.spi.utils.baidu;
public class UidGenerateException extends RuntimeException {
/**
* Serial Version UID
*/
private static final long serialVersionUID = -27048199131316992L;
/**
* Default constructor
*/
public UidGenerateException() {
super();
}
/**
* Constructor with message & cause
*
* @param message
* @param cause
*/
public UidGenerateException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructor with message
*
* @param message
*/
public UidGenerateException(String message) {
super(message);
}
/**
* Constructor with message format
*
* @param msgFormat
* @param args
*/
public UidGenerateException(String msgFormat, Object... args) {
super(String.format(msgFormat, args));
}
/**
* Constructor with cause
*
* @param cause
*/
public UidGenerateException(Throwable cause) {
super(cause);
}
}
配置类: UidGeneratorConfig
java
package org.com.spi.config;
import org.com.spi.dao.WorkerNodeMapper;
import org.com.spi.enums.ProjectTypeEnum;
import org.com.spi.model.WorkerNode;
import org.com.spi.model.WorkerNodeExample;
import org.com.spi.utils.ListUtils;
import org.com.spi.utils.baidu.DefaultUidGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Date;
import java.util.List;
@Configuration
public class UidGeneratorConfig {
@Autowired
private WorkerNodeMapper workerNodeMapper;
@Value("${server.port}")
private String port;
@Bean
public DefaultUidGenerator defaultUidGenerator(){
DefaultUidGenerator defaultUidGenerator = new DefaultUidGenerator();
String podIp = defaultUidGenerator.getPodIp();
System.out.println("ip:"+podIp+",port:"+port);
//是否已存在workId
WorkerNodeExample example = new WorkerNodeExample();
example.createCriteria().andHostNameEqualTo(podIp)
.andPortEqualTo(port);
List<WorkerNode> workerNodes = workerNodeMapper.selectByExample(example);
WorkerNode workerNode = null;
if(!ListUtils.anyList(workerNodes)){
//新增
Date date = new Date();
workerNode = new WorkerNode();
workerNode.setCreated(date);
workerNode.setHostName(podIp);
workerNode.setModified(date);
workerNode.setLaunchDate(date);
workerNode.setPort(port);
workerNode.setType(ProjectTypeEnum.DEMO.getType());
int i = workerNodeMapper.insertSelective(workerNode);
if(i > 0){
workerNodes = workerNodeMapper.selectByExample(example);
workerNode = workerNodes.get(0);
}
}else{
workerNode = workerNodes.get(0);
}
defaultUidGenerator.setWorkerId(workerNode.getId());
return defaultUidGenerator;
}
}
日期时间处理类DateUtils:
java
package org.com.spi.utils.baidu;
import org.apache.commons.lang.time.DateFormatUtils;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
public abstract class DateUtils extends org.apache.commons.lang.time.DateUtils {
/**
* Patterns
*/
public static final String DAY_PATTERN = "yyyy-MM-dd";
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static final String DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
public static final Date DEFAULT_DATE = DateUtils.parseByDayPattern("1970-01-01");
/**
* Parse date by 'yyyy-MM-dd' pattern
*
* @param str
* @return
*/
public static Date parseByDayPattern(String str) {
return parseDate(str, DAY_PATTERN);
}
/**
* Parse date by 'yyyy-MM-dd HH:mm:ss' pattern
*
* @param str
* @return
*/
public static Date parseByDateTimePattern(String str) {
return parseDate(str, DATETIME_PATTERN);
}
/**
* Parse date without Checked exception
*
* @param str
* @param pattern
* @return
* @throws RuntimeException when ParseException occurred
*/
public static Date parseDate(String str, String pattern) {
try {
return parseDate(str, new String[]{pattern});
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
/**
* Format date into string
*
* @param date
* @param pattern
* @return
*/
public static String formatDate(Date date, String pattern) {
return DateFormatUtils.format(date, pattern);
}
/**
* Format date by 'yyyy-MM-dd' pattern
*
* @param date
* @return
*/
public static String formatByDayPattern(Date date) {
if (date != null) {
return DateFormatUtils.format(date, DAY_PATTERN);
} else {
return null;
}
}
/**
* Format date by 'yyyy-MM-dd HH:mm:ss' pattern
*
* @param date
* @return
*/
public static String formatByDateTimePattern(Date date) {
return DateFormatUtils.format(date, DATETIME_PATTERN);
}
/**
* Get current day using format date by 'yyyy-MM-dd HH:mm:ss' pattern
*
* @return
* @author yebo
*/
public static String getCurrentDayByDayPattern() {
Calendar cal = Calendar.getInstance();
return formatByDayPattern(cal.getTime());
}
}
特点: 百度Uid generator是基于雪花算法实现,不同点在于其workId是动态的,即不同机器生成的workId不同,将主键ID作为wrokId,在项目启动时完成workId的生成及获取.遗憾的是 目前百度的这个开源算法已经停止了维护!