Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
N
note
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
黄夏豪
note
Commits
17e2da46
提交
17e2da46
authored
5月 28, 2020
作者:
黄夏豪
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/master'
上级
430fb793
8fcefb47
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
243 行增加
和
8 行删除
+243
-8
datetime和timestamp.md
许旸/mysql/datetime和timestamp.md
+12
-0
SnowflakeDemo.java
许旸/snowflake/SnowflakeDemo.java
+102
-0
snowflake.md
许旸/snowflake/snowflake.md
+90
-0
AOP.md
许旸/springboot/AOP.md
+10
-3
JPA.md
许旸/springboot/JPA.md
+29
-5
image-20200426111508494.png
许旸/springboot/upload/image-20200426111508494.png
+0
-0
没有找到文件。
许旸/mysql/datetime和timestamp.md
0 → 100644
浏览文件 @
17e2da46
# datetime和timestamp的区别
## 1、自动更新日期
datetime默认值是null,不会自动更新
timestamp默认值not null,默认时间为CURRENT_TIMESTAMP,当行数据发生变化的时候采用当前时间
## 2、日期存储方式
timestamp有八小时的时差
\ No newline at end of file
许旸/snowflake/SnowflakeDemo.java
0 → 100644
浏览文件 @
17e2da46
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
public
class
SnowflakeDemo
{
private
final
long
sequenceLength
=
12L
;
private
final
long
workerIdLength
=
10L
;
private
final
long
lastTimeStampLength
=
41L
;
private
final
long
workerIdShift
=
sequenceLength
;
private
final
long
lastTimeStampShift
=
sequenceLength
+
workerIdLength
;
private
long
lastTimeStamp
=
-
1L
;
private
long
workerId
;
private
long
sequence
=
0L
;
private
long
mark
=
~(-
1L
<<
sequenceLength
);
private
static
final
int
loopNum
=
1
*
10000
;
public
synchronized
String
getId
()
{
long
timeStamp
=
System
.
currentTimeMillis
();
if
(
timeStamp
<
lastTimeStamp
)
{
throw
new
RuntimeException
(
"time error"
);
}
if
(
timeStamp
==
lastTimeStamp
)
{
sequence
=
(
sequence
+
1
)
&
mark
;
if
(
sequence
==
0
)
{
while
(
timeStamp
<=
lastTimeStamp
)
{
timeStamp
=
System
.
currentTimeMillis
();
}
}
}
else
{
sequence
=
0
;
}
lastTimeStamp
=
timeStamp
;
return
Long
.
toBinaryString
(
sequence
|
(
workerId
<<
workerIdShift
)
|
(
timeStamp
<<
lastTimeStampShift
));
}
public
synchronized
long
waitTime
(
long
lastTimeStamp
)
{
long
timeStamp
=
System
.
currentTimeMillis
();
while
(
timeStamp
<=
lastTimeStamp
)
{
timeStamp
=
System
.
currentTimeMillis
();
}
return
timeStamp
;
}
private
SnowflakeDemo
(){}
private
SnowflakeDemo
(
long
lastTimeStamp
,
long
workerId
,
long
sequence
)
{
this
.
lastTimeStamp
=
lastTimeStamp
;
this
.
workerId
=
workerId
;
this
.
sequence
=
sequence
;
}
public
void
m1
()
{
ExecutorService
pool
=
Executors
.
newCachedThreadPool
();
long
currentTime
=
System
.
currentTimeMillis
();
SnowflakeDemo
snowflakeDemo
=
new
SnowflakeDemo
(
currentTime
,
0
,
0
);
for
(
int
index
=
0
;
index
<
loopNum
;
index
++)
{
Runnable
run
=
new
Runnable
()
{
public
void
run
()
{
try
{
//new Thread().sleep(1000); //模拟耗时操作
System
.
out
.
println
(
"[1]"
+
Thread
.
currentThread
().
getName
()
+
" "
+
snowflakeDemo
.
getId
());
}
catch
(
Exception
e
)
{
}
}
};
pool
.
execute
(
run
);
}
System
.
out
.
println
(
"[1] done!"
);
pool
.
shutdown
();
}
public
static
void
main
(
String
[]
args
)
{
long
bt
=
System
.
currentTimeMillis
();
SnowflakeDemo
snowflakeWorker0
=
new
SnowflakeDemo
(
bt
,
0
,
0
);
for
(
int
i
=
0
;
i
<
loopNum
;
i
++)
{
System
.
out
.
println
(
snowflakeWorker0
.
getId
());
}
long
et
=
System
.
currentTimeMillis
();
System
.
out
.
println
(
"耗时:"
+(
et2
-
bt
)+
"ms"
);
System
.
out
.
println
(
"吞吐量为:"
+
loopNum
*
1.0
/(
et
-
bt
));
/*SnowflakeDemo TestThreadPool = new SnowflakeDemo();
long bt = System.currentTimeMillis();
TestThreadPool.m1();
long et2 = System.currentTimeMillis();
System.out.println("耗时:"+(et2 - bt)+ "ms");
System.out.println("吞吐量为:"+loopNum*1.0/(et2 - bt));*/
}
}
许旸/snowflake/snowflake.md
0 → 100644
浏览文件 @
17e2da46
### **1. 数据库自增长序列或字段**
最常见的方式。利用数据库,全数据库唯一。
优点:
1)简单,代码方便,性能可以接受。
2)数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点:
1)不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候需要处理。
2)在单个数据库或读写分离或一主多从的情况下,只有一个主库可以生成。有单点故障的风险。
3)在性能达不到要求的情况下,比较难于扩展。
4)如果遇见多个系统需要合并或者涉及到数据迁移会相当痛苦。
5)分表分库的时候会有麻烦。
优化方案:
1)针对主库单点,如果有多个Master库,则每个Master库设置的起始数字不一样,步长一样,可以是Master的个数。比如:Master1 生成的是 1,4,7,10,Master2生成的是2,5,8,11 Master3生成的是 3,6,9,12。这样就可以有效生成集群中的唯一ID,也可以大大降低ID生成数据库操作的负载。
### **2. UUID**
常见的方式。可以利用数据库也可以利用程序生成,一般来说全球唯一。
优点:
1)简单,代码方便。
2)生成ID性能非常好,基本不会有性能问题。
3)全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。
缺点:
1)没有排序,无法保证趋势递增。
2)UUID往往是使用字符串存储,查询的效率比较低。
3)存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。
4)传输数据量大
5)不可读。
### **3.snowflake算法 **
snowflake是Twitter开源的分布式ID生成算法。
**· 优点:**
1)不依赖于数据库,灵活方便,且性能优于数据库。
2)ID按照时间在单机上是递增的。
**· 缺点:**
1)在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完全同步,也许有时候也会出现不是全局递增的情况。
2)存在时间回退问题,时间回退后,生成的ID就有可能重复。
**· ID结构:**
结果是一个long型的ID,分成四个部分:
0(符号位)— 000···000(41位表示毫秒数)— 000···000(10位表示机器的ID)— 000···000(12位作为序列号)
**· 原理:**
①设置一个初始对照时间戳
*lastTime*
,默认为0
②获取当前时间戳
*currentTime*
与
*lastTime*
比较,假如在同一毫秒内,序列号+1;假如
*currentTime*
>
*lastTime*
,重置序列号为0;假如
*currentTime*
<
*lastTime*
,说明时间倒退应该报错。
③若序列号达到最大值(12位全为1),则会触发等待直到下一毫秒,并将下一毫秒的时间戳作为
*currentTime*
④将
*lastTime*
更新为
*currentTime*
作为对照时间戳
·
**关于如何解决时间回退问题:**
可以使用RingBuffer环形数组,预先生成一批ID,放在数组中。当低于阈值时触发数据填充。填充的时候时间戳为当前的时间戳。
\ No newline at end of file
许旸/springboot/AOP.md
浏览文件 @
17e2da46
...
...
@@ -32,9 +32,16 @@
⑥环绕增强,相当于MethodInterceptor
`@Around("Pointcut()")`
```
@Around("Pointcut()")
public Object Around(ProceedingJoinPoint pjp) throws Throwable {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); //获取http请求数据
Object object = pjp.proceed();
log.info("Request IP>>>"+request.getRemoteAddr()+"#######Response result>>>" +object);
return object;
}
```
执行顺序:
**@Around**
===>
**@Before**
===>
**方法调用**
===>
**@Around**
===>
**@After**
===>
**@AfterReturning**
...
...
许旸/springboot/JPA.md
浏览文件 @
17e2da46
...
...
@@ -2,6 +2,8 @@
Springboot整合JPA
#### 使用实例
实体类
```
...
...
@@ -25,10 +27,32 @@ DAO层使用接口继承JpaRepository
public interface UserRepository extends JpaRepository<Person, Long> { }
```
## 使用jpa的 CrudRepository 基本查询
使用jpa的 CrudRepository 基本查询
使用jpa的 PagingAndSortingRepository 分页查询和排序
使用jpa的 Repository 自定义声明式查询方法
使用jpa的 JpaRepository 使用hql、jpql或sql查询,@Query等注解

#### 关于save方法:
###### 当传入的时候不带自增主键时
无论每次传入的数据是否一样,都会当做一条新的数据插入
即只有一条insert语句,即直接插入一条
id为数据库中最后一条ID+1
##
使用jpa的 PagingAndSortingRepository 分页查询和排序
##
#### 当传入的时候带自增主键时
## 使用jpa的 Repository 自定义声明式查询方法
若数据不存在或者主键不存在,则先select再insert
## 使用jpa的 JpaRepository 使用hql、jpql或sql查询,@Query等注解
\ No newline at end of file
若此主键有数据存在,则先select再update
\ No newline at end of file
许旸/springboot/upload/image-20200426111508494.png
0 → 100644
浏览文件 @
17e2da46
55.3 KB
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论