公司study three"/>
公司study three
ctrl+win+d:新建桌面
ctrl+win +箭头 切换桌面
WIN + CTRL + F4 删除桌面
stream
- 根据某个字段去重
List<BpmBoAttribute> boAttributes = newMainBoEntityDTO.getBoAttributeList().stream().filter(distinctByKey(BpmBoAttribute::getFieldName)).collect(Collectors.toList());newMainBoEntityDTO.setBoAttributeList(boAttributes);public static <T> java.util.function.Predicate<T> distinctByKey(java.util.function.Function<? super T, Object> keyExtractor) {Set<Object> seen = new HashSet<>();return t -> seen.add(keyExtractor.apply(t));}
- filter多条件过滤
List<String> agentUserIds =infos.stream().filter(info -> {Date startDate = info.getStartTime();Date endDate = info.getEndTime();if (hasValid(startDate, endDate) && delegateUser.equals(info.getUserId())) {return true;//true才会返回当前数据,不然是不符合规则,被过滤}return false;}).map(CustDelegateInfo::getDelegateUser).collect(Collectors.toList());
- filter过滤,记得加上返回值,否则会被忽略,过滤条件无效
List<IdentityInfoDTO> collect = idInfos.stream().filter(a -> !a.getIdentityId().equals(task.getAssignee())).collect(Collectors.toList());//过滤掉自己
- foreach遍历
instFormModifytracesList.stream().forEach(s->{ s.setModifyUser(sysUserTemplate.getNameById(s.getModifyUser()));});
- 拼接
String collect2 = peopleList.stream().map(People::getName).collect(Collectors.joining(","));
- list转成 map<string,实体>
Map<String, Sample> sampleCodeMap = list.stream().collect(Collectors.toMap(Sample::getSampleCode, sample -> sample));
- list去重
List<String> collect = departmentList.stream().map(TaskDepartment::getDepartmentId).collect(Collectors.toList());List<String> departmentIds = new ArrayList<String>(new TreeSet<String>(collect));
- list根据某个字段去重
//根据值班日期去重,一天只需要获取一条数据List<SiteScheduling> siteSchedulings = schedulingList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparatorparing(SiteScheduling::getOnDutyDate))), ArrayList::new));
mybatis-plus+stream+lambda
- mybatisplus的select语句
QueryWrapper<InstCaseInfo> caseQueryWrapper = new QueryWrapper<>();caseQueryWrapper.eq("inst_id", businessViewBatch.getInstId());caseQueryWrapper.select("zxjdzt", "gczjze", "gcfw", "gcssqymj");List<Map<String, Object>> instCaseInfos = instCaseInfoMapper.selectMaps(caseQueryWrapper);
- mybatisplus查询区间
queryWrapper.between("node_type", 10, 20);
- mybatisplus根据id批量查询数据
List<InstFileInfo> instFileInfos =instFileInfoMapper.selectBatchIds(instBusinessContents.stream().map(InstBusinessContent::getDataId).collect(Collectors.toList()));
- mybatisplus修改
LambdaUpdateWrapper<InstMessageInfo> updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(InstMessageInfo::getInstId,instId)
.eq(InstMessageInfo::getKey,key)
.eq(InstMessageInfo::getStatus,0).set(InstMessageInfo::getStatus,1);
messageMapper.update(null, updateWrapper);
- mybatisplus分页查询
LambdaQueryWrapper<InstMessageInfo> wrapper = new LambdaQueryWrapper<>();wrapper.eq(Func.isNotEmpty(request.getStatus()),InstMessageInfo::getStatus,request.getStatus()).eq(Func.isNotEmpty(request.getUserId()),InstMessageInfo::getReceiver,request.getUserId()).eq(Func.isNotEmpty(request.getMsgType()),InstMessageInfo::getMsgType,request.getMsgType()).like(Func.isNotEmpty(request.getContent()),InstMessageInfo::getContent,request.getContent()).orderByDesc(InstMessageInfo::getCreateTime);Page<InstMessageInfo> instMessageInfoPage = messageMapper.selectPage(page, wrapper);
- mybatisplus的and和or
LambdaQueryWrapper<InstBusinessRelationship> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.and(QueryWrapper -> QueryWrapper.eq(InstBusinessRelationship::getPInstId, request.getInstId()).eq(InstBusinessRelationship::getRInstId, refInstId));queryWrapper.or(QueryWrapper -> QueryWrapper.eq(InstBusinessRelationship::getRInstId, request.getInstId()).eq(InstBusinessRelationship::getPInstId, refInstId));
- 查询时间区间,自定义sql查询条件
queryWrapper.apply(request.getExpirationStartDate() != null, "end_time >= to_timestamp({0},'yyyy-mm-dd')", request.getExpirationStartDate()).apply(request.getExpirationEndDate()!=null,"end_time <= to_timestamp({0},'yyyy-mm-dd')", request.getExpirationEndDate());
- 删除
bpmSolMapAttributeMapper.delete(new LambdaQueryWrapper<BpmSolMapAttribute>().eq(BpmSolMapAttribute::getSolId,bpmSolMapDefine.getSolId()).or().eq(BpmSolMapAttribute::getAttrType,0));
- lambda遍历 存值
if (bpmBoEntityList != null && !bpmBoEntityList.isEmpty()) {bpmBoEntityList.forEach(x -> {BpmBoEntityDTO dto = new BpmBoEntityDTO();BeanUtil.copyProperties(x, dto);dtoList.add(dto);});}
- lambda+stream 遍历
List<BpmSolresContent> bpmSolresContentList=bpmSolresContentMapper.selectList(lambdaQueryWrapper);bpmSolresContentList.stream().forEach(w->{if(Func.isNotEmpty(w.getRoute())){w.setRoute(varParamService.replaceVarString(w.getRoute(),userId,instId, VarParamGroupEnum.INST));}});
集合
- list删除数据
children.removeIf(e->StringUtils.isNotBlank(e.getDataId()));
- map检查键是否存在
boolean exists = map.containsKey("apple"); // 返回值为true
-
map忽略大小写
-
list判断是否有这个值
//创建一个新的map,忽略大小写
Map<String, Object> paramMap
Map<String, Object> datasMap = new CaseInsensitiveMap(paramMap);
dataSourceKeyList.contains(key)
-
map遍历
- foreach遍历方式【JDK8以下推荐写法】
for(Map.Entry<Integer,String> entry:map.entrySet()){System.out.println(entry.getKey());System.out.println(entry.getValue());};
- lambda表达式遍历【JDK8推荐写法,简捷】
map.forEach((key,value)->{System.out.println(key);System.out.println(value);});
-
map的key不区分大小写CaseInsensitiveMap
Map<String, Object> originalData = new CaseInsensitiveMap<>();
- 对象转成map
Map<String, Object> dataMap = MapUtil.toMap(vo);
-
判断list和map是否包含这个值
-
contains方法是用来判断集合中是否包含某个元素的方法
例子:
Connection c=new ArrayList();
c.add(1);
System.out.println(c.contains(1));结果:
ture
代码学习
- 自动补0(如果有小数位的四舍五入)
- 如果所操作的数字小数位数不足 4 位,
.setScale(4)
方法会在不足的末尾补上零。
- 如果所操作的数字小数位数不足 4 位,
例如,假设有一个 BigDecimal 对象 number
,它表示一个数值为 3.14。如果你调用 number.setScale(4)
,它将返回一个新的 BigDecimal 对象,表示 3.1400。这里,.setScale(4)
设置了保留小数点后 4 位,因为原始数值只有 2 位小数,所以补充了两个零。
.setScale(4)
-
实体自动填充实现
-
redis
- 删除缓存(加在调用方法前自动更新)
@CacheEvict
- 增加缓存@Cacheable("SysRegionTrees")
- 自定义sql插入
private List getFormDataForCondition(String tableName, Map<String, Object> conditionMap) {String sql = "SELECT * FROM %s WHERE %s";String condition = "";if (!StrUtil.isBlank(tableName)) {if (conditionMap != null && conditionMap.size() > 0) {for (Map.Entry<String, Object> item : conditionMap.entrySet()) {if (!StrUtil.isBlank(condition)) {condition += " and ";}condition += String.format("%s=%s", item.getKey(), this.getParamsName(item.getKey(), Column.COLUMN_TYPE_VARCHAR));}sql = String.format(sql, tableName, condition);} else {throw new RuntimeException("未定义数据加载条件!");}} else {throw new RuntimeException("未定义数据表名!");}return commonService.query(sql, conditionMap);}
- 构造map函数
public class CustomRenderDataCompute implements RenderDataCompute {private final Map<String, Object> map;public CustomRenderDataCompute(Map<String, Object> dataMap) {this.map=dataMap;}
}
- 格式化字符串占位符
String.format("处理子表[%s-%s]数据保存出错,原因:%s", controlName, tableName, ex.getMessage())
- 注意查看项目中的其他调用,模仿
- 拼接
newDoingUsers += doingUsersStrings[i];
newDoingUsers += ",";
- 枚举
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** 消息类型枚举* @author 梁伟浩* @date 2023/7/10 15:36* @study 星期一*/
public enum MessageTypeEnum {TO_DO("待办业务"),TIME_WARNING("预警业务"),TIME_OUT("超时业务"),NODE_TIME_WARNING("节点预警业务"),NODE_TIME_OUT("节点超时业务"),SUPERVISE("督办业务"),BACK("退回业务"),CORRECTION("补正业务");private String messageType;MessageTypeEnum(String messageType) {this.messageType = messageType;}public String getMessageType() {return messageType;}
}//获取枚举listpublic List<MessageTypeDTO> getMessageTypeList() {List<MessageTypeEnum> messageTypeEnums = Arrays.asList(MessageTypeEnum.values());List<MessageTypeDTO> list = new ArrayList<>();messageTypeEnums.forEach(a-> {MessageTypeDTO messageTypeDTO = new MessageTypeDTO();messageTypeDTO.setName(a.name());messageTypeDTO.setValue(a.getMessageType());list.add(messageTypeDTO);});return list;}
- 三元表达式
sysBoAttr.setFieldComment(options.get("comment") != null? options.get("comment").toString() : null);
- 截取字符串
request.setTemplatePath(":9000/bpm/temp/print/INST00001086/F000112_2023-07-13 10:37:10.docx");String objectName = templatePath.substring(templatePath.indexOf("temp"));输出:temp/print/INST00001086/F000112_2023-07-13 10:37:10.docx
- 获取枚举name
String name = DateCnEnum.DATECN.name();
-
indexOf用法
- indexOf这个方法是用于判断一个字符串中是否有某个字符或某个字符串,有的话就返回所在的下标(首次出现的位置)没有的话就返回-1
-
substring:返回指定的子字符串
-
"hamburger".substring(4,8) returns "urge""smiles".substring(1,5) returns "mile"
-
-
String[] split = text.split("[{}]");//截取{}每个值
-
含头不含尾
data.substring(data.indexOf("c"),data.indexOf("f")
- json转成对象
JSONObject rootJSONObject = JSON.parseObject(template);
List<JSONObject> jsonObjectList = JSONArray.parseArray(rootJSONObject.get("widgetList").toString(), JSONObject.class);
- 将list的id分割
String userIds = StringUtils.join(userIdList,",");`
- 复制实体
BeanUtil.copyProperties(x, dto);
selectBatchIds:mybatus-plus批量查询集合
- 判断类型是否为空,是返回信息
Asserts.isEmpty(treeDTO.getNodeType(), "节点类型不能为空!");
-
删除新增修改保存 @PostMapping+@BpmApiLog
-
新增或修改
if (holidayService.insertBpmHolidayWorkhours(holidayWorkhours) > 0) {return R.success("设置工作时间成功");}return R.fail("设置工作时间失败!");}
- 获取当前登录用户id
Long userId = AuthUtil.getUserId(true);
String userId=AuthUtil.getUserId().toString();
- 根据报错信息,找到所在位置,然后查看报错信息原因
- 获取就是response
- 设置保存 就是request
- vo:用于给前端显示信息
- dto:用于service层跟mapper层数据交换
- equals() 会判断大小写区别,equalsIgnoreCase() 不会判断大小写区别
创建视图
作用:
-
数据库视图是一个虚拟表,由一个或多个数据库表中的数据组成。它可以根据特定的需求或查询创建,并呈现一个特定的数据结果集。数据库视图的作用有以下几个方面:
-
简化数据访问:数据库视图可以隐藏底层表的复杂结构,提供一个简化的数据访问接口。用户可以通过查询视图来获取需要的数据,而无需了解底层表的具体结构和关系。
-
数据安全性:数据库视图可以限制用户对底层表的访问权限。通过只向用户暴露特定的列或行数据,视图可以提供更严格的数据安全性,确保敏感数据得到保护。
-
数据一致性:数据库视图可以将多个表中的数据组合成逻辑上相关的数据,确保数据的一致性。通过对底层表进行联接和过滤操作,视图可以呈现出一个逻辑上衔接的数据结果集。
-
简化数据操作:数据库视图可以对底层表进行简化的增删改操作。用户可以通过对视图进行相应操作,从而影响底层表的数据,而无需直接操作底层表。
-
总之,数据库视图提供了一种灵活的数据访问和管理机制,可以简化数据库操作,提高数据安全性和一致性。它在复杂的数据模型中起到了重要的作用,提供了对数据的抽象和封装。
- 人大金仓视图
SELECT zwyth_sys.id,zwyth_sys.user_nameFROM dblink('host=10.0.5.133 port=54321 user=zwyth_sys password=zwyth_sys dbname=zwyth_sys'::text, 'select id,user_name from sys_user'::text) zwyth_sys(id numeric, user_name varchar);
- pg视图
sql
- sql条件插入
-
在 `INSERT` 语句中加上条件语句可以使用 `INSERT INTO... SELECT` 语法,即先使用 `SELECT` 语句检查符合条件的记录是否存在,如果存在则执行 `INSERT` 操作。
insert into sf_lwhcs(id,rel_id,inst_id)
select '111','22','33' from
(select '111','22','33') T where
(select count(*) from sf_lwhcs where id='111')=0
- sql参数封装
private HashMap<String, String[]> childrenFormMap = new HashMap<String, String[]>() {{put("SS_JXZT", new String[]{"F000011", "F000084"});put("SS_JXND", new String[]{"F000011", "F000084"});put("SS_GCJD", new String[]{"F000040", "F000029"});put("SS_BA", new String[]{"F000078", "F000035", "F000036", "F000033"});}};private HashMap<String, String[]> formInsertMap = new HashMap<String, String[]>() {{put("F000011", new String[]{"insert into SS_JX_GCJXMBXX(id,inst_id,nd,sbcs,gcdm,gcmc) values(#{id},#{instid},#{first},#{sencond},#{gcdm},#{gcmc});", "SS_SB_GCJBXX", "GC"});put("F000084", new String[]{"insert into SS_JX_GCTZJEXX(id,inst_id,nd,sbcs,gcdm,gcmc) values(#{id},#{instid},#{first},#{sencond},#{gcdm},#{gcmc});", "SS_SB_GCJBXX", "GC"});put("F000040", new String[]{"insert into SS_SS_GCTZSSB(id,inst_id,jdq,gcdm,gcmc) values(#{id},#{instid},#{first+sencond},#{gcdm},#{gcmc});", "SS_SB_GCJBXX", "GC"});put("F000029", new String[]{"insert into SS_SS_GCJXMBSSB(id,inst_id,jdq,gcdm,gcmc) values(#{id},#{instid},#{first+sencond},#{gcdm},#{gcmc});", "SS_SB_GCJBXX", "GC"});put("F000078", new String[]{"insert into SS_BA_GCJXMBXXZB(id,inst_id,nd,gcdm,gcmc) values(#{id},#{instid},#{first},#{gcdm},#{gcmc});", "SS_SB_GCJBXX", "GC"});put("F000033", new String[]{"insert into SS_BA_STBHXFGCTZSSJHBZB(id,inst_id,nd,gcdm,gcmc) values(#{id},#{instid},#{first},#{gcdm},#{gcmc});", "SS_SB_GCJBXX", "GC"});put("F000035", new String[]{"insert into SS_BA_STBHXFDYJXMBXXZB(id,inst_id,nd,gcdm,gcmc,stbhxfdydm,stbhxfdymc) values(#{id},#{instid},#{first},#{gcdm},#{gcmc},#{stbhxfdydm},#{stbhxfdymc});", "SS_SB_STBHXFDYJBXX", "DY"});put("F000036", new String[]{"insert into SS_BA_ZXMJXMBXXZB(id,inst_id,nd,gcdm,gcmc,stbhxfdydm,stbhxfdymc,zxmdm,zxmmc) values(#{id},#{instid},#{first},#{gcdm},#{gcmc},#{stbhxfdydm},#{stbhxfdymc},#{zxmdm},#{zxmmc});", "SS_SB_ZXMJBXX", "ZXM"});}};private void insertInitData(String instId, String dataId, String formId, String first, String sencond, String parentDataId) {if (formInsertMap.containsKey(formId)) {String[] arr = formInsertMap.get(formId);Map<String, Object> params = new HashMap<>();params.put("id", dataId);params.put("instid", instId);params.put("first", first);params.put("sencond", sencond);params.put("first+sencond", first + sencond);params.put("dataId", parentDataId);List<Map<String, Object>> jbxxMap = null;switch (arr[2]) {case "GC":jbxxMap = commonService.query(String.format("select * from %s where inst_id=#{instid}", arr[1]), params);break;case "DY":jbxxMap = commonService.query(String.format("select * from %s where inst_id=#{instid} and id=#{dataId}", arr[1]), params);params.put("stbhxfdydm", jbxxMap.get(0).get("stbhxfdydm"));params.put("stbhxfdymc", jbxxMap.get(0).get("stbhxfdymc"));break;case "ZXM":jbxxMap = commonService.query(String.format("select * from %s where inst_id=#{instid} and id=#{dataId}", arr[1]), params);params.put("stbhxfdydm", jbxxMap.get(0).get("stbhxfdydm"));params.put("stbhxfdymc", jbxxMap.get(0).get("stbhxfdymc"));params.put("zxmdm", jbxxMap.get(0).get("zxmdm"));params.put("zxmmc", jbxxMap.get(0).get("zxmmc"));break;}params.put("gcdm", jbxxMap.get(0).get("gcdm"));params.put("gcmc", jbxxMap.get(0).get("gcmc"));commonService.execute(arr[0], params);}}
- sql封装查询,防止sql注入
String sql = "select * from %s where rel_id=#{rel_id}";Map<String, Object> params = new HashMap<>();params.put("rel_id", ssShb.getId());params.put("id", ssShb.getId());List<Map<String, Object>> gcList = commonService.query(String.format("select * from %s where id=#{id}", "ss_shb"), params);List<Map<String, Object>> dyList = commonService.query(String.format(sql, "ss_shb_stbhxfdyshb"), params);List<Map<String, Object>> zxmList = commonService.query(String.format(sql, "ss_shb_zxmshb"), params);rowData.put("shb_id", ssShb.getId());rowData.put("inst_id", instId);rowData.put("id", sencondDataId);rowData.put("rel_id", null);rowData.put("cjr_id", userId);rowData.put("cj_sj", new Timestamp(DateUtil.now().getTime()));String fields = "id,inst_id,cjr_id,cj_sj,gcmc,gcdm,shfksjblx,zjjg,shjg,sjbb,sfsc,wtjjy,shyj,cj,shb_id";String values = "#{id},#{inst_id},#{cjr_id},#{cj_sj},#{gcmc},#{gcdm},#{shfksjblx},#{zjjg},#{shjg},#{sjbb},#{sfsc},#{wtjjy},#{shyj},#{cj},#{shb_id}";rowData.put("cj", "1");if (rowData.containsKey("stbhxfdydm")) {fields += ",stbhxfdydm,stbhxfdymc";values += ",#{stbhxfdydm},#{stbhxfdymc}";rowData.put("cj", "2");}if (rowData.containsKey("zxmdm")) {fields += ",zxmdm,zxmmc";values += ",#{zxmdm},#{zxmmc}";rowData.put("cj", "3");}String sql = String.format("insert into %s(%s) values(%s)", xgsmTable, fields, values);commonService.execute(sql, rowData);
- sql优化
select user_id,role_id from sys_user_role where user_id in ( SELECT user_id FROM sys_user_org WHERE org_id = (SELECT org_id FROM sys_user_org WHERE user_id = '1712413856360525826'))
-- 嵌套子查询
SELECT sys_user_role.user_id
FROM sys_user_role
INNER JOIN sys_user_org ON sys_user_role.user_id = sys_user_org.user_id
WHERE sys_user_role.role_id = '1712409158517772289'
AND sys_user_org_id = (SELECT org_id FROM sys_user_org WHERE user_id = '1712413558145511425')-- 查询每个字段的总和
select sum(zxmsflx) zxmsflx,sum(zxmsfkg) zxmsfkg,sum(zxmsfjg) zxmsfjg,sum(zxmsfystg) zxmsfystg from SS_SS_ZXMSSJZQKB where inst_id = '2a4dad27-b098-424b-addf-ed2c7528c02e'
-- 字段为不同值转换总和
SELECT SUM(CASE WHEN zxmsflx = '是' THEN 1 ELSE 0 END) AS zxmsflx,SUM(CASE WHEN zxmsfkg = '是' THEN 1 ELSE 0 END) AS zxmsfkg,SUM(CASE WHEN zxmsfjg = '是' THEN 1 ELSE 0 END) AS zxmsfjg,SUM(CASE WHEN zxmsfystg = '是' THEN 1 ELSE 0 END) AS zxmsfystg
FROM SS_SS_ZXMSSJZQKB
WHERE inst_id = '2a4dad27-b098-424b-addf-ed2c7528c02e'--查询字符转数字总和 SELECT SUM(CAST(sjzycz AS DECIMAL)) AS sjzycz,SUM(CAST(sjdfcz AS DECIMAL)) AS sjdfcz,SUM(CAST(sjshzb AS DECIMAL)) AS sjshzb,SUM(CAST(zjsjtzze AS DECIMAL)) AS zjsjtzze
FROM SS_YS_ZXMSSQK
WHERE inst_id = '61a0cd09-19d6-48c7-becc-f62a121dded3';
- sql的foreach查询
<if test="treeIdList != null and treeIdList.size() > 0">AND bfi.group_id IN<foreach collection="treeIdList" item="treeId" open="(" close=")" separator=",">#{treeId}</foreach></if>
-
mapper实体不需要加注解@parm
-
parameterType:参数类型
-
根据角色id递归查询父级角色sql
"WITH RECURSIVE dict AS ( SELECT * FROM sys_role WHERE ID IN (%s) " +"UNION ALL SELECT sys_role.* FROM sys_role, dict WHERE sys_role.ID = dict.parent_id ) SELECT\n" +" distinct * \n" +"FROM\n" +"\tdict where is_deleted = 0 "
- 多表子表查询sql
SELECT bfi.form_name AS formOrNode,ici.node_name AS formOrNode,rule_log.rule_reply,rule_log.rule_event,rule_log.trigger_content,rule_log.create_user,rule_log.create_time FROM(SELECT id,inst_id,rule_id,rule_reply,rule_event,trigger_content ,node_id,NULL AS form_key,create_user,create_time FROM inst_case_rule WHERE 1=1UNIONSELECT id,inst_id,rule_id,rule_reply,rule_event,trigger_content ,NULL AS node_id,form_key,create_user,create_time FROM inst_form_rule WHERE 1=1)rule_logLEFT JOIN inst_casenode_info ici ON ici.inst_id = rule_log.inst_id and ici.node_id = rule_log.node_idLEFT JOIN bpm_form_info bfi ON bfi.form_key = rule_log.form_keyORDER BY rule_log.create_time DESC
- 自定义拼装sql查询数据库
@Select("<script> " +"SELECT inst_id FROM ${tableName}" +"<where>\n" +"${field} = #{controlNameValue}"+"<if test=\"soldIdList!=null\">\n" +"and sol_id in " +"<foreach item='solId' collection='soldIdList' open='(' separator=',' close=')'>" +"#{solId}" +"</foreach>" +"</if>\n" +"</where>\n" +"</script>")List<String> selectInstId(@Param("tableName") String tableName,@Param("field") String field,@Param("soldIdList") List<String> soldIdList,@Param("controlNameValue") String controlNameValue);
- 在mapper接口写sql
/*** 表单数据源模版定义* @author 梁伟浩* @date 2023/8/16 9:10* @study 星期三*/
public interface BpmFormdsTemplateMapper extends BaseMapper<BpmFormdsTemplate> {@Select("select ifnull(max(sindex),0) from bpm_formds_template")int getSindex();
}
- sql拼接
StringBuilder sql = new StringBuilder();sql.append("SELECT ").append(sqlDatasourceVO.getFieldnames()).append(" FROM ").append(sqlDatasourceVO.getTablenames()).append(" WHERE 1=1 ");
-
查询,需要定义返回类型resultMap=“BaseResultMap”
-
多表查询sql
select inst_casenode_cache.* from inst_casenode_cache,inst_business_info where
inst_casenode_cache.inst_id=inst_business_info.inst_id and
is_done=0 and doing_user='1123598821738675201' and sol_id='AS000027' and inst_business_info.is_delete=0
注解
- @Validated:为了在实体中使用对应的注解对参数进行校验
@Null(message = "无需上传id!程序会根据年份入参自适应修改!")
循环
- 多重判断
List<Map<String,Object>> data = commonService.query(sql,params);if(data!=null && data.size()>0 && data.get(0).containsKey("region_code") && data.get(0).get("region_code")!=null){return data.get(0).get("region_code").toString();}
- 多重判断
if (!item.containsKey("children")) {if (item.containsKey("datatype") && "date".equals(item.get("datatype"))) {headerRow.add(label + "|" + prop + "|" + "date");} else {headerRow.add(label + "|" + prop);}} else {headerRow.add(label);}
-
if只进一个就写成if else只需要进一次就行
-
三元表达式
column.setIsNull((attribute.getIsNullable() == null || attribute.getIsNullable() == 1)? true : false);
- 遍历数组,递归找到子目录id
private String getChildrenId(String[] split, String pathId, List<InstBusinessContent> businessContents, int i) {String s = split[i];String id = null;for (InstBusinessContent businessContent : businessContents) {if (businessContent.getNodeName().equals(s)&& (pathId == null || businessContent.getParentId().equals(pathId))) {pathId = businessContent.getId();i++;if (i < split.length) {id = getChildrenId(split, pathId, businessContents, i);}}}//判断层数与数组是否一致,不一致证明路径不存在返回nullif (split.length == i) {return pathId;} else {return id;}}
- 判断对象类型instanceof
Object tbDate = datasMap.get(s);
tbDate instanceof List
递归
- 递归行政区域
public List<SysRegionTreeResponse> getTripleCascade(String type, String firstLevelArr, String secondLevelArr) {//查询行政区的所有数据List<SysRegionVo> sysRegions = null;sysRegions = sysTemplate.getSysRegionTrees();//根据类型返回层级数据(1级,2级,3级)String[] typeNum = type.split("/");int num = typeNum.length;//返回省级if (1 == num) {sysRegions = sysRegions.stream().filter(region -> region.getCode().length() == 2).collect(Collectors.toList());//返回省级市级} else if (2 == num) {sysRegions = sysRegions.stream().filter(region -> region.getCode().length() != 6).collect(Collectors.toList());}//返回前端需要的格式value,labelList<SysRegionTreeResponse> regionTreeResponses = new ArrayList<>();sysRegions.forEach(a -> {SysRegionTreeResponse treeResponse = new SysRegionTreeResponse();treeResponse.setValue(a.getCode());treeResponse.setLabel(a.getRegionName());treeResponse.setParentCode(a.getParentCode());treeResponse.setProvinceName(a.getProvinceName());treeResponse.setCityName(a.getCityName());regionTreeResponses.add(treeResponse);});//构建树List<SysRegionTreeResponse> sysRegionVoList = ListTreeUtil.build(regionTreeResponses, "value", "parentCode", "00");//过滤一级,二级数据if (StringUtils.isNotBlank(firstLevelArr)) {List<String> codes = Arrays.asList(firstLevelArr.split(","));sysRegionVoList = this.filterByCodeAndParentCode(sysRegionVoList, codes, "00");System.out.println(sysRegionVoList);if (StringUtils.isNotBlank(secondLevelArr)) {List<String> secondCodes = Arrays.asList(secondLevelArr.split(","));sysRegionVoList = this.filterSecondCode(sysRegionVoList, secondCodes);}}//长度不够六位的在后面补0this.padCode(sysRegionVoList);return sysRegionVoList;}//递归过滤省级List<SysRegionTreeResponse> filterByCodeAndParentCode(List<SysRegionTreeResponse> regionList, List<String> codes, String parentId) {List<SysRegionTreeResponse> filteredList = new ArrayList<>();for (SysRegionTreeResponse region : regionList) {if (codes.contains(region.getValue()) && region.getParentCode().equals(parentId)) {filteredList.add(region);}List<SysRegionTreeResponse> children = region.getChildren();if (children != null) {List<SysRegionTreeResponse> filteredChildren = filterByCodeAndParentCode(children, codes, region.getValue());if (!filteredChildren.isEmpty()) {region.setChildren(filteredChildren);filteredList.add(region);}}}return filteredList;}//递归过滤市级List<SysRegionTreeResponse> filterSecondCode(List<SysRegionTreeResponse> regionList, List<String> codes) {List<SysRegionTreeResponse> filteredList = new ArrayList<>();for (SysRegionTreeResponse region : regionList) {if (codes.contains(region.getValue())) {filteredList.add(region);}List<SysRegionTreeResponse> children = region.getChildren();if (children != null) {List<SysRegionTreeResponse> filteredChildren = filterSecondCode(children, codes);if (!filteredChildren.isEmpty()) {region.setChildren(filteredChildren);filteredList.add(region);}}}return filteredList;}public void padCode(List<SysRegionTreeResponse> sysRegionVoList) {if (sysRegionVoList == null) {return;}for (SysRegionTreeResponse sysRegionVo : sysRegionVoList) {String code = sysRegionVo.getValue();if (code.length() < 6) {StringBuilder paddedCode = new StringBuilder(code);while (paddedCode.length() < 6) {paddedCode.append("0");}sysRegionVo.setValue(paddedCode.toString());}// 递归调用子区域padCode(sysRegionVo.getChildren());}}
- 递归补正
public void processBOMList(List<BusinessContentVO> contentVOList) {for (BusinessContentVO businessContentVO : contentVOList) {List<BusinessContentVO> children = businessContentVO.getChildren();// 过滤拿到有dataid的文件数据List<BusinessContentVO> collect = new ArrayList<>();if (children != null) {collect = children.stream().filter(response -> StringUtils.isNotBlank(response.getDataId())).collect(Collectors.toList());// 处理目录,把对应的文件放到对应目录中List<BusinessContentVO> correctionOneList = new ArrayList<>();List<BusinessContentVO> correctionTwoList = new ArrayList<>();List<BusinessContentVO> correctionList = new ArrayList<>();for (BusinessContentVO contentVO : collect) {if ("第1次补正".equals(contentVO.getDescription()) && contentVO.getParentId().equals(businessContentVO.getId())) {correctionOneList.add(contentVO);businessContentVO.setCorrectionOneList(correctionOneList);} else if ("第2次补正".equals(contentVO.getDescription()) && contentVO.getParentId().equals(businessContentVO.getId())) {correctionTwoList.add(contentVO);businessContentVO.setCorrectionTwoList(correctionTwoList);} else if (contentVO.getParentId().equals(businessContentVO.getId())) {correctionList.add(contentVO);businessContentVO.setCorrectionList(correctionList);}}// 删除有dataId的数据children.removeIf(e -> StringUtils.isNotBlank(e.getDataId()));// 递归processBOMList(children);}}}
- 递归判断是否为容器,是容器则继续递归获取到widgetList添加到List result中生成字段
if (jsonObjectList != null && jsonObjectList.get(0).get("type").equals("tab")) {Object tabs = jsonObjectList.get(0).get("tabs");jsonObjectList = (List<JSONObject>) tabs;for (JSONObject jsonObject : jsonObjectList) {//每次tab标签进来都是新的widgetListList<JSONObject> widgetList = new ArrayList<>();//每个tab标签的widgetListjsonObjectList = JSONArray.parseArray(jsonObject.get("widgetList").toString(), JSONObject.class);//调用递归函数获取容器的最后一个widgetListjsonObjectList = recursionJsonList(jsonObjectList, widgetList);this.handContainer(bpmBoEntity, relBoDefIdList, jsonObjectList);}}//递归获取容器的widgetListpublic List<JSONObject> recursionJsonList(List<JSONObject> jsonObjectList, List<JSONObject> result) {for (JSONObject jsonObject : jsonObjectList) {String type = jsonObject.getString("type");JSONArray widgetList = jsonObject.getJSONArray("widgetList");if ("tab".equals(type) || "gdFixed".equals(type) || "table".equals(type)) {if (widgetList != null) {// 递归调用recursionJsonList(widgetList.toJavaList(JSONObject.class), result);}else {//是容器但是没有widgetList,直接生成字段result.add(jsonObject);}} else {result.add(jsonObject);}}return result;}
- 递归拼接目录名称
//递归获取文件名称public List<StringBuilder> getFileName(List<BusinessContentVO> contentVOList, StringBuilder sb) {List<StringBuilder> fileNames = new ArrayList<>();for (BusinessContentVO contentVO : contentVOList) {StringBuilder newSb = new StringBuilder(sb); // 创建新的 StringBuilder 对象newSb.append(contentVO.getNodeName() + "/");List<BusinessContentVO> childrenList = contentVO.getChildren();if (childrenList != null) {fileNames.addAll(getFileName(childrenList, newSb)); // 递归调用时使用新的 StringBuilder 对象} else {fileNames.add(newSb); // 将新的 StringBuilder 对象添加到结果列表}}return fileNames;}
- 遍历数组,递归找到子目录id
private String getChildrenId(String[] split, String pathId, List<InstBusinessContent> businessContents, int i) {String s = split[i];String id = null;for (InstBusinessContent businessContent : businessContents) {if (businessContent.getNodeName().equals(s)&& (pathId == null || businessContent.getParentId().equals(pathId))) {pathId = businessContent.getId();i++;if (i < split.length) {id = getChildrenId(split, pathId, businessContents, i);}}}//判断层数与数组是否一致,不一致证明路径不存在返回nullif (split.length == i) {return pathId;} else {return id;}}
- 递归找出对应数据,插入数据
void updateParentId(List<BpmSolResContentDTO> solresContentList,String parentId,String resId){for (BpmSolResContentDTO bpmSolresContent : solresContentList) {Long id = IdUtil.getId();BpmSolresContent solresContent = new BpmSolresContent();bpmSolresContent.setId(id+"");bpmSolresContent.setResId(resId);bpmSolresContent.setParentId(parentId);BeanUtil.copyProperties(bpmSolresContent,solresContent);// 新增数据bpmSolresContentMapper.insert(solresContent);// 递归List<BpmSolResContentDTO> children = bpmSolresContent.getChildren();if(Func.isNotEmpty(children)){updateParentId(children,id+"",resId);}}}
- break用于完全结束一个循环,跳出循环体,执行循环之后的代码
- continue语句用于终止本次循环,接着开始下一次循环。
截串
- 判断字符串s首字母 是否为指定 字符
s.startsWith("@")
- 截取字符串s指定下标以后的字符串
s.substring(1)
实体
- 实体属性赋值
LogInstance logInstance = BeanUtil.toBean(source, LogInstance.class);
io流
-
Java 创建目录./是什么意思
-
流读写
-
将流写到文件中
MultipartFile fileInputStream is = file.getInputStream();ZipInputStream zipInputStream = new ZipInputStream(is, Charset.forName("UTF-8"));File jsonFile = new File("./pre/" + zipEntryNameStr);this.writeFile(jsonFile.getAbsolutePath(), zipInputStream);/*** @描述 将流写到文件中* @作者 吕嘉伟* @日期 2023/3/30 17:49*/public void writeFile(String filePath, ZipInputStream zipInputStream) {try (OutputStream outputStream = new FileOutputStream(filePath)) {byte[] bytes = new byte[4096];int len;while ((len = zipInputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, len);}} catch (IOException ex) {System.out.println("解压文件时,写出到文件出错");}}
- 重启流会关闭(提前关闭流)
- finally关闭流
finally {try {if (outputStream != null) {outputStream.close();}} catch (IOException ex) {throw new RuntimeException(ex);}try {if (inputStream != null) {inputStream.close();}} catch (IOException ex) {throw new RuntimeException(ex);}}
多线程
- 在方法上加上@Async注解,然后去启动类加上@EnableAsync启动注解开启异步
- @Async失效的原因
- 1、注解@Async的方法不是public方法
2、注解@Async的返回值只能为void或者Future
3、注解@Async方法使用static修饰也会失效
4、spring无法扫描到异步类,没加注解@Async 或 @EnableAsync注解
5、调用方与被调方不能在同一个类
- 1、注解@Async的方法不是public方法
- 测试异步是否成功,成功了就直接走到 保存成功,不会进入休眠,最后才进入对应休眠的方法
- 异步处理线程
- 开启异步后无论异步 方法是否执行成功 ,都会 直接走到保存成功,互不影响
// 异步线程处理数据源xml解析ExecutorService es = Executors.newFixedThreadPool(1);es.submit(new Callable<BpmFormInfo>() {@Overridepublic BpmFormInfo call() {formDatasourceService.updateFormXmlJson(bpmFormInfo.getFormId());return null;}});es.shutdown();
- 异步 开启了新线程所以 获取不到当前的登录人的id,需要获取传值过来
apifox调试工具
-
参数json格式 (@Validated @RequestBody),post请求默认json格式
-
get请求拼接
-
form-data参数格式 (不能加校验注解 @Validated @RequestBody)
-
接口调试(post:form-data),加@RequestBody就是json格式(@RequestBody FormDataRequest request)
-
上传附件
方法工具类
- 将旧数据转map
Map<String, BpmBoAttribute> baseMap = convertToMap(oldAttributeList);
private Map<String, BpmBoAttribute> convertToMap(List<BpmBoAttribute> attrs) {Map<String, BpmBoAttribute> maps = new HashMap<>();for (BpmBoAttribute attr : attrs) {maps.put(attr.getFieldName().toLowerCase(), attr);}return maps;}
- 比较时间
/*** 是否有效** @param startDate 开始日期* @param endDate 结束日期* @return 是否有效*/
private boolean hasValid(Date startDate, Date endDate) {Date curDate = new Date();boolean status = curDate.after(startDate) && curDate.before(endDate);return status;
}
实体参数
- get请求不能使用@RequestBody获取参数,post才使用@RequestBody传参,get传参有长度限制
- 实体继承会和当前 实体展示在 同一列表
类型转换
- list树结构赋值给另一个实体
List<BusinessContentDTO> newlist= BeanUtil.copyToList(contentVOList,BusinessContentDTO.class);
- map转实体
// 将Map对象转换为JSON字符串String jsonString = JSONObject.toJSONString(map);// 使用FastJSON的JSONObject类创建一个新的JSON对象JSONObject jsonObject = JSONObject.parseObject(jsonString);// 将JSON对象转换为SsRwb对象SsRwb ssRwb = jsonObject.toJavaObject(SsRwb.class);
- list转json
String jsonStr = JSONUtil.toJsonStr(formRuleList);
- object转map
public Map<String,Object> obj2Map(Object obj) throws Exception{Map<String,Object> map=new HashMap<>();BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor property : propertyDescriptors) {String key = property.getName();if (keypareToIgnoreCase("class") == 0) {continue;}Method getter = property.getReadMethod();Object value = getter!=null ? getter.invoke(obj) : null;map.put(key, value);}return map;}
- java把string转成JSON数组
[{"fileId":"1686222279572836354","fileName":"梁伟浩测试上传附件.jpg","extension":"jpg","filePath":"bpm/from-file/INST00001837/1135901806031900672.jpg","fileSize":"18412"},{"fileId":"1686222298426232833","fileName":"小悟空.png","extension":"png","filePath":"bpm/from-file/INST00001837/1135901824725913600.png","fileSize":"22254"}]
JSONArray jsonArray = new JSONArray(value);for (int i = 0; i < jsonArray.size(); i++) {JSONObject jsonObject = jsonArray.getJSONObject(i);//获取checkbox的值与是否勾选标识String checkBoxValue = jsonObject.getStr("value");String ifCheckBox = jsonObject.getStr("checked");boolean aBoolean = Boolean.parseBoolean(ifCheckBox);checkColorMap.put(checkBoxValue, aBoolean);}
- list
HashMap<String, Object> map = (HashMap) oldFormDatum;
事务
- 事务问题,在另一个方法 调用 其他 方法插入数据 ,两个方法 都加了事务注解 ,会失效
- 在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚
响应
- 解决导response出中文乱码问题
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
- 正常
- 注意查看项目中的其他调用,模仿
异常
- 数据库连接超时(重启服务)
- 注意查看异常抛出的上一层
try {bpmBoEntity = businessObjectService.save(bpmBoEntityRequest);
}catch (Exception e){throw new BusinessException(String.format("不能创建已存在的数据表[%s]", request.getTableName()));
}
- try出现问题直接进catch没返回所以前端 没收到
try {String docxUrl = formService.print(request);return R.data(docxUrl);} catch (Exception e) {LOGGER.error(e.getMessage(), e);return R.fail(e.getMessage());}
- 输出流后,try catch 最后关闭流
public void print(@RequestBody FormPrintRequest request, HttpServletResponse response) {Asserts.isEmpty(request.getTemplatePath(), "模板路径[templatePath]不能为空");Asserts.isEmpty(request.getFormKey(), "表单标识[formKey]不能为空");Asserts.isEmpty(request.getInstId(), "实例ID[instId]不能为空");OutputStream outputStream = null;try {String fileName = request.getFileName();if (StringUtil.isBlank(fileName)) {fileName = String.valueOf(System.currentTimeMillis());}fileName = fileName +"."+ FileUtil.getSuffix(request.getTemplatePath());response.reset();response.setHeader("Content-Type","application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ";filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));outputStream = response.getOutputStream();formService.print(request, outputStream);outputStream.flush();} catch (Exception e) {LOGGER.error(e.getMessage(), e);response.setStatus(SC_BAD_REQUEST);try {if (outputStream != null) {response.setCharacterEncoding("utf-8");response.setHeader("Content-Type","application/json;charset=utf-8");outputStream.write(JSON.toJSONString(R.fail(e.getMessage())).getBytes());}} catch (IOException ex) {throw new RuntimeException(ex);}} finally {try {if (outputStream != null) {outputStream.close();}} catch (IOException ex) {throw new RuntimeException(ex);}}}
- try catch
try {this.setAssignee(taskEntity);// 插入task日志,并将当前任务id设置为parentKey存到工作流参数this.createCaseNodeInfo(taskEntity);} catch (Exception e) {e.printStackTrace();throw new BusinessException("创建任务失败,原因:" + e.getMessage());}
- 条件不符合可以抛出异常,回滚之前执行的事务
throw new BusinessException("is_key关键字段只允许有一个!");
概念
- 能用对象不 用map
- 新建模块扫描不到对应的接口类
- 需要在对应的yaml配置文件加上识别路径
com.guodi.bpm.ssxf.service.impl
- 构造函数注入是一种将依赖作为构造函数的参数传递来注入的方式。它可以确保依赖在对象创建时就被注入,可以更好地保证对象的完整性和一致性。以下是使用构造函数注入的示例代码,构造依赖
public SsxfRuleServiceImpl(IVarParamService iVarParamService){this.iVarParamService = iVarParamService;this.initRegionUserParams();}
-
黑窗口有选择 证明在暂停状态(选中回车退出选择状态)
-
工具类一般都是静态方法
-
调用父类注意是否为public方法,不是 super调用不了
-
注意配置文件的注册nacos是否正确,否则会导致查不到数据(要多从自身找问题)
-
判断Integer类型是否为null使用objects.isnull工具类判断
-
慎用,构造器一定要加条件,不然会操作全表数据
delete(updateWrapper)
-
构造器
-
注意看返回给前端 的数据,是否是自己改还是 前端改
-
xml注意类型判断,如果类型为int就直接错误了,不需要判不等于" "
-
注意查看官方文档
-
注意枚举返回值类型再进行equals比较
ActivityNodeTypeConstant endEvent = ActivityNodeTypeConstant.endEvent;
String name = ActivityNodeTypeConstant.endEvent.name();
-
注意流关闭的位置,最好定义在finally里
-
注意插入值的时候是否为对应实体
-
注意循环符合条件退出,提高效率
-
map不能遍历自己再增加数据,只能使用迭代器
-
map少遍历,直接get获取value即可
-
不要在遍历里面,写sql查询
instCaseNodeInfos.forEach(a->{InstBusinessInfo businessInfo = instBusinessInfoMapper.selectById(a.getInstId());//找出业务实例基本信息,获取到审批方案for (String solId : request.getSolIds()) {if (businessInfo.getSolId().equals(solId)) { //如果委办方案id=当前代办件的方案id,则委托转办DoChangeUserRequest changeUserRequest = new DoChangeUserRequest();changeUserRequest.setChangeUserId(request.getDelegateUser());changeUserRequest.setInstId(a.getInstId());changeUserRequest.setKey(a.getKey());changeUserRequest.setIsDelegate("true");try {iCaseService.doChangeUser(changeUserRequest);//转办} catch (Exception e) {e.printStackTrace();}}}});
-
注意点方法进去看里面的方法
-
equals方法会判断大小写的区别,而equalsIgnoreCase方法不会判断大小写的区别,所以用equalsIgnoreCase方法来比较”abc“和”ABC“时,返回的是true。
-
注意点击 方法 查看报错,报错上下代码 都要检查
-
注意 逻辑删除
-
加多一个条件即可不必循环遍历获取指定值
-
筛选器
bpmSolMapAttributes.stream().filter();
-
updatebyid更改实体
-
debug时间过长会导致锁表
-
long类型返回到前端可能会导致精度 丢失,id不一致
-
没加@requestbody的不能用json,只能用form-data
-
stream的Collectors.toList(),加了分组就等于转化成list了,不加 就要Collectors.toList()
-
java回调:回调是一种双向调用模式,什么意思呢,就是说,被调用方在被调用时也会调用对方,这就叫回调。“If you call me, i will call back”
- 所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法
-
if,elseif,else,三者语句只执行一条,谁的语句先为真就执行哪条,后面的条件的语句就不用管了。
-
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求
更多推荐
公司study three
发布评论