diff --git a/mybatis-jpa-extra-2.2.jar b/mybatis-jpa-extra-2.2.jar deleted file mode 100644 index f6d3cb220323a3c936294c3195b382269ae4158b..0000000000000000000000000000000000000000 Binary files a/mybatis-jpa-extra-2.2.jar and /dev/null differ diff --git a/mybatis-jpa-extra-2.3.jar b/mybatis-jpa-extra-2.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..3601745e3be06d18532d39c30729ebb335fabb70 Binary files /dev/null and b/mybatis-jpa-extra-2.3.jar differ diff --git a/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/IdentifierGeneratorFactory.java b/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/IdentifierGeneratorFactory.java index f21d14c3ba306906480fd1e9a7051a0b4e8c4bac..9823cc08c7930e977b48a78d8ea37c1d91daec33 100644 --- a/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/IdentifierGeneratorFactory.java +++ b/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/IdentifierGeneratorFactory.java @@ -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 getGeneratorStrategyMap() { diff --git a/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/SnowFlakeIdGenerator.java b/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/SnowFlakeIdGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..298f885cd2c6765ea167b261f5ab3d89e7a8e111 --- /dev/null +++ b/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/id/SnowFlakeIdGenerator.java @@ -0,0 +1,194 @@ +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 diff --git a/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/util/WebContext.java b/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/util/WebContext.java index 7d0d82643830b49bd25b2240794d6cd83221292c..5e22eca89370d361738a43e8afb895f1d17e7c0e 100644 --- a/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/util/WebContext.java +++ b/mybatis-jpa-extra-core/src/main/java/org/apache/mybatis/jpa/util/WebContext.java @@ -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 diff --git a/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/SnowFlakeIdGeneratorTest.java b/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/SnowFlakeIdGeneratorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ae0e9108543469db14678a6ce24bc85ee63455b3 --- /dev/null +++ b/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/SnowFlakeIdGeneratorTest.java @@ -0,0 +1,19 @@ +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("")); + } + +} diff --git a/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/domain/Students.java b/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/domain/Students.java index 882db9f488527f9c8a4e05ea3bebe3edeaf379c8..42119340cdcdf05bbe11d9552fc54c663712c978 100644 --- a/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/domain/Students.java +++ b/mybatis-jpa-extra-core/src/test/java/org/apache/mybatis/jpa/test/domain/Students.java @@ -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; diff --git a/mybatis-jpa-extra-spring-boot-starter-2.2.jar b/mybatis-jpa-extra-spring-boot-starter-2.2.jar deleted file mode 100644 index aa39b1ced1e6a0beff90c4bde8c68fd62485b79f..0000000000000000000000000000000000000000 Binary files a/mybatis-jpa-extra-spring-boot-starter-2.2.jar and /dev/null differ diff --git a/mybatis-jpa-extra-spring-boot-starter-2.3.jar b/mybatis-jpa-extra-spring-boot-starter-2.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..75f3ae8836de06d09d7ef4d02acb1464f278f54e Binary files /dev/null and b/mybatis-jpa-extra-spring-boot-starter-2.3.jar differ diff --git a/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisAutoConfiguration.java b/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisAutoConfiguration.java index 96cea5e70e54cac37d6b2e2e67e50b5f20f38a92..ea74100cdaa05107bdfcf768761c384bf746c0df 100644 --- a/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisAutoConfiguration.java +++ b/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisAutoConfiguration.java @@ -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); } diff --git a/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisProperties.java b/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisProperties.java index a83338d91c824c020e6790f605c58f98858b816c..94ab9d098cd0826650cbf1f012b7f679f37990ca 100644 --- a/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisProperties.java +++ b/mybatis-jpa-extra-spring-boot-starter/src/main/java/org/apache/mybatis/jpa/starter/MybatisProperties.java @@ -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; } diff --git a/mybatis-jpa-extra-spring-boot-starter/src/test/resources/application.properties b/mybatis-jpa-extra-spring-boot-starter/src/test/resources/application.properties index 4d8a9af18efbba439fe4de0b16877573b33e47a8..b2cb683af5ad84f36fa1b3a7012f665cb7d3ebee 100644 --- a/mybatis-jpa-extra-spring-boot-starter/src/test/resources/application.properties +++ b/mybatis-jpa-extra-spring-boot-starter/src/test/resources/application.properties @@ -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 diff --git a/mybatis-jpa-extra-spring-boot-starter/src/test/resources/log4j2.xml b/mybatis-jpa-extra-spring-boot-starter/src/test/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..a45f96e61d61020e6b600e40f97c7aa05630e6b0 --- /dev/null +++ b/mybatis-jpa-extra-spring-boot-starter/src/test/resources/log4j2.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/mybatis-jpa-extra-test/src/main/java/org/apache/mybatis/jpa/test/domain/Students.java b/mybatis-jpa-extra-test/src/main/java/org/apache/mybatis/jpa/test/domain/Students.java index 524f1b331c62117a746042deb7e6eefe568a2920..50316091dcf5a66d8fce770b32185f469bc1ec47 100644 --- a/mybatis-jpa-extra-test/src/main/java/org/apache/mybatis/jpa/test/domain/Students.java +++ b/mybatis-jpa-extra-test/src/main/java/org/apache/mybatis/jpa/test/domain/Students.java @@ -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; diff --git a/pom.xml b/pom.xml index 186fee893353a5ccb224128ab72322c85d4a6fac..0d1f0cb2c0776cb9e51fb7cd7e2824ef7b76151d 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ - 2.2 + 2.3 UTF-8 1.8 5.2.0.RELEASE @@ -35,6 +35,12 @@ + + + aliyunrepository + aliyunrepository + https://maven.aliyun.com/nexus/content/groups/public/ + mvnrepository mvnrepository