公司study three

  • idea选中生成方法快捷键ctrl+alt+m
  • idea搜索行数快捷键ctrl+G
  • idea驼峰快捷键: shift+alt+u
  • idea规范编码格式:ctrl + alt + l
  • idea快捷键:ctrl + alt + T
  • idea批量改变字母,选中需要修改的字母shit+f6改成你对应的
  • Ctrl+h 全文搜索替换
  • 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<>(Comparator.comparing(SiteScheduling::getOnDutyDate))), ArrayList::new));

mybatis-plus+stream+lambda

  • mybatisplus多个字段查询检索
     // 多个关键字检索
        if(StringUtil.isNotEmpty(assetsAllocationContract.getKeyword())){
            queryWrapper.and(x -> x.like("name", assetsAllocationContract.getKeyword()).or().like("contract_number", assetsAllocationContract.getKeyword())
                    .or().like("approval_number", assetsAllocationContract.getKeyword()).or().like("MINERAL_NAME", assetsAllocationContract.getKeyword()));
        }
  • mybatisplus用sql查询
      String inSql = String.format("select template_id from %s where id = '%s'" , instBusinessInfo.getContentTable(),instContentParentId);
        LambdaQueryWrapper<DirtreeContent> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.inSql(DirtreeContent::getDirId,inSql);
        DirtreeContent dirtreeContent = dirtreeContentMapper.selectOne(queryWrapper);
  • 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));
                    }
                });

集合

  • 迭代器优化
前:Iterator<IdentityInfoDTO> iteratorItems = selectItems.iterator();
                    while (iteratorItems.hasNext()) {
                        IdentityInfoDTO infoDTO = iteratorItems.next();
                        if (!createUserId.equals(infoDTO.getIdentityId())) {
                            iteratorItems.remove();
                        }
                    }

后:selectItems.removeIf(infoDTO -> !createUserId.equals(infoDTO.getIdentityId()));
  • 改变map的key值,重新put移除掉旧的即可
    // 将 dataLengthStr 键改为 length
            if (column.containsKey("dataLengthStr")) {
                Object dataLengthStr = column.get("dataLengthStr");
                column.put("length", dataLengthStr);
                column.remove("dataLengthStr");
            }
  • 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

代码学习

  • mapper通用查询结果继承
<!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.guodi.bpm.model.entity.BpmBoEntity">
        <result column="ENT_ID" property="entId" jdbcType="VARCHAR"/>
        <result column="TABLE_NAME" property="tableName" jdbcType="VARCHAR"/>
        <result column="TABLE_CNAME" property="tableCName" jdbcType="VARCHAR"/>
        <result column="TABLE_TYPE" property="tableType" jdbcType="NUMERIC"/>
        <result column="DESCRIPTION" property="description" jdbcType="VARCHAR"/>
        <result column="CREATE_USER" property="createUser" jdbcType="VARCHAR"/>
        <result column="UPDATE_USER" property="updateUser" jdbcType="VARCHAR"/>
        <result column="CREATE_TIME" property="createTime" jdbcType="TIMESTAMP"/>
        <result column="UPDATE_TIME" property="updateTime" jdbcType="TIMESTAMP"/>
    </resultMap>

    <resultMap id="BpmBoEntityDTOResultMap" type="com.guodi.bpm.model.dto.BpmBoEntityDTO" extends="BaseResultMap">
        <association property="boAttributeList" javaType="com.guodi.bpm.model.entity.BpmBoAttribute">
            <result column="ATTR_ID" property="attrId" jdbcType="VARCHAR"/>
            <result column="ENT_ID" property="entId" jdbcType="VARCHAR"/>
            <result column="FIELD_NAME" property="fieldName" jdbcType="VARCHAR"/>
            <result column="FIELD_COMMENT" property="fieldComment" jdbcType="VARCHAR"/>
            <result column="FIELD_TYPE" property="fieldType" jdbcType="VARCHAR"/>
            <result column="LENGTH" property="length" jdbcType="NUMERIC"/>
            <result column="DEFAULT_VALUE" property="defaultValue" jdbcType="VARCHAR"/>
            <result column="IS_NULLABLE" property="isNullable" jdbcType="NUMERIC"/>
            <result column="IS_UNIQUE" property="isUnique" jdbcType="NUMERIC"/>
            <result column="DECIMALLEN" property="decimalLen" jdbcType="NUMERIC"/>
            <result column="IS_PRIMARY" property="isPrimary" jdbcType="NUMERIC"/>
            <result column="IS_SYSFIELD" property="isSysfield" jdbcType="NUMERIC"/>
            <result column="CONTROL" property="control" jdbcType="VARCHAR"/>
            <result column="SINDEX" property="sindex" jdbcType="NUMERIC"/>
        </association>
    </resultMap>
  • 查数据可以通过sql查返回值
   <select id="selectListWithAttr" resultMap="BpmBoEntityDTOResultMap">
        SELECT bbe.*, bba.* FROM bpm_bo_entity bbe LEFT JOIN bpm_bo_attribute bba ON bbe.ent_id = bba.ent_id where bbe.table_type = 0 order by bbe.CREATE_TIME DESC
    </select>
  • 防止精度丢失(计算)
     BigDecimal totalSsqymj = BigDecimal.ZERO;
                for (HashMap<String, Object> item : entry.getValue()) {
                    BigDecimal ssqymj = new BigDecimal(item.get("ssqymj").toString());
                    totalSsqymj = totalSsqymj.add(ssqymj);
                }
  • 自动补0(如果有小数位的四舍五入)
    • 如果所操作的数字小数位数不足 4 位,.setScale(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;
    }
}


//获取枚举list
    public 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("http://10.3.2.18: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_name
   FROM 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

  • 判断一张表一个字段是否有重复的值
SELECT table_name, COUNT(*)
FROM "bpm_bo_entity" bbe 
GROUP BY table_name
HAVING COUNT(*) > 1;
  • sql封装参数
   String tableName = tableSetting.get().getValue();
   String sql = "select * from %s where inst_id=#{instid}";
   HashMap<String,Object> params=new HashMap<>();
   params.put("instid",instId);
   List<Map<String,Object>> dataList = commonService.query(String.format(sql,tableName),params);
  • 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参数封装
    • 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.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=1
        UNION
        SELECT 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_log
        LEFT JOIN inst_casenode_info ici ON ici.inst_id = rule_log.inst_id and ici.node_id = rule_log.node_id
        LEFT JOIN bpm_form_info bfi ON bfi.form_key = rule_log.form_key
        ORDER 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!程序会根据年份入参自适应修改!")

在这里插入图片描述

循环

  • forEach()遍历:使用了forEach()函数来遍历listMapentrySet()
    然而,报错是因为你在lambda表达式中使用了return语句,但是forEach()函数期望的lambda表达式是一个Consumer类型的函数接口,它没有返回值。

  • 多重判断

   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);
                }
            }
        }
        //判断层数与数组是否一致,不一致证明路径不存在返回null
        if (split.length == i) {
            return pathId;
        } else {
            return id;
        }
    }
  • 判断对象类型instanceof
Object tbDate = datasMap.get(s);
tbDate instanceof List

递归

  • 参数请求
    在这里插入图片描述

  • 递归处理附件树目录(**)

    public void processCatalog(List<BusinessContentVO> contentVOList) {
        contentVOList.forEach(a -> {
            //只处理目录
            if (a.getDataId() == null) {
                String nodeName = a.getNodeName();
                if (nodeName != null) {
                    if (nodeName.contains("(申报)")) {
                        nodeName = nodeName.replace("(申报)", "");
                    } else if (nodeName.contains("(验收)")) {
                        nodeName = nodeName.replace("(验收)", "");
                    } else if (nodeName.contains("(实施)")) {
                        nodeName = nodeName.replace("(实施)", "");
                    } else if (nodeName.contains("(绩效)")) {
                        nodeName = nodeName.replace("(绩效)", "");
                    } else if (nodeName.contains("(备案)")) {
                        nodeName = nodeName.replace("(备案)", "");
                    }
                    a.setNodeName(nodeName);
                }
                if (a.getChildren() != null) {
                    processCatalog(a.getChildren());
                }
            }
        });
    }
  • 递归行政区域
  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,label
        List<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);
            }
        }
        //长度不够六位的在后面补0
        this.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标签进来都是新的widgetList
                    List<JSONObject> widgetList = new ArrayList<>();
                    //每个tab标签的widgetList
                    jsonObjectList = JSONArray.parseArray(jsonObject.get("widgetList").toString(), JSONObject.class);
                    //调用递归函数获取容器的最后一个widgetList
                    jsonObjectList = recursionJsonList(jsonObjectList, widgetList);
                    this.handContainer(bpmBoEntity, relBoDefIdList, jsonObjectList);
                }
            }

    //递归获取容器的widgetList
    public 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);
                }
            }
        }
        //判断层数与数组是否一致,不一致证明路径不存在返回null
        if (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语句用于终止本次循环,接着开始下一次循环。

截串

  • 截取指定区域的值
string result=(10,2)          
String result = input.substring(input.indexOf(",") + 1, input.indexOf(")"));  最后取到的值是2
  • 判断字符串s首字母 是否为指定 字符
s.startsWith("@")
  • 截取字符串s指定下标以后的字符串
s.substring(1)

实体

  • 实体属性赋值
LogInstance logInstance = BeanUtil.toBean(source, LogInstance.class);

io流

  • 重置流
 inputStream = fileService.getObject(objectName);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            buffer = outputStream.toByteArray();
            //创建ByteArrayInputStream对象,用于处理缓冲区中的数据
            inputStreamWrapper = new ByteArrayInputStream(buffer);
            if (inputStreamWrapper.markSupported()) {
                //在这里设置标记,并将参数设置为缓冲区的长度
                inputStreamWrapper.mark(buffer.length);
            } else {
                //inputstream不支持mark/reset方法
            }
            //处理模版打印图片获取minio路径
            XWPFDocument document = new XWPFDocument(inputStreamWrapper);
            //获取表格内容
            XWPFWordExtractor xwpfWordExtractor = new XWPFWordExtractor(document);
            String text = xwpfWordExtractor.getText();
            //格式化处理特殊格式图片
            this.customPhotoUrl(formPrintData, text);
            //如果需要重置输入流,可以调用reset()方法
            inputStreamWrapper.reset();
  • Java 创建目录./是什么意思
    在这里插入图片描述

  • 流读写

  • 将流写到文件中

 MultipartFile file
 InputStream 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、调用方与被调方不能在同一个类
  • 测试异步是否成功,成功了就直接走到 保存成功,不会进入休眠,最后才进入对应休眠的方法
  • 异步处理线程
  • 开启异步后无论异步 方法是否执行成功 ,都会 直接走到保存成功,互不影响在这里插入图片描述在这里插入图片描述
    // 异步线程处理数据源xml解析
        ExecutorService es = Executors.newFixedThreadPool(1);
        es.submit(new Callable<BpmFormInfo>() {
            @Override
            public BpmFormInfo call() {
                formDatasourceService.updateFormXmlJson(bpmFormInfo.getFormId());
                return null;
            }
        });
        es.shutdown();
  • 异步 开启了新线程所以 获取不到当前的登录人的id,需要获取传值过来

apifox调试工具

  • post请求(参数类型请求)
    • query
      在这里插入图片描述

    • body (加了注解@RequestBody)

在这里插入图片描述

  • json参数传数组(apifox)

  • public R updateSort(@RequestBody List<Long> ids){ }

  • 在这里插入图片描述

  • 加了这个注解@RequestBody为json模式传参
    不加默认为form-data格式

public R<ApplyContentDto> updateApplyContent(@RequestBody String json) {}
  • 请求参数
@Validated BusinessAbandonRequest request
@NotBlank(message = "参数opinion(意见)不能为null")
private String opinion;

  • get请求也可以用实体接
    @GetMapping("/outputNavInfo")
    @ApiOperation(value = "导出视图")
    @BpmApiLog(name = "导出视图", group = BpmConstant.MODULE_NAV, dataIdName = "navId", opType = OpType.Export)
    public void outputNavInfo(HttpServletResponse response,
                              @RequestParam(name = "navId", required = true) String navId,
                              @Valid NavInfoIOValid navInfoIOValid) throws IOException {
        navManagerService.outputNavInfo(response,navId, navInfoIOValid);
    }
  • list<实体>接收参数
    在这里插入图片描述
    在这里插入图片描述
  • post请求多个参数
    @PostMapping("/bpmFormReport/save")
    @ApiOperation(value = "新增表单打印模板", notes = "新增表单打印模板")
    @ApiOperationSupport(order = 14)
    @BpmApiLog(name = "新增表单打印模板", group = BpmConstant.MODULE_FORM, dataIdName = "id", opType = OpType.ADD)
    public R save(BpmFormReportRequest request, MultipartFile file) throws IOException {
        Asserts.isEmpty(request.getFormId(), "表单id不能为空!");
        request.setFileByte(file.getBytes());
        request.setSize(file.getSize());
        request.setOriginalFilename(file.getOriginalFilename());
        return formManagerService.save(request);
    }

在这里插入图片描述

  • 参数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传参有长度限制
  • 实体继承会和当前 实体展示在 同一列表
    用户
    在这里插入图片描述
    在这里插入图片描述

类型转换

  • string转json
string params = "{"projectExtend":"true","formKey":"F000004","edit":"true","detailShow":"false"}";
JSONObject jsonObject = new JSONObject(params);
//判断是否需要过滤,有配置扩展参数detailShow则过滤不显示按钮
String detailShow = jsonObject.getStr("detailShow");
  • 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 (key.compareToIgnoreCase("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
HashMap<String, Object> map = (HashMap) oldFormDatum;

事务

  • 事务问题,在另一个方法 调用 其他 方法插入数据 ,两个方法 都加了事务注解 ,会失效
  • 在@Transactional注解中如果不配置rollbackFor属性,那么事物只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事物在遇到非运行时异常时也回滚

响应

  • 导出报错信息乱码问题
response.setHeader("Content-Type", "application/octet-stream");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "application/json;charset=utf-8");
  • 解决导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关键字段只允许有一个!");

乱码

  • 导出信息报错中文乱码
response.setHeader("Content-Type", "application/octet-stream");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "application/json;charset=utf-8");

概念

  • 能用对象不 用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请求

环境配置

  • 解决启动命令窗口中文乱码问题
  • chcp 65001jiejue- 环境变量搞到bin上一层
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java中的战斗机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值