提交 fe7bc164 编写于 作者: M MaxKey

2.3

上级 11140f38
......@@ -13,7 +13,13 @@ public class IdentifierGeneratorFactory {
public IdentifierGeneratorFactory() {
register("uuid", new UUIDGenerator());
register("uuid.hex", new UUIDHexGenerator());
//register("serial", new SerialGenerator());
register("snowflakeid", new SnowFlakeIdGenerator());
}
public IdentifierGeneratorFactory(long datacenterId, long machineId) {
register("uuid", new UUIDGenerator());
register("uuid.hex", new UUIDHexGenerator());
register("snowflakeid", new SnowFlakeIdGenerator(datacenterId,machineId));
}
public ConcurrentHashMap<String, IdentifierGenerator> getGeneratorStrategyMap() {
......
package org.apache.mybatis.jpa.id;
import java.util.Calendar;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.chrono.ISOChronology;
/**
* 描述: Twitter的分布式自增ID雪花算法snowflake (Java版)
*
* @author Crystal.Sea
* @create 2021-04-17
**/
public class SnowFlakeIdGenerator implements IdentifierGenerator{
/**
* 起始的时间戳
*/
private final static long START_STMP = 1480166465631L;
/**
* 每一部分占用的位数
*/
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
private final static long MACHINE_BIT = 5; //机器标识占用的位数
private final static long DATACENTER_BIT = 5;//数据中心占用的位数
/**
* 每一部分的最大值
*/
private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
/**
* 每一部分向左的位移
*/
private final static long MACHINE_LEFT = SEQUENCE_BIT;
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
private long datacenterId; //数据中心
private long machineId; //机器标识
private long sequence = 0L; //序列号
private long lastStmp = -1L;//上一次时间戳
private String dateTime;
public SnowFlakeIdGenerator() {}
public SnowFlakeIdGenerator(long datacenterId, long machineId) {
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
}
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
}
this.datacenterId = datacenterId;
this.machineId = machineId;
}
public SnowFlakeIdGenerator(long datacenterId, long machineId, long sequence, long lastStmp) {
super();
this.datacenterId = datacenterId;
this.machineId = machineId;
this.sequence = sequence;
this.lastStmp = lastStmp;
DateTime datetime=
new DateTime(
fromatTime(lastStmp),
ISOChronology.getInstanceUTC()
);
dateTime = datetime.toString();
}
/**
* 产生下一个ID
*
* @return
*/
public synchronized long nextId() {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (currStmp == lastStmp) {
//相同毫秒内,序列号自增
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大
if (sequence == 0L) {
currStmp = getNextMill();
}
} else {
//不同毫秒内,序列号置为0
sequence = 0L;
}
lastStmp = currStmp;
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
| datacenterId << DATACENTER_LEFT //数据中心部分
| machineId << MACHINE_LEFT //机器标识部分
| sequence; //序列号部分
}
private long getNextMill() {
long mill = getNewstmp();
while (mill <= lastStmp) {
mill = getNewstmp();
}
return mill;
}
private long getNewstmp() {
return System.currentTimeMillis();
}
public SnowFlakeIdGenerator parse(long id) {
String sonwFlakeId = Long.toBinaryString(id);
System.out.println(sonwFlakeId);
int len = sonwFlakeId.length();
int sequenceStart = (int) (len < MACHINE_LEFT ? 0 : len - MACHINE_LEFT);
int workerStart = (int) (len < DATACENTER_LEFT ? 0 : len - DATACENTER_LEFT);
int timeStart = (int) (len < TIMESTMP_LEFT ? 0 : len - TIMESTMP_LEFT);
String sequence = sonwFlakeId.substring(sequenceStart, len);
String workerId = sequenceStart == 0 ? "0" : sonwFlakeId.substring(workerStart, sequenceStart);
String dataCenterId = workerStart == 0 ? "0" : sonwFlakeId.substring(timeStart, workerStart);
String time = timeStart == 0 ? "0" : sonwFlakeId.substring(0, timeStart);
int sequenceInt = Integer.valueOf(sequence, 2);
int workerIdInt = Integer.valueOf(workerId, 2);
int dataCenterIdInt = Integer.valueOf(dataCenterId, 2);
long diffTime = Long.parseLong(time, 2);
long timeLong = diffTime + START_STMP;
SnowFlakeIdGenerator snowFlakeIdParse =new SnowFlakeIdGenerator(dataCenterIdInt,workerIdInt,sequenceInt,timeLong);
return snowFlakeIdParse;
}
private static Date fromatTime(long date) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(date);
return calendar.getTime();
}
public long getDatacenterId() {
return datacenterId;
}
public void setDatacenterId(long datacenterId) {
this.datacenterId = datacenterId;
}
public long getMachineId() {
return machineId;
}
public void setMachineId(long machineId) {
this.machineId = machineId;
}
public long getSequence() {
return sequence;
}
public void setSequence(long sequence) {
this.sequence = sequence;
}
public long getLastStmp() {
return lastStmp;
}
public void setLastStmp(long lastStmp) {
this.lastStmp = lastStmp;
}
public String getDateTime() {
return dateTime;
}
public void setDateTime(String dateTime) {
this.dateTime = dateTime;
}
@Override
public String generate(Object object) {
return this.nextId()+"";
}
}
\ No newline at end of file
......@@ -2,13 +2,10 @@ package org.apache.mybatis.jpa.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.ModelAndView;
......@@ -52,28 +49,7 @@ public final class WebContext {
public static HttpServletRequest getRequest(){
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
}
/**
* get Http Context full Path,if port equals 80 is omitted
* @return String
* eg:http://192.168.1.20:9080/webcontext or http://www.website.com/webcontext
*/
public static String getHttpContextPath(){
HttpServletRequest httpServletRequest = WebContext.getRequest();
String domainName="";
String httpContextPath=httpServletRequest.getScheme()+"://"+domainName;
int port =httpServletRequest.getServerPort();
if(port==443 && httpServletRequest.getScheme().equalsIgnoreCase("https")){
}else if(port==80 && httpServletRequest.getScheme().equalsIgnoreCase("http")){
}else{
httpContextPath += ":"+port;
}
httpContextPath += httpServletRequest.getContextPath()+"";
return httpContextPath;
}
/**
* get current Session
......@@ -126,41 +102,5 @@ public final class WebContext {
public static String getParameter(String name){
return getRequest().getParameter(name);
}
/**
* get Request IpAddress,for current Request
* @return String,100.167.216.100
*/
public static final String getRequestIpAddress(){
return getRequestIpAddress(getRequest());
}
/**
* get Request IpAddress by request
* @param request
* @return String
*/
public static final String getRequestIpAddress(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
LogFactory.getLog(WebContext.class).debug("getRequestIpAddress() RequestIpAddress:"+ipAddress);
return ipAddress;
}
public static ModelAndView redirect(String redirectUrl){
return new ModelAndView("redirect:"+redirectUrl);
}
public static ModelAndView forward(String forwardUrl){
return new ModelAndView("forward:"+forwardUrl);
}
}
\ No newline at end of file
package org.apache.mybatis.jpa.test;
import org.apache.mybatis.jpa.id.SnowFlakeIdGenerator;
import org.apache.mybatis.jpa.id.UUIDHexGenerator;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SnowFlakeIdGeneratorTest {
private static final Logger _logger = LoggerFactory.getLogger(SnowFlakeIdGeneratorTest.class);
@Test
public void generator() {
// TODO Auto-generated method stub
SnowFlakeIdGenerator uhg=new SnowFlakeIdGenerator();
_logger.info(uhg.generate(""));
_logger.info(uhg.generate(""));
}
}
......@@ -37,7 +37,7 @@ public class Students extends JpaBaseDomain implements Serializable{
@Id
@Column
@GeneratedValue(strategy=GenerationType.AUTO,generator="serial")
@GeneratedValue(strategy=GenerationType.AUTO,generator="snowflakeid")
//@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="SEQ_MYBATIS_STUD")
//@GeneratedValue(strategy=GenerationType.IDENTITY,generator="SEQ_MYBATIS_STUD")
private String id;
......
......@@ -32,6 +32,7 @@ import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.apache.mybatis.jpa.MyBatisSessionFactoryBean;
import org.apache.mybatis.jpa.id.IdentifierGeneratorFactory;
import org.apache.mybatis.jpa.persistence.MapperMetadata;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
......@@ -163,6 +164,15 @@ public class MybatisAutoConfiguration implements InitializingBean {
MapperMetadata.TABLE_COLUMN_UPCASE = true;
}
if(this.properties.getTableColumnSnowflakeDatacenterId()>0 &&
this.properties.getTableColumnSnowflakeMachineId()>0) {
logger.debug("TableColumn Snowflake init ");
IdentifierGeneratorFactory identifierGeneratorFactory = new IdentifierGeneratorFactory(
this.properties.getTableColumnSnowflakeDatacenterId(),this.properties.getTableColumnSnowflakeMachineId());
MapperMetadata.identifierGeneratorFactory = identifierGeneratorFactory;
}
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
......
......@@ -66,6 +66,10 @@ public class MybatisProperties {
private boolean tableColumnUpcase;
private int tableColumnSnowflakeDatacenterId;
private int tableColumnSnowflakeMachineId;
/**
* The super class for filtering type alias. If this not specifies, the MyBatis deal as type alias all classes that
* searched from typeAliasesPackage.
......@@ -245,7 +249,23 @@ public class MybatisProperties {
this.tableColumnUpcase = tableColumnUpcase;
}
public String getDialect() {
public int getTableColumnSnowflakeDatacenterId() {
return tableColumnSnowflakeDatacenterId;
}
public void setTableColumnSnowflakeDatacenterId(int tableColumnSnowflakeDatacenterId) {
this.tableColumnSnowflakeDatacenterId = tableColumnSnowflakeDatacenterId;
}
public int getTableColumnSnowflakeMachineId() {
return tableColumnSnowflakeMachineId;
}
public void setTableColumnSnowflakeMachineId(int tableColumnSnowflakeMachineId) {
this.tableColumnSnowflakeMachineId = tableColumnSnowflakeMachineId;
}
public String getDialect() {
return dialect;
}
......
......@@ -10,4 +10,6 @@ spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.type-aliases-package=org.apache.mybatis.jpa.test.domain
mybatis.mapper-locations=classpath*:/org/apache/mybatis/jpa/test/dao/persistence/xml/mysql/*.xml
mybatis.table-column-escape=true
mybatis.table-column-snowflake-datacenter-id=1
mybatis.table-column-snowflake-machine-id=1
#mybatis.table-column-escape-char=`
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="DEBUG">
<appenders>
<Console name="consolePrint" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss,SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</appenders>
<loggers>
<Logger name="org.springframework" level="INFO"></Logger>
<Logger name="org.apache.mybatis" level="DEBUG"></Logger>
<Logger name="org.apache.mybatis.jpa" level="TRACE"></Logger>
<root level="INFO">
<appender-ref ref="consolePrint" />
</root>
</loggers>
</configuration>
\ No newline at end of file
......@@ -37,7 +37,7 @@ public class Students extends JpaBaseDomain implements Serializable{
@Id
@Column
@GeneratedValue(strategy=GenerationType.AUTO,generator="serial")
@GeneratedValue(strategy=GenerationType.AUTO,generator="snowflakeid")
//@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="SEQ_MYBATIS_STUD")
//@GeneratedValue(strategy=GenerationType.IDENTITY,generator="SEQ_MYBATIS_STUD")
private String id;
......
......@@ -15,7 +15,7 @@
</modules>
<properties>
<mybatis.jpa.extra.version>2.2</mybatis.jpa.extra.version><!--project version-->
<mybatis.jpa.extra.version>2.3</mybatis.jpa.extra.version><!--project version-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.8</jdk.version>
<spring.version>5.2.0.RELEASE</spring.version>
......@@ -35,6 +35,12 @@
</properties>
<repositories>
<repository>
<id>aliyunrepository</id>
<name>aliyunrepository</name>
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<repository>
<id>mvnrepository</id>
<name>mvnrepository</name>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册