1、Stream流常用操作
1.1 根据单个字段获取集合
List<String> skuIdList = list.stream().map(WmsStock::getStockId).collect(Collectors.toList());
1.2 对List集合进行分组
1.2.1 根据单个字段进行分组
Map<String, List<Advice>> adviceMap = adviceList.stream()
.collect(Collectors.groupingBy(Advice::getIdMedord));
Map<String, Person> groupedPersons = persons.stream()
.collect(Collectors.toMap(Person::getName, Function.identity()));
1.2.2 根据两个字段进行分组
根据主键id和日期中间作为map的key,进行分组:
Map<String, List<AdvicePlan>> groupMap = addList.stream()
.collect(Collectors.groupingBy(o->o.getIdMedord()+"_"+o.getDtPlan()));
分组完成之后,我们肯定会遍历这个map集合,具体操作如下:
外层forEach遍历key,内层forEach遍历value,对value集合中的对象进行一些值的操作。最后可以使用addAll方法将设置好的集合都添加到这个中间集合中去进行我们自己的一些业务操作
groupMap.forEach((k, v) -> {
String groupNo = IdentityUtils.getId();
v.forEach(plan->{
//设置组号
plan.setGroupNo(groupNo);
//医嘱计划id(打印二维码用)
plan.setIdMedordipex(groupNo);
//条码号(扫码要用)
plan.setBarcodeNo(groupNo);
});
//将集合存放到中间集合中去,方便后续操作
newAddList.addAll(v);
});
1.3 List 集合对象的属性进行求和操作
这里需要注意PerRecChaOutCount的类型为Integer类型,可能为空,需要过滤掉为空的
int chaOut = list.stream()
.filter(per->per.getPerRecChaOutCount()!=null)
.mapToInt(PerTranChaBarChart::getPerRecChaOutCount)
.sum();
1.4 List集合转换为Map集合
wardMenus.stream()
.collect(Collectors.toMap(WardMenu::geItdMenu,WardMenu::getOrderNo);
1.5 List集合对象日期属性排序
1.5.1 对象单属性简单排序
缺陷:如果对象的这个日期为空,会报空指针异常
List<AdvicePlan> collect = list.stream()
.sorted(Comparator.comparing(AdvicePlan::getDtPlan))
.collect(Collectors.toList());
1.5.2 对象单属性排序,并指定日期为空时的策略
对日期属性进行排序,并指定日期为空时的策略,防止空指针异常。
//空值放最后,剩下的倒叙排序
List<AdvicePlan> collect = list.stream()
.sorted(Comparator.comparing(AdvicePlan::getDtPlan,
Comparator.nullsFirst(Comparator.reverseOrder())))
.collect(Collectors.toList());
- Comparator.nullsFirst(Comparator.naturalOrder())):空值放前面,剩下的升序排序(从小到大顺序)
- Comparator.nullsFirst(Comparator.reverseOrder())):空值放前面,剩下的倒序排序(从大到小顺序)
- Comparator.nullsLast(Comparator.naturalOrder())):空值放最后,剩下的升序排序
- Comparator.nullsLast(Comparator.reverseOrder())):空值放最后,剩下的倒序排序
1.5.3 对象的多个属性进行排序
先按照开始时间倒叙排序,在按照结束时间倒叙排序:
//先按照开始时间倒叙排序,在按照结束时间倒叙排序
List<AdvicePlan> collect = list.stream().sorted(
Comparator.comparing(AdvicePlan::getDtStart,
Comparator.nullsFirst(Comparator.reverseOrder()))
.thenComparing(AdvicePlan::getDtEnd,
Comparator.nullsFirst(Comparator.reverseOrder())))
.collect(Collectors.toList());
1.6 将集合中的对象的id用逗号拼接
String collect = list.stream()
.map(HandOverCount::getIdVismed)
.collect(Collectors.joining(","));
1.7 两个List集合进行对比,根据字段过滤掉重复记录
List<TempProjectDTO> insertTempProject = tempProjects.stream()
.filter(t1 -> tempProjectDTOList.stream()
.noneMatch(t2 -> Objects.equals(t1.getIdPro(), t2.getIdPro())))
.collect(Collectors.toList());
1.8 根据字段过滤掉记录
List<WmsWarehouseLocation> filteredData = locations.stream()
.filter(data -> data.getStatus().equals("0"))
.collect(Collectors.toList());
2、MyBaits常用操作(针对Oracle数据库)
2.1 使用 begin end 批量插入
<insert id="insertBatch">
<foreach collection="list" item = "item" open = "begin" close = "end;">
insert into NP_DETAIL (id, content, content_id, evaluate_id)
values (#{item.id,jdbcType=VARCHAR}, #{item.content,jdbcType=VARCHAR},
#{item.contentId,jdbcType=VARCHAR},#{item.evaluateId,jdbcType=VARCHAR});
</foreach>
</insert>
解析后的语句:
begin
insert into NP_DETAIL (id, content, content_id, evaluate_id)
values (?, ?,
?,?);
insert into NP_DETAIL (id, content, content_id, evaluate_id)
values (?, ?,
?,?);
end;
2.2 使用 union all,union 实现批量插入
<insert id="insertBatch">
insert into NP_DETAIL (id, content, content_id,evaluate_id)
<foreach collection="list" item="item" index="index" open="(" close=")" separator="union all">
SELECT
#{item.id,jdbcType=VARCHAR},
#{item.content,jdbcType=VARCHAR},
#{item.contentId,jdbcType=VARCHAR},
#{item.evaluateId,jdbcType=VARCHAR}
FROM dual
</foreach>
</insert>
<insert id="insertBatch" parameterType="com.bsoft.nenr.scene.handover.pojo.HandOverType" >
insert into HANDOVER (id, temp_id, type, max_num, depts, fg_delete,patient_type)
<foreach item="item" index="index" collection="list" separator="union all">
(
select #{item.id,jdbcType=VARCHAR}, #{item.tempId,jdbcType=VARCHAR},
#{item.type,jdbcType=NUMERIC},#{item.maxNum,jdbcType=NUMERIC},
#{item.depts,jdbcType=VARCHAR}, #{item.fgDelete,jdbcType=NUMERIC},
#{item.patientType,jdbcType=NUMERIC}
from dual
)
</foreach>
</insert>
解析后的语句:
insert into NP_DETAIL (id, content, content_id, evaluate_id)
(
SELECT
?,
?,
?,
?
FROM dual
union all
SELECT
?,
?,
?,
?
FROM dual
union all
SELECT
?,
?,
?,
?
FROM dual
)
2.3 批量更新
<update id="updateBatchDetails">
<foreach collection="updateDetails" item="item" index="index" separator=";" open="begin" close=";end;">
update FORM_DETAIL
<set>
ID_REC = #{item.idRec,jdbcType=VARCHAR},
ID_ITEM = #{item.idItem,jdbcType=VARCHAR},
ID_META = #{item.idMeta,jdbcType=VARCHAR}
</set>
where ID_DETAIL = #{item.idDetail,jdbcType=VARCHAR}
</foreach>
</update>
3、日期格式化问题
3.1 @JsonFormat
@JsonFormat注解主要解决后台从数据库中取出时间类型赋予java对象的Date属性值无法在前端以一定的日期格式来呈现,默认返回的是一个带时区的格式串,不符合我们日常要呈现的yyyy-MM-dd格式的日期。
同样,我们在对应的接收对象时间类型上加上@JsonFormat注解,并在注解中加上pattern属性以及timezone属性。
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 调动时间 @JsonFormat控制后台到前台的日期格式
*/
@ApiModelProperty(value="调配时间")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
private Date dtCha;
3.2 MyBatis中jdbcType=DATE和jdbcType=TIMESTAMP区别
MyBatis处理日期有两种的jdbcType:
- jdbcType=DATE
- jdbcType=TIMESTAMP
注意:此时的DATE指的是java.sql.Date,不是java.util.Date,要注意两者的区别。java.util.Date通常情况下用它获取当前时间,java.sql.Date是针对SQL语句使用的,它只包含日期而没有时间部分。
MySQL数据库常用日期类型:
(1)DATETIME 显示格式:YYYY-MM-DD HH:MM:SS
时间范围:[ '1000-01-01 00:00:00'到'9999-12-31 23:59:59']
(2)DATE 显示格式:YYYY-MM-DD
时间范围:['1000-01-01'到'9999-12-31']
(3)TIMESTAMP 显示格式:YYYY-MM-DD HH:MM:SS
时间范围:[ '1970-01-01 00:00:00'到'2037-12-31 23:59:59']