# oriole **Repository Path**: syhsmile/oriole ## Basic Information - **Project Name**: oriole - **Description**: SpringBoot-JPA - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2020-09-27 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README oriole ==== 介绍 ---- 写代码,过生活。 springboot --> 2.2.5.RELEASE springcloud --> Hoxton.RELEASE 软件架构 ---- 软件架构说明 安装教程 ---- 使用说明 ---- Git各个分支 •master: 主分支,主要用来版本发布。 •develop:日常开发分支,该分支正常保存了开发的最新代码。 •feature:具体的功能开发分支,只与 develop 分支交互。 •release:release 分支可以认为是 master 分支的未测试版。比如说某一期的功能全部开发完成,那么就将 develop 分支合并到 release 分支,测试没有问题并且到了发布日期就合并到 master 分支,进行发布。 •hotfix:线上 bug 修复分支。 首先介绍企业的一般流程,就是版本发布(假设为V3R2)和开发新版本(假设新版本为V3R3)的问题,其实一条时间线同时存在这两个版本,一个是稳定的已发布版本,另一个是正在开发的未来需要发布的版本。那么为什么要开发新版本呢?因为软件是要演进的,要适应变化和需求,一段时间迭代后发布的软件比喻V3R2也会不断暴露出问题,这类问题也需要在新版本中变得可用。因为V3R3的都是新特征新变化 feature: 只与develop交互,因为feature就是新版本开发为了升级和演进需要用的,里面的所有代码只能在发布新版本且经过测试的时候才合进去master,然后在master打tag表明所有新功能开发完毕,一次性合并。同时我们开发一般是不同的人开发不同的功能,因此各自都应该有自己的feature,然后断断续续并进develop所以,保证develop是个新功能持续集成的版本。 hotfix: 这个分支用来修复主线master的BUG,但是要注意的是,在旧版本的BUG,新版本也是存在的,因此develop分支也存在该BUG,具体来说就是V3R2和V3R3都有该BUG,因此,修复的时候必须要提交两个分支master和develo否则,后面需要rebase就麻烦了。 JPA ---- 1. JPA中关联关系中set与list使用 jpa设计的时候用的是set不是没有道理的,主要是利用set的数据不可重复性,用于避免数据的重复,比如新增数据的时候避免数据的重复插入。 问题:因为set查询出的数据是无序的,如果当一的一端对应5条数据,而分页的单页只显示3条数据,当到下一页时,其中的两条数据可能与上一页的3条数据出现随机相同的情况,因此会导致数据显示的缺失和无序。 完美的解决办法:在实体类set属性上加上@orderBy("id asc")属性进行排序,然后在取值的时候使用LinkedHashSet(不可重复且有序)即可 2. JPA懒加载典型的N+1问题 多对一,一对多的映射关系,在加载其关联对象的时候,为了性能考虑,很自然的想到了懒加载。 通常1的这方,通过1条SQL查找得到1个对象,而JPA基于Hibernate,fetch策略默认为select(并非联表查询),由于关联的存在 ,又需要将这个对象关联的集合取出,集合数量是N,则要发出N条SQL,于是本来的1条联表查询SQL可解决的问题变成了N+1条SQL 解决方法:@EntityGraph(attributePaths = {"sysRoles", "sysDept", "sysRoles.sysMenus"}) 3. Oauth2中授权码模式,code只能使用一次 4. Oauth2中tokenStore方法支持很多种令牌的存储方式: (1)InMemoryTokenStore:这个版本的实现是被默认采用的,它可以完美的工作在单服务器上(即访问并发量压力不大的情况下,并且它在失败的时候不会进行备份),大多数的项目都可以使用这个版本的实现来进行尝试, 你可以在开发的时候使用它来进行管理,因为不会被保存到磁盘中,所以更易于调试。 (2)JwtTokenStore:这个版本的全称是 JSON Web Token(JWT),它可以把令牌相关的数据进行编码(因此对于后端服务来说,它不需要进行存储,这将是一个重大优势), 但是它有一个缺点,那就是撤销一个已经授权令牌将会非常困难,所以它通常用来处理一个生命周期较短的令牌以及撤销刷新令牌(refresh_token)。 另外一个缺点就是这个令牌占用的空间会比较大,如果你加入了比较多用户凭证信息。JwtTokenStore 不会保存任何数据,但是它在转换令牌值以及授权信息方面与 DefaultTokenServices 所扮演的角色是一样的。 (3)JdbcTokenStore:这是一个基于JDBC的实现,令牌会被保存进关系型数据库。使用这个实现时,你可以在不同的服务器之间共享令牌信息。 (4)RedisTokenStore:这是一个基于Redis的实现,令牌会被保Redis缓存中。使用这个实现时,你可以在不同的服务器之间共享令牌信息。 5. JWT如何在Spring Cloud微服务系统中在服务相互调时传递: 在Feign中开启了hystrix,hystrix默认采用的是线程池作为隔离策略。 线程隔离有一个难点需要处理,即隔离的线程无法获取当前请求线程的Jwt, 这用ThredLocal类可以去解决,但是比较麻烦,所以我才用的是信号量模式 写一个Feign的拦截器 6. Oauth2普通token必须远程校验,Jwt-token只需要自己验证自己即可 7. 使用非对称密钥(公钥和私钥)来执行签名过程: 第一步:生成JKS Java KeyStore文件:我们首先使用命令行工具keytool生成密钥 - 更具体地说.jks文件: keytool -genkeypair -alias mytest -keyalg RSA -keypass mypass -keystore mytest.jks -storepass mypass 该命令将生成一个名为mytest.jks的文件,其中包含我们的密钥 - 公钥和私钥。 还要确保keypass和storepass是一样的。 第二步:导出公钥:接下来,我们需要从生成的JKS中导出我们的公钥,我们可以使用下面的命令来实现: keytool -list -rfc --keystore mytest.jks | openssl x509 -inform pem -pubkey 8. Oauth2退出踩坑: The URL that triggers log out to occur (default is "/logout"). If CSRF protection is enabled (default), then the request must also be a POST. This means that by default POST "/logout" is required to trigger a log out. If CSRF protection is disabled, then any HTTP method is allowed. 大概意思是说:logout在CSRF开启时只能使用POST请求,在CSRF关闭时,任何请求方式都能被访问。 参与贡献 ----