解释 Boolean everyoneWriteOnce = setting.getEveryoneWriteOnce(); Boolean everyoneDayWriteOnce = setting.getEveryoneDayWriteOnce(); if (everyoneWriteOnce || everyoneDayWriteOnce) { LambdaQueryWrapper<FormData> wrapper = Wrappers.<FormData>lambdaQuery() .eq(FormData::getFormKey, formKey) .eq(FormData::getSubmitRequestIp, requestIp); if (everyoneDayWriteOnce) { wrapper.apply(StrUtil.format("date_format({},'%Y-%m-%d') = '{}'", StrUtil.toUnderlineCase(FormData.Fields.createTime), DateUtil.today())); } long writeCount = formDataService.count(wrapper); if (1 <= writeCount) { return ReturnData.error().errorMessage(setting.getWriteOncePromptText()); } } return ReturnData.success().data(setting); }
时间: 2024-02-16 22:27:56 浏览: 76
这段代码是一个判断表单提交次数的逻辑。首先获取了两个布尔类型的变量:`everyoneWriteOnce`和`everyoneDayWriteOnce`,分别表示是否开启了全局限制和每天限制。接着通过LambdaQueryWrapper构建查询条件,筛选出指定`formKey`和`requestIp`的表单数据。如果开启了每天限制,还会加入一条查询条件,确保只查询当天的表单数据。然后调用formDataService的count方法获取符合条件的表单数据数量,如果数量大于等于1,则表明用户已经提交过表单,返回错误提示信息;否则返回成功并返回当前表单设置。
相关问题
private String computerActiveSe(ArrayList<String> seArrayList) { // Select active SE strategy as follows: // 1. if SE is not actived by user, and SIM1 or SIM2 is avaiable, select SIM SE as defualt. // 2. set last active SE as default if it is available; // 3. set previous active SE as default if avaiable; // 4. set HCE as as default if both 2&3 are not avaiable. int selectBydefault = mContentProviderUtil.getActiveSeChangeByUser(); String candidateSE = mContentProviderUtil.getActiveSeString(); //#ifdef OPLUS_BUG_STABILITY //[email protected], 2024/03/19, modfiy when not oversea not set NFC-SIM to default paymet boolean overseaRegion = NfcService.getInstance().isOverSeaRegion(); //#endif /*OPLUS_BUG_STABILITY*/ if (selectBydefault == NFC_MULTISE_ACTIVE_DEFAULT) { //#ifdef OPLUS_BUG_STABILITY //[email protected], 2024/03/19, modfiy when not oversea not set NFC-SIM to default paymet if (seArrayList.contains(SETTING_STR_SIM1) && !overseaRegion) { candidateSE = SETTING_STR_SIM1; } else if (seArrayList.contains(SETTING_STR_SIM2) && !overseaRegion) { candidateSE = SETTING_STR_SIM2; //#endif /*OPLUS_BUG_STABILITY*/ } else { //#ifdef OPLUS_FEATURE_NFC_SE //[email protected], 2020/04/11, Add for:SN100T/Q support Gp Felica in same repository and branch if (mIsSupportGpFelica) { candidateSE = SETTING_STR_ESE; } else { candidateSE = SETTING_STR_HCE; } //#endif /* OPLUS_FEATURE_NFC_SE */ } } else { if (!seArrayList.contains(candidateSE)) { candidateSE = mContentProviderUtil.getPreActiveSeString(); if (!seArrayList.contains(candidateSE)) { candidateSE = SETTING_STR_HCE; } } //#ifdef OPLUS_FEATURE_NFC_GPFELICA //[email protected], 2021/03/16, //Add for : del SIM1 do not observe nfc_multise_active for GPFelica if (mIsSupportGpFelica) { if (DBG) { Log.d(TAG,"[computerActiveSe] is gpfelica, set route to ese"); } candidateSE = SETTING_STR_ESE; } //#endif /* OPLUS_FEATURE_NFC_GPFELICA */ } mLastActiveSe = mContentProviderUtil.getActiveSeString(); if ((mLastActiveSe == null) || mLastActiveSe.equals("")) { //for the first boot, set HCE as previous active SE. mContentProviderUtil.setPreActiveSeString(SETTING_STR_HCE); } if (!candidateSE.equals(mLastActiveSe)) { mContentProviderUtil.setPreActiveSeString(mLastActiveSe); } else { //since candiate SE is the same to last SE, we won't change the previous setting. } mContentProviderUtil.setActiveSeString(candidateSE); if (DBG) { Log.d(TAG, "candidate SE = " + candidateSE + ", last active SE = " + mLastActiveSe); } mLastActiveSe = candidateSE; return candidateSE; }
<think>好的,我现在需要帮助用户理解这段Java方法`computerActiveSe`的逻辑。首先,我会通读代码,了解它的整体结构和各个条件分支。
这个方法的主要功能是确定NFC的默认安全元件(SE)。根据注释,策略分四个步骤:首先检查用户是否未激活SE,若有可用的SIM卡则选SIM;否则按最后使用、之前使用、最后HCE的顺序选择。代码中有很多条件判断和厂商定制逻辑,比如OPLUS的bug修复和功能开关。
接下来,我需要理清各个条件分支。首先,`selectBydefault`的值决定了是否走默认策略。当它是`NFC_MULTISE_ACTIVE_DEFAULT`时,进入第一个大分支,这里涉及到海外区域的判断,可能影响是否选择SIM卡作为默认。如果不在海外,优先选SIM1或SIM2;否则,根据是否支持GP Felica选择ESE或HCE。
另一个分支是当用户已选择过SE时,检查当前候选是否可用,不可用则尝试之前的,最后回退到HCE。此外,存在针对GP Felica的特殊处理,强制设置ESE。
然后,代码处理记录上一次的SE,确保首次启动时HCE作为默认,并在SE变更时更新之前的记录。最后,设置并返回候选SE。
需要注意的是,代码中的预处理指令(如#ifdef)可能表示不同编译条件下的行为差异,但用户可能更关注核心逻辑。需要将条件编译的部分转化为普通注释,方便用户理解不同场景下的逻辑。
在解释过程中,应分步骤说明每个条件判断的目的,例如为何检查海外区域,GP Felica支持的影响,以及各个SETTING_STR常量的含义。同时,需要指出方法如何维护上次和当前的SE状态,确保下次选择时能正确回退。
可能存在的疑问点包括:`mContentProviderUtil`的作用,各个常量的具体值,以及`isOverSeaRegion`如何判断地区。但用户可能不需要这些细节,只需理解逻辑流程即可。
最后,总结整个方法的决策流程,用清晰的步骤和条件分支图来展示,帮助用户快速掌握代码功能。</think>这个方法是用于确定NFC支付默认安全元件(SE)的选择策略。以下是逐层分析:
$$流程图$$
开始
├─ 获取用户配置和候选SE
├─ 判断是否是默认选择模式?
│ ├─ 是 → 检查海外版本
│ │ ├─ 非海外版优先选SIM卡(SIM1/SIM2)
│ │ └─ 否则根据芯片支持选择ESE或HCE
│ └─ 否 → 按历史记录选择
│ ├─ 检查上次使用的SE是否可用
│ ├─ 不可用则用之前使用的SE
│ └─ 最后回退到HCE
├─ 特殊处理GP Felica芯片
├─ 更新历史记录
└─ 返回最终选择的SE
$$
具体实现步骤说明:
1. **初始配置获取**
- 通过`mContentProviderUtil`获取用户配置`selectBydefault`
- 获取当前候选SE`candidateSE`(来自系统设置)
2. **默认选择逻辑**(当`selectBydefault == NFC_MULTISE_ACTIVE_DEFAULT`)
```java
if (seArrayList.contains(SETTING_STR_SIM1) && !overseaRegion) {
candidateSE = SETTING_STR_SIM1;
} else if (...) // SIM2同理
```
- 优先选择SIM卡作为支付载体
- 新增海外区域判断:仅非海外版本才会默认使用SIM卡
3. **备选方案**(当SIM不可用时)
```java
if (mIsSupportGpFelica) {
candidateSE = SETTING_STR_ESE; // 嵌入式安全元件
} else {
candidateSE = SETTING_STR_HCE; // 主机卡模拟
}
```
4. **历史记录选择逻辑**(当用户自定义过SE)
```java
if (!seArrayList.contains(candidateSE)) {
candidateSE = getPreActiveSeString(); // 尝试前次使用的SE
if (!seArrayList.contains(candidateSE)) {
candidateSE = SETTING_STR_HCE; // 最终回退方案
}
}
```
5. **特殊芯片处理**
```java
if (mIsSupportGpFelica) {
candidateSE = SETTING_STR_ESE; // 强制使用嵌入式安全元件
}
```
6. **状态持久化**
- 通过`mContentProviderUtil`存储当前选择的SE
- 记录最后一次使用的SE到`mLastActiveSe`
- 首次启动时初始化HCE为默认值
典型常量说明:
- `SETTING_STR_SIM1`: SIM卡1
- `SETTING_STR_ESE`: 设备内置安全芯片
- `SETTING_STR_HCE`: 软件模拟方案
设计亮点:
- 通过`mContentProviderUtil`实现配置持久化
- 使用海外区域判断实现差异化策略
- 历史记录双缓存机制(last/pre)
- 芯片兼容性处理(GP Felica)
该方法体现了典型的多条件优先级决策模式,建议在实际使用中通过日志`Log.d(TAG,...)`观察选择路径。
LambdaUpdateWrapper<DlRebate> updateWrapper = new LambdaUpdateWrapper<DlRebate>().in(DlRebate::getId, ids); updateWrapper.set(DlRebate::getStatusCode, FIRST_EXAMINED.getCode()); updateWrapper.set(DlRebate::getSecondApprove, 0); updateWrapper.set(DlRebate::getSecondApproveTime, null); updateWrapper.set(DlRebate::getSecondApproveBy, null); boolean update = dlRebateMapperDao.update(null,updateWrapper);报错Could not set parameters for mapping: ParameterMapping{property='ew.paramNameValuePairs.MPGENVAL3', mode=IN, javaType=class java.lang.Object, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting null for parameter #3 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111
<think>好的,我现在需要解决用户在使用MyBatis的LambdaUpdateWrapper进行更新时遇到的参数映射异常问题,具体是TypeException和无效列类型1111的错误。首先,我得回忆一下相关的MyBatis知识,特别是关于参数映射和类型处理的部分。
用户提到的错误“无效列类型1111”通常是因为MyBatis在处理null值时无法确定正确的JDBC类型。根据引用[1]、[3]和[5],这个问题通常出现在参数为null时,没有指定jdbcType,导致MyBatis无法识别类型。在传统的XML映射文件中,解决方法是在参数中添加jdbcType属性,比如#{id, jdbcType=INTEGER}。但用户现在使用的是LambdaUpdateWrapper,属于MyBatis Plus的写法,可能需要不同的处理方式。
接下来,我需要考虑LambdaUpdateWrapper的使用场景。LambdaUpdateWrapper通常通过Java代码链式调用设置更新字段和值。例如:
```java
lambdaUpdateWrapper.set(User::getName, name).eq(User::getId, id);
```
如果这里的name变量为null,MyBatis在生成SQL时可能需要处理null值,但如果没有指定jdbcType,就可能引发问题。这时,需要确保在设置null值时明确指定JDBC类型。
根据引用[5]中的解决方案,一种方法是避免字段为null,或者在条件构造时进行空值判断。但用户的问题可能出现在必须允许null值的情况下,这时候需要另一种处理方式。在MyBatis Plus中,可能没有直接的方法在LambdaUpdateWrapper中设置jdbcType,但可以尝试使用其他方法,比如通过UpdateWrapper的setSql方法直接写SQL片段,并手动处理参数类型。
另外,引用[2]和[4]提到,当参数类型不一致时(比如Map或对象属性类型混合),MyBatis可能无法正确解析类型。这可能意味着在使用LambdaUpdateWrapper时,如果某些字段的值是null,而其他字段有值,类型推断会失败。因此,需要统一处理所有可能为null的字段,显式指定它们的jdbcType。
可能的解决步骤包括:
1. 在设置可能为null的字段时,使用MyBatis Plus的`set`方法的重载版本,允许传入一个条件,当值为null时不设置该字段。但用户可能需要允许更新为null,所以这种方法可能不适用。
2. 在MyBatis的配置文件中全局设置jdbcTypeForNull。根据MyBatis文档,可以配置`jdbcTypeForNull`为NULL,例如在mybatis-config.xml中添加:
```xml
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
```
这样,当参数为null时,MyBatis会使用JDBC的NULL类型,避免类型推断错误。引用[3]提到,默认配置可能有问题,所以显式设置这个值可能有效。
3. 在代码中,使用`SqlHelper`或自定义的SQL方法,手动指定类型。例如,通过`setSql("name = #{name, jdbcType=VARCHAR}")`,但这种方法可能破坏了LambdaUpdateWrapper的类型安全优势。
需要验证这些方法是否适用于LambdaUpdateWrapper。特别是全局配置jdbcTypeForNull,这应该会影响所有操作,包括UpdateWrapper的设置。如果用户已经配置了这个设置但问题仍然存在,可能需要进一步检查其他原因,比如字段类型是否正确映射,或者是否有其他配置覆盖了这个设置。
另外,用户可能没有使用MyBatis的全局配置,因此建议他们在配置文件中添加jdbcTypeForNull的设置。同时,如果某些字段必须允许null,但在更新时出现类型错误,可能需要检查实体类的字段是否为包装类型,如引用[4]所述,基本类型无法为null,必须使用包装类如Integer而不是int。
总结可能的解决方案:
- 检查实体类字段是否使用包装类型。
- 在MyBatis配置中设置jdbcTypeForNull为NULL。
- 在LambdaUpdateWrapper中避免设置null值,或通过条件判断排除null值。
- 如果必须设置null,尝试通过自定义SQL片段指定jdbcType。
最后,用户可能需要结合这些方法,根据具体情况选择最适合的解决方案。例如,全局配置加上使用包装类型可能是根本的解决办法,而条件判断可以在业务逻辑中处理null值的情况。</think>### 解决MyBatis LambdaUpdateWrapper更新时参数映射异常的步骤
#### 1. 问题原因分析
当使用`LambdaUpdateWrapper`设置字段值为`null`时,MyBatis无法自动推断`null`值的JDBC类型,导致报错`TypeException`和`无效列类型: 1111`。根本原因是**未显式声明`null`值的JDBC类型**,MyBatis默认尝试用`OTHER`类型(对应代码1111)处理,但部分数据库驱动不支持该类型[^3]。
---
#### 2. 解决方案
##### 方法一:全局配置`jdbcTypeForNull`
在MyBatis配置文件中(如`mybatis-config.xml`)添加以下配置,强制所有`null`值使用`NULL`类型:
```xml
<configuration>
<settings>
<setting name="jdbcTypeForNull" value="NULL"/>
</settings>
</configuration>
```
此配置会使所有`null`参数映射为`JDBC.NULL`,避免类型推断错误[^3][^5]。
---
##### 方法二:实体类字段使用包装类型
确保实体类中可能为`null`的字段使用**包装类型**(如`Integer`代替`int`)。MyBatis对基本类型无法处理`null`值,会因缺少`getter`方法报错[^4]:
```java
public class User {
private Integer age; // ✔️ 正确:包装类型允许null
private int status; // ❌ 错误:基本类型无法为null
}
```
---
##### 方法三:LambdaUpdateWrapper条件过滤null值
通过条件判断跳过`null`值的设置,避免触发类型推断问题:
```java
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getId, 1)
.set(value != null, User::getName, value) // 仅当value非null时设置
.set(value == null, User::getName, "default");
```
---
##### 方法四:手动指定JDBC类型(需结合XML)
若必须设置`null`值,可在XML映射文件中定义更新语句,显式声明`jdbcType`:
```xml
<update id="updateUser">
UPDATE user
SET name = #{name, jdbcType=VARCHAR}
WHERE id = #{id}
</update>
```
在Java代码中调用此XML映射方法,替代`LambdaUpdateWrapper`的动态条件。
---
#### 3. 总结
| 方案 | 适用场景 | 优点 | 缺点 |
|---------------|----------------------------------|--------------------------|----------------------|
| 全局配置 | 所有涉及`null`值的操作 | 一劳永逸 | 需修改全局配置 |
| 包装类型 | 实体类字段设计阶段 | 符合规范,避免基础类型问题 | 需修改实体类 |
| 条件过滤 | 动态更新场景 | 代码灵活 | 需手动处理逻辑 |
| XML映射 | 复杂更新逻辑 | 精准控制参数类型 | 失去Lambda类型安全优势 |
---
阅读全文
相关推荐









@Override
@Transactional
public void createTemporarySpotCheckOrder(CreateTemporarySpotCheckLo createTemporarySpotCheckLo) {
MaintTypeEnum maintType = MaintTypeEnum.DRC;
MaintForm maintForm;
List<MaintFormEqp> formEqps = new ArrayList<>();
List<MaintFormAction> equipmentActions = new ArrayList<>();
List<MaintFormActionInput> cells = new ArrayList<>();
String eqpCode = createTemporarySpotCheckLo.getEqpCode();
String planEffectTime = createTemporarySpotCheckLo.getPlanEffectTime();
LocalDate planDate = null;
LocalDateTime planEffectDate = null;
if (StringUtils.isNotEmpty(planEffectTime)) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
planDate = LocalDate.parse(planEffectTime, formatter);
planEffectDate = LocalDateTime.parse(planEffectTime, formatter);
}
String isImedEffect = createTemporarySpotCheckLo.getIsImedEffect();
maintForm = newForm(null, planDate, eqpCode, new MaintPlan(), MaintTypeEnum.TRC, new MaintPlanItem(), null, isImedEffect, planEffectDate);
LambdaQueryWrapper<EquipmentCapability> qm = new LambdaQueryWrapper<>();
qm.eq(EquipmentCapability::getEqpCode, eqpCode);
qm.eq(EquipmentCapability::getActive, "Y");
EquipmentCapability equipmentCapability = equipmentCapabilityMapper.selectOne(qm);
LambdaQueryWrapper<EquipmentDef> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(EquipmentDef::getEqpCode, eqpCode);
EquipmentDef equipmentDef = equipmentDefMapper.selectOne(queryWrapper);
MaintManual manual = getManual(equipmentDef.getBrandCode(), maintType, equipmentCapability, createTemporarySpotCheckLo.getDescEncode());
if (manual == null) {
throw new BusinessException("9999", "该设备不存在已激活的维保手册!");
}
//临时点检名称使用手册全名
maintForm.setMaintPlanFullname(manual.getMaintManualFullname());
//临时点检标题使用手册描述
maintForm.setFormTitle(manual.getDescription());
//表单编号和版本
maintForm.setCode(manual.getCode());
maintForm.setVersion(manual.getVersion());
//临时点检备注提示取手册中的
maintForm.setFillinComment(manual.getNotes());
//设置表单类型
maintForm.setFormType(createTemporarySpotCheckLo.getDescEncode());
MaintFormEqp formEqp = new MaintFormEqp();
formEqp.setFormCode(maintForm.getFormCode());
formEqp.setEqpCode(equipmentDef.getEqpCode());
formEqp.setMaintManualFullname(manual.getMaintManualFullname());
formEqp.setMaintType(maintType.name());
formEqp.setSortingOrder(String.valueOf(0));
formEqp.setPeriodConditionCode("UNSCHEDULED");
formEqps.add(formEqp);
String maintManualFullname = manual.getMaintManualFullname();
if (StringUtils.isNotBlank(manual.getRefMaintManualName())) {
MaintManual refMaintManual = getMaintManualByVersionOrActive(manual.getRefMaintManualName(), manual.getRefMaintManualVersion());
if (null == refMaintManual) {
throw new BusinessException("9999", "refMaintManual不存在!");
}
maintManualFullname = refMaintManual.getMaintManualFullname();
}
// equipment action record
List<MaintManualItem> manualItems = getMaintManualItems(maintManualFullname, "UNSCHEDULED");
if (CollectionUtils.isEmpty(manualItems)) {
throw new BusinessException("9999", "该设备的激活维保手册没有维护不定期点检项目!");
}
List<BasicActionWrapper> basicActions = new ArrayList<>();
for (MaintManualItem manualItem : manualItems) {
if (manualItem.getGroupAction()) {
List<BasicActionWrapper> actions = getBasicActionsOfGroup(manualItem.getActionName(), manualItem.getActionVersion());
basicActions.addAll(actions);
} else {
BasicAction action = getBasicActionByNameVersion(manualItem.getActionName(), manualItem.getActionVersion());
BasicAction basicAction = new BasicAction();
try {
BeanUtils.copyProperties(action, basicAction);
} catch (Exception e) {
throw new BusinessException("9999", "事项" + manualItem.getActionName() + "不存在" + (manualItem.getActionVersion().equals(ModelVersion.AA) ? "激活的版本!" : manualItem.getActionVersion() + "版本!"));
}
// 取manual中的PhotoRequired
basicAction.setPhotoRequired(manualItem.getPhotoRequired());
BasicActionWrapper wrapper = new BasicActionWrapper(basicAction, null);
basicActions.add(wrapper);
}
}
calculateSortOrderForActions(basicActions); // 计算每个form action的序号
for (int j = 0; j < basicActions.size(); j++) {
BasicActionWrapper actionWrapper = basicActions.get(j);
MaintFormAction formAction = new MaintFormAction();
formAction.setFormCode(maintForm.getFormCode());
formAction.setEqpCode(formEqp.getEqpCode());
formAction.setBasicActionFullname(actionWrapper.basicAction.getBasicActionFullname());
formAction.setPhotoRequired(actionWrapper.basicAction.getPhotoRequired());
formAction.setGroupActionFullname(actionWrapper.groupActionFullname);
formAction.setSortingOrder(actionWrapper.sortingOrder);
equipmentActions.add(formAction);
// action items(cells)
for (int row = 0; row < actionWrapper.basicAction.getTotalRow(); row++) {
for (int col = 0; col < actionWrapper.basicAction.getTotalCol(); col++) {
MaintFormActionInput cell = new MaintFormActionInput();
cell.setFormCode(maintForm.getFormCode());
cell.setEqpCode(equipmentDef.getEqpCode());
cell.setBasicActionFullname(actionWrapper.basicAction.getBasicActionFullname());
cell.setRow(row);
cell.setCol(col);
cell.setSortingOrder(formAction.getSortingOrder());
cells.add(cell);
}
}
}
// save records to db
maintFormMapper.insert(maintForm);
LOGGER.info("formEqps:" + formEqps);
for (MaintFormEqp maintFormEqp : formEqps) {
maintFormEqpMapper.insert(maintFormEqp);
}
LOGGER.info("equipmentActions:" + equipmentActions);
for (MaintFormAction maintFormAction : equipmentActions) {
maintFormActionMapper.insert(maintFormAction);
}
LOGGER.info("cells:" + cells);
for (MaintFormActionInput maintFormActionInput : cells) {
maintFormActionInputMapper.insert(maintFormActionInput);
}
//推送消息
LambdaQueryWrapper<SpotCheckPushSetting> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SpotCheckPushSetting::getEqpCode, eqpCode)
.eq(SpotCheckPushSetting::getNoticeType, SpotCheckPushSettingEnum.CREATED.getCode())
.eq(SpotCheckPushSetting::getDeleteStatus, "Y");
SpotCheckPushSetting setting = spotCheckPushSettingMapper.selectOne(wrapper);
String userNumber = null;
//判断是否有维护点检通知
if (setting != null) {
//获取周期频率的中文描述使用
//查询定期的维保周期
List periods = new LambdaQueryChainWrapper<>(periodMapper).list();
//基于维保周期Code将集合转化为map
Map<String, Period> periodMap = periods.stream()
.collect(Collectors.toMap(Period::getPeriodCode, Function.identity()));
Period period = periodMap.get(maintForm.getPeriodCode());
//维保周期没有维护,但是计划里面有相应的定期动作,则提示异常并结束
if (null == period) {
LOGGER.error(String.format("The period [%s] is not existed", maintForm.getPeriodCode()));
return;
}
userNumber = setting.getNoticePersonNumber();
String descEncode = createTemporarySpotCheckLo.getDescEncode();
if (descEncode.length() >= "SBGCDJ".length() &&
descEncode.substring(0, "SBGCDJ".length()).equals("SBGCDJ")) {
// 进入这个代码块如果前几位(至少和"SBGCDJ"一样长)是"SBGCDJ"
String emailContent = "有一份设备过程点检工单创建成功!"
+ "
表单:"+ maintForm.getFormTitle()
+ "
点检工单编号:" + maintForm.getFormCode()
+ "
设备:" + maintForm.getMaintObject() +"("+ equipmentDef.getDescription()+ ")"
+ "
生成时间:" + maintForm.getCreatedTimestamp().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+ "
如有疑请查看:PMS设备管理系统" + jumpIp + "/platform/#/TM20/login";
String wechatContent = "有一份设备过程点检工单创建成功!"
+ "\n表单:"+ maintForm.getFormTitle()
+ "\n点检工单编号:" + maintForm.getFormCode()
+ "\n设备:" + maintForm.getMaintObject() + "(" + equipmentDef.getDescription()+ ")"
+ "\n周期频率:" + maintForm.getPeriodCode() + "(" + period.getDescription() + ")"
+ "\n生成时间:" + maintForm.getCreatedTimestamp().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+ "\n如有疑请查看:PMS设备管理系统";
LogInfo logInfo = new LogInfo();
logInfo.setFormCode(maintForm.getFormCode());
logInfo.setEqpCode(maintForm.getMaintObject());
logInfo.setNoticeType(SpotCheckPushSettingEnum.CREATED.getCode());
logInfo.setUpgradeTime(setting.getUpgradeTime());
emailWeComSendBo.sendMessage(userNumber, "设备过程点检工单创建通知", emailContent, wechatContent, true, true, logInfo);
}else {
String emailContent = "有一份工艺过程点检工单创建成功!"
+ "
表单:"+ maintForm.getFormTitle()
+ "
点检工单编号:" + maintForm.getFormCode()
+ "
设备:" + maintForm.getMaintObject() +"("+ equipmentDef.getDescription()+ ")"
+ "
生成时间:" + maintForm.getCreatedTimestamp().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+ "
如有疑请查看:PMS设备管理系统" + jumpIp + "/platform/#/TM20/login";
String wechatContent = "有一份工艺过程点检工单创建成功!"
+ "\n表单:"+ maintForm.getFormTitle()
+ "\n点检工单编号:" + maintForm.getFormCode()
+ "\n设备:" + maintForm.getMaintObject() + "(" + equipmentDef.getDescription()+ ")"
+ "\n周期频率:" + maintForm.getPeriodCode() + "(" + period.getDescription() + ")"
+ "\n生成时间:" + maintForm.getCreatedTimestamp().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+ "\n如有疑请查看:PMS设备管理系统";
LogInfo logInfo = new LogInfo();
logInfo.setFormCode(maintForm.getFormCode());
logInfo.setEqpCode(maintForm.getMaintObject());
logInfo.setNoticeType(SpotCheckPushSettingEnum.CREATED.getCode());
logInfo.setUpgradeTime(setting.getUpgradeTime());
emailWeComSendBo.sendMessage(userNumber, "工艺过程点检工单创建通知", emailContent, wechatContent, true, true, logInfo);
}
}
}在这个方法中maintFormMapper.insert(maintForm);可以插入成功,请给出我在 /**
* 批量保存数据到数据库
*/
@Override
@Transactional
public void batchSaveData(List<MaintForm> forms, List<MaintFormEqp> formEqps,
List<MaintFormAction> equipmentActions, List<MaintFormActionInput> cells) {
if (!forms.isEmpty()) {
if (forms.stream().anyMatch(Objects::isNull)) {
throw new IllegalArgumentException("列表中存在null元素");
}
forms.forEach(form -> LOGGER.info("Form to insert: {}", form));
for (MaintForm maintForm : forms) {
maintFormMapper.insert(maintForm);
}
// maintFormMapper.maintFormBatchInsert(forms);
LOGGER.info("Saved {} forms", forms.size());
}
if (!formEqps.isEmpty()) {
maintFormEqpMapper.formEqpsBatchInsert(formEqps);
LOGGER.info("Saved {} formEqps", formEqps.size());
}
if (!equipmentActions.isEmpty()) {
maintFormActionMapper.equipmentActionsBatchInsert(equipmentActions);
LOGGER.info("Saved {} equipmentActions", equipmentActions.size());
}
if (!cells.isEmpty()) {
maintFormActionInputMapper.cellsBatchInsert(cells);
LOGGER.info("Saved {} cells", cells.size());
}
}错误的原因








