- 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)
方法会在不足的末尾补上零。
- 如果所操作的数字小数位数不足 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()
函数来遍历listMap
的entrySet()
。
然而,报错是因为你在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、调用方与被调方不能在同一个类
- 1、注解@Async的方法不是public方法
- 测试异步是否成功,成功了就直接走到 保存成功,不会进入休眠,最后才进入对应休眠的方法
- 异步处理线程
- 开启异步后无论异步 方法是否执行成功 ,都会 直接走到保存成功,互不影响
// 异步线程处理数据源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<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 65001
- 环境变量搞到bin上一层