增删查改/批量增删查改
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xch.mapper.WorkMapper">
<resultMap id="BaseResultMap" type="com.xch.pojo.Work">
<id property="wId" jdbcType="VARCHAR" column="w_id"/>
<result property="wDept" jdbcType="VARCHAR" column="w_dept"/>
<result property="wPosition" jdbcType="VARCHAR" column="w_position"/>
<result property="wSalary" jdbcType="DECIMAL" column="w_salary"/>
<result property="wCreateTime" jdbcType="TIMESTAMP" column="w_create_time"/>
<result property="uId" jdbcType="VARCHAR" column="u_id"/>
</resultMap>
<sql id="Base_Column_List">
w_id, w_dept, w_position, w_salary, w_create_time, u_id
</sql>
<sql id="Alias_Column_List">
work.w_id, work.w_dept, work.w_position, work.w_salary, work.w_create_time, work.u_id
</sql>
<!--单表增删查改模板-->
<insert id="baseInsertWork" parameterType="com.xch.pojo.Work">
insert into dynamic_sql_work
values (
#{wId,jdbcType=VARCHAR},
#{wDept,jdbcType=VARCHAR},
#{wPosition,jdbcType=VARCHAR},
#{wSalary,jdbcType=DECIMAL},
#{wCreateTime,jdbcType=TIMESTAMP},
#{uId,jdbcType=VARCHAR}
)
</insert>
<delete id="baseDeleteWork" parameterType="string">
delete from dynamic_sql_work
where w_id=#{wId,jdbcType=VARCHAR}
</delete>
<select id="baseSelectWork" parameterType="string" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from dynamic_sql_work
where u_id=#{uId,jdbcType=VARCHAR}
</select>
<update id="baseUpdateWork" parameterType="com.xch.pojo.Work">
update dynamic_sql_work
set w_position=#{wPosition,jdbcType=VARCHAR},
w_salary=#{wSalary,jdbcType=DECIMAL},
w_create_time=#{wCreateTime,jdbcType=TIMESTAMP}
where u_id=#{uId,jdbcType=VARCHAR}
and w_id=#{wId,jdbcType=VARCHAR}
</update>
<!--单表批量增删查改模板-->
<insert id="batchInsertWork" parameterType="list">
insert into dynamic_sql_work
values
<foreach collection="workList" item="work" separator=",">
(
#{work.wId,jdbcType=VARCHAR},
#{work.wDept,jdbcType=VARCHAR},
#{work.wPosition,jdbcType=VARCHAR},
#{work.wSalary,jdbcType=DECIMAL},
#{work.wCreateTime,jdbcType=TIMESTAMP},
#{work.uId,jdbcType=VARCHAR}
)
</foreach>
</insert>
<delete id="batchDeleteWork" parameterType="list">
delete from dynamic_sql_work
where w_id in
<foreach collection="wIdList" item="wId" open="(" close=")" separator=",">
#{wId,jdbcType=VARCHAR}
</foreach>
</delete>
<select id="batchSelectWork" parameterType="list" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from dynamic_sql_work
where w_id in
<foreach collection="wIdList" item="wId" open="(" close=")" separator=",">
#{wId,jdbcType=VARCHAR}
</foreach>
</select>
<update id="batchUpdateWork1">
update dynamic_sql_work
set w_position=#{work.wPosition,jdbcType=VARCHAR},
w_salary=#{work.wSalary,jdbcType=DECIMAL},
w_create_time=#{work.wCreateTime,jdbcType=TIMESTAMP},
u_id=#{work.uId,jdbcType=VARCHAR}
where w_id in
<foreach collection="wIdList" item="wId" open="(" close=")" separator=",">
#{wId,jdbcType=VARCHAR}
</foreach>
</update>
<update id="batchUpdateWork2" parameterType="list">
update dynamic_sql_work
set w_salary=
case
<foreach collection="workList" item="work">
when w_id=#{work.wId,jdbcType=VARCHAR} then #{work.wSalary,jdbcType=DECIMAL}
</foreach>
end
where w_id in
<foreach collection="workList" item="work" open="(" close=")" separator=",">
#{work.wId,jdbcType=VARCHAR}
</foreach>
</update>
</mapper>
SqlSessionBatch-SqlSessionTemplateBatch
package com.xch.sqlSessionTemplate;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Chenghe Xu
* @date 2022/9/5 22:58
*
* 申明多个注入Bean注释,只会注入一个Bean
* 因为注释的底层都会有@ConditionalOnMissingBean(xxx.class),没有该Bean才创建,防止重复创建
*/
@Configuration
public class CreateSqlSessionTemplate {
/**
* 注入开启Batch模式的SqlSessionTemplate对象
*/
@Bean({"sqlSessionTemplateBatch"})
@ConditionalOnMissingBean(name = {"sqlSessionTemplateBatch"})
@Autowired
public SqlSessionTemplate createSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory, ExecutorType.BATCH);
}
}
package com.xch.dao.impl;
import com.xch.dao.WorkDAO;
import com.xch.mapper.WorkMapper;
import com.xch.pojo.Work;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
/**
* @author Chenghe Xu
* @date 2022/9/5 20:47
*/
@Repository
public class WorkDAOImpl implements WorkDAO {
@Resource
ApplicationContext applicationContext;
private final SqlSessionFactory sqlSessionFactory;
private final SqlSessionTemplate sqlSessionTemplate;
/**
* SqlSessionFactory/SqlSessionTemplate默认在Spring容器中的
* 注入开启Batch模式的SqlSessionTemplate自定义对象splSessionTemplateBatch
* 代替原有的SqlSessionTemplate对象
*/
@Autowired
public WorkDAOImpl(SqlSessionFactory sqlSessionFactory, @Qualifier("sqlSessionTemplateBatch") SqlSessionTemplate sqlSessionTemplate) {
this.sqlSessionFactory = sqlSessionFactory;
this.sqlSessionTemplate = sqlSessionTemplate;
}
public void test(){
System.out.println(sqlSessionFactory);
System.out.println(sqlSessionTemplate);
System.out.println(applicationContext.getBeansOfType(SqlSessionTemplate.class));
System.out.println(Arrays.toString(applicationContext.getBeanNamesForType(SqlSessionTemplate.class)));
}
/**
* SqlSession/SqlSessionTemplate异同:
* 1、SqlSession需要手动commit和close流
* SqlSessionTemplate自动commit和close流
* 2、SqlSession并发下线程不安全
* SqlSessionTemplate并发下线程安全
* 3、SqlSessionTemplate是SqlSession的实现类
* 其底层都是通过jdbc的PreparedStatement.executeBatch()执行批量操作的
*
* 用法:
* 业务逻辑中其它操作(删查改)混合,使用SqlSession
* 业务逻辑中只有批量新增操作,使用SqlSessionTemplate
*/
@Override
public Integer advanceBatchWork1(List<Work> workList) {
//try (AutoCloseable/Closeable 需要自动关闭的资源)
//jdk1.7新特性:try ()中申明的流资源,在try语句结束后自动关闭
//相当于简化了finally{ManualCloseable 需要手动关闭的资源}
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)){
WorkMapper workMapper = sqlSession.getMapper(WorkMapper.class);
workList.forEach(workMapper::baseInsertWork);
sqlSession.commit();
return workList.size();
}
//不需要捕获catch (){rollback();},发生异常后Spring会回滚方法的执行
}
@Override
public Integer advanceBatchWork2(List<Work> workList) {
//SqlSessionTemplate自动管理了提交commit和关闭流close
WorkMapper workMapper = sqlSessionTemplate.getMapper(WorkMapper.class);
workList.forEach(workMapper::baseInsertWork);
return workList.size();
}
}
动态拼装SQL/多表连接操作属性使用
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xch.mapper.UserMapper">
<resultMap id="BaseResultMap" type="com.xch.pojo.User">
<id property="uId" jdbcType="VARCHAR" column="u_id"/>
<result property="uName" jdbcType="VARCHAR" column="u_name"/>
<result property="uAge" jdbcType="INTEGER" column="u_age"/>
<result property="uPhone" jdbcType="CHAR" column="u_phone"/>
<result property="uCreateTime" jdbcType="TIMESTAMP" column="u_create_time"/>
</resultMap>
<sql id="Base_Column_List">
u_id, u_name, u_age, u_phone, u_create_time
</sql>
<sql id="Alias_Column_List">
user.u_id, user.u_name, user.u_age, user.u_phone, user.u_create_time
</sql>
<!--动态拼装SQL-->
<!--if标签可以判断 not true false null '' ! == != < <= > >= -->
<!--if标签可以转义 eq neq lt lte < <= gt gte > %gt;= -->
<!--if标签可以运算 + - * / % ^ << >> >>> | & -->
<!--if标签可以组合判断 || or && and ? : -->
<!--if标签可以调用方法 xxx.equals() xxx.hashCode() -->
<select id="ifTest" parameterType="com.xch.pojo.User" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from dynamic_sql_user
where 1=1
<if test="uName neq null and uName != ''">
and u_name=#{uName,jdbcType=VARCHAR}
</if>
<if test="uAge neq null and uAge >= 0 and uAge lte 160">
and u_age=#{uAge,jdbcType=INTEGER}
</if>
</select>
<!--where标签可以替代where/where 1=1,动态去除多余and-->
<select id="whereTest" parameterType="com.xch.pojo.User" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from dynamic_sql_user
<where>
<if test="uName neq null and uName != ''">
and u_name=#{uName,jdbcType=VARCHAR}
</if>
<if test="uAge neq null and uAge >= 0 and uAge lte 160">
and u_age=#{uAge,jdbcType=INTEGER}
</if>
</where>
</select>
<!--choose when otherwise标签-->
<select id="chooseTest" parameterType="com.xch.pojo.User" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from dynamic_sql_user
where 1=1
<choose>
<when test="uName neq null and uName != ''">
and u_name=#{uName,jdbcType=VARCHAR}
</when>
<when test="uAge neq null and uAge >= 0 and uAge lte 160">
and u_age=#{uAge,jdbcType=INTEGER}
</when>
<otherwise>
order by u_age, u_id
</otherwise>
</choose>
</select>
<!--set标签可以代替set,动态去除多余,-->
<update id="setTest" parameterType="com.xch.pojo.User">
update dynamic_sql_user
<set>
<if test="uName neq null and uName != ''">
u_name=#{uName,jdbcType=VARCHAR},
</if>
<if test="uAge neq null and uAge >= 0 and uAge lte 160">
and u_age=#{uAge,jdbcType=INTEGER}
</if>
</set>
where u_id=#{uId,jdbcType=VARCHAR}
</update>
<!--trim标签可以代替where/where 1=1,动态去除多余and-->
<select id="trimTest1" parameterType="com.xch.pojo.User" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from dynamic_sql_user
<trim prefix="where" prefixOverrides="and">
<if test="uName neq null and uName != ''">
and u_name=#{uName,jdbcType=VARCHAR}
</if>
<if test="uAge neq null and uAge >= 0 and uAge lte 160">
and u_age=#{uAge,jdbcType=INTEGER}
</if>
</trim>
</select>
<!--trim标签可以代替set,动态去除多余,-->
<update id="trimTest2" parameterType="com.xch.pojo.User">
update dynamic_sql_user
<trim prefix="set" suffixOverrides=",">
<if test="uName neq null and uName != ''">
u_name=#{uName,jdbcType=VARCHAR},
</if>
<if test="uAge neq null and uAge >= 0 and uAge lte 160">
and u_age=#{uAge,jdbcType=INTEGER}
</if>
</trim>
where u_id=#{uId,jdbcType=VARCHAR}
</update>
<!--多表连接操作-->
<!--association属性-一对一关联-->
<resultMap id="BaseResultWithWorkMap1" type="com.xch.pojo.UserWithWork">
<id property="uId" jdbcType="VARCHAR" column="u_id"/>
<result property="uName" jdbcType="VARCHAR" column="u_name"/>
<result property="uAge" jdbcType="INTEGER" column="u_age"/>
<result property="uPhone" jdbcType="CHAR" column="u_phone"/>
<result property="uCreateTime" jdbcType="TIMESTAMP" column="u_create_time"/>
<!--说明:property是出参,jdbcType/javaType是指明类型-->
<association property="work" javaType="com.xch.pojo.Work">
<id property="wId" jdbcType="VARCHAR" column="w_id"/>
<result property="wDept" jdbcType="VARCHAR" column="w_dept"/>
<result property="wPosition" jdbcType="VARCHAR" column="w_position"/>
<result property="wSalary" jdbcType="DECIMAL" column="w_salary"/>
<result property="wCreateTime" jdbcType="TIMESTAMP" column="w_create_time"/>
<result property="uId" jdbcType="VARCHAR" column="u_id"/>
</association>
</resultMap>
<select id="associationTest" parameterType="string" resultMap="BaseResultWithWorkMap1">
select <include refid="Alias_Column_List"/>,<include refid="com.xch.mapper.WorkMapper.Alias_Column_List"/>
from dynamic_sql_user user
left join dynamic_sql_work work
on user.u_id=work.u_id
where work.u_id=#{uId,jdbcType=VARCHAR}
</select>
<!--collection属性-一对多关联-->
<resultMap id="BaseResultWithWorkMap2" type="com.xch.pojo.UserWithWork">
<id property="uId" jdbcType="VARCHAR" column="u_id"/>
<result property="uName" jdbcType="VARCHAR" column="u_name"/>
<result property="uAge" jdbcType="INTEGER" column="u_age"/>
<result property="uPhone" jdbcType="CHAR" column="u_phone"/>
<result property="uCreateTime" jdbcType="TIMESTAMP" column="u_create_time"/>
<!--说明:property是出参,jdbcType/ofType是指明类型-->
<collection property="workList" ofType="com.xch.pojo.Work">
<id property="wId" jdbcType="VARCHAR" column="w_id"/>
<result property="wDept" jdbcType="VARCHAR" column="w_dept"/>
<result property="wPosition" jdbcType="VARCHAR" column="w_position"/>
<result property="wSalary" jdbcType="DECIMAL" column="w_salary"/>
<result property="wCreateTime" jdbcType="TIMESTAMP" column="w_create_time"/>
<result property="uId" jdbcType="VARCHAR" column="u_id"/>
</collection>
</resultMap>
<select id="collectionTest" parameterType="string" resultMap="BaseResultWithWorkMap2">
select <include refid="Alias_Column_List"/>,<include refid="com.xch.mapper.WorkMapper.Alias_Column_List"/>
from dynamic_sql_user user
left join dynamic_sql_work work
on user.u_id=work.u_id
where work.u_id=#{uId,jdbcType=VARCHAR}
</select>
<!--extend属性-继承映射关系-->
<resultMap id="BaseResultWithWorkMap3" type="com.xch.pojo.UserWithWork" extends="BaseResultMap">
<!--说明:property是出参,jdbcType/javaType是指明类型-->
<association property="work" javaType="com.xch.pojo.Work">
<id property="wId" jdbcType="VARCHAR" column="w_id"/>
<result property="wDept" jdbcType="VARCHAR" column="w_dept"/>
<result property="wPosition" jdbcType="VARCHAR" column="w_position"/>
<result property="wSalary" jdbcType="DECIMAL" column="w_salary"/>
<result property="wCreateTime" jdbcType="TIMESTAMP" column="w_create_time"/>
<result property="uId" jdbcType="VARCHAR" column="u_id"/>
</association>
</resultMap>
<select id="extendTest" parameterType="string" resultMap="BaseResultWithWorkMap3">
select <include refid="Alias_Column_List"/>,<include refid="com.xch.mapper.WorkMapper.Alias_Column_List"/>
from dynamic_sql_user user
left join dynamic_sql_work work
on user.u_id=work.u_id
where work.u_id=#{uId,jdbcType=VARCHAR}
</select>
<!--resultMap属性-继承映射关系-->
<resultMap id="BaseResultWithWorkMap4" type="com.xch.pojo.UserWithWork" extends="BaseResultMap">
<!--说明:property是出参-->
<association property="work" resultMap="com.xch.mapper.WorkMapper.BaseResultMap"/>
</resultMap>
<select id="resultMapTest" parameterType="string" resultMap="BaseResultWithWorkMap4">
select <include refid="Alias_Column_List"/>,<include refid="com.xch.mapper.WorkMapper.Alias_Column_List"/>
from dynamic_sql_user user
left join dynamic_sql_work work
on user.u_id=work.u_id
where work.u_id=#{uId,jdbcType=VARCHAR}
</select>
<!--select属性-关联SQL-->
<resultMap id="BaseResultWithWorkMap5" type="com.xch.pojo.UserWithWork" extends="BaseResultMap">
<!--说明:property是出参,column是入参:数据库列名/{连接SQL需要的参数名=本SQL提供的数据库列名},逗号分隔-->
<!--写法一:数据库列名(适用于单一参数)-->
<!--写法二:{连接SQL需要的参数名=本SQL提供的数据库列名},逗号分隔(适用于多个参数即封装为类,需有GET/SET函数)-->
<association property="work" column="u_id" select="com.xch.mapper.WorkMapper.baseSelectWork"/>
</resultMap>
<select id="selectTest" parameterType="string" resultMap="BaseResultWithWorkMap5">
select <include refid="Base_Column_List"/>
from dynamic_sql_user
where u_id=#{uId,jdbcType=VARCHAR}
</select>
</mapper>
多层结构树综合查询使用比较
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xch.mapper.LevelTreeExtraMapper">
<resultMap id="BaseResultMap" type="com.xch.pojo.LevelTreeExtra">
<id property="id" jdbcType="INTEGER" column="id"/>
<result property="parentId" jdbcType="INTEGER" column="parent_id"/>
<result property="name" jdbcType="VARCHAR" column="name"/>
<result property="otherProperties" jdbcType="VARCHAR" column="other_properties"/>
</resultMap>
<sql id="Base_Column_List">
id, parent_id, name, other_properties
</sql>
<sql id="Alias_Column_List1">
lt1.id lt1_id, lt1.parent_id lt1_parent_id, lt1.name lt1_name, lt1.other_properties lt1_other_properties
</sql>
<sql id="Alias_Column_List2">
lt2.id lt2_id, lt2.parent_id lt2_parent_id, lt2.name lt2_name, lt2.other_properties lt2_other_properties
</sql>
<sql id="Alias_Column_List3">
lt3.id lt3_id, lt3.parent_id lt3_parent_id, lt3.name lt3_name, lt3.other_properties lt3_other_properties
</sql>
<!-- Mysql连接查询语句(不能使用lt1.id形式,需要用别名区分) -->
<resultMap id="BaseResultWithNextLevelMap" type="com.xch.pojo.LevelTreeExtra">
<id property="id" jdbcType="INTEGER" column="lt1_id"/>
<result property="parentId" jdbcType="INTEGER" column="lt1_parent_id"/>
<result property="name" jdbcType="VARCHAR" column="lt1_name"/>
<result property="otherProperties" jdbcType="VARCHAR" column="lt1_other_properties"/>
<collection property="nextLevelTreeList" ofType="com.xch.pojo.LevelTreeExtra">
<id property="id" jdbcType="INTEGER" column="lt2_id"/>
<result property="parentId" jdbcType="INTEGER" column="lt2_parent_id"/>
<result property="name" jdbcType="VARCHAR" column="lt2_name"/>
<result property="otherProperties" jdbcType="VARCHAR" column="lt2_other_properties"/>
<collection property="nextLevelTreeList" ofType="com.xch.pojo.LevelTreeExtra">
<id property="id" jdbcType="INTEGER" column="lt3_id"/>
<result property="parentId" jdbcType="INTEGER" column="lt3_parent_id"/>
<result property="name" jdbcType="VARCHAR" column="lt3_name"/>
<result property="otherProperties" jdbcType="VARCHAR" column="lt3_other_properties"/>
</collection>
</collection>
</resultMap>
<!-- inner效果为必须有,left效果为可以有,where效果为限定查询开始层级 -->
<select id="selectLevelTree1" resultMap="BaseResultWithNextLevelMap">
select <include refid="Alias_Column_List1"/>,
<include refid="Alias_Column_List2"/>,
<include refid="Alias_Column_List3"/>
from level_tree lt1
inner join level_tree lt2
on lt1.id = lt2.parent_id
left join level_tree lt3
on lt2.id = lt3.parent_id
where lt1.parent_id = -1
</select>
<!-- Mybatis子查询语法(写法一) -->
<resultMap id="BaseResultWithNextLevelMap1" type="com.xch.pojo.LevelTreeExtra" extends="BaseResultMap">
<!-- 写法一:数据库列名(适用于单一参数) -->
<collection property="nextLevelTreeList" column="id" select="selectLevelTree2"/>
</resultMap>
<select id="selectLevelTree2" parameterType="com.xch.pojo.LevelTreeExtra" resultMap="BaseResultWithNextLevelMap1">
select <include refid="Base_Column_List"/>
from level_tree
where parent_id = #{parentId}
</select>
<!-- Mybatis子查询语法(写法二) -->
<resultMap id="BaseResultWithNextLevelMap2" type="com.xch.pojo.LevelTreeExtra" extends="BaseResultMap">
<!-- 写法二:{连接SQL需要的参数名=本SQL提供的数据库列名},逗号分隔(适用于多个参数即封装为类,需有GET/SET函数) -->
<collection property="nextLevelTreeList" column="{parentId=id}" select="selectLevelTree2"/>
</resultMap>
<select id="selectLevelTree22" parameterType="com.xch.pojo.LevelTree" resultMap="BaseResultWithNextLevelMap2">
select <include refid="Base_Column_List"/>
from level_tree
where parent_id = #{parentId}
</select>
<!-- 业务层手动组装结构树 -->
<select id="selectLevelTree3" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from level_tree
where parent_id is not null
<!-- 拼装过滤有效数据条件 -->
</select>
</mapper>
/**
* 组装结构树算法工具方法(可以抽离到公共工具类中定义)
*/
public List<LevelTreeExtra> fixLevelTreeExtra(List<LevelTreeExtra> levelTreeList) {
// 入参判断(公共的工具方法,需要做强检验,确保健壮性/兼容性/适配性)
Assert.notEmpty(levelTreeList, "不能组装空集合");
// if (ObjectUtil.isEmpty(levelTreeList)) {
// // 返回不可操作的空集合
// Collections.emptyList();
// }
// 业务逻辑
// 先进行JDK8新特性去重再按parentId分组
Map<Integer, List<LevelTreeExtra>> levelTreeListMapByParentId = levelTreeList.stream()
.distinct().collect(Collectors.groupingBy(LevelTreeExtra::getParentId));
// 再递归(DFS)批量组装
return fixDFS(levelTreeListMapByParentId);
}
/**
* 递归(DFS)批量组装结果树
*/
public List<LevelTreeExtra> fixDFS(Map<Integer, List<LevelTreeExtra>> levelTreeListMapByParentId) {
List<LevelTreeExtra> levelTreeExtraList = levelTreeListMapByParentId.get(-1);
if (ObjectUtil.isEmpty(levelTreeExtraList)) {
return Collections.emptyList();
}
levelTreeExtraList.forEach(levelTreeExtra -> DFS(levelTreeListMapByParentId, levelTreeExtra));
return levelTreeExtraList;
}
/**
* 递归函数(写法一:参数传递/写法二:调用传递,仅适用于调用者是递归方法体类本身,才可以用this)
*/
public void DFS(Map<Integer, List<LevelTreeExtra>> levelTreeListMapByParentId, LevelTreeExtra levelTreeExtra) {
// 递归出口(判断的是当前状态的内容,通常判断为结束时,不再做操作)
List<LevelTreeExtra> nextLevelTreeList = levelTreeListMapByParentId.get(levelTreeExtra.getId());
if (ObjectUtil.isEmpty(nextLevelTreeList)) {
return;
}
// 递归体
levelTreeExtra.setNextLevelTreeList(nextLevelTreeList);
nextLevelTreeList.forEach(nextLevelTree -> DFS(levelTreeListMapByParentId, nextLevelTree));
}
其中:
1、基本数据类型可以简写(全小写)代替完整包.类名(可以通过Idea跳转测试)
2、入参有多个时,mybatis接口层用@param("xxx")标注,映射文件SQL不用写入参类型