feat: 代码生成器生成subject_liked模块基础代码

This commit is contained in:
2024-03-08 13:54:28 +08:00
parent dfe75eec5a
commit f613d757c0
71 changed files with 3293 additions and 0 deletions

31
qing-yu-club-gen/pom.xml Normal file
View File

@@ -0,0 +1,31 @@
<?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.landaiqing</groupId>
<artifactId>qing-yu-club-gen</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>qing-yu-club-gen</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.landaiqing</groupId>
<artifactId>easy-gen-code-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,58 @@
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.landaiqing.core.config.GenConfig;
import com.landaiqing.core.config.MapperConfig;
import com.landaiqing.core.core.sdk.PostCurFiledContextAware;
import com.landaiqing.core.entity.TableInfo;
import com.landaiqing.core.utils.MySQLToJavaTypeConverter;
import org.apache.velocity.VelocityContext;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BizPutContextHandler implements PostCurFiledContextAware {
public static String underlineToHump(String str, boolean removePre) {
if (removePre) {
str = str.substring(str.indexOf("_"));
}
str = str.toLowerCase();
Pattern compile = Pattern.compile("_[a-z]");
Matcher matcher = compile.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group(0).toUpperCase().replace("_", ""));
}
matcher.appendTail(sb);
return StrUtil.upperFirst(sb.toString());
}
private static String convert(String str) {
if (str == null || str.isEmpty()) {
return str;
}
char firstChar = str.charAt(0);
char lowerFirstChar = Character.toLowerCase(firstChar);
return lowerFirstChar + str.substring(1);
}
@Override
public void doAware(GenConfig genConfig, MapperConfig mapperConfig, VelocityContext context) {
// 处理导包标志位
List<TableInfo> files = JSONObject.parseArray(JSONObject.toJSONString(context.get("fields")), TableInfo.class);
for (TableInfo tableInfo : files) {
MySQLToJavaTypeConverter.Item typeInfo = tableInfo.getTypeInfo(tableInfo.getType());
if (typeInfo.isFlag()) {
context.put("import" + typeInfo.getType(), true);
}
}
context.put("modelName", underlineToHump(genConfig.getJdbc().getTableName(), Convert.toBool(context.get("removePre"))));
context.put("_modelName", convert(context.get("modelName").toString()));
context.put("tableName", genConfig.getJdbc().getTableName());
}
}

View File

@@ -0,0 +1,9 @@
import com.landaiqing.core.core.CodeGenerationCode;
public class GenCodeMain {
public static void main(String[] args) {
CodeGenerationCode.doGenCode(new BizPutContextHandler());
}
}

View File

@@ -0,0 +1,69 @@
# auth模块映射关系 ${module} 占位符
# 模板文件和生成类的映射关系 多个文件 数组形式配置
mappers:
-
- fileId: 001
template: genCode/template/DemoDTO.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-application/qing-yu-club-${module}-application-controller/src/main/java/com/landaiqing/${module}/application/dto
name: ${modelName}DTO
ext: java
- fileId: 002
template: genCode/template/DemoController.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-application/qing-yu-club-${module}-application-controller/src/main/java/com/landaiqing/${module}/application/controller
name: ${modelName}Controller
ext: java
- fileId: 003
template: genCode/template/DemoDTOConverter.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-application/qing-yu-club-${module}-application-controller/src/main/java/com/landaiqing/${module}/application/convert
name: ${modelName}DTOConverter
ext: java
- fileId: 004
template: genCode/template/DemoBO.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-domain/src/main/java/com/landaiqing/${module}/domain/entity
name: ${modelName}BO
ext: java
- fileId: 005
template: genCode/template/DemoDomainService.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-domain/src/main/java/com/landaiqing/${module}/domain/service
name: ${modelName}DomainService
ext: java
- fileId: 006
template: genCode/template/DemoDomainServiceImpl.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-domain/src/main/java/com/landaiqing/${module}/domain/service/impl
name: ${modelName}DomainServiceImpl
ext: java
- fileId: 007
template: genCode/template/DemoBOConverter.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-domain/src/main/java/com/landaiqing/${module}/domain/convert
name: ${modelName}BOConverter
ext: java
- fileId: 008
template: genCode/template/DemoService.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-infra/src/main/java/com/landaiqing/${module}/infra/basic/service
name: ${modelName}Service
ext: java
- fileId: 009
template: genCode/template/DemoTable.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-infra/src/main/java/com/landaiqing/${module}/infra/basic/entity
name: ${modelName}
ext: java
- fileId: 010
template: genCode/template/DemoServiceImpl.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-infra/src/main/java/com/landaiqing/${module}/infra/basic/service/impl
name: ${modelName}ServiceImpl
ext: java
- fileId: 011
template: genCode/template/DemoDao.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-infra/src/main/java/com/landaiqing/${module}/infra/basic/mapper
name: ${modelName}Dao
ext: java
- fileId: 012
template: genCode/template/DemoXml.xml.vm
filePath: /qing-yu-club-${module}/qing-yu-club-${module}-infra/src/main/resources/mapper
name: ${modelName}Dao
ext: xml

View File

@@ -0,0 +1,33 @@
# 使用步骤
# 01 替换数据库连接信息及对应表 jdbc:*
# 02 替换模板映射关系 mapperInfos
# 03 替换作者信息 params:loser
# 04 替换模块 params:module
# 05 替换 controller 前缀 params:api
# 数据库连接信息
jdbc:
dbName: qing-yu-club
tableName: subject_liked
url: jdbc:mysql://116.196.80.239:3306/
username: landaiqing
password: $LDQ20020618xxx$
driver: com.mysql.cj.jdbc.Driver
# 使用的模板与生成文件映射给关系
mapperInfos: genCode/subjectLikedMapper.yml
# 全局参数
params:
# 作者
author: landaiqing
# 模块
module: subject
# controller 通用前缀
api: /subjectLiked
# 生成对象是否移除前缀
removePre: false
# 使用内置函数赋值给变量 FunctionUtils 中替换
genDate: now()
# win 需要补充模板具体目录
templateBasePath: E:/JavaProjects_IDEA/qing-yu-club/qing-yu-club-gen/src/main/resources/

View File

@@ -0,0 +1,69 @@
# subject 模块映射关系 ${module} 占位符
# 模板文件和生成类的映射关系 多个文件 数组形式配置
mappers:
-
- fileId: 001
template: genCode/template/DemoDTO.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/${module}/application/dto
name: ${modelName}DTO
ext: java
- fileId: 002
template: genCode/template/DemoController.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/${module}/application/controller
name: ${modelName}Controller
ext: java
- fileId: 003
template: genCode/template/DemoDTOConverter.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/${module}/application/convert
name: ${modelName}DTOConverter
ext: java
- fileId: 004
template: genCode/template/DemoBO.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/entity
name: ${modelName}BO
ext: java
- fileId: 005
template: genCode/template/DemoDomainService.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/service
name: ${modelName}DomainService
ext: java
- fileId: 006
template: genCode/template/DemoDomainServiceImpl.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/service/impl
name: ${modelName}DomainServiceImpl
ext: java
- fileId: 007
template: genCode/template/DemoBOConverter.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/convert
name: ${modelName}BOConverter
ext: java
- fileId: 008
template: genCode/template/DemoService.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/service
name: ${modelName}Service
ext: java
- fileId: 009
template: genCode/template/DemoTable.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/entity
name: ${modelName}
ext: java
- fileId: 010
template: genCode/template/DemoServiceImpl.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/service/impl
name: ${modelName}ServiceImpl
ext: java
- fileId: 011
template: genCode/template/DemoDao.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/mapper
name: ${modelName}Dao
ext: java
- fileId: 012
template: genCode/template/DemoXml.xml.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/resources/mapper
name: ${modelName}Dao
ext: xml

View File

@@ -0,0 +1,69 @@
# subject 模块映射关系 ${module} 占位符
# 模板文件和生成类的映射关系 多个文件 数组形式配置
mappers:
-
- fileId: 001
template: genCode/template/DemoDTO.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/${module}/application/dto
name: ${modelName}DTO
ext: java
- fileId: 002
template: genCode/template/DemoController.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/${module}/application/controller
name: ${modelName}Controller
ext: java
- fileId: 003
template: genCode/template/DemoDTOConverter.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-application/qing-yu-club-application-controller/src/main/java/com/landaiqing/${module}/application/convert
name: ${modelName}DTOConverter
ext: java
- fileId: 004
template: genCode/template/DemoBO.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/entity
name: ${modelName}BO
ext: java
- fileId: 005
template: genCode/template/DemoDomainService.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/service
name: ${modelName}DomainService
ext: java
- fileId: 006
template: genCode/template/DemoDomainServiceImpl.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/service/impl
name: ${modelName}DomainServiceImpl
ext: java
- fileId: 007
template: genCode/template/DemoBOConverter.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-domain/src/main/java/com/landaiqing/${module}/domain/convert
name: ${modelName}BOConverter
ext: java
- fileId: 008
template: genCode/template/DemoService.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/service
name: ${modelName}Service
ext: java
- fileId: 009
template: genCode/template/DemoTable.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/entity
name: ${modelName}
ext: java
- fileId: 010
template: genCode/template/DemoServiceImpl.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/service/impl
name: ${modelName}ServiceImpl
ext: java
- fileId: 011
template: genCode/template/DemoDao.java.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/java/com/landaiqing/${module}/infra/basic/mapper
name: ${modelName}Dao
ext: java
- fileId: 012
template: genCode/template/DemoXml.xml.vm
filePath: /qing-yu-club-${module}/qing-yu-club-infra/src/main/resources/mapper
name: ${modelName}Dao
ext: xml

View File

@@ -0,0 +1,24 @@
package com.landaiqing.${module}.domain.entity;
import lombok.Data;
import java.io.Serializable;
/**
* ${tableComment} bo
*
* @author ${author}
* @since ${genDate}
*/
@Data
public class ${modelName}BO implements Serializable {
#foreach($field in $fields)
/**
* ${field.comment}
*/
private $field.type $field.name;
#end
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.${module}.domain.convert;
${module}.domain.entity.${modelName}BO;
${module}.infra.basic.entity.${modelName};
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* ${tableComment} bo转换器
*
* @author ${author}
* @since ${genDate}
*/
@Mapper
public interface ${modelName}BOConverter {
${modelName}BOConverter INSTANCE = Mappers.getMapper(${modelName}BOConverter.class);
${modelName} convertBOToEntity(${modelName}BO ${_modelName}BO);
}

View File

@@ -0,0 +1,97 @@
package com.landaiqing.${module}.application.controller;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
${module}.application.convert.${modelName}DTOConverter;
${module}.application.dto.${modelName}DTO;
${module}.common.entity.Result;
${module}.domain.entity.${modelName}BO;
${module}.domain.service.${modelName}DomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* ${tableComment} controller
*
* @author ${author}
* @since ${genDate}
*/
@RestController
@RequestMapping("${api}/")
@Slf4j
public class ${modelName}Controller {
@Resource
private ${modelName}DomainService ${_modelName}DomainService;
/**
* 新增${tableComment}
*/
@RequestMapping("add")
public Result<Boolean> add(@RequestBody ${modelName}DTO ${_modelName}DTO) {
try {
if (log.isInfoEnabled()) {
log.info("${modelName}Controller.add.dto:{}", JSON.toJSONString(${_modelName}DTO));
}
#foreach($field in $fields)
Preconditions.checkNotNull(${_modelName}DTO.get${field.upName}(), "${field.comment}不能为空");
#end
${modelName}BO ${modelName}BO = ${modelName}DTOConverter.INSTANCE.convertDTOToBO(${_modelName}DTO);
return Result.ok(${_modelName}DomainService.add(${modelName}BO));
} catch (Exception e) {
log.error("${modelName}Controller.register.error:{}", e.getMessage(), e);
return Result.fail("新增${tableComment}失败");
}
}
/**
* 修改${tableComment}
*/
@RequestMapping("update")
public Result<Boolean> update(@RequestBody ${modelName}DTO ${_modelName}DTO) {
try {
if (log.isInfoEnabled()) {
log.info("${modelName}Controller.update.dto:{}", JSON.toJSONString(${_modelName}DTO));
}
#foreach($field in $fields)
Preconditions.checkNotNull(${_modelName}DTO.get${field.upName}(), "${field.comment}不能为空");
#end
${modelName}BO ${_modelName}BO = ${modelName}DTOConverter.INSTANCE.convertDTOToBO(${_modelName}DTO);
return Result.ok(${_modelName}DomainService.update(${_modelName}BO));
} catch (Exception e) {
log.error("${modelName}Controller.update.error:{}", e.getMessage(), e);
return Result.fail("更新${tableComment}信息失败");
}
}
/**
* 删除${tableComment}
*/
@RequestMapping("delete")
public Result<Boolean> delete(@RequestBody ${modelName}DTO ${_modelName}DTO) {
try {
if (log.isInfoEnabled()) {
log.info("${modelName}Controller.delete.dto:{}", JSON.toJSONString(${_modelName}DTO));
}
#foreach($field in $fields)
Preconditions.checkNotNull(${_modelName}DTO.get${field.upName}(), "${field.comment}不能为空");
#end
${modelName}BO ${_modelName}BO = ${modelName}DTOConverter.INSTANCE.convertDTOToBO(${_modelName}DTO);
return Result.ok(${_modelName}DomainService.delete(${_modelName}BO));
} catch (Exception e) {
log.error("${modelName}Controller.delete.error:{}", e.getMessage(), e);
return Result.fail("删除${tableComment}信息失败");
}
}
}

View File

@@ -0,0 +1,24 @@
package com.landaiqing.${module}.application.dto;
import lombok.Data;
import java.io.Serializable;
/**
* ${tableComment} dto
*
* @author ${author}
* @since ${genDate}
*/
@Data
public class ${modelName}DTO implements Serializable {
#foreach($field in $fields)
/**
* ${field.comment}
*/
private $field.type $field.name;
#end
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.${module}.application.convert;
${module}.application.dto.${modelName}DTO;
${module}.domain.entity.${modelName}BO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* ${tableComment} dto转换器
*
* @author ${author}
* @since ${genDate}
*/
@Mapper
public interface ${modelName}DTOConverter {
${modelName}DTOConverter INSTANCE = Mappers.getMapper(${modelName}DTOConverter.class);
${modelName}BO convertDTOToBO(${modelName}DTO ${_modelName}DTO);
}

View File

@@ -0,0 +1,17 @@
package com.landaiqing.${module}.infra.basic.mapper;
${module}.infra.basic.entity.${modelName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
/**
* ${tableComment} 表数据库访问层
*
* @author ${author}
* @since ${genDate}
*/
@Repository
public interface ${modelName}Dao extends BaseMapper<${modelName}> {
}

View File

@@ -0,0 +1,26 @@
package com.landaiqing.${module}.domain.service;${module}.domain.entity.${modelName}BO;
/**
* ${tableComment} 领域service
*
* @author ${author}
* @since ${genDate}
*/
public interface ${modelName}DomainService {
/**
* 添加 ${tableComment} 信息
*/
Boolean add(${modelName}BO ${_modelName}BO);
/**
* 更新 ${tableComment} 信息
*/
Boolean update(${modelName}BO ${_modelName}BO);
/**
* 删除 ${tableComment} 信息
*/
Boolean delete(${modelName}BO ${_modelName}BO);
}

View File

@@ -0,0 +1,48 @@
package com.landaiqing.${module}.domain.service.impl;
${module}.common.enums.IsDeletedFlagEnum;
${module}.domain.convert.${modelName}BOConverter;
${module}.domain.entity.${modelName}BO;
${module}.domain.service.${modelName}DomainService;
${module}.infra.basic.entity.${modelName};
${module}.infra.basic.service.${modelName}Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* ${tableComment} 领域service实现了
*
* @author ${author}
* @since ${genDate}
*/
@Service
@Slf4j
public class ${modelName}DomainServiceImpl implements ${modelName}DomainService {
@Resource
private ${modelName}Service ${_modelName}Service;
@Override
public Boolean add(${modelName}BO ${_modelName}BO) {
${modelName} ${_modelName} = ${modelName}BOConverter.INSTANCE.convertBOToEntity(${_modelName}BO);
${_modelName}.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
return ${_modelName}Service.insert(${_modelName}) > 0;
}
@Override
public Boolean update(${modelName}BO ${_modelName}BO) {
${modelName} ${_modelName} = ${modelName}BOConverter.INSTANCE.convertBOToEntity(${_modelName}BO);
return ${_modelName}Service.update(${_modelName}) > 0;
}
@Override
public Boolean delete(${modelName}BO ${_modelName}BO) {
${modelName} ${_modelName} = new ${modelName}();
${_modelName}.setId(${_modelName}BO.getId());
${_modelName}.setIsDeleted(IsDeletedFlagEnum.DELETED.getCode());
return ${_modelName}Service.update(${_modelName}) > 0;
}
}

View File

@@ -0,0 +1,48 @@
package com.landaiqing.${module}.infra.basic.service;${module}.infra.basic.entity.${modelName};
/**
* ${tableComment} 表服务接口
*
* @author ${author}
* @since ${genDate}
*/
public interface ${modelName}Service {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
${modelName} queryById(Long id);
/**
* 新增数据
*
* @param ${_modelName} 实例对象
* @return 实例对象
*/
int insert(${modelName} ${_modelName});
/**
* 修改数据
*
* @param ${_modelName} 实例对象
* @return 实例对象
*/
int update(${modelName} ${_modelName});
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
boolean deleteById(Long id);
/**
* 根据条件查询角色
*/
${modelName} queryByCondition(${modelName} ${_modelName});
}

View File

@@ -0,0 +1,87 @@
package com.landaiqing.${module}.infra.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
${module}.infra.basic.entity.${modelName};
${module}.infra.basic.mapper.${modelName}Dao;
${module}.infra.basic.service.${modelName}Service;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
/**
* ${tableComment} 表服务实现类
*
* @author ${author}
* @since ${genDate}
*/
@Service("${modelName}Service")
public class ${modelName}ServiceImpl implements ${modelName}Service {
@Resource
private ${modelName}Dao ${_modelName}Dao;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public ${modelName} queryById(Long id) {
return this.${_modelName}Dao.selectById(id);
}
/**
* 新增数据
*
* @param ${_modelName} 实例对象
* @return 实例对象
*/
@Override
public int insert(${modelName} ${_modelName}) {
return this.${_modelName}Dao.insert(${_modelName});
}
/**
* 修改数据
*
* @param ${_modelName} 实例对象
* @return 实例对象
*/
@Override
public int update(${modelName} ${_modelName}) {
return this.${_modelName}Dao.updateById(${_modelName});
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Long id) {
return this.${_modelName}Dao.deleteById(id) > 0;
}
/**
* 条件查询
*
* @param ${_modelName} 条件
* @return 实例对象
*/
@Override
public ${modelName} queryByCondition(${modelName} ${_modelName}) {
LambdaQueryWrapper<${modelName}> queryWrapper = Wrappers.<${modelName}>lambdaQuery()
#foreach($field in $fields)
.eq(Objects.nonNull(${_modelName}.get${field.upName}()), ${modelName}::get${field.upName}, ${_modelName}.get${field.upName}())
#end
;
return ${_modelName}Dao.selectOne(queryWrapper);
}
}

View File

@@ -0,0 +1,33 @@
package com.landaiqing.${module}.infra.basic.entity;
import lombok.Data;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
/**
* ${tableComment} 实体类
*
* @author ${author}
* @since ${genDate}
*/
@Data
@TableName("${tableName}")
public class ${modelName} implements Serializable {
#foreach($field in $fields)
/**
* ${field.comment}
*/
#if($field.keyType=='PRI')
@TableId(value = "`$field.col`", type = IdType.AUTO)
#end
#if($field.keyType!='PRI')
@TableField("`$field.col`")
#end
private $field.type $field.name;
#end
}

View File

@@ -0,0 +1,16 @@
<?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.landaiqing.${module}.infra.basic.mapper.${modelName}Dao">
<resultMap id="BaseResultMap" type="com.landaiqing.${module}.infra.basic.entity.${modelName}">
#foreach($field in $fields)
#if($field.keyType=='PRI')
<id column="${field.col}" jdbcType="${field.myBatisType}" property="${field.name}"/>
#end
#if($field.keyType!='PRI')
<result column="${field.col}" jdbcType="${field.myBatisType}" property="${field.name}"/>
#end
#end
</resultMap>
</mapper>

View File

@@ -0,0 +1,115 @@
package com.landaiqing.subject.application.controller;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import com.landaiqing.subject.application.convert.SubjectLikedDTOConverter;
import com.landaiqing.subject.application.dto.SubjectLikedDTO;
import com.landaiqing.subject.common.entity.Result;
import com.landaiqing.subject.domain.entity.SubjectLikedBO;
import com.landaiqing.subject.domain.service.SubjectLikedDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 题目点赞表 controller
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@RestController
@RequestMapping("/subjectLiked/")
@Slf4j
public class SubjectLikedController {
@Resource
private SubjectLikedDomainService subjectLikedDomainService;
/**
* 新增题目点赞表
*/
@RequestMapping("add")
public Result<Boolean> add(@RequestBody SubjectLikedDTO subjectLikedDTO) {
try {
if (log.isInfoEnabled()) {
log.info("SubjectLikedController.add.dto:{}", JSON.toJSONString(subjectLikedDTO));
}
Preconditions.checkNotNull(subjectLikedDTO.getId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getSubjectId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getLikeUserId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getStatus(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getCreatedBy(), "创建人不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getCreatedTime(), "创建时间不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getUpdateBy(), "更新人不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getUpdateTime(), "更新时间不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getIsDeleted(), "不能为空");
SubjectLikedBO SubjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO);
return Result.ok(subjectLikedDomainService.add(SubjectLikedBO));
} catch (Exception e) {
log.error("SubjectLikedController.register.error:{}", e.getMessage(), e);
return Result.fail("新增题目点赞表失败");
}
}
/**
* 修改题目点赞表
*/
@RequestMapping("update")
public Result<Boolean> update(@RequestBody SubjectLikedDTO subjectLikedDTO) {
try {
if (log.isInfoEnabled()) {
log.info("SubjectLikedController.update.dto:{}", JSON.toJSONString(subjectLikedDTO));
}
Preconditions.checkNotNull(subjectLikedDTO.getId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getSubjectId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getLikeUserId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getStatus(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getCreatedBy(), "创建人不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getCreatedTime(), "创建时间不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getUpdateBy(), "更新人不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getUpdateTime(), "更新时间不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getIsDeleted(), "不能为空");
SubjectLikedBO subjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO);
return Result.ok(subjectLikedDomainService.update(subjectLikedBO));
} catch (Exception e) {
log.error("SubjectLikedController.update.error:{}", e.getMessage(), e);
return Result.fail("更新题目点赞表信息失败");
}
}
/**
* 删除题目点赞表
*/
@RequestMapping("delete")
public Result<Boolean> delete(@RequestBody SubjectLikedDTO subjectLikedDTO) {
try {
if (log.isInfoEnabled()) {
log.info("SubjectLikedController.delete.dto:{}", JSON.toJSONString(subjectLikedDTO));
}
Preconditions.checkNotNull(subjectLikedDTO.getId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getSubjectId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getLikeUserId(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getStatus(), "不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getCreatedBy(), "创建人不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getCreatedTime(), "创建时间不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getUpdateBy(), "更新人不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getUpdateTime(), "更新时间不能为空");
Preconditions.checkNotNull(subjectLikedDTO.getIsDeleted(), "不能为空");
SubjectLikedBO subjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO);
return Result.ok(subjectLikedDomainService.delete(subjectLikedBO));
} catch (Exception e) {
log.error("SubjectLikedController.delete.error:{}", e.getMessage(), e);
return Result.fail("删除题目点赞表信息失败");
}
}
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.subject.application.convert;
import com.landaiqing.subject.application.dto.SubjectLikedDTO;
import com.landaiqing.subject.domain.entity.SubjectLikedBO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 题目点赞表 dto转换器
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Mapper
public interface SubjectLikedDTOConverter {
SubjectLikedDTOConverter INSTANCE = Mappers.getMapper(SubjectLikedDTOConverter.class);
SubjectLikedBO convertDTOToBO(SubjectLikedDTO subjectLikedDTO);
}

View File

@@ -0,0 +1,63 @@
package com.landaiqing.subject.application.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 题目点赞表 dto
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Data
public class SubjectLikedDTO implements Serializable {
/**
*
*/
private Long id;
/**
*
*/
private Long subjectId;
/**
*
*/
private String likeUserId;
/**
*
*/
private Integer status;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
/**
*
*/
private Integer isDeleted;
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.subject.domain.convert;
import com.landaiqing.subject.domain.entity.SubjectLikedBO;
import com.landaiqing.subject.infra.basic.entity.SubjectLiked;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 题目点赞表 bo转换器
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Mapper
public interface SubjectLikedBOConverter {
SubjectLikedBOConverter INSTANCE = Mappers.getMapper(SubjectLikedBOConverter.class);
SubjectLiked convertBOToEntity(SubjectLikedBO subjectLikedBO);
}

View File

@@ -0,0 +1,63 @@
package com.landaiqing.subject.domain.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 题目点赞表 bo
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Data
public class SubjectLikedBO implements Serializable {
/**
*
*/
private Long id;
/**
*
*/
private Long subjectId;
/**
*
*/
private String likeUserId;
/**
*
*/
private Integer status;
/**
* 创建人
*/
private String createdBy;
/**
* 创建时间
*/
private Date createdTime;
/**
* 更新人
*/
private String updateBy;
/**
* 更新时间
*/
private Date updateTime;
/**
*
*/
private Integer isDeleted;
}

View File

@@ -0,0 +1,29 @@
package com.landaiqing.subject.domain.service;
import com.landaiqing.subject.domain.entity.SubjectLikedBO;
/**
* 题目点赞表 领域service
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
public interface SubjectLikedDomainService {
/**
* 添加 题目点赞表 信息
*/
Boolean add(SubjectLikedBO subjectLikedBO);
/**
* 更新 题目点赞表 信息
*/
Boolean update(SubjectLikedBO subjectLikedBO);
/**
* 删除 题目点赞表 信息
*/
Boolean delete(SubjectLikedBO subjectLikedBO);
}

View File

@@ -0,0 +1,48 @@
package com.landaiqing.subject.domain.service.impl;
import com.landaiqing.subject.common.enums.IsDeletedFlagEnum;
import com.landaiqing.subject.domain.convert.SubjectLikedBOConverter;
import com.landaiqing.subject.domain.entity.SubjectLikedBO;
import com.landaiqing.subject.domain.service.SubjectLikedDomainService;
import com.landaiqing.subject.infra.basic.entity.SubjectLiked;
import com.landaiqing.subject.infra.basic.service.SubjectLikedService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 题目点赞表 领域service实现了
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Service
@Slf4j
public class SubjectLikedDomainServiceImpl implements SubjectLikedDomainService {
@Resource
private SubjectLikedService subjectLikedService;
@Override
public Boolean add(SubjectLikedBO subjectLikedBO) {
SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO);
subjectLiked.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
return subjectLikedService.insert(subjectLiked) > 0;
}
@Override
public Boolean update(SubjectLikedBO subjectLikedBO) {
SubjectLiked subjectLiked = SubjectLikedBOConverter.INSTANCE.convertBOToEntity(subjectLikedBO);
return subjectLikedService.update(subjectLiked) > 0;
}
@Override
public Boolean delete(SubjectLikedBO subjectLikedBO) {
SubjectLiked subjectLiked = new SubjectLiked();
subjectLiked.setId(subjectLikedBO.getId());
subjectLiked.setIsDeleted(IsDeletedFlagEnum.DELETED.getCode());
return subjectLikedService.update(subjectLiked) > 0;
}
}

View File

@@ -0,0 +1,77 @@
package com.landaiqing.subject.infra.basic.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 题目点赞表 实体类
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Data
@TableName("subject_liked")
public class SubjectLiked implements Serializable {
/**
*
*/
@TableId(value = "`id`", type = IdType.AUTO)
private Long id;
/**
*
*/
@TableField("`subject_id`")
private Long subjectId;
/**
*
*/
@TableField("`like_user_id`")
private String likeUserId;
/**
*
*/
@TableField("`status`")
private Integer status;
/**
* 创建人
*/
@TableField("`created_by`")
private String createdBy;
/**
* 创建时间
*/
@TableField("`created_time`")
private Date createdTime;
/**
* 更新人
*/
@TableField("`update_by`")
private String updateBy;
/**
* 更新时间
*/
@TableField("`update_time`")
private Date updateTime;
/**
*
*/
@TableField("`is_deleted`")
private Integer isDeleted;
}

View File

@@ -0,0 +1,17 @@
package com.landaiqing.subject.infra.basic.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.landaiqing.subject.infra.basic.entity.SubjectLiked;
import org.springframework.stereotype.Repository;
/**
* 题目点赞表 表数据库访问层
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Repository
public interface SubjectLikedDao extends BaseMapper<SubjectLiked> {
}

View File

@@ -0,0 +1,51 @@
package com.landaiqing.subject.infra.basic.service;
import com.landaiqing.subject.infra.basic.entity.SubjectLiked;
/**
* 题目点赞表 表服务接口
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
public interface SubjectLikedService {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
SubjectLiked queryById(Long id);
/**
* 新增数据
*
* @param subjectLiked 实例对象
* @return 实例对象
*/
int insert(SubjectLiked subjectLiked);
/**
* 修改数据
*
* @param subjectLiked 实例对象
* @return 实例对象
*/
int update(SubjectLiked subjectLiked);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
boolean deleteById(Long id);
/**
* 根据条件查询角色
*/
SubjectLiked queryByCondition(SubjectLiked subjectLiked);
}

View File

@@ -0,0 +1,93 @@
package com.landaiqing.subject.infra.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.landaiqing.subject.infra.basic.entity.SubjectLiked;
import com.landaiqing.subject.infra.basic.mapper.SubjectLikedDao;
import com.landaiqing.subject.infra.basic.service.SubjectLikedService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
/**
* 题目点赞表 表服务实现类
*
* @author landaiqing
* @since 2024-03-08 13:44:59
*/
@Service("SubjectLikedService")
public class SubjectLikedServiceImpl implements SubjectLikedService {
@Resource
private SubjectLikedDao subjectLikedDao;
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
@Override
public SubjectLiked queryById(Long id) {
return this.subjectLikedDao.selectById(id);
}
/**
* 新增数据
*
* @param subjectLiked 实例对象
* @return 实例对象
*/
@Override
public int insert(SubjectLiked subjectLiked) {
return this.subjectLikedDao.insert(subjectLiked);
}
/**
* 修改数据
*
* @param subjectLiked 实例对象
* @return 实例对象
*/
@Override
public int update(SubjectLiked subjectLiked) {
return this.subjectLikedDao.updateById(subjectLiked);
}
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
@Override
public boolean deleteById(Long id) {
return this.subjectLikedDao.deleteById(id) > 0;
}
/**
* 条件查询
*
* @param subjectLiked 条件
* @return 实例对象
*/
@Override
public SubjectLiked queryByCondition(SubjectLiked subjectLiked) {
LambdaQueryWrapper<SubjectLiked> queryWrapper = Wrappers.<SubjectLiked>lambdaQuery()
.eq(Objects.nonNull(subjectLiked.getId()), SubjectLiked::getId, subjectLiked.getId())
.eq(Objects.nonNull(subjectLiked.getSubjectId()), SubjectLiked::getSubjectId, subjectLiked.getSubjectId())
.eq(Objects.nonNull(subjectLiked.getLikeUserId()), SubjectLiked::getLikeUserId, subjectLiked.getLikeUserId())
.eq(Objects.nonNull(subjectLiked.getStatus()), SubjectLiked::getStatus, subjectLiked.getStatus())
.eq(Objects.nonNull(subjectLiked.getCreatedBy()), SubjectLiked::getCreatedBy, subjectLiked.getCreatedBy())
.eq(Objects.nonNull(subjectLiked.getCreatedTime()), SubjectLiked::getCreatedTime, subjectLiked.getCreatedTime())
.eq(Objects.nonNull(subjectLiked.getUpdateBy()), SubjectLiked::getUpdateBy, subjectLiked.getUpdateBy())
.eq(Objects.nonNull(subjectLiked.getUpdateTime()), SubjectLiked::getUpdateTime, subjectLiked.getUpdateTime())
.eq(Objects.nonNull(subjectLiked.getIsDeleted()), SubjectLiked::getIsDeleted, subjectLiked.getIsDeleted())
;
return subjectLikedDao.selectOne(queryWrapper);
}
}

View File

@@ -0,0 +1,17 @@
<?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.landaiqing.subject.infra.basic.mapper.SubjectLikedDao">
<resultMap id="BaseResultMap" type="com.landaiqing.subject.infra.basic.entity.SubjectLiked">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="subject_id" jdbcType="BIGINT" property="subjectId"/>
<result column="like_user_id" jdbcType="VARCHAR" property="likeUserId"/>
<result column="status" jdbcType="INTEGER" property="status"/>
<result column="created_by" jdbcType="VARCHAR" property="createdBy"/>
<result column="created_time" jdbcType="TIMESTAMP" property="createdTime"/>
<result column="update_by" jdbcType="VARCHAR" property="updateBy"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
<result column="is_deleted" jdbcType="INTEGER" property="isDeleted"/>
</resultMap>
</mapper>

View File

@@ -0,0 +1,100 @@
<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>
<parent>
<groupId>com.landaiqing</groupId>
<artifactId>qing-yu-common-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>easy-gen-code-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<name>easy-gen-code-spring-boot-starter</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.12.3</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
</dependencies>
<distributionManagement>
<repository>
<id>rdc-releases</id>
<name>dw-repo-releases</name>
<url>https://packages.aliyun.com/maven/repository/2012812-release-SiITng/</url>
</repository>
<snapshotRepository>
<id>rdc-snapshots</id>
<name>dw-repo-snapshots</name>
<url>https://packages.aliyun.com/maven/repository/2012812-snapshot-LHGmjL/</url>
</snapshotRepository>
</distributionManagement>
</project>

View File

@@ -0,0 +1,26 @@
package com.landaiqing.core.anno;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value() default "";
String keyType() default "";
String col() default "";
String comment() default "";
String myBatisType() default "";
String jdbcType() default "";
}

View File

@@ -0,0 +1,47 @@
package com.landaiqing.core.config;
import com.landaiqing.core.entity.JdbcConfig;
import lombok.Data;
import java.util.Map;
/**
* 代码生成器配置
*
* @author loser
* @date 2023/9/4
*/
@Data
public class GenConfig {
/**
* 从自定义的类中获取数据
*/
private String handler;
/**
* 从classPath下的json文件中获取数据
*/
private String json;
/**
* 使用jdbc从表结构中获取数据
*/
private JdbcConfig jdbc;
/**
* 模板与生成文件的映射配置文件
*/
private String mapperInfos;
/**
* 针对某一个模板将数据写入该模板上下文
*/
private String filePutHandler;
/**
* 自定义写入全局的参数
*/
private Map<String, Object> params;
}

View File

@@ -0,0 +1,27 @@
package com.landaiqing.core.config;
import com.landaiqing.core.entity.Mapper;
import lombok.Data;
import java.util.List;
/**
* 模板与生成文件的映射关系
*
* @author loser
* @date 2023/9/4
*/
@Data
public class MapperConfig {
/**
* 文件生成到该项目的哪个模块
*/
private String module;
/**
* 映射关系
*/
private List<Mapper> mappers;
}

View File

@@ -0,0 +1,241 @@
package com.landaiqing.core.core;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.landaiqing.core.config.GenConfig;
import com.landaiqing.core.config.MapperConfig;
import com.landaiqing.core.core.impl.JdbcPutContextHandler;
import com.landaiqing.core.core.sdk.FilePutContextHandler;
import com.landaiqing.core.core.sdk.PostCurFiledContextAware;
import com.landaiqing.core.entity.Context;
import com.landaiqing.core.entity.MapperInfo;
import com.landaiqing.core.utils.*;
import org.apache.velocity.VelocityContext;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class CodeGenerationCode {
public static void doGenCode() {
doGenCode(null);
}
public static void doGenCode(PostCurFiledContextAware aware) {
try {
// 01 获取入口配置文件
GenConfig genConfig = YamlUtils.loadYaml("genCode/gen.yml", GenConfig.class);
// 02 获取全局的配置上下文
assert genConfig != null;
VelocityContext context = getGlobalContext(genConfig);
Map<String, Object> contexts = new HashMap<>();
for (String key : context.getKeys()) {
Object value = context.get(key);
if (value instanceof String && FunctionUtils.isFunction(value)) {
value = FunctionUtils.doFunction(value);
context.put(key, value);
}
contexts.put(key, context.get(key));
}
System.out.println("==========> getGlobalContext:" + System.lineSeparator() + JSONObject.toJSONString(contexts));
System.out.println();
// 03 获取 模板与生成文件的映射关系
List<MapperInfo> infos = getMapperInfos(genConfig, context, aware);
// 04 通过映射关系生成代码文件
genCode(infos, genConfig.getParams().getOrDefault("templateBasePath", "").toString());
} catch (Exception e) {
e.printStackTrace();
}
}
private static void genCode(List<MapperInfo> infos, String templateBasePath) {
AtomicInteger count = new AtomicInteger(1);
infos.forEach(info -> {
CodeGeneratorUtils codeGenerator = new CodeGeneratorUtils(templateBasePath);
codeGenerator.generateCode(
info.getContext(),
info.getTemplatePath(),
info.getOutPutPath(),
count);
});
}
private static List<MapperInfo> getMapperInfos(GenConfig genConfig, VelocityContext context, PostCurFiledContextAware aware) {
MapperConfig mapperConfig = YamlUtils.loadYaml(genConfig.getMapperInfos(), MapperConfig.class);
assert mapperConfig != null;
// 允许在生成文件前对上下文中的数据进行修改 处理一些导包之类的不好控制业务
if (Objects.nonNull(aware)) {
aware.doAware(genConfig, mapperConfig, context);
Map<String, Object> contexts = new HashMap<>();
for (String key : context.getKeys()) {
Object value = context.get(key);
contexts.put(key, value);
}
System.out.println("==========> modify file context :" + System.lineSeparator() + JSONObject.toJSONString(contexts));
}
AtomicInteger count = new AtomicInteger(1);
return mapperConfig.getMappers().stream().filter(Objects::nonNull).map(item -> {
MapperInfo info = new MapperInfo();
info.setTemplatePath(getResPath(item.getTemplate()));
String cName = item.getName();
if (cName.contains("$")) {
cName = replace$key(context, cName);
}
String pkg = item.getPackageName();
if (StrUtil.isNotEmpty(pkg) && pkg.contains("$")) {
pkg = replace$key(context, pkg);
}
String filePath = item.getFilePath();
if (StrUtil.isNotEmpty(filePath) && filePath.contains("$")) {
filePath = replace$key(context, filePath);
}
String outPutPath = getTargetPath(mapperConfig.getModule(), pkg, filePath);
File file = new File(outPutPath);
if (!file.exists()) {
boolean mkdirs = file.mkdirs();
System.out.println("==========> mkdir " + mkdirs + " " + file.getAbsolutePath());
System.out.println();
}
outPutPath += ("/" + cName + "." + item.getExt());
VelocityContext cloneCtx = (VelocityContext) context.clone();
info.setOutPutPath(outPutPath);
if (StrUtil.isNotBlank(genConfig.getFilePutHandler())) {
try {
FilePutContextHandler handler = (FilePutContextHandler) Class.forName(genConfig.getFilePutHandler()).newInstance();
handler.put(cloneCtx, item.getFileId());
} catch (Exception e) {
e.printStackTrace();
}
}
cloneCtx.put("className", cName);
cloneCtx.put("packageName", pkg);
System.out.println("==========> " + count.get() + " MapperInfo : " + System.lineSeparator() + info);
System.out.println();
Map<String, Object> contexts = new HashMap<>();
for (String key : cloneCtx.getKeys()) {
contexts.put(key, cloneCtx.get(key));
}
System.out.println("==========> MapperInfo context : " + System.lineSeparator() + JSONObject.toJSONString(contexts));
System.out.println();
System.out.println("=============================================================================================================================================");
System.out.println();
info.setContext(cloneCtx);
return info;
}).collect(Collectors.toList());
}
private static String replace$key(VelocityContext velocityContext, String conextkey) {
String key = conextkey.substring(conextkey.indexOf("${") + 2, conextkey.indexOf("}"));
Object value = velocityContext.get(key);
conextkey = conextkey.replace("${" + key + "}", value.toString());
if (conextkey.contains("$")) {
conextkey = replace$key(velocityContext, conextkey);
}
return conextkey;
}
private static VelocityContext getGlobalContext(GenConfig genConfig) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Context context = ConfigUtils.getContext();
boolean putData = false;
// 01 处理优先级第一的处理器
if (StrUtil.isNotBlank(genConfig.getHandler())) {
JdbcPutContextHandler jdbcPutContextHandler = (JdbcPutContextHandler) Class.forName(genConfig.getHandler()).newInstance();
putData = jdbcPutContextHandler.put();
}
// 02 处理优先级第二的json导入
if (!putData && StrUtil.isNotBlank(genConfig.getJson())) {
List<String> lines = FileUtil.readLines(getRealResPath(genConfig.getJson()), "UTF-8");
StringBuilder json = new StringBuilder();
for (String line : lines) {
json.append(line);
}
context = ContextUtils.buildContext(json.toString());
ConfigUtils.reSetContext(context);
putData = true;
}
// 03 处理优先级第三的mysql导入
if (!putData) {
JdbcPutContextHandler jdbcPutContextHandler = new JdbcPutContextHandler();
jdbcPutContextHandler.put();
}
// 04 添加配置中的全局参数
Map<String, Object> params = genConfig.getParams();
for (Map.Entry<String, Object> entry : params.entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
return context.get();
}
private static String getTargetPath(String module, String packageName, String filePath) {
if (StrUtil.isEmpty(module)) {
module = "/";
}
if (SystemUtils.isMacOs()) {
if (StrUtil.isEmpty(filePath)) {
return getCurPath().substring(0, getCurPath().length() - 2) + module + "src/main/java/" + packageName.replaceAll("\\.", "/");
} else {
return getCurPath().substring(0, getCurPath().length() - 2) + module + filePath;
}
} else {
if (StrUtil.isEmpty(filePath)) {
return getCurPath() + module + "src/main/java/" + packageName.replaceAll("\\.", "\\");
} else {
return getCurPath() + module + filePath;
}
}
}
private static URL getRealResPath(String res) {
ClassLoader classLoader = CodeGenerationCode.class.getClassLoader();
return classLoader.getResource(res);
}
private static String getResPath(String res) {
if (SystemUtils.isMacOs()) {
ClassLoader classLoader = CodeGenerationCode.class.getClassLoader();
return classLoader.getResource(res).getPath()
.replaceAll(getCurPath().substring(0, getCurPath().length() - 1), "");
} else {
return res;
}
}
private static String getCurPath() {
if (SystemUtils.isMacOs()) {
return new File("./").getAbsolutePath();
} else {
return System.getProperty("user.dir");
}
}
}

View File

@@ -0,0 +1,134 @@
package com.landaiqing.core.core;
import cn.hutool.core.collection.CollectionUtil;
import com.landaiqing.core.entity.JdbcConfig;
import com.landaiqing.core.entity.TableInfo;
import com.landaiqing.core.utils.Lists;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import javax.sql.DataSource;
import java.sql.Driver;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 简易mysql处理器 查询表备注及表字段
*
* @author loser
* @date 2023/9/4
*/
@AllArgsConstructor
public class MysqlDataHandler {
private String tableName;
private String dbUrl;
private String dbUser;
private String dbPw;
private String dbName;
private String driver;
public String getTableComment() {
JdbcConfig config = new JdbcConfig(
dbUrl + dbName + "?useUnicode=true",
dbUser,
dbPw,
dbName,
driver,
tableName
);
JdbcTemplate jdbcTemplate = initJdbcTemplate(config);
String sql = "SELECT table_comment tableComment FROM information_schema.TABLES WHERE table_schema = ? and table_name = ? ";
List<Object> params = Lists.newArrayList();
params.add(config.getDbName());
params.add(tableName);
BeanPropertyRowMapper<TableInfo> rowMapper = new BeanPropertyRowMapper<>(TableInfo.class);
if (CollectionUtil.isEmpty(params)) {
return jdbcTemplate.query(sql, rowMapper).get(0).getTableComment();
}
List<TableInfo> query = jdbcTemplate.query(sql, rowMapper, params.toArray());
if (CollectionUtil.isEmpty(query)) {
throw new RuntimeException("表不存在:" + tableName);
}
return query.get(0).getTableComment();
}
/**
* 使用表名 查询表结构信息
*/
public List<TableInfo> searchByDb() {
JdbcConfig config = new JdbcConfig(
dbUrl + dbName + "?useUnicode=true",
dbUser,
dbPw,
dbName,
driver,
tableName
);
JdbcTemplate jdbcTemplate = initJdbcTemplate(config);
String sql = "select column_name as name, column_comment as comment,DATA_TYPE as dataType,COLUMN_KEY as keyType " +
"from information_schema.columns where table_schema = ? and table_name = ? ORDER BY ORDINAL_POSITION";
List<Object> params = Lists.newArrayList();
params.add(config.getDbName());
params.add(tableName);
BeanPropertyRowMapper<TableInfo> rowMapper = new BeanPropertyRowMapper<>(TableInfo.class);
if (CollectionUtil.isEmpty(params)) {
return jdbcTemplate.query(sql, rowMapper);
}
List<TableInfo> list = jdbcTemplate.query(sql, rowMapper, params.toArray());
return list.stream().peek(item -> {
item.setCol(item.getName());
item.setName(underlineToHump(item.getName()));
}).collect(Collectors.toList());
}
/**
* 初始化一个jdbc
*/
private static JdbcTemplate initJdbcTemplate(JdbcConfig config) {
DataSource dataSource;
try {
dataSource = new SimpleDriverDataSource(
BeanUtils.instantiateClass((Class<Driver>) Class.forName(config.getDriver())),
config.getUrl(),
config.getUsername(),
config.getPassword());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return new JdbcTemplate(dataSource);
}
private static Pattern UNDERLINE_PATTERN = Pattern.compile("_([a-z])");
public static String underlineToHump(String str) {
//正则匹配下划线及后一个字符,删除下划线并将匹配的字符转成大写
Matcher matcher = UNDERLINE_PATTERN.matcher(str);
StringBuffer sb = new StringBuffer(str);
if (matcher.find()) {
sb = new StringBuffer();
//将当前匹配的子串替换成指定字符串并且将替换后的子串及之前到上次匹配的子串之后的字符串添加到StringBuffer对象中
//正则之前的字符和被替换的字符
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
//把之后的字符串也添加到StringBuffer对象中
matcher.appendTail(sb);
} else {
//去除除字母之外的前面带的下划线
return sb.toString().replaceAll("_", "");
}
return underlineToHump(sb.toString());
}
}

View File

@@ -0,0 +1,36 @@
package com.landaiqing.core.core.impl;
import com.landaiqing.core.config.GenConfig;
import com.landaiqing.core.config.MapperConfig;
import com.landaiqing.core.core.sdk.PostCurFiledContextAware;
import com.landaiqing.core.entity.TableInfo;
import com.landaiqing.core.utils.TableUtils;
import org.apache.velocity.VelocityContext;
import java.util.List;
/**
* 从字段注解中获取数据
*
* @author loser
* @date 2023/9/4
*/
public class ClassPutContextHandler implements PostCurFiledContextAware {
private Class<?> clazz;
public ClassPutContextHandler(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public void doAware(GenConfig genConfig, MapperConfig mapperConfig, VelocityContext context) {
String tableComment = TableUtils.getComment(clazz);
List<TableInfo> fields = TableUtils.build(clazz);
context.put("tableComment", tableComment);
context.put("fields", fields);
}
}

View File

@@ -0,0 +1,14 @@
package com.landaiqing.core.core.impl;
import com.landaiqing.core.core.sdk.FilePutContextHandler;
import java.util.Map;
public class DemoFilePutContextHandler implements FilePutContextHandler {
@Override
public Map<String, Object> putData(String fileId) {
return null;
}
}

View File

@@ -0,0 +1,34 @@
package com.landaiqing.core.core.impl;
import com.landaiqing.core.config.GenConfig;
import com.landaiqing.core.core.sdk.PutContextHandler;
import com.landaiqing.core.entity.TableInfo;
import com.landaiqing.core.utils.JdbcUtil;
import com.landaiqing.core.utils.YamlUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 从配置的mysql数据源中获取表字段及表备注写入到全局上下文
*
* @author loser
* @date 2023/9/4
*/
public class JdbcPutContextHandler implements PutContextHandler {
@Override
public Map<String, Object> putData() {
GenConfig genConfig = YamlUtils.loadYaml("genCode/gen.yml", GenConfig.class);
String tableComment = JdbcUtil.getComment(genConfig.getJdbc(), genConfig.getJdbc().getTableName());
List<TableInfo> fields = JdbcUtil.queryTableInfo(genConfig.getJdbc(), genConfig.getJdbc().getTableName());
Map<String, Object> res = new HashMap<>();
res.put("tableComment", tableComment);
res.put("fields", fields);
return res;
}
}

View File

@@ -0,0 +1,36 @@
package com.landaiqing.core.core.sdk;
import cn.hutool.core.map.MapUtil;
import org.apache.velocity.VelocityContext;
import java.util.Map;
/**
* 针对某个生成文件写入独有上下文
*
* @author loser
* @date 2023/9/4
*/
public interface FilePutContextHandler {
/**
* 将map中的键值对写入当前文件的上下文
*
* @param fileId 文件id
* @return 写入的数据
*/
Map<String, Object> putData(String fileId);
default void put(VelocityContext context, String fileId) {
Map<String, Object> map = putData(fileId);
if (MapUtil.isNotEmpty(map)) {
for (Map.Entry<String, Object> entity : map.entrySet()) {
context.put(entity.getKey(), entity.getValue());
}
}
}
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.core.core.sdk;
/**
* 内置函数
*
* @author loser
* @date 2023/9/4
*/
public interface Function {
/**
* 函数key
*/
String funcKey();
/**
* 执行函授后的返回值
*/
String doFunc();
}

View File

@@ -0,0 +1,18 @@
package com.landaiqing.core.core.sdk;
import com.landaiqing.core.config.GenConfig;
import com.landaiqing.core.config.MapperConfig;
import org.apache.velocity.VelocityContext;
/**
* 针对当前文件的上下文进行操作
*
* @author loser
* @date 2023/9/4
*/
@FunctionalInterface
public interface PostCurFiledContextAware {
void doAware(GenConfig genConfig, MapperConfig mapperConfig, VelocityContext context);
}

View File

@@ -0,0 +1,31 @@
package com.landaiqing.core.core.sdk;
import com.landaiqing.core.entity.Context;
import com.landaiqing.core.utils.ConfigUtils;
import java.util.Map;
/**
* 从类中写入数据到全局上下文
*
* @author loser
* @date 2023/9/4
*/
public interface PutContextHandler {
Map<String, Object> putData();
default boolean put() {
boolean res = false;
Map<String, Object> map = putData();
Context context = ConfigUtils.getContext();
for (Map.Entry<String, Object> entry : map.entrySet()) {
context.put(entry.getKey(), entry.getValue());
res = true;
}
return res;
}
}

View File

@@ -0,0 +1,83 @@
package com.landaiqing.core.entity;
import com.landaiqing.core.utils.PrimitiveTypeUtils;
import lombok.Data;
import org.apache.velocity.VelocityContext;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 自定义上下文
*
* @author loser
* @date 2023/9/4
*/
@Data
public class Context implements Cloneable {
private VelocityContext context = new VelocityContext();
public VelocityContext get() {
for (Map.Entry<String, Object> entry : contexts.entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
return context;
}
private Map<String, Object> contexts = new ConcurrentHashMap<>();
public void put(String key, Object obj) {
contexts.put(key, obj);
}
public void remove(String key) {
contexts.remove(key);
}
public void put(Object obj) {
if (PrimitiveTypeUtils.isPrimitive(obj)) {
return;
}
Class<?> aClass = obj.getClass();
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
Object value = field.get(obj);
put(field.getName(), value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void removeObj(Object obj) {
if (PrimitiveTypeUtils.isPrimitive(obj)) {
return;
}
Class<?> aClass = obj.getClass();
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
remove(name);
}
}
@Override
public Context clone() {
try {
Context clone = (Context) super.clone();
// TODO: copy mutable state here, so the clone can't change the internals of the original
return clone;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}

View File

@@ -0,0 +1,25 @@
package com.landaiqing.core.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 数据库配置
*
* @author loser
* @date 2023/9/4
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JdbcConfig {
private String url;
private String username;
private String password;
private String dbName;
private String driver;
private String tableName;
}

View File

@@ -0,0 +1,43 @@
package com.landaiqing.core.entity;
import lombok.Data;
/**
* 映射关系
*
* @author loser
* @date 2023/9/4
*/
@Data
public class Mapper {
/**
* 生成文件的id
*/
private String fileId;
/**
* 模板地址
*/
private String template;
/**
* 生成类包名称 可使用占位符 ${}
*/
private String packageName;
/**
* 生成文件的路径 没有指定则用 packageName 进行替换处理 可使用占位符 ${}
*/
private String filePath;
/**
* 生成文件的名称 可使用占位符 ${}
*/
private String name;
/**
* 生成文件的扩展名
*/
private String ext;
}

View File

@@ -0,0 +1,47 @@
package com.landaiqing.core.entity;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.apache.velocity.VelocityContext;
import java.util.HashMap;
import java.util.Map;
/**
* 映射关系包裹对象
*
* @author loser
* @date 2023/9/4
*/
@Data
public class MapperInfo {
/**
* 文件id用于自定义忘 context 中存入自己特有的信息
*/
private String fileId;
/**
* 模板路径
*/
private String templatePath;
/**
* 生成文件路径
*/
private String outPutPath;
/**
* 每个文件自个持有的上下文 包含全局的上下文数据
*/
private VelocityContext context;
@Override
public String toString() {
Map<String, Object> res = new HashMap<>();
res.put("fileId", fileId);
res.put("templatePath", templatePath);
res.put("outPutPath", outPutPath);
return JSONObject.toJSONString(res);
}
}

View File

@@ -0,0 +1,65 @@
package com.landaiqing.core.entity;
import cn.hutool.core.util.StrUtil;
import com.landaiqing.core.utils.MySQLToJavaTypeConverter;
import com.landaiqing.core.utils.MySQLToMyBatisTypeConverter;
import lombok.Data;
import org.springframework.util.StringUtils;
/**
* 表信息
*
* @author loser
* @date 2023/9/4
*/
@Data
public class TableInfo {
// 字段索引类型
private String keyType;
private String col;
private String name;
private String upName;
private String comment;
private String dataType;
private String tableComment;
// 转化为java中的数据类型
private String type;
// 转为mybatis中的数据类型
private String myBatisType;
public String getMyBatisType() {
if (StrUtil.isNotEmpty(myBatisType)) {
return myBatisType;
}
return MySQLToMyBatisTypeConverter.convert(dataType);
}
public String getUpName() {
return StrUtil.upperFirst(name);
}
public String getType() {
if (StrUtil.isNotEmpty(type)) {
return type;
}
return MySQLToJavaTypeConverter.convert(dataType).getType();
}
public MySQLToJavaTypeConverter.Item getTypeInfo() {
return MySQLToJavaTypeConverter.convert(dataType);
}
public MySQLToJavaTypeConverter.Item getTypeInfo(String type) {
return MySQLToJavaTypeConverter.trans(type);
}
public String getComment() {
if (StringUtils.isEmpty(comment)) {
return "";
}
return comment.trim().replace("\n" , "");
}
}

View File

@@ -0,0 +1,46 @@
package com.landaiqing.core.utils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 使用velocity生成文件
*
* @author loser
* @date 2023/9/4
*/
public class CodeGeneratorUtils {
private final VelocityEngine velocityEngine;
public CodeGeneratorUtils(String templateBasePath) {
this.velocityEngine = new VelocityEngine();
if (SystemUtils.isWindows()) {
this.velocityEngine.setProperty("file.resource.loader.path", templateBasePath);
}
velocityEngine.init();
}
public void generateCode(VelocityContext context, String templatePath, String outputPath, AtomicInteger count) {
Template template = velocityEngine.getTemplate(templatePath, "UTF-8");
StringWriter writer = new StringWriter();
template.merge(context, writer);
try (FileWriter fileWriter = new FileWriter(outputPath)) {
fileWriter.write(writer.toString());
System.out.println();
System.out.println("==========> " + count.getAndIncrement() + " genFile succeed : " + outputPath);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,23 @@
package com.landaiqing.core.utils;
import com.landaiqing.core.entity.Context;
/**
* 获取全局上下文的配置工具
*
* @author loser
* @date 2023/9/4
*/
public class ConfigUtils {
private static Context ctx = new Context();
public static Context getContext() {
return ctx;
}
public static void reSetContext(Context context) {
ctx = context;
}
}

View File

@@ -0,0 +1,27 @@
package com.landaiqing.core.utils;
import com.alibaba.fastjson.JSONObject;
import com.landaiqing.core.entity.Context;
import java.util.Map;
/**
* 使用json构建上下文的上下文工具
*
* @author loser
* @date 2023/9/4
*/
public class ContextUtils {
public static Context buildContext(String json) {
Context context = new Context();
JSONObject jsonObject = JSONObject.parseObject(json);
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
return context;
}
}

View File

@@ -0,0 +1,96 @@
package com.landaiqing.core.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.landaiqing.core.core.sdk.Function;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
public class FunctionUtils implements Serializable {
private static final Map<String, Function> functionMap = new ConcurrentHashMap<>();
static {
register(new Function() {
@Override
public String funcKey() {
return "now()";
}
@Override
public String doFunc() {
return DateUtil.now();
}
});
register(new Function() {
@Override
public String funcKey() {
return "svUid()";
}
@Override
public String doFunc() {
try {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(RandomUtil.randomBigDecimal());
objectStream.flush();
objectStream.close();
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] byteArray = md5.digest(byteStream.toByteArray());
long serialVersionUID = 0L;
for (int i = Math.min(byteArray.length, 8) - 1; i >= 0; i--) {
serialVersionUID = (serialVersionUID << 8) | (byteArray[i] & 0xFF);
}
return Long.toString(serialVersionUID);
} catch (Exception ignore) {
}
return null;
}
});
register(new Function() {
@Override
public String funcKey() {
return "date()";
}
@Override
public String doFunc() {
return DateUtil.formatDate(DateUtil.date());
}
});
}
public static boolean isFunction(Object funKey) {
if (!(funKey instanceof String)) {
return false;
}
return functionMap.containsKey(funKey);
}
public static void register(Function function) {
functionMap.put(function.funcKey(), function);
}
public static Object doFunction(Object funKey) {
if (!(funKey instanceof String)) {
return funKey;
}
Function function = functionMap.get(funKey);
if (Objects.isNull(function)) {
return funKey;
}
return function.doFunc();
}
}

View File

@@ -0,0 +1,36 @@
package com.landaiqing.core.utils;
import com.landaiqing.core.core.MysqlDataHandler;
import com.landaiqing.core.entity.JdbcConfig;
import com.landaiqing.core.entity.TableInfo;
import java.util.List;
/**
* jdbc工具 用于查询表字段信息 及 表结构信息
*
* @author loser
* @date 2023/9/4
*/
public class JdbcUtil {
private JdbcUtil() {
}
public static List<TableInfo> queryTableInfo(JdbcConfig config, String table) {
return new MysqlDataHandler(table, config.getUrl(), config.getUsername(),
config.getPassword(), config.getDbName(), config.getDriver())
.searchByDb();
}
public static String getComment(JdbcConfig config, String table) {
return new MysqlDataHandler(table, config.getUrl(), config.getUsername(),
config.getPassword(), config.getDbName(), config.getDriver())
.getTableComment();
}
}

View File

@@ -0,0 +1,18 @@
package com.landaiqing.core.utils;
import java.util.ArrayList;
import java.util.List;
/**
* 集合类
*
* @author loser
* @date 2023/9/4
*/
public class Lists {
public static List<Object> newArrayList() {
return new ArrayList<>();
}
}

View File

@@ -0,0 +1,64 @@
package com.landaiqing.core.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* mysql转java转换器
*
* @author loser
* @date 2023/9/4
*/
public class MySQLToJavaTypeConverter {
private static final Map<String, Item> typeMap = new HashMap<>();
static {
typeMap.put("tinyint", new Item(false, "Integer"));
typeMap.put("smallint", new Item(false, "Short"));
typeMap.put("mediumint", new Item(false, "Integer"));
typeMap.put("int", new Item(false, "Integer"));
typeMap.put("bigint", new Item(false, "Long"));
typeMap.put("float", new Item(false, "Float"));
typeMap.put("double", new Item(false, "Double"));
typeMap.put("char", new Item(false, "String"));
typeMap.put("varchar", new Item(false, "String"));
typeMap.put("text", new Item(false, "String"));
typeMap.put("longtext", new Item(false, "String"));
typeMap.put("blob", new Item(false, "Byte"));
typeMap.put("decimal", new Item(true, "BigDecimal"));
typeMap.put("date", new Item(true, "Date"));
typeMap.put("time", new Item(true, "Date"));
typeMap.put("datetime", new Item(true, "Date"));
typeMap.put("timestamp", new Item(true, "Date"));
}
public static Item convert(String mysqlType) {
Item item = typeMap.get(mysqlType.toLowerCase());
if (Objects.isNull(item)) {
return new Item(false, mysqlType);
}
return item;
}
public static Item trans(String type) {
for (Item value : typeMap.values()) {
if (value.type.equals(type)) {
return value;
}
}
return new Item(false, type);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Item {
private boolean flag;
private String type;
}
}

View File

@@ -0,0 +1,33 @@
package com.landaiqing.core.utils;
import java.util.HashMap;
import java.util.Map;
public class MySQLToMyBatisTypeConverter {
private static final Map<String, String> typeMap = new HashMap<>();
static {
// 添加MySQL数据类型到MyBatis数据类型的映射关系
typeMap.put("VARCHAR", "VARCHAR");
typeMap.put("CHAR", "CHAR");
typeMap.put("TEXT", "VARCHAR");
typeMap.put("LONGTEXT", "VARCHAR");
typeMap.put("INT", "INTEGER");
typeMap.put("TINYINT", "TINYINT");
typeMap.put("SMALLINT", "SMALLINT");
typeMap.put("MEDIUMINT", "INTEGER");
typeMap.put("BIGINT", "BIGINT");
typeMap.put("FLOAT", "REAL");
typeMap.put("DOUBLE", "DOUBLE");
typeMap.put("DECIMAL", "DECIMAL");
typeMap.put("DATE", "DATE");
typeMap.put("TIME", "TIME");
typeMap.put("DATETIME", "TIMESTAMP");
typeMap.put("TIMESTAMP", "TIMESTAMP");
typeMap.put("YEAR", "DATE");
}
public static String convert(String mysqlType) {
return typeMap.getOrDefault(mysqlType.toUpperCase(), "VARCHAR");
}
}

View File

@@ -0,0 +1,21 @@
package com.landaiqing.core.utils;
/**
* 判断是否是基本类型工具类
*
* @author loser
* @date 2023/9/4
*/
public class PrimitiveTypeUtils {
public static boolean isPrimitive(Object obj) {
return obj instanceof Integer ||
obj instanceof Long ||
obj instanceof Float ||
obj instanceof Double ||
obj instanceof Boolean ||
obj instanceof Character ||
obj instanceof Byte;
}
}

View File

@@ -0,0 +1,49 @@
package com.landaiqing.core.utils;
public class SystemUtils {
/**
* 判断操作系统是否是 Windows
*
* @return true操作系统是 Windows
* false其它操作系统
*/
public static boolean isWindows() {
String osName = getOsName();
return osName != null && osName.startsWith("Windows");
}
/**
* 判断操作系统是否是 MacOS
*
* @return true操作系统是 MacOS
* false其它操作系统
*/
public static boolean isMacOs() {
String osName = getOsName();
return osName != null && osName.startsWith("Mac");
}
/**
* 判断操作系统是否是 Linux
*
* @return true操作系统是 Linux
* false其它操作系统
*/
public static boolean isLinux() {
String osName = getOsName();
return (osName != null && osName.startsWith("Linux")) || (!isWindows() && !isMacOs());
}
/**
* 获取操作系统名称
*
* @return os.name 属性值
*/
public static String getOsName() {
return System.getProperty("os.name");
}
}

View File

@@ -0,0 +1,46 @@
package com.landaiqing.core.utils;
import com.landaiqing.core.anno.Table;
import com.landaiqing.core.entity.TableInfo;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class TableUtils {
private TableUtils() {
}
public static String getComment(Class<?> clazz) {
Table table = clazz.getAnnotation(Table.class);
if (Objects.isNull(table)) {
return "";
}
return table.value();
}
public static List<TableInfo> build(Class<?> clazz) {
String comment = getComment(clazz);
return Arrays.stream(clazz.getDeclaredFields()).filter(item -> {
Table table = item.getAnnotation(Table.class);
return Objects.nonNull(table);
}).map(item -> {
Table table = item.getAnnotation(Table.class);
TableInfo info = new TableInfo();
info.setKeyType(table.keyType());
info.setCol(table.col());
info.setTableComment(comment);
info.setType(table.jdbcType());
info.setMyBatisType(table.myBatisType());
info.setName(item.getName());
info.setComment(table.value());
info.setDataType(item.getType().getSimpleName());
return info;
}).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,31 @@
package com.landaiqing.core.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.landaiqing.core.core.CodeGenerationCode;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* yml 转对象工具类
*
* @author loser
* @date 2023/9/4
*/
public class YamlUtils {
private static final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
public static <T> T loadYaml(String filePath, Class<T> valueType) {
try {
ClassLoader classLoader = CodeGenerationCode.class.getClassLoader();
URL resource = classLoader.getResource(filePath);
InputStream inputStream = resource.openStream();
return objectMapper.readValue(inputStream, valueType);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View File

@@ -0,0 +1,44 @@
{
"fields": [
{
"type": "int",
"name": "Element1"
},
{
"type": "boolean",
"name": "Element2"
},
{
"type": "byte",
"name": "Element3"
},
{
"type": "double",
"name": "Element4"
},
{
"type": "float",
"name": "Element5"
},
{
"type": "short",
"name": "Element6"
},
{
"type": "int",
"name": "Element7"
},
{
"type": "char",
"name": "Element8"
},
{
"type": "boolean",
"name": "Element9"
},
{
"type": "long",
"name": "Element10"
}
]
}

View File

@@ -0,0 +1,28 @@
# 01 数据源输入 填充到全局的context中
# 1.1 通过指定类的返回值写入 (优先级第一)
#handler: com.loser.core.impl.JdbcPutContextHandler
# 1.2 直接从classPath中引入一个json数据 可配合 mapperInfos 替换模板 (优先级第二)
json: genCode/fields.json
# 1.3 配置数据库信息从表字段中获取数据 (优先级第三)
#jdbc:
# url: jdbc:mysql://119.91.155.174:3306/
# username: root
# password: 6666888123
# dbName: ape
# driver: com.mysql.cj.jdbc.Driver
# tableName: sys_user
# 02 模板与生成类的映射关系 通过修改该配置 切换不同的生成模板 比如从基础的crud代码模板 切换到 rpc代码模板等
mapperInfos: genCode/mapper.yml
# 03 针对某个生成文件写入独有上下文 通过 mapper.yml > mappers > fileId 关联
#filePutHandler: com.loser.core.impl.DemoFilePutContextHandler
# 04 全局上下文参数
params:
pre: Loser
module: test
author: loser
# 内置函数:now()-获取当前时间;date()-获取当前时间不带时分秒;svUid()-生成序列化ID;
# 扩展新的函数 则在调用生成方法前 使用 FunctionUtils.register(Function function)
date: now()

View File

@@ -0,0 +1,74 @@
# 生成到当前项目的那个子模块,没有则配置 /
module: /ape-demo/
# 模板文件和生成类的映射关系 多个文件 数组形式配置
mappers:
-
- fileId: 001
template: genCode/template/ReqAndRespTemplate.java.vm
# 生成到 src.main.java 下的对应包中
packageName: com.loser.user.${module}.vo.resp
name: ${pre}InfoResp
ext: java
# fileId 用于实现 FilePutContextHandler 接口时 忘对应文件的上下文补充数据
- fileId: 002
template: genCode/template/ReqAndRespTemplate.java.vm
# 优先级比 packageName 使用场景为需要指定目录的文件比如resources下的 mapper 文件等
filePath: src/main/resources/${module}/template
name: ${pre}InfoResp
ext: java.vm
- fileId: 003
template: genCode/template/EntityTemplate.java.vm
packageName: com.loser.user.${module}.entity
name: ${pre}
ext: java
- fileId: 004
template: genCode/template/ReqAndRespTemplate.java.vm
packageName: com.loser.user.${module}.vo.req
name: ${pre}Req
ext: java
- fileId: 005
template: genCode/template/ReqAndRespTemplate.java.vm
packageName: com.loser.user.${module}.vo.resp
name: ${pre}Resp
ext: java
- fileId: 006
template: genCode/template/ServiceTemplate.java.vm
packageName: com.loser.user.${module}.service
name: ${pre}Service
ext: java
- fileId: 007
template: genCode/template/ServiceImplTemplate.java.vm
packageName: com.loser.user.${module}.service.impl
name: ${pre}ServiceImpl
ext: java
- fileId: 008
template: genCode/template/HandlerTemplate.java.vm
packageName: com.loser.user.${module}.handler
name: ${pre}Handler
ext: java
- fileId: 009
template: genCode/template/PageReqTemplate.java.vm
packageName: com.loser.user.${module}.vo.req
name: ${pre}PageReq
ext: java
- fileId: 010
template: genCode/template/ReqAndRespTemplate.java.vm
packageName: com.loser.user.${module}.vo.req
name: ${pre}SaveReq
ext: java
- fileId: 011
template: genCode/template/ReqAndRespTemplate.java.vm
packageName: com.loser.user.${module}.vo.req
name: ${pre}UpdateReq
ext: java

View File

@@ -0,0 +1,19 @@
package ${packageName};
#if($importDate)
import java.util.Date;
#end
/**
* ${tableComment}实体
*
* @author ${author}
* @date ${date}
*/
public class ${className} {
#foreach($field in $fields)
private $field.type $field.name;
#end
}

View File

@@ -0,0 +1,84 @@
package ${packageName};
import com.loser.bean.Result;
import com.loser.user.mongo.ParamsUtil;
import com.loser.user.${module}.entity.${pre};
import com.loser.user.${module}.service.${pre}Service;
import com.loser.user.${module}.vo.req.${pre}PageReq;
import com.loser.user.${module}.vo.req.${pre}SaveReq;
import com.loser.user.${module}.vo.req.${pre}UpdateReq;
import com.loser.user.${module}.vo.resp.${pre}InfoResp;
import com.loser.core.entity.Page;
import com.loser.core.wrapper.LambdaQueryWrapper;
import com.loser.core.wrapper.Wrappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
* 测试数据 处理器
*
* @author loser
* @date 2023-06-13
*/
@Component
public class ${pre}Handler {
@Autowired
private ${pre}Service ${pre}Service;
/**
* 新增测试数据
*/
public Result<Boolean> save(${pre}SaveReq req) {
${pre} save = ParamsUtil.copyProperties(req, ${pre}.class);
return Result.ok(${pre}Service.save(save));
}
/**
* 修改测试数据
*/
public Result<Boolean> update(${pre}UpdateReq req) {
${pre} update = ParamsUtil.copyProperties(req, ${pre}.class);
return Result.ok(${pre}Service.updateById(update));
}
/**
* 通过id删除测试数据
*/
public Result<Boolean> deleteById(String id) {
return Result.ok(${pre}Service.removeById(id));
}
/**
* 通过id获取测试数据
*/
public Result<${pre}InfoResp> getById(String id) {
${pre} dbData = ${pre}Service.getById(id);
if (Objects.isNull(dbData)) {
return Result.ok();
}
return Result.ok(ParamsUtil.copyProperties(dbData, ${pre}InfoResp.class));
}
/**
* 分页获取测试数据
*/
public Result<Page<${pre}>> queryList(${pre}PageReq req) {
LambdaQueryWrapper<${pre}> query = Wrappers.<${pre}>lambdaQuery();
Page<${pre}> page = ${pre}Service.page(query, req.getPageNo(), req.getPageSize());
return Result.ok(page);
}
}

View File

@@ -0,0 +1,26 @@
package ${packageName};
#if($importDate)
import java.util.Date;
#end
import lombok.Data;
/**
* ${tableComment}实体
*
* @author ${author}
* @date ${date}
*/
@Data
public class ${className} {
private Integer pageNo = 1;
private Integer pageSize = 20;
#foreach($field in $fields)
private $field.type $field.name;
#end
}

View File

@@ -0,0 +1,21 @@
package ${packageName};
#if($importDate)
import java.util.Date;
#end
import lombok.Data;
/**
* ${tableComment}试图
*
* @author ${author}
* @date ${date}
*/
@Data
public class $className {
#foreach($field in $fields)
private $field.type $field.name;
#end
}

View File

@@ -0,0 +1,11 @@
package ${packageName};
import com.loser.user.${module}.entity.${pre};
import com.loser.user.${module}.service.${pre}Service;
import com.loser.core.impl.EasyMongoServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class ${pre}ServiceImpl extends EasyMongoServiceImpl<String, ${pre}> implements ${pre}Service {
}

View File

@@ -0,0 +1,8 @@
package ${packageName};
import com.loser.user.${module}.entity.${pre};
import com.loser.core.sdk.EasyMongoService;
public interface ${pre}Service extends EasyMongoService<String, ${pre}> {
}

View File

@@ -0,0 +1,45 @@
<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.landaiqing</groupId>
<artifactId>qing-yu-common-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>qing-yu-common-starter</name>
<url>http://maven.apache.org</url>
<modules>
<module>easy-gen-code-spring-boot-starter</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>