2021-9.10---------至今
项目之外所用到的技术:
操作日志记录springboot+Aop自定义注解实现
excel表格导出,word,html,pdf相互转换
文件上传、文件删除
jwt+拦截器实现单点登录
4.6号
finalshell(服务器)
启动项目命令 ======== java -jar 项目名.jar
显示当前所有的Java进程===== ps -ef|grep java
windows下cmd查看所有端口======netstat –ano
windows下cmd关闭当前进程====== taskkill /PID 14104 /F
linux下查看某个端口的状态 netstat -anp | grep 端口号
linux下终止某个端口 kill -9 247223
进入mysql命令:mysql -u root -p
进入MySQL密码:Zsft@123
异常统计:
1.空指针异常的出现,基本上不能怪别人,只能怪自己的编码形式有问题
2.查询的对象有空值时,要进行判断if(参数!=null){}
3.String index out of range: -1 (下标越界) 出现此类错误,说明substring语句出错了,这里是由于数据库里面多了一个null值。
4.MySQL 8.0 Public Key Retrieval is not allowed (数据库密码错误的原因)
5.异常解决:Content type ‘application/json;charset=UTF-8‘ not supported
我这里的原因是因为数据库里面一个字段被加上了@jsonformat注解,导致报错(字段属性)。
6.No constructor found in com.zufengst.intelcom.entity.TabYh matching
实体类无参构造器未写。
idea快捷键
shift+ctrl+r 全局搜索
shift+ctrl +F8 显示所有断点
ctrl+Alt+L 代码自动对齐
4.7号
时间 内容 名字查询模糊查询
列表分页查询
在实体类中定义参数 startTime 和endTime字段,
使用@TabileFileld(exists="false")表示不是数据库中存在的字段。
时间段的模糊查询
<select id="selectListForPage" resultType="com.zufengst.dataplatform.domain.DpLog">
select id,user_id,content_type,create_time
from dp_log
where 1=1
<if test="id!=null and id != ''">
and id like concat('%',#{id},'%')
</if>
<if test="user_id!=null and user_id != ''">
and user_id like concat('%',#{user_id},'%')
</if>
<if test="content_type!=null and content_type != ''">
and content_type like concat('%',#{content_type},'%')
</if>
<!-- <if test="selectType==4">and gmt_modified between #{startTime} and date_add(#{endTime},interval 1 day)</if>-->
<!-- <if test="selectType==10">and gmt_approve between #{startTime} and date_add(#{endTime},interval 1 day)</if>-->
<!-- <if test="selectType==2">and entry_time between #{startTime} and date_add(#{endTime},interval 1 day)</if>-->
<if test=" startTime!=null and startTime!=''">
AND create_time >= CONCAT('','${startTime}',' 00:00:00')
</if>
<if test=" endTime!=null and endTime!=''">
AND create_time <= CONCAT('','${endTime}',' 23:59:59')
</if>
</select>
可以跟全查使用同一个方法 对key值进行判断即可 //根据关键字、时间段、查询(方法中需要传入参数开始时间和结束时间) select zf.id, zf.head, zf.account, zf.position, zf.prereview, zf.qyzt, zf.registrationtime, zf.sjh, zf.dw, zf.email, zf.ssxz, zf.uname ,zd.NAME ,zf.UpdateTime from zf_users zf left join zf_departments zd on zf.DEPARTMENTID=zd.ID where 1=1 <if test="key !=null and key !=''" > and concat( IFNULL(ACCOUNT,''),IFNULL(DEPARTMENTID,''),IFNULL(POSITION,''),IFNULL(PREREVIEW,''), IFNULL(QYZT,''),IFNULL(SJH,''),IFNULL(zf.UpdateTime,'')) like concat('%',#{key},'%') </if> <if test=" startTime!=null and startTime!=''"> AND REGISTRATIONTIME >= CONCAT('','${startTime}',' 00:00:00') </if> <if test=" endTime!=null and endTime!=''"> AND REGISTRATIONTIME <= CONCAT('','${endTime}',' 23:59:59') </if> order by zf.UpdateTime desc
4.8号
部署项目
修改本地项目端口 再修改服务器 nginx.conf文件端口号(data文件里面)
先idea 打包jar包 然后再finalshell上面上传jar包 最后就发布jar包
然后在前端文件proxy.js(src中)修改端口号(镇海项目打包发布)
日志excel 导出()
pom.xml依赖
4.11号
idea调试模式,先确定 断点,然后debug运行 ,点击调试器(DeBugger),点击步过(也就是拐弯的那个箭头F8),看是否有值传过来,传过来的值是否正确,进行一步步调试。
如果使用分页查询,使用postman测试获取值为null,那就可能是 mapper.xml层少了一个resultMap=“BaseResultMap”
4.12号
从一张表复制一条数据及内容到另一张表。
select * from 表 like '%/_id'(表示只查包含_id的字段,如要查_sssid,去掉 / 即可)
共享平台项目信息表中,为各环节确定一个是否推送的字段,代码相应更新(开始)
在流程表中添加name1字段,填入环节代号
项目信息表中添加各环节id字段
字段表中添加环节ID记录
4.13号
resolve 解析
4.18号
string id 只是定义字段.
//修改
@Override
public int updateHjid(String projectId, String flowId) {
//service字符串拼接(根据一个表id查出来name1也就是idField 拼接+_id)
String idField=dpFlowMapper.selectName1ByflowId(flowId)+"_id";
String sqlStr="update dp_sp_bind_project_info set " + idField + "= 1 where record_id = '" + projectId+"'";
return spBindProjectInfoMapper.updateHjid(sqlStr);
}
可以通过在mapper层定义SQL语句在xml层使用${sqlStr}来调用
4.19号
获取操作日志通过Springboot+Aop自定义注解实现
日志excel表导出问题 查询的SQL需要写在mapper.xml层 通过resultmap值才不会为null。注解方式写法可能会为null。
now()只有字段是datetime型时才会显示时分秒,数据库字段类型是datetime
实体类中定义的字段类型和数据库并不冲突,比如excel导出时间 可以直接在实体类定义string类型时间,相对应mapper层的jdbcType 也要改成varchar,这样就可以直接导出数据的时间数据。
4.21号
文件上传使用postman测试需要设置key,文件名设置file。
4.21-4.29号
定义一个接收对象的列表集合
List<实体> list = new ArrayList<实体>();
定义实体对象
实体 dpFjxx=new 实体();
定义字符串列表(fld_result)。
List<String> fld_result = new ArrayList<String>();
定义字符串变量(fjstr)
String fjstr;
定义字符串数组(也可以叫字段数组)(fjlist)
String[] fjlist;
定义字段实体
实体类 实体;
判断对象时 要用equals
添加属性时,列表集合要用add(属性.get字段();)
给实体字段赋值时,可以通过定义的实体set字段来赋值,比如:实体.set字段(把要赋的属性放进来)
split可以将列表分割成数组比如:flds = dpRole.getFieldIds().split(",");
linux与windows文件上传时,要判断他们的操作系统是linux 还是windows要不然可能会出现上传失败,或者上传的文件大小为0 打不开的 情况,而且linux的路径格式与windows的不一样。
linux的路径:/data; (直接/data就行,后续可以改路径)
windows的路径: c:/home/....(根据自己情况设置)
具体的代码
try {
// 保存文件相关名
String original1 = file.getOriginalFilename();
//分割后缀名判断类型
String flex = "." + original1.split("\\.")[original1.split("\\.").length - 1];
// String typeName = "普通附件";
//在文件 名中加入时间戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String time = sdf.format(new Date());
String newFileName = RandomUtil.randomString(20) + time;
// String pathstr="C:\\home\\data-platform\\file";
String pathstr=null;
//判断系统是windows 还是linux
String os = System.getProperty("os.name");
if (os != null && os.toLowerCase().startsWith("windows")) {
System.out.println(String.format("当前系统版本是:%s", os));
pathstr= "C:/home/data-platform/file";
} else if (os != null && os.toLowerCase().startsWith("linux")) {//Linux操作系统
System.out.println(String.format("当前系统版本是:%s", os));
pathstr="/data";
} else { //其它操作系统
System.out.println(String.format("当前系统版本是:%s", os));
}
File dest = new File(pathstr +"/"+ newFileName +flex);
FileUtil.touch(dest);
file.transferTo(dest);
//后续发现 其实windows路径可以兼容linux路径,所以统一用linux系统路径就行。
File file = new File(fjpath+"/"+fjid+filex);解释:文件路径下的文件名比如(c:/home/go.pdf),
/就代表 home和文件之间的/。
5月7号
只有集合才可以执行遍历。String创建的只是对象 ,可用List<string>来接受对象,遍历,然后对元素进行判断
动态SQL中resultype 对应所对应的类型 String a 对应 string ,list<a> 对应 a
处理空指针异常 如果 字段类型是 String a 则使用a==null 或a!=null,如果是list则使用list.isEmpty.
数据库中的字段用#{} 代码中临时定义的动态字段要用${}
postman测试请求体@requestbody类型时 需要在Headers 设置Content-type,
application-json,在Body中
{
"参数1":""
,"参数2":""
}
5.19号
newFileNameStr=newFileNameStr.replaceAll(fj," ");字符串替换 ,表示newFileNameStr中fj部分用空格代替。
if (fjstr != null && StringUtils.isNotBlank(fjstr) 有空字符串用,要不会报字符串越界。
6.6号
//代表收集,将数据以集合的方式收集起来并用逗号分割成数组。
collect = Arrays.stream(fileNameStr.split(",")).collect(Collectors.toList());
将收集起来的数据进行过滤筛选,对不等于fj的元素收集起来并使用逗号连接,等于的话就过滤掉。
newFileNameStr = collect.stream().filter(s -> !s.equals(fj)).collect(Collectors.joining(","));
6.8号
//给前端返回失败值,reponse不能定义在方法之外(要在一块儿),else(getWriter() has already been called for this response)
PrintWriter pw=response.getWriter();
pw.write(JSONUtils.toJSONString(-1));
6.15号
要修改前端展示的数据不动数据库数据,可以在查询时进行修改。
git签出是移出这个分支,切换到远程或本地分支(也就是切换提交代码的分支)。
如果不动数据库数据,想要使datetime类型数据返给前端时忽略时分秒,可以在查询的时候将字段进行截取,然后再set赋值。
6.20号
RestTemplate 用于接口调用,里面封装了设置传送请求头、请求体和接收返回值的方法。
6.28号
使用map类型设置返回值时,记得用new实例化一下对象。不然会空指针
7.1号
在使用string做字符串操作时
mapper层sql语句,设置resultType,resultmap就不需要了,否则会出现异常
7.11号
static关键字理解:代表静态,每次只会调用一次,做登录时可判断登录次数,在方法外定义private static int flag=0; 方法内部判断 if(++flag>=3)则锁定账户。
final关键字代表最终的不可变,使用final定义的值为常量,是不可以对其进行操作的。
7.28号
@jsonformat("yyyy")注解 是用在实体类某个字段上面,用于给前端返回自定义格式时间字段。
在使用mybatis时,想要返回指定的查询的字段,可以使用resultmap="map"; 方法用List<Map<String, Object>> result=zfUsersMapper.getlist();来接收, 记得在yml配置中加入
8.3号
角色表、用户表、角色用户表三表联查语句(c.*.代表只查询展示该表数据)
SELECT c.* FROM zf_users as a left join zf_user_role as b on a.ID=b.USERID left join zf_roles as c on b.ROLEID=c.ID WHERE a.ID='10028'
分组查询 ,COUNT(zf_user_role.USERID) as roleCount表示将数据结果返回roleCunt字段并展示
SELECT COUNT(zf_user_role.USERID) as roleCount from zf_roles left join zf_user_role on zf_user_role.ROLEID=zf_roles.ID GROUP BY zf_roles.ID
使用集合字段动态展示每个用户下的角色列表(三表联查)
SELECT c.* FROM zf_users as a left join zf_user_role as b on a.ID=b.USERID left join zf_roles as c on b.ROLEID=c.ID WHERE a.ID='10028'
添加时判断账号重复
修改时判断账号重复
8.4号
今天用了一个JAVA8新特性
场景是要给每个用户下的所有角色信息,用list集合形式返给前端,其中出现了问题就是当用户没有角色权限时,list集合会以null的形式并且占用了一个元素返给前端。这就代表了这个用户有一个空的权限。
筛选空值
这样的话就筛选掉了null值,并且以空集合的方式返给前端。
根据判断某个元素对集合筛选掉这个对象元素整条对象信息(相当于双重for循环去重遍历)
该方法等同于上方(该方法繁琐,但有利于数据库)