c5c67ee1 by 荆蔚杰

不动产登记档案系统

0 parents
.idea
*.iml
.classpath
.factorypath
.project
.settings
.DS_Store
target
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.pashanhoo</groupId>
<artifactId>archive-system</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${org.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.29</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.29</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${org.spring.boot.version}</version>
</dependency>
<!--<dependency>-->
<!-- <groupId>org.springframework.session</groupId>-->
<!-- <artifactId>spring-session-data-redis</artifactId>-->
<!-- <version>${org.spring.session.version}</version>-->
<!--</dependency>-->
<!--&lt;!&ndash; 引入Redis依赖 &ndash;&gt;-->
<!--<dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!-- <version>${org.spring.boot.version}</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!-- <groupId>redis.clients</groupId>-->
<!-- <artifactId>jedis</artifactId>-->
<!-- <version>2.9.3</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!-- <groupId>org.springframework.session</groupId>-->
<!-- <artifactId>spring-session</artifactId>-->
<!-- <version>1.0.2.RELEASE</version>-->
<!--</dependency>-->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.12.RELEASE</version>
</dependency>
<!-- Swagger API文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox.swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox.swagger2.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.13</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${org.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.10.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>3.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<!--<dependency>-->
<!-- <groupId>polaris</groupId>-->
<!-- <artifactId>polaris-fileattachment</artifactId>-->
<!-- <version>1.0</version>-->
<!-- <scope>compile</scope>-->
<!--</dependency>-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>6.0.11</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<!--使用通配符,当然可以定义多个exclude标签进行排除-->
<exclude>application*.yml</exclude>
</excludes>
</resource>
<!--根据激活条件引入打包所需的配置和文件-->
<resource>
<directory>src/main/resources</directory>
<!--引入所需环境的配置文件-->
<filtering>true</filtering>
<includes>
<include>application.yml</include>
<!--根据maven选择环境导入配置文件-->
<include>application-${profile.active}.yml</include>
</includes>
</resource>
</resources>
</build>
<profiles>
<profile>
<!--不同环境的唯一id-->
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profile.active>dev</profile.active>
</properties>
</profile>
<!--生产环境-->
<profile>
<id>prod</id>
<properties>
<profile.active>prod</profile.active>
</properties>
</profile>
</profiles>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<oracle.version>11.2.0.4</oracle.version>
<geotools.version>24-SNAPSHOT</geotools.version>
<org.springframework.version>5.1.8.RELEASE</org.springframework.version>
<org.spring.boot.version>2.1.8.RELEASE</org.spring.boot.version>
<org.spring.amqp>2.2.2.RELEASE</org.spring.amqp>
<org.spring.security.version>5.1.6.RELEASE</org.spring.security.version>
<!--<org.spring.session.version>2.1.4.RELEASE</org.spring.session.version>-->
<fasterxml.jackson.version>2.10.0</fasterxml.jackson.version>
<maven-deploy-plugin_version>2.8.2</maven-deploy-plugin_version>
<mybatis-plus.version>3.1.2</mybatis-plus.version>
<springfox.spring.web.version>2.9.2</springfox.spring.web.version>
<springfox.swagger2.version>2.9.2</springfox.swagger2.version>
<mapstruct.version>1.3.0.Final</mapstruct.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
package com.pashanhoo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication(scanBasePackages={"com.pashanhoo"})
@EnableTransactionManagement
@MapperScan(basePackages = {"com.pashanhoo.**.mapper"})
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.run(args);
}
}
package com.pashanhoo;
import io.swagger.annotations.Api;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* swagger配置类
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
// 为当前包路径
// .apis(RequestHandlerSelectors.basePackage("com.pashanhoo"))
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build();
}
// 构建 api文档的详细信息函数,注意这里的注解引用的是哪个
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 页面标题
.title("档案系统 接口文档")
// 版本号
.version("1.0")
// 描述
.description("API 描述")
.build();
}
}
package com.pashanhoo.common;
public interface CommonConstant {
/**
* 新增校验报错状态
*/
Integer CHECK_ERROR_2002=2002;
/**
* {@code 500 Server Error} (HTTP/1.0 - RFC 1945)
*/
Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
/**
* {@code 200 OK} (HTTP/1.0 - RFC 1945)
*/
Integer SC_OK_200 = 200;
/**
* {@code 200 OK} (HTTP/1.0 - RFC 1945)
*/
Integer SC_INFO_206 = 206;
/**
* {@code 200 OK} (HTTP/1.0 - RFC 1945)
*/
Integer SC_INFO_210 = 210;
/**
* 字典信息缓存
*/
String SYS_DICT_NAME = "sys:dict:name:";
/**
* 字典信息缓存
*/
String SYS_DICT_ID = "sys:dict:id:";
/**
* 字典信息单条
*/
String SYS_DICT_ALL = "sys:dict:all:";
/**
* 字典信息缓存
*/
String SYS_DICT_CODE = "sys:dict:code:";
/**
* 菜单列表
*/
String MENU_TREE = "sys:menu:";
}
package com.pashanhoo.common;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class PageInfo {
@ApiModelProperty(name = "currentPage",value = "页码")
private Integer currentPage = 1;
@ApiModelProperty(name = "pageSize",value = "每页个数")
private Integer pageSize = 10;
@ApiModelProperty(name = "sortField",value = "排序字段" )
private String sortField;
@ApiModelProperty(name = "sortOrder",value = "升序(asc)或降序(desc)")
private String sortOrder;
public void defaultFillPageProp(String sortField, String sortOrder) {
if(StringUtils.isBlank(this.sortField)) {
this.sortField = sortField;
this.sortOrder = sortOrder;
}
}
}
package com.pashanhoo.common;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
@ApiModel(value = "接口返回对象", description = "接口返回对象")
@JsonInclude
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
@ApiModelProperty(value = "成功标志")
private boolean success = true;
/**
* 返回处理消息
*/
@ApiModelProperty(value = "返回处理消息")
private String message = "操作成功!";
/**
* 返回代码
*/
@ApiModelProperty(value = "返回代码")
private Integer code = 0;
/**
* 返回数据对象 data
*/
@ApiModelProperty(value = "返回数据对象")
private T result;
/**
* 时间戳
*/
@ApiModelProperty(value = "时间戳")
private long timestamp = System.currentTimeMillis();
public Result() {
}
public Result<T> success(String message) {
this.message = message;
this.code = CommonConstant.SC_OK_200;
this.success = true;
return this;
}
public static Result<Object> ok() {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage("成功");
return r;
}
public static Result<Object> ok(String msg) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setMessage(msg);
return r;
}
public static <T> Result<T> ok(T data) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static Result<String> content(String data) {
Result<String> r = new Result<String>();
r.setSuccess(true);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static Result<Object> info(Object data) {
Result<Object> r = new Result<Object>();
r.setSuccess(false);
r.setCode(CommonConstant.SC_INFO_206);
r.setResult(data);
return r;
}
public static Result<Object> exception(String data) {
Result<Object> r = new Result<Object>();
r.setSuccess(false);
r.setCode(CommonConstant.SC_INFO_210);
r.setMessage(data);
return r;
}
public static <T> Result<T> ok(T data, String msg) {
Result<T> r = new Result<T>();
r.setSuccess(true);
r.setMessage(msg);
r.setCode(CommonConstant.SC_OK_200);
r.setResult(data);
return r;
}
public static Result<String> error(String msg) {
return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
}
public static Result<String> checkError(String msg) {
return error(CommonConstant.CHECK_ERROR_2002, msg);
}
public static Result<String> error(int code, String msg) {
Result<String> r = new Result<String>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
}
public static <T> Result<T> error(String message, T data) {
Result<T> r = new Result<T>();
r.setMessage(message);
r.setResult(data);
r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500);
r.setSuccess(false);
return r;
}
public Result<T> error500(String message) {
this.message = message;
this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
this.success = false;
return this;
}
// /**
// * 无权限访问返回结果
// */
// public static Result<String> noauth(String msg) {
// return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg);
// }
public static long getSerialVersionUID() {
return serialVersionUID;
}
public boolean getSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
}
package com.pashanhoo.common.util;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.pashanhoo.common.util.mybatisplus.MyFreemarkerTemplateEngine;
/**
* 代码自动生成器
*/
public class CodeGenerator {
public static void main(String[] args) {
// 需要构建一个 代码自动生成器 对象
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("");
gc.setOpen(false);
// 是否覆盖
gc.setFileOverride(false);
// 去Service的I前缀
// gc.setEntityName("%sDO");
gc.setServiceName("%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");
gc.setDateType(DateType.ONLY_DATE);
gc.setIdType(IdType.UUID);
// gc.setSwagger2(true); 实体属性 Swagger2 注解
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:oracle:thin:@192.168.2.218:1521:orcl");
dsc.setDriverName("oracle.jdbc.driver.OracleDriver");
dsc.setUsername("bdcdjsb");
dsc.setPassword("bdcdjsb");
dsc.setDbType(DbType.ORACLE);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
//TODO
pc.setModuleName("system");
pc.setParent("com");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
templateConfig.setEntity("templates/entity2.java");
templateConfig.setMapper("templates/mapper2.java");
templateConfig.setService("templates/service2.java");
templateConfig.setServiceImpl("templates/serviceImpl2.java");
templateConfig.setController("templates/controller2.java");
templateConfig.setXml("templates/mapper2.xml");
mpg.setTemplate(templateConfig);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
// 设置要映射的表名
strategy.setInclude("DJF_DJ_SJ");
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// 自动lombok;
strategy.setEntityLombokModel(true);
mpg.setStrategy(strategy);
//设置Freemarker模板引擎
mpg.setTemplateEngine(new MyFreemarkerTemplateEngine());
mpg.execute(); //执行
}
}
package com.pashanhoo.common.util;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import org.apache.commons.collections.CollectionUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TreeUtil {
/**
* 比较规则
*/
private static Comparator comparator;
/**
* 树节点Class类型
*/
private static Class<?> treeNodeClass;
/**
* 主键的get方法对应的Method对象
*/
private static Method getKeyMethod;
/**
* 获取父节点id的get方法对应的Method对象
*/
private static Method getParentIdMethod;
/**
* 设置子元素对应的方法的Method对象
*/
private static Method setChildrenMethod;
/**
* @param comparator
* @param treeNodeClass
* @param key 首字母大写的主键字段名称
*/
public static void setRule(Comparator comparator, Class<?> treeNodeClass, String key) {
TreeUtil.comparator = comparator;
TreeUtil.treeNodeClass = treeNodeClass;
try {
TreeUtil.getKeyMethod = treeNodeClass.getMethod("get" + key);
TreeUtil.getParentIdMethod = treeNodeClass.getMethod("getParentId");
TreeUtil.setChildrenMethod = treeNodeClass.getMethod("setChildren", List.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
/**
* 将符合条件的List转为Tree
*
* @param
* @param rootId
* @return
*/
public static <TreeNode> List<TreeNode> listToTree(List<TreeNode> treeNodes, String rootId) {
if (CollectionUtils.isEmpty(treeNodes)) {
return Lists.newArrayList();
}
//parent -> [data1, data2 ...]
Multimap<String, TreeNode> parentMap = ArrayListMultimap.create();
//记录parentMap
List<TreeNode> rootList = Lists.newArrayList();
for (TreeNode treeNode : treeNodes) {
String parentId = null;
try {
parentId = (String) getParentIdMethod.invoke(treeNode);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
parentMap.put(parentId, treeNode);
//从根节点的下一级构造树
//rootId为null,从最顶部构造整棵树
if (rootId == null) {
if (parentId == null) {
rootList.add(treeNode);
}
}
if (StringUtils.isNotBlank(parentId) && parentId.equals(rootId)) {
rootList.add(treeNode);
}
}
// 对树节点进行排序
Collections.sort(rootList, comparator);
// 递归生成树
transformTree(rootList, parentMap);
return rootList;
}
private static <TreeNode> void transformTree(List<TreeNode> treeNodeList, Multimap<String, TreeNode> parentMap) {
for (int i = 0; i < treeNodeList.size(); i++) {
// 遍历该层的每个元素
TreeNode treeNode = treeNodeList.get(i);
//获取当前节点下一层节点的List数据
List<TreeNode> tempList = null;
try {
tempList = (List<TreeNode>) parentMap.get((String) getKeyMethod.invoke(treeNode));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
if (CollectionUtils.isNotEmpty(tempList)) {
//首先排序下一层节点
Collections.sort(tempList, comparator);
//将下一层节点数据设置为当前节点的Children数据
try {
setChildrenMethod.invoke(treeNode, tempList);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
// 进入到下一层处理
transformTree(tempList, parentMap);
}
}
}
}
package com.pashanhoo.common.util.mybatisplus;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import java.io.File;
import java.util.*;
public abstract class AbstractTemplateEngineLocal extends AbstractTemplateEngine {
private void fitAddEntityRequest(List<TableField> tableFields, TableInfo tableInfo) {
for(Iterator<TableField> it = tableFields.iterator(); it.hasNext();){
TableField tableField =it.next();
if(tableField.isKeyIdentityFlag() || "ADDTIME".equals(tableField.getName()) || "EDITTIME".equals(tableField.getName())) {
it.remove();
}
}
Set<String> importPacks = tableInfo.getImportPackages();
for(Iterator<String> it = importPacks.iterator(); it.hasNext();){
String importPack = it.next();
if(importPack.indexOf("baomidou") > 0){
it.remove();
}
}
}
private void fillEntityProp(Map<String, Object> objectMap) {
TableInfo tableInfo = (TableInfo) objectMap.get("table");
int addFieldFillPacCount = 0;
for(TableField tableField : tableInfo.getFields()) {
tableField.setConvert(true);
if("ADDTIME".equals(tableField.getName())) {
tableField.setFill("INSERT");
if(addFieldFillPacCount == 0) {
tableInfo.getImportPackages().add("com.baomidou.mybatisplus.annotation.FieldFill");
addFieldFillPacCount++;
}
}
if("UPDATETIME".equals(tableField.getName())) {
tableField.setFill("INSERT_UPDATE");
}
}
}
/**
* list深度拷贝
* @param list
* @return
*/
public List copyList(List list) {
//list深度拷贝
List<Integer> newList = new ArrayList<>();
org.apache.commons.collections.CollectionUtils.addAll(newList, new Object[list.size()]);
Collections.copy(newList, list);
return newList;
}
/**
* 输出 java xml 文件
*/
@Override
public AbstractTemplateEngine batchOutput() {
try {
List<TableInfo> tableInfoList = getConfigBuilder().getTableInfoList();
for (TableInfo tableInfo : tableInfoList) {
Map<String, Object> objectMap = getObjectMap(tableInfo);
Map<String, String> pathInfo = getConfigBuilder().getPathInfo();
TemplateConfig template = getConfigBuilder().getTemplate();
// 自定义内容
InjectionConfig injectionConfig = getConfigBuilder().getInjectionConfig();
if (null != injectionConfig) {
injectionConfig.initTableMap(tableInfo);
objectMap.put("cfg", injectionConfig.getMap());
List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
if (CollectionUtils.isNotEmpty(focList)) {
for (FileOutConfig foc : focList) {
if (isCreate(FileType.OTHER, foc.outputFile(tableInfo))) {
writer(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
}
}
}
}
// Mp.java
String entityName = tableInfo.getEntityName();
List<TableField> originalTableFieldList = tableInfo.getFields();
if (null != entityName && null != pathInfo.get(ConstVal.ENTITY_PATH)) {
fillEntityProp(objectMap);
String entityFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + "DO" + suffixJavaOrKt()), entityName) ;
if (isCreate(FileType.ENTITY, entityFile)) {
writer(objectMap, templateFilePath(template.getEntity(getConfigBuilder().getGlobalConfig().isKotlin())), entityFile);
}
List<TableField> originalTableFields = tableInfo.getFields();
List<TableField> addEntityTableFieldList = copyList(tableInfo.getFields());
fitAddEntityRequest(addEntityTableFieldList, tableInfo);
tableInfo.setFields(addEntityTableFieldList);
//向ObjectMap中添加首字母小写的实体对象名
String entity = (String) objectMap.get("entity");
objectMap.put("lowerEntity", entity.toLowerCase());
//AddEntityRequest.java
fitAddEntityRequest(tableInfo.getFields(), tableInfo);
String addEntityRequestFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), "Add" + entityName + "Request");
if (isCreate(FileType.ENTITY, addEntityRequestFile)) {
writer(objectMap, "templates/AddEntityRequest.java.ftl", addEntityRequestFile);
}
//UpdateEntityRequest.java
fitAddEntityRequest(tableInfo.getFields(), tableInfo);
String updateEntityRequestFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), "Update" + entityName + "Request");
if (isCreate(FileType.ENTITY, updateEntityRequestFile)) {
writer(objectMap, "templates/UpdateEntityRequest.java.ftl", updateEntityRequestFile);
}
//EntitySearchRequest.java
String entitySearchRequestFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), entityName + "SearchRequest");
if (isCreate(FileType.ENTITY, entitySearchRequestFile)) {
writer(objectMap, "templates/EntitySearchRequest.java.ftl", entitySearchRequestFile);
}
tableInfo.setFields(originalTableFields);
//EntityListVO.java
String entityListVOFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), entityName + "ListVO");
if (isCreate(FileType.ENTITY, entityListVOFile)) {
writer(objectMap, "templates/EntityListVO.java.ftl", entityListVOFile);
}
//EntityDetailVO.java
String entityDetailVOFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), entityName + "DetailVO");
if (isCreate(FileType.ENTITY, entityDetailVOFile)) {
writer(objectMap, "templates/EntityDetailVO.java.ftl", entityDetailVOFile);
}
}
//converter.java
String entityConverterFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), entityName + "Converter");
if (isCreate(FileType.ENTITY, entityConverterFile)) {
writer(objectMap, "templates/entityConverter.java.ftl", entityConverterFile);
}
// MpMapper.java
if (null != tableInfo.getMapperName() && null != pathInfo.get(ConstVal.MAPPER_PATH)) {
String mapperFile = String.format((pathInfo.get(ConstVal.MAPPER_PATH) + File.separator + tableInfo.getMapperName() + suffixJavaOrKt()), entityName);
if (isCreate(FileType.MAPPER, mapperFile)) {
writer(objectMap, templateFilePath(template.getMapper()), mapperFile);
}
}
// MpMapper.xml
if (null != tableInfo.getXmlName() && null != pathInfo.get(ConstVal.XML_PATH)) {
String xmlFile = String.format((pathInfo.get(ConstVal.XML_PATH) + File.separator + tableInfo.getXmlName() + ConstVal.XML_SUFFIX), entityName);
if (isCreate(FileType.XML, xmlFile)) {
writer(objectMap, templateFilePath(template.getXml()), xmlFile);
}
}
// IMpService.java
if (null != tableInfo.getServiceName() && null != pathInfo.get(ConstVal.SERVICE_PATH)) {
String serviceFile = String.format((pathInfo.get(ConstVal.SERVICE_PATH) + File.separator + tableInfo.getServiceName() + suffixJavaOrKt()), entityName);
if (isCreate(FileType.SERVICE, serviceFile)) {
writer(objectMap, templateFilePath(template.getService()), serviceFile);
}
}
// MpServiceImpl.java
if (null != tableInfo.getServiceImplName() && null != pathInfo.get(ConstVal.SERVICE_IMPL_PATH)) {
String implFile = String.format((pathInfo.get(ConstVal.SERVICE_IMPL_PATH) + File.separator + tableInfo.getServiceImplName() + suffixJavaOrKt()), entityName);
if (isCreate(FileType.SERVICE_IMPL, implFile)) {
writer(objectMap, templateFilePath(template.getServiceImpl()), implFile);
}
}
// MpController.java
if (null != tableInfo.getControllerName() && null != pathInfo.get(ConstVal.CONTROLLER_PATH)) {
String controllerFile = String.format((pathInfo.get(ConstVal.CONTROLLER_PATH) + File.separator + tableInfo.getControllerName() + suffixJavaOrKt()), entityName);
if (isCreate(FileType.CONTROLLER, controllerFile)) {
writer(objectMap, templateFilePath(template.getController()), controllerFile);
}
}
}
} catch (Exception e) {
logger.error("无法创建文件,请检查配置信息!", e);
}
return this;
}
}
package com.pashanhoo.common.util.mybatisplus;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Map;
public class MyFreemarkerTemplateEngine extends AbstractTemplateEngineLocal {
private Configuration configuration;
@Override
public MyFreemarkerTemplateEngine init(ConfigBuilder configBuilder) {
super.init(configBuilder);
configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
configuration.setDefaultEncoding(ConstVal.UTF8);
configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, StringPool.SLASH);
return this;
}
@Override
public void writer(Map<String, Object> objectMap, String templatePath, String outputFile) throws Exception {
Template template = configuration.getTemplate(templatePath);
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFile)) {
template.process(objectMap, new OutputStreamWriter(fileOutputStream, ConstVal.UTF8));
}
logger.debug("模板:" + templatePath + "; 文件:" + outputFile);
}
@Override
public String templateFilePath(String filePath) {
return filePath + ".ftl";
}
}
package com.pashanhoo.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
package com.pashanhoo.dictionary.controller;
import com.github.pagehelper.PageInfo;
import com.pashanhoo.common.Result;
import com.pashanhoo.common.util.TreeUtil;
import com.pashanhoo.dictionary.model.dto.SysDict;
import com.pashanhoo.dictionary.model.vo.EditDictVo;
import com.pashanhoo.dictionary.model.vo.GetSysDictParentVo;
import com.pashanhoo.dictionary.model.vo.SysDictVo;
import com.pashanhoo.dictionary.service.SysDictService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Api(tags = "字典表")
@RestController
@RequestMapping("/SysDict")
public class SysDictController {
@Autowired
SysDictService sysDictService;
@ApiOperation("获取字典表父级集合")
@PostMapping("getSysDictParent")
public Result<PageInfo<GetSysDictParentVo>> getSysDictParent(@RequestBody SysDictVo request) {
return Result.ok(sysDictService.getSysDictParent(request));
}
@ApiOperation("编辑界面获取指定字典编码子集")
@GetMapping("getSysDictByTypeId")
public Result<List<SysDict>> getSysDictByTypeId(@ApiParam("类型ID") @RequestParam String typeId) {
List<SysDict> dicts = sysDictService.getSysDictByTypeId(typeId);
TreeUtil.setRule((o1, o2) -> 0, SysDict.class,"DictId");
List<SysDict> tree = TreeUtil.listToTree(dicts, typeId);
return Result.ok(tree);
}
@ApiOperation("编辑")
@PostMapping("editSysDictByTypeId")
public Result editSysDictByTypeId(@RequestBody EditDictVo request) {
int row = sysDictService.editSysDict(request);
if (row != 0) {
return Result.ok("修改成功");
} else {
return Result.ok("修改失败");
}
}
@ApiOperation("返回json")
@GetMapping("getJson")
public Result getJson() {
List<SysDict> dicts = sysDictService.selectAll();
TreeUtil.setRule(new Comparator<SysDict>() {
@Override
public int compare(SysDict o1, SysDict o2) {
if (o1.getSort() == null) {
o1.setSort((short) 0);
}
if (o2.getSort() == null) {
o2.setSort((short) 0);
}
return o1.getSort() - o2.getSort();
}
}, SysDict.class, "DictId");
List<SysDict> tree = TreeUtil.listToTree(dicts, null);
Map<String, List<SysDict>> map = new HashMap<>();
for (SysDict SYSDICT : tree) {
map.put(SYSDICT.getDcode(), SYSDICT.getChildren());
}
return Result.ok(map);
}
}
package com.pashanhoo.dictionary.dao;
import com.pashanhoo.dictionary.model.dto.SysDict;
import com.pashanhoo.dictionary.model.vo.GetSysDictParentVo;
import com.pashanhoo.dictionary.model.vo.SysDictVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface SysDictMapper {
/**
* delete by primary key
*
* @param dictid primaryKey
* @return deleteCount
*/
int deleteByPrimaryKey(String dictid);
/**
* insert record to table
*
* @param record the record
* @return insert count
*/
int insert(SysDict record);
/**
* insert record to table selective
*
* @param record the record
* @return insert count
*/
int insertSelective(SysDict record);
/**
* select by primary key
*
* @param dictid primary key
* @return object by primary key
*/
SysDict selectByPrimaryKey(String dictid);
/**
* update record selective
*
* @param record the updated record
* @return update count
*/
int updateByPrimaryKeySelective(SysDict record);
/**
* update record
*
* @param record the updated record
* @return update count
*/
int updateByPrimaryKey(SysDict record);
int updateBatch(List<SysDict> list);
int updateBatchSelective(List<SysDict> list);
int batchInsert(@Param("list") List<SysDict> list);
List<GetSysDictParentVo> getSysDictParent(@Param("request") SysDictVo request);
List<SysDict> getSysDictByTypeId(@Param("typeId") String typeId);
int deleteListByPrimaryKey(@Param("dictWithoutParent") List<SysDict> dictWithoutParent);
List<SysDict> selectAll();
int deleteByTypeId(@Param("typeid") String typeid);
}
package com.pashanhoo.dictionary.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 字典表
*/
@ApiModel(value = "extraction-model-SysDict")
@Data
public class SysDict implements Serializable {
/**
* 字典主键
*/
@ApiModelProperty(value = "字典主键")
private String dictId;
/**
* 父级ID
*/
@ApiModelProperty(value = "父级ID")
private String parentId;
/**
* 字典编码
*/
@ApiModelProperty(value = "字典编码")
private String dcode;
/**
* 字典名称
*/
@ApiModelProperty(value = "字典名称")
private String dname;
/**
* 排序号
*/
@ApiModelProperty(value = "排序号")
private Short sort;
/**
* 是否树形
*/
@ApiModelProperty(value = "是否树形")
private String isTree;
/**
* 类型ID
*/
@ApiModelProperty(value = "类型ID")
private String typeId;
private List<SysDict> children;
private static final long serialVersionUID = 1L;
}
package com.pashanhoo.dictionary.model.vo;
import com.pashanhoo.dictionary.model.dto.SysDict;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@ApiModel("字典表编辑请求实体")
@EqualsAndHashCode(callSuper = false)
public class EditDictVo {
List<SysDict> editDicts;
}
package com.pashanhoo.dictionary.model.vo;
import com.pashanhoo.dictionary.model.dto.SysDict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@ApiModel("获取字典表父级集合实体")
@EqualsAndHashCode(callSuper = false)
public class GetSysDictParentVo {
/**
* 字典主键
*/
@ApiModelProperty(value = "字典主键")
private String dictId;
/**
* 父级ID
*/
@ApiModelProperty(value = "父级ID")
private String parentId;
/**
* 字典编码
*/
@ApiModelProperty(value = "字典编码")
private String dcode;
/**
* 字典名称
*/
@ApiModelProperty(value = "字典名称")
private String dname;
/**
* 排序号
*/
@ApiModelProperty(value = "排序号")
private Short sort;
/**
* 是否树形
*/
@ApiModelProperty(value = "是否树形")
private String isTree;
/**
* 类型ID
*/
@ApiModelProperty(value = "类型ID")
private String typeId;
/**
* 序号
*/
@ApiModelProperty(value = "序号")
private Integer rowNum;
private List<SysDict> children;
private static final long serialVersionUID = 1L;
}
package com.pashanhoo.dictionary.model.vo;
import com.pashanhoo.common.PageInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@ApiModel("字典表请求实体")
@EqualsAndHashCode(callSuper = false)
public class SysDictVo extends PageInfo implements Serializable {
/**
* 字典编码
*/
@ApiModelProperty(value = "字典编码")
private String dcode;
/**
* 字典名称
*/
@ApiModelProperty(value = "字典名称")
private String dname;
/**
* 类型ID
*/
@ApiModelProperty(value = "类型ID")
private String typeId;
}
package com.pashanhoo.dictionary.service;
import com.github.pagehelper.PageInfo;
import com.pashanhoo.dictionary.model.dto.SysDict;
import com.pashanhoo.dictionary.model.vo.EditDictVo;
import com.pashanhoo.dictionary.model.vo.GetSysDictParentVo;
import com.pashanhoo.dictionary.model.vo.SysDictVo;
import java.util.List;
public interface SysDictService {
/**
* 删除
* @param dictid
* @return
*/
int deleteByPrimaryKey(String dictid);
/**
* 插入
* @param record
* @return
*/
int insert(SysDict record);
/**
* 插入
* @param record
* @return
*/
int insertSelective(SysDict record);
/**
* 查询
* @param dictid
* @return
*/
SysDict selectByPrimaryKey(String dictid);
/**
* 更新
* @param record
* @return
*/
int updateByPrimaryKeySelective(SysDict record);
/**
* 更新
* @param record
* @return
*/
int updateByPrimaryKey(SysDict record);
/**
* 批量更新
* @param list
* @return
*/
int updateBatch(List<SysDict> list);
/**
* 批量更新
* @param list
* @return
*/
int updateBatchSelective(List<SysDict> list);
/**
* 批量插入
* @param list
* @return
*/
int batchInsert(List<SysDict> list);
/**
* 获取父级字典表
* @param request
* @return
*/
PageInfo<GetSysDictParentVo> getSysDictParent(SysDictVo request);
/**
* 根据typeId查询
* @param typeId
* @return
*/
List<SysDict> getSysDictByTypeId(String typeId);
/**
* 编辑字典表
* @param request
* @return
*/
int editSysDict(EditDictVo request);
/**
* 查询全部
* @return
*/
List<SysDict> selectAll();
}
package com.pashanhoo.dictionary.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.pashanhoo.dictionary.dao.SysDictMapper;
import com.pashanhoo.dictionary.model.dto.SysDict;
import com.pashanhoo.dictionary.model.vo.EditDictVo;
import com.pashanhoo.dictionary.model.vo.GetSysDictParentVo;
import com.pashanhoo.dictionary.model.vo.SysDictVo;
import com.pashanhoo.dictionary.service.SysDictService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class SysDictServiceImpl implements SysDictService {
@Resource
private SysDictMapper sysDictMapper;
/**
* 查询
* @param dictid
* @return
*/
@Override
public int deleteByPrimaryKey(String dictid) {
return sysDictMapper.deleteByPrimaryKey(dictid);
}
/**
* 插入
* @param record
* @return
*/
@Override
public int insert(SysDict record) {
return sysDictMapper.insert(record);
}
/**
* 插入
* @param record
* @return
*/
@Override
public int insertSelective(SysDict record) {
return sysDictMapper.insertSelective(record);
}
/**
* 查询
* @param dictid
* @return
*/
@Override
public SysDict selectByPrimaryKey(String dictid) {
return sysDictMapper.selectByPrimaryKey(dictid);
}
/**
* 更新
* @param record
* @return
*/
@Override
public int updateByPrimaryKeySelective(SysDict record) {
return sysDictMapper.updateByPrimaryKeySelective(record);
}
/**
* 更新
* @param record
* @return
*/
@Override
public int updateByPrimaryKey(SysDict record) {
return sysDictMapper.updateByPrimaryKey(record);
}
/**
* 批量更新
* @param list
* @return
*/
@Override
public int updateBatch(List<SysDict> list) {
return sysDictMapper.updateBatch(list);
}
/**
* 批量更新
* @param list
* @return
*/
@Override
public int updateBatchSelective(List<SysDict> list) {
return sysDictMapper.updateBatchSelective(list);
}
/**
* 批量插入
* @param list
* @return
*/
@Override
public int batchInsert(List<SysDict> list) {
return sysDictMapper.batchInsert(list);
}
/**
* 获取父级字典表
* @param request
* @return
*/
@Override
public PageInfo<GetSysDictParentVo> getSysDictParent(SysDictVo request) {
PageHelper.startPage(request.getCurrentPage(), request.getPageSize());
List<GetSysDictParentVo> list = sysDictMapper.getSysDictParent(request);
return new PageInfo<>(list);
}
/**
* 根据typeId查询字典表
* @param typeId
* @return
*/
@Override
public List<SysDict> getSysDictByTypeId(String typeId) {
return sysDictMapper.getSysDictByTypeId(typeId);
}
/**
* root节点只做更新,子节点全部删除再批量插入
* @param request
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int editSysDict(EditDictVo request) {
List<SysDict> editDicts = request.getEditDicts();
List<SysDict> parent = editDicts.stream().filter(item -> item.getParentId() == null).collect(Collectors.toList());
sysDictMapper.updateByPrimaryKey(parent.get(0));
List<SysDict> dictWithoutParent = editDicts.stream().filter(item -> item.getParentId() != null).collect(Collectors.toList());
List<SysDict> result = new ArrayList<>();
//递归所有子集
List<SysDict> resultList = getAllSysDict(dictWithoutParent,result);
//删除除了根目录的所有子集
sysDictMapper.deleteByTypeId(resultList.get(0).getTypeId());
return sysDictMapper.batchInsert(resultList);
}
/**
* 查询所有字典表
* @return
*/
@Override
public List<SysDict> selectAll() {
return sysDictMapper.selectAll();
}
private List<SysDict> getAllSysDict(List<SysDict> dicts, List<SysDict> result) {
for (SysDict SYSDICT : dicts) {
List<SysDict> children = SYSDICT.getChildren();
result.add(SYSDICT);
if (children != null) {
getAllSysDict(children, result);
}
}
return result;
}
}
server:
port: 8866
servlet:
session:
timeout: 43200
spring:
servlet:
multipart:
maxFileSize: 10MB
maxRequestSize: 10MB
application:
name: archive-system
profiles:
active: dev
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
default-property-inclusion: non_null
datasource:
driver-class-name: oracle.jdbc.driver.OracleDriver
username: bdcdjsb
password: bdcdjsb
url: jdbc:oracle:thin:@192.168.2.218:1521:orcl
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
typeAliasesPackage: archive
global-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: 2
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: 1
#驼峰下划线转换
db-column-underline: true
#刷新mapper 调试神器
refresh-mapper: true
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
#key-generator: com.baomidou.springboot.xxx
#逻辑删除配置
logic-delete-value: -1
logic-not-delete-0: 0
#自定义填充策略接口实现
#meta-object-handler: com.baomidou.springboot.xxx
#自定义SQL注入器
# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
management:
endpoints:
web:
exposure:
include: "*"
logging:
level:
rent:
mapper: debug
config: "classpath:logback-spring.xml"
#app:
# attachment[0]:
# name: S1
# type: minIO
# params:
# type: http://
# bucket: archiveSystem
# host: 192.168.2.218
# port: 9000
# user: minioadmin
# password: minioadmin
spring:
profiles:
active: @profile.active@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->
<contextName>logback</contextName>
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
<property name="log.path" value="/home/project/logs" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--输出到文件-->
<!-- 时间滚动输出 level为 DEBUG 日志 -->
<!-- <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">-->
<!-- &lt;!&ndash; 正在记录的日志文件的路径及文件名 &ndash;&gt;-->
<!-- <file>${log.path}/log_debug.log</file>-->
<!-- &lt;!&ndash;日志文件输出格式&ndash;&gt;-->
<!-- <encoder>-->
<!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>-->
<!-- <charset>UTF-8</charset> &lt;!&ndash; 设置字符集 &ndash;&gt;-->
<!-- </encoder>-->
<!-- &lt;!&ndash; 日志记录器的滚动策略,按日期,按大小记录 &ndash;&gt;-->
<!-- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">-->
<!-- &lt;!&ndash; 日志归档 &ndash;&gt;-->
<!-- <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>-->
<!-- <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">-->
<!-- <maxFileSize>100MB</maxFileSize>-->
<!-- </timeBasedFileNamingAndTriggeringPolicy>-->
<!-- &lt;!&ndash;日志文件保留天数&ndash;&gt;-->
<!-- <maxHistory>15</maxHistory>-->
<!-- </rollingPolicy>-->
<!-- &lt;!&ndash; 此日志文件只记录debug级别的 &ndash;&gt;-->
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!-- <level>debug</level>-->
<!-- <onMatch>ACCEPT</onMatch>-->
<!-- <onMismatch>DENY</onMismatch>-->
<!-- </filter>-->
<!-- </appender>-->
<!-- 时间滚动输出 level为 INFO 日志 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_info.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 时间滚动输出 level为 WARN 日志 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<logger name="house.platform.mapper" level="DEBUG" />
<!-- 时间滚动输出 level为 ERROR 日志 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文件的路径及文件名 -->
<file>${log.path}/log_error.log</file>
<!--日志文件输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文件只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性,
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
如果未设置此属性,那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true。
-->
<!--<logger name="org.springframework.web" level="info"/>-->
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->
<!--
使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
-->
<!--
root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
不能设置为INHERITED或者同义词NULL。默认是DEBUG
可以包含零个或多个元素,标识这个appender将会添加到这个logger。
-->
<!--开发环境:打印控制台-->
<springProfile name="dev">
<logger name="com.house" level="info"/>
</springProfile>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<!-- <appender-ref ref="DEBUG_FILE" />-->
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!--生产环境:输出到文件-->
<!--<springProfile name="pro">-->
<!--<root level="info">-->
<!--<appender-ref ref="CONSOLE" />-->
<!--<appender-ref ref="DEBUG_FILE" />-->
<!--<appender-ref ref="INFO_FILE" />-->
<!--<appender-ref ref="ERROR_FILE" />-->
<!--<appender-ref ref="WARN_FILE" />-->
<!--</root>-->
<!--</springProfile>-->
</configuration>
<?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.pashanhoo.dictionary.dao.SysDictMapper">
<resultMap id="BaseResultMap" type="com.pashanhoo.dictionary.model.dto.SysDict">
<!--@mbg.generated-->
<!--@Table SYS_DICT-->
<id column="DICTID" jdbcType="VARCHAR" property="dictId"/>
<result column="PARENTID" jdbcType="VARCHAR" property="parentId"/>
<result column="DCODE" jdbcType="VARCHAR" property="dcode"/>
<result column="DNAME" jdbcType="VARCHAR" property="dname"/>
<result column="SORT" jdbcType="DECIMAL" property="sort"/>
<result column="ISTREE" jdbcType="CHAR" property="isTree"/>
<result column="TYPEID" jdbcType="VARCHAR" property="typeId"/>
</resultMap>
<sql id="Base_Column_List">
<!--@mbg.generated-->
DICTID, PARENTID, DCODE, DNAME, SORT, ISTREE, TYPEID
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
<!--@mbg.generated-->
select
<include refid="Base_Column_List"/>
from SYS_DICT
where DICTID = #{dictid,jdbcType=VARCHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
<!--@mbg.generated-->
delete
from SYS_DICT
where DICTID = #{dictid,jdbcType=VARCHAR}
</delete>
<insert id="insert" parameterType="com.pashanhoo.dictionary.model.dto.SysDict">
<!--@mbg.generated-->
insert into SYS_DICT (DICTID, PARENTID, DCODE,
DNAME, SORT, ISTREE, TYPEID)
values (#{dictId,jdbcType=VARCHAR}, #{parentId,jdbcType=VARCHAR}, #{dcode,jdbcType=VARCHAR},
#{dname,jdbcType=VARCHAR}, #{sort,jdbcType=DECIMAL}, #{isTree,jdbcType=CHAR},
#{typeId,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.pashanhoo.dictionary.model.dto.SysDict">
<!--@mbg.generated-->
insert into SYS_DICT
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="dictId != null">
DICTID,
</if>
<if test="parentId != null">
PARENTID,
</if>
<if test="dcode != null">
DCODE,
</if>
<if test="dname != null">
DNAME,
</if>
<if test="sort != null">
SORT,
</if>
<if test="isTree != null">
ISTREE,
</if>
<if test="typeId != null">
TYPEID,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="dictId != null">
#{dictId,jdbcType=VARCHAR},
</if>
<if test="parentId != null">
#{parentId,jdbcType=VARCHAR},
</if>
<if test="dcode != null">
#{dcode,jdbcType=VARCHAR},
</if>
<if test="dname != null">
#{dname,jdbcType=VARCHAR},
</if>
<if test="sort != null">
#{sort,jdbcType=DECIMAL},
</if>
<if test="isTree != null">
#{isTree,jdbcType=CHAR},
</if>
<if test="typeId != null">
#{typeId,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.pashanhoo.dictionary.model.dto.SysDict">
<!--@mbg.generated-->
update SYS_DICT
<set>
<if test="parentId != null">
PARENTID = #{parentId,jdbcType=VARCHAR},
</if>
<if test="dcode != null">
DCODE = #{dcode,jdbcType=VARCHAR},
</if>
<if test="dname != null">
DNAME = #{dname,jdbcType=VARCHAR},
</if>
<if test="sort != null">
SORT = #{sort,jdbcType=DECIMAL},
</if>
<if test="isTree != null">
ISTREE = #{isTree,jdbcType=CHAR},
</if>
<if test="typeId != null">
TYPEID = #{typeId,jdbcType=VARCHAR},
</if>
</set>
where DICTID = #{dictId,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKey" parameterType="com.pashanhoo.dictionary.model.dto.SysDict">
<!--@mbg.generated-->
update SYS_DICT
set PARENTID = #{parentId,jdbcType=VARCHAR},
DCODE = #{dcode,jdbcType=VARCHAR},
DNAME = #{dname,jdbcType=VARCHAR},
SORT = #{sort,jdbcType=DECIMAL},
ISTREE = #{isTree,jdbcType=CHAR},
TYPEID = #{typeId,jdbcType=VARCHAR}
where DICTID = #{dictId,jdbcType=VARCHAR}
</update>
<update id="updateBatch" parameterType="java.util.List">
<!--@mbg.generated-->
update SYS_DICT
<trim prefix="set" suffixOverrides=",">
<trim prefix="PARENTID = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.parentId,jdbcType=VARCHAR}
</foreach>
</trim>
<trim prefix="DCODE = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.dcode,jdbcType=VARCHAR}
</foreach>
</trim>
<trim prefix="DNAME = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.dname,jdbcType=VARCHAR}
</foreach>
</trim>
<trim prefix="SORT = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.sort,jdbcType=DECIMAL}
</foreach>
</trim>
<trim prefix="ISTREE = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.isTree,jdbcType=CHAR}
</foreach>
</trim>
<trim prefix="TYPEID = case" suffix="end,">
<foreach collection="list" index="index" item="item">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.typeId,jdbcType=VARCHAR}
</foreach>
</trim>
</trim>
where DICTID in
<foreach close=")" collection="list" item="item" open="(" separator=", ">
#{item.dictId,jdbcType=VARCHAR}
</foreach>
</update>
<update id="updateBatchSelective" parameterType="java.util.List">
<!--@mbg.generated-->
update SYS_DICT
<trim prefix="set" suffixOverrides=",">
<trim prefix="PARENTID = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.parentId != null">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.parentId,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
<trim prefix="DCODE = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.dcode != null">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.dcode,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
<trim prefix="DNAME = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.dname != null">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.dname,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
<trim prefix="SORT = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.sort != null">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.sort,jdbcType=DECIMAL}
</if>
</foreach>
</trim>
<trim prefix="ISTREE = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.isTree != null">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.isTree,jdbcType=CHAR}
</if>
</foreach>
</trim>
<trim prefix="TYPEID = case" suffix="end,">
<foreach collection="list" index="index" item="item">
<if test="item.typeId != null">
when DICTID = #{item.dictId,jdbcType=VARCHAR} then #{item.typeId,jdbcType=VARCHAR}
</if>
</foreach>
</trim>
</trim>
where DICTID in
<foreach close=")" collection="list" item="item" open="(" separator=", ">
#{item.dictId,jdbcType=VARCHAR}
</foreach>
</update>
<insert id="batchInsert" parameterType="map">
<!--@mbg.generated-->
insert into SYS_DICT
(DICTID, PARENTID, DCODE, DNAME, SORT, ISTREE, TYPEID)
<foreach collection="list" item="item" index="index" separator="union all">
(select #{item.dictId,jdbcType=VARCHAR},
#{item.parentId,jdbcType=VARCHAR},
#{item.dcode,jdbcType=VARCHAR},
#{item.dname,jdbcType=VARCHAR},
#{item.sort,jdbcType=DECIMAL},
#{item.isTree,jdbcType=CHAR},
#{item.typeId,jdbcType=VARCHAR}
from dual)
</foreach>
</insert>
<select id="getSysDictParent" resultType="com.pashanhoo.dictionary.model.vo.GetSysDictParentVo">
select rownum,SD.*
from SYS_DICT SD
<where>
PARENTID is null
<if test="request.dcode != null and request.dcode != ''">
and DCODE like '%'||#{request.dcode,jdbcType=VARCHAR}||'%'
</if>
<if test="request.dname != null and request.dname != ''">
and DNAME like '%'||#{request.dname,jdbcType=VARCHAR}||'%'
</if>
</where>
</select>
<select id="getSysDictByTypeId" resultMap="BaseResultMap">
select *
from SYS_DICT
where TYPEID = #{typeId,jdbcType=VARCHAR}
and PARENTID is not null
</select>
<delete id="deleteListByPrimaryKey">
delete
from SYS_DICT
where
DICTID in
<foreach collection="dictWithoutParent" index="index" item="item" open="(" close=")" separator=",">
#{item.dictId,jdbcType=VARCHAR}
</foreach>
</delete>
<select id="selectAll" resultMap="BaseResultMap">
select *
from SYS_DICT
</select>
<delete id="deleteByTypeId">
delete from SYS_DICT where TYPEID = #{typeid,jdbcType=VARCHAR} and PARENTID is not null
</delete>
</mapper>