开发规范
rest 风格
缩写:REST (不是"rest"这个单词)
外文名:Representational State Transfer,简称REST。
中文名:表现层状态转移。1
URL中只使用名词来定位资源,用HTTP协议里的动词(GET、POST、PUT、DELETE)来实现资源的增删改查操作。
Service CRUD 接口
说明:
- 通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用前缀命名方式区分Mapper层避免混淆,
get
查询单行 select
remove
删除 delte
querypage
分页 selectpage
- 泛型
T
为任意实体对象 - 建议如果存在自定义通用 Service 方法的可能,请创建自己的
IBaseService
继承Mybatis-Plus
提供的基类 - 对象
Wrapper
为 条件构造器
Mapper CRUD 接口
说明:
-
通用 CRUD 封装BaseMapper接口,为
Mybatis-Plus
启动时自动解析实体表关系映射转换为Mybatis
内部对象注入容器 -
泛型
T
为任意实体对象 -
参数
Serializable
为任意类型主键Mybatis-Plus
不推荐使用复合主键约定每一张表都有自己的唯一id
主键 -
对象
Wrapper
为 条件构造器
springboottest
maven与yml 多环境配置
yml 写法
5.2.1约定
-
k: v 表示键值对关系,冒号后面必须有一个空格
-
使用空格的缩进表示层级关系,空格数目不重要,只要是左对齐的一列数据,都是同一个层级的
-
大小写敏感
-
缩进时不允许使用Tab键,只允许使用空格。
-
java中对于驼峰命名法,可用原名或使用-代替驼峰,如java中的lastName属性,在yml中使用lastName或 last-name都可正确映射。
-
yml中注释前面要加#
5.2.2键值关系
普通值(字面量)
k: v:字面量直接写;
字符串默认不用加上单引号或者双绰号;
"": 双引号;转意字符能够起作用
name: "sangeng \n caotang":输出;sangeng 换行 caotang
'':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
name1: sangeng
name2: 'sangeng \n caotang'
name3: "sangeng \n caotang"
age: 15
flag: true
日期
date: 2019/01/01
对象(属性和值)、Map(键值对)
多行写法:
在下一行来写对象的属性和值的关系,注意缩进
student:
name: zhangsan
age: 20
行内写法:
student: {name: zhangsan,age: 20}
数组、list、set
用- 值表示数组中的一个元素
多行写法:
pets:
- dog
- pig
- cat
行内写法:
pets: [dog,pig,cat]
对象数组、对象list、对象set
students:
- name: zhangsan
age: 22
- name: lisi
age: 20
- {name: wangwu,age: 18}
5.2.3 占位符赋值
可以使用 ${key:defaultValue} 的方式来赋值,若key不存在,则会使用defaultValue来赋值。
例如
server:
port: ${myPort:88}
myPort: 80
5.2.4 @@
SpringBoot中读取maven设置值
spring:
profiles:
active: @profile.active@
上面的@属性名@就是读取maven中配置的属性值的语法格式。
配置文件书写技巧
作为程序员在搞配置的时候往往处于一种分久必合合久必分的局面。开始先写一起,后来为了方便维护就拆分。对于多环境开发也是如此,下面给大家说一下如何基于多环境开发做配置独立管理,务必掌握。
准备工作
将所有的配置根据功能对配置文件中的信息进行拆分,并制作成独立的配置文件,命名规则如下
- application-devDB.yml
- application-devRedis.yml
- application-devMVC.yml
使用
使用include属性在激活指定环境的情况下,同时对多个环境进行加载使其生效,多个环境间使用逗号分隔
spring:
profiles:
active: dev
include: devDB,devRedis,devMVC
比较一下,现在相当于加载dev配置时,再加载对应的3组配置,从结构上就很清晰,用了什么,对应的名称是什么
注意
当主环境dev与其他环境有相同属性时,主环境属性生效;其他环境中有相同属性时,最后加载的环境属性生效
改良
但是上面的设置也有一个问题,比如我要切换dev环境为pro时,include也要修改。因为include属性只能使用一次,这就比较麻烦了。SpringBoot从2.4版开始使用group属性替代include属性,降低了配置书写量。简单说就是我先写好,你爱用哪个用哪个。
spring:
profiles:
active: dev
group:
"dev": devDB,devRedis,devMVC
"pro": proDB,proRedis,proMVC
"test": testDB,testRedis,testMVC
现在再来看,如果切换dev到pro,只需要改一下是不是就结束了?完美!
总结
- 多环境开发使用group属性设置配置文件分组,便于线上维护管理
多环境开发控制
多环境开发到这里基本上说完了,最后说一个冲突问题。就是maven和SpringBoot同时设置多环境的话怎么搞。
要想处理这个冲突问题,你要先理清一个关系,究竟谁在多环境开发中其主导地位。也就是说如果现在都设置了多环境,谁的应该是保留下来的,另一个应该遵从相同的设置。
maven是做什么的?项目构建管理的,最终生成代码包的,SpringBoot是干什么的?简化开发的。简化,又不是其主导作用。最终还是要靠maven来管理整个工程,所以SpringBoot应该听maven的。整个确认后下面就好做了。大体思想如下:
- 先在maven环境中设置用什么具体的环境
- 在SpringBoot中读取maven设置的环境即可
maven中设置多环境(使用属性方式区分环境)
<profiles>
<profile>
<id>env_dev</id>
<properties>
<profile.active>dev</profile.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault> <!--默认启动环境-->
</activation>
</profile>
<profile>
<id>env_pro</id>
<properties>
<profile.active>pro</profile.active>
</properties>
</profile>
</profiles>
SpringBoot中读取maven设置值
spring:
profiles:
active: @profile.active@
上面的@属性名@就是读取maven中配置的属性值的语法格式。
总结
- 当Maven与SpringBoot同时对多环境进行控制时,以Mavn为主,SpringBoot使用@..@占位符读取Maven对应的配置属性值
- 基于SpringBoot读取Maven配置属性的前提下,如果在Idea下测试工程时pom.xml每次更新需要手动compile方可生效
async
@Override
@Async
@Transactional(rollbackFor = Exception.class)
public void getZip(List<CertificateVo> certificateVos, Long collegeId, String grade, Integer type, String fileUUID) throws Exception {
List<String> filePaths = new ArrayList<>();
for (CertificateVo certificateVo : certificateVos) {
String certificateType = certificateVo.getCertificateType() == 1 ? "积分版" : "记录版";
String pdfTitle = certificateVo.getUserName() + certificateVo.getNickName() + "(" + certificateType + ")" + ".pdf";
String pdfPath = fileUploadPath + certificateVo.getCollegeName() + "/" + certificateVo.getGrade() + "/" + certificateType + "/" + certificateVo.getClassName() + "/" + certificateVo.getUserName() + "-" + certificateVo.getNickName() + "/" + pdfTitle;
filePaths.add(pdfPath);
}
transactional
hutool
UUID
httpstatus
qrcode
mybatisplus 使用 与 datascope
QueryWrapper
QueryWrapper<Certificate> qw = Wrappers.query();
qw.eq(bo.getCollegeId() != null, "scc.college_id", bo.getCollegeId());
qw.eq(bo.getCertificateType() != null, "scc.certificate_type", bo.getCertificateType());
qw.eq(bo.getGrade() != null, "scc.grade", bo.getGrade());
Map<String, Object> params = bo.getParams();
Object dataScope = params.get("dataScope");
qw.apply(dataScope != null && StrUtil.isNotBlank(dataScope.toString()),
dataScope != null ? dataScope.toString() : null);
实现数据权限控制 以及分页条件查询
@Override
@DataScope(deptAlias = "sccj")
public TableDataInfo<CertificateJobVo> queryPageJobList(CertificateJobQueryBo bo) {
QueryWrapper<CertificateJob> qw = Wrappers.query();
qw.eq(bo.getCollegeId() != null, "sccj.college_id", bo.getCollegeId());
qw.eq(bo.getZipType() != null, "sccj.certificate_type", bo.getZipType());
qw.eq(bo.getGrade() != null, "sccj.grade", bo.getGrade());
qw.eq(bo.getCreatorNickName() != null, "sccj.grade", bo.getCreatorNickName());
Map<String, Object> params = bo.getParams();
Object dataScope = params.get("dataScope");
qw.apply(dataScope != null && StrUtil.isNotBlank(dataScope.toString()),
dataScope != null ? dataScope.toString() : null);
Page<CertificateJobVo> page = PageUtils.buildPage();
List<CertificateJobVo> certificateJobVos = certificateMapper.queryCertificateJobList(page, qw);
page.setRecords(certificateJobVos);
return PageUtils.buildDataInfo(page);
}
List<CertificateJobVo> queryCertificateJobList(
Page<CertificateJobVo> page,
@Param(Constants.WRAPPER) QueryWrapper<CertificateJob> qw);
<select id="queryCertificateJobList" resultType="com.ruoyi.secondClass.vo.CertificateJobVo">
SELECT *
FROM
sc_certificate_job as sccj
left join sys_dept as d on d.dept_id = sccj.dept_id
<where>
${ew.sqlSegment}
</where>
</select>
LambdaQueryWrapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
User user = new User();
user.setName("Jone");
user.setAge(20);
//条件 函数式接口 值
queryWrapper.eq(StringUtils.isNotBlank(user.getName()),User::getName,user.getName());
queryWrapper.ge(user.getAge()!=null,User::getAge,user.getAge());
userMapper.selectList(queryWrapper).forEach(System.out::println);
git
git branch
git checkout
git remote -add 添加远程分支
git push -f master
git checkout -b 分支名
git push origin 分支名:分支名
git branch -a查看所有分支
- feat:提交新功能
- fix:修复了bug
- docs:只修改了文档
- style:调整代码格式,未修改代码逻辑(比如修改空格、格式化、缺少分号等)
- refactor:代码重构,既没修复bug也没有添加新功能
- perf:性能优化,提高性能的代码更改
- test:添加或修改代码测试
- chore:对构建流程或辅助工具和依赖库(如文档生成等)的更改
git rebase(变基) vs git merge(合并)
日志
debug info warn error
快捷键
快捷键 Shift+F6 重新命名 Ctrl+w 选中单词
Comments NOTHING