diff --git a/README.md b/README.md index 9fdf02c0e40637d147109d81825ae10825c9076a..54d1c6fa9e1a72f0dd458f14740b0ceb78348089 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,9 @@ project 项目根目录 最新版本`last.version`= maven +### MyBatis版本要求 +`mybatis.version ≥ 3.5.6` + ### 如仅需要增删改查的增强功能 >仅依赖robin-base项目即可 ```xml @@ -73,3 +76,5 @@ project 项目根目录 ### [示例项目](https://gitee.com/opensource4clive/robin-example) +### [更新日志](doc/release-log.md) + diff --git a/doc/index.md b/doc/index.md deleted file mode 100644 index 0e51c22bc267b8b75478eda9cebce38abafeb0b5..0000000000000000000000000000000000000000 --- a/doc/index.md +++ /dev/null @@ -1,152 +0,0 @@ -# 简介 - -`code-generator`是一个简单的代码生成工具,在不侵入框架底层的前提下,达到简化开发、提高开发效率的目的。 - -## 项目背景 - -此项目分为两个部分:第一个部分为通用Mapper和Service提供CRUD基本操作的支持;第二个部分是代码生成功能,为表结构变动时提供高效快速生成对应的实体对象。 -此项目参考了[mybatis-generator](http://mybatis.org/generator/)和[mybatis-plus](https://mybatis.plus/), 取其精华并与grus框架融合。mybatis-generator会生成很多冗余代码,而mybatis-plus则不用生成冗余代码,功能也很强大,但是其对底层侵入太深,对mybatis的SqlSessionFactory进行了重写,不能直接集成到我司项目中使用;参考两者优秀之处code-generator诞生了,既不需要生成冗余代码,也不需要对底层侵入,使用方便集成快速,适合快速开发,将更多的时间用在业务逻辑上。 - -## 特性 -- **无侵入**:只做增强不做改变,引入它不会对现有工程产生影响 -- **无损耗**:启动即会自动注入基本增删改查功能,性能无损耗,直接面向对象操作 -- **CRUD 操作**:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 -- **支持 Lambda 形式调用**:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 -- **代码生成器**:可快速生成 Entity、Mapper、Service、Controller 层代码,支持自定义模板 -- **分页**:基于 MyBatis 物理分页,直接返回grus框架封装的分页对象, 同时支持pagehelper分页插件 - -## 快速开始 - -这里以一个空的工程来示例 - -#### 添加依赖 - -引入 Grus Boot Starter 父工程: - -```xml - - com.ciicgat.grus.boot - grus-boot-starter-parent - 2020.12.1.RELEASE - -``` - -引入服务端应用常用的依赖 - -```xml - - grus-boot-starter-server-general - com.ciicgat.grus.boot - -``` - -引入数据依赖 - -```xml - - com.ciicgat.grus.boot - grus-boot-starter-data - -``` - -引入测试依赖 - -```xml - - org.springframework.boot - spring-boot-starter-test - test - -``` - -#### 配置 - -在`application.properties`中配置基本信息 - -```properties -spring.application.name=ecappetc -server.port=8088 -server.tomcat.uri-encoding=UTF-8 -logging.level.com.ciicgat.grusgenerator.codegenerator.example.mapper=debug -spring.jackson.date-format=yyyy-MM-dd HH:mm:ss -spring.jackson.time-zone=GMT+8 -grus.feign.log-req=true -grus.feign.log-resp=true -mybatis.mapper-locations=classpath*:mapper/*.xml - -``` - -添加启动类`Application.java` - -```java -@SpringBootApplication -@MapperScan("com.ciicgat.grusgenerator.codegenerator.example.mapper") -public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} -``` - -#### 编码 - -编写实体类`ShopTip.java` - -```java -@Data -@TableName("ShopTip") -public class ShopTip { - @TableId - private Long id; - @TableField(ignoreSaving = true) - private Date timeCreated; - @TableField(ignoreSaving = true) - private Date timeModified; - private Long ecappId; - private Integer type; - private String title; - private String content; - private Integer enable; -} -``` - -编写Mapper类`ShopTipMapper.java` - -```java -public interface ShopTipMapper extends BaseMapper { - // 如有其他方法直接书写其中即可 - // ShopTip selectOne(Long id); -} -``` - -同时也支持`@Mapper`注解 - -#### 开始使用 - -添加测试类 - -```java -@RunWith(SpringRunner.class) -@SpringBootTest -public class SampleTest { - @Resource - private ShopTipMapper shopTipMapper; - @Test - public void testList() { - Example example = new ConditionExample<>(); - List list = shopTipMapper.list(example); - Assert.assertTrue(list.size() > 0); - list.forEach(System.out::println); - } -} -``` - -## [CRUD 接口](doc/code-generator/crud-interface.md) - -## [条件构造器](doc/code-generator/conditional.md) - -## [代码生成器](doc/code-generator/generator.md) - -## [读写分离](doc/code-generator/read-write-separation.md) - -## [常见问题](doc/code-generator/faq.md) diff --git a/doc/release-log.md b/doc/release-log.md new file mode 100644 index 0000000000000000000000000000000000000000..9fb15ff591498fd4dfb74a168a43f08b6a13d9ec --- /dev/null +++ b/doc/release-log.md @@ -0,0 +1,11 @@ +# 更新日志 + + +## v1.2.3 2021-09-06 +- fix issue: https://gitee.com/opensource4clive/robin/issues/I45XJH + +## v1.2.4 2021-12-23 +- fix issues: + - https://gitee.com/opensource4clive/robin/issues/I4NGRG + - https://gitee.com/opensource4clive/robin/issues/I4NQ4V + - https://gitee.com/opensource4clive/robin/issues/I4NQ4U diff --git a/doc/xml-config.md b/doc/xml-config.md index 81106506c302236e7e3fa23f06f72568a3973969..a6de3116a139214e24d1908867b95123d6655e58 100644 --- a/doc/xml-config.md +++ b/doc/xml-config.md @@ -85,6 +85,7 @@ | createTimeColumn | 创建时间字段 | 否 | 默认为`created_at` | | updateTimeColumn | 更新时间字段 | 否 | 默认为`updated_at` | | entityObjectSuffix | 实体后缀 | 否 | 给生成的实体加上统一后缀, 如 `DO` -> UserDO | +| removePrefix | 移除表前缀 | 否 | 用于生成对象的名字时统一移除前缀
如 表名为`t_user`, `removePrefix=false` -> TUserDO, `removePrefix=true` -> UserDO | #### table 要生成的表 diff --git a/pom.xml b/pom.xml index 2c1c5091a7333c1b688b319f954db17d871706d5..f2e6d61f6fa6a2e0de7dcf34644fe46bd8c29f8e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.gitee.opensource4clive robin pom - 1.2.0 + 1.2.4 robin Robin is a lightweight framework based on MyBatis that provides adding, deleting, modifying and querying capabilities. https://gitee.com/opensource4clive/robin diff --git a/robin-base/pom.xml b/robin-base/pom.xml index fac9fa3580df799db549107215962998503f2da2..459b1e50f89b1d7bfc55293cd3851182c216ced1 100644 --- a/robin-base/pom.xml +++ b/robin-base/pom.xml @@ -3,11 +3,11 @@ 4.0.0 robin-base jar - 1.2.0 + 1.2.4 com.gitee.opensource4clive robin - 1.2.0 + 1.2.3 diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/BaseServiceImpl.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/BaseServiceImpl.java index 7b9afb651caac88ed09339fad64b4d2312393953..1a2e405dababad9321c66e6441cf6e750ec1286b 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/BaseServiceImpl.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/BaseServiceImpl.java @@ -155,7 +155,7 @@ public class BaseServiceImpl implements BaseService { private Example convertQueryToExample(Query query) { T entity = query.getEntity(); if (Objects.nonNull(entity)) { - Map fieldAndValue = ReflectUtils.resolveEntityFieldAndValue(entity); + Map fieldAndValue = ReflectUtils.resolveEntityFieldAndValue(entity); GeneratedCriteria criteria = query.getExistCriteria(); if (criteria instanceof LambdaCriteria) { LambdaCriteria lambdaCriteria = (LambdaCriteria) criteria; diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/common/Pagination.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/common/Pagination.java index aee6a5c0440bca2fd736728959ccd68bf481e825..4a27a26149dcb6a323819c7c8ea474e58888f471 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/common/Pagination.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/common/Pagination.java @@ -18,8 +18,7 @@ import java.util.Objects; public class Pagination implements Serializable { public static final int DEFAULT_PAGE_NUM = 1; - public static final int DEFAULT_PAGE_SIZE = 20; - public static final int MAX_PAGE_SIZE = 200; + public static final int DEFAULT_PAGE_SIZE = 10; private static final long serialVersionUID = 1L; /** * 总条数 @@ -36,8 +35,22 @@ public class Pagination implements Serializable { */ private boolean hasNext; - public Pagination() { + /** + * 总页数 + */ + private int totalPages; + + /** + * 页码 + */ + private int pageNo; + /** + * 页面大小 + */ + private int pageSize; + + public Pagination() { } /** @@ -49,11 +62,26 @@ public class Pagination implements Serializable { return new Pagination(0, new ArrayList<>(), DEFAULT_PAGE_NUM, DEFAULT_PAGE_SIZE); } + /** + * 通过分页构建分页 + * + * @param dataList 数据列表 + * @param pagination 旧分页 + * @param 新分页对象 + * @param 旧分页对象 + * @return + */ + public static Pagination buildByPagination(List dataList, Pagination pagination) { + return new Pagination(pagination.getTotalCount(), dataList, pagination.getPageNo(), pagination.getPageSize()); + } + public Pagination(int totalCount, List dataList, int pageNo, int pageSize) { + this.pageNo = pageNo; + this.pageSize = pageSize; this.totalCount = totalCount; this.dataList = dataList; - int pageNum = (totalCount / pageSize) + ((totalCount % pageSize == 0) ? 0 : 1); - this.hasNext = pageNo < pageNum; + this.totalPages = (totalCount / pageSize) + ((totalCount % pageSize == 0) ? 0 : 1); + this.hasNext = pageNo < this.totalPages; } public int getTotalCount() { @@ -80,6 +108,18 @@ public class Pagination implements Serializable { this.hasNext = hasNext; } + public int getPageNo() { + return pageNo; + } + + public int getPageSize() { + return pageSize; + } + + public int getTotalPages() { + return totalPages; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/common/ApiResponse.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/common/WebApiResponse.java similarity index 53% rename from robin-base/src/main/java/cn/cliveyuan/robin/base/common/ApiResponse.java rename to robin-base/src/main/java/cn/cliveyuan/robin/base/common/WebApiResponse.java index 7d143ca3f9504cf32c3ac2b451b49ccc84fdf9fe..c0e642bf5af3808975c0589264ce0d9c12c71d9b 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/common/ApiResponse.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/common/WebApiResponse.java @@ -9,7 +9,7 @@ import java.util.Objects; * @author Clive Yuan * @date 2020/12/24 */ -public class ApiResponse implements Serializable { +public class WebApiResponse implements Serializable { private static final long serialVersionUID = 1L; /** * 编码 @@ -25,38 +25,38 @@ public class ApiResponse implements Serializable { private T data; - public ApiResponse() { + public WebApiResponse() { } - public static ApiResponse success(T data) { - ApiResponse apiResponse = new ApiResponse<>(); - apiResponse.setCode(0); - apiResponse.setMsg("success"); - apiResponse.setData(data); - return apiResponse; + public static WebApiResponse success(T data) { + WebApiResponse webApiResponse = new WebApiResponse<>(); + webApiResponse.setCode(0); + webApiResponse.setMsg("success"); + webApiResponse.setData(data); + return webApiResponse; } - public static ApiResponse fail(ApiErrorCode apiErrorCode) { - ApiResponse apiResponse = new ApiResponse<>(); - apiResponse.setCode(apiErrorCode.getCode()); - apiResponse.setMsg(apiErrorCode.getMsg()); - return apiResponse; + public static WebApiResponse fail(ApiErrorCode apiErrorCode) { + WebApiResponse webApiResponse = new WebApiResponse<>(); + webApiResponse.setCode(apiErrorCode.getCode()); + webApiResponse.setMsg(apiErrorCode.getMsg()); + return webApiResponse; } - public static ApiResponse fail(ApiErrorCode apiErrorCode, T data) { - ApiResponse apiResponse = new ApiResponse<>(); - apiResponse.setCode(apiErrorCode.getCode()); - apiResponse.setMsg(apiErrorCode.getMsg()); - apiResponse.setData(data); - return apiResponse; + public static WebApiResponse fail(ApiErrorCode apiErrorCode, T data) { + WebApiResponse webApiResponse = new WebApiResponse<>(); + webApiResponse.setCode(apiErrorCode.getCode()); + webApiResponse.setMsg(apiErrorCode.getMsg()); + webApiResponse.setData(data); + return webApiResponse; } - public static ApiResponse fail(int code, String msg) { - ApiResponse apiResponse = new ApiResponse<>(); - apiResponse.setCode(code); - apiResponse.setMsg(msg); - return apiResponse; + public static WebApiResponse fail(int code, String msg) { + WebApiResponse webApiResponse = new WebApiResponse<>(); + webApiResponse.setCode(code); + webApiResponse.setMsg(msg); + return webApiResponse; } @@ -97,7 +97,7 @@ public class ApiResponse implements Serializable { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - ApiResponse that = (ApiResponse) o; + WebApiResponse that = (WebApiResponse) o; return code == that.code && Objects.equals(msg, that.msg) && Objects.equals(data, that.data); diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Compare.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Compare.java index 461949d11a8be1aae05102fd837f7cc08fdb9af7..1a3535750c27a290c8f75835364801bd3de1ee4a 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Compare.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Compare.java @@ -32,6 +32,26 @@ public interface Compare extends Serializable { */ Children ne(R column, Object val); + /** + * 等于 = + * (支持空字符串) + * + * @param column 字段 + * @param val 值 + * @return children + */ + Children eqBlankable(R column, Object val); + + /** + * 不等于 <> + * (支持空字符串) + * + * @param column 字段 + * @param val 值 + * @return children + */ + Children neBlankable(R column, Object val); + /** * 大于 > * diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Func.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Func.java index e87789783c5d6433fbc063802b2d0bbcd6163d47..074c2f1881c2268d0e35ac54953ee43266b39443 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Func.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/Func.java @@ -38,6 +38,24 @@ public interface Func extends Serializable { */ Children isNotNull(R column); + /** + * 字段 = 空字符串("") + *

例: isBlank("name")

+ * + * @param column 字段 + * @return children + */ + Children isBlank(R column); + + /** + * 字段 != 空字符串("") + *

例: isNotBlank("name")

+ * + * @param column 字段 + * @return children + */ + Children isNotBlank(R column); + /** * 字段 IN (value.get(0), value.get(1), ...) *

例: in("id", Arrays.asList(1, 2, 3, 4, 5))

diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/GeneratedCriteria.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/GeneratedCriteria.java index 71242599e336db81dd36c70f22a0c0237b79079b..006701867151ef33036ba1cefb8775348e80ebee 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/GeneratedCriteria.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/condition/GeneratedCriteria.java @@ -4,7 +4,10 @@ package cn.cliveyuan.robin.base.condition; +import cn.cliveyuan.robin.base.util.RobinStrUtils; import cn.cliveyuan.robin.base.util.SqlUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; @@ -19,7 +22,7 @@ import java.util.Objects; */ @SuppressWarnings({"serial", "unchecked"}) public abstract class GeneratedCriteria implements Compare, Func { - + private static final Logger LOGGER = LoggerFactory.getLogger(GeneratedCriteria.class); /** * 占位符 */ @@ -65,8 +68,17 @@ public abstract class GeneratedCriteria implements Compare Objects.equals(x.getCondition(), condition)); criteria.add(new Criterion(condition, value)); @@ -75,14 +87,19 @@ public abstract class GeneratedCriteria implements Compare implements Compare implements Compare coll) { addCriterion(column, SqlKeyword.IN, coll); diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/util/LambdaUtils.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/util/LambdaUtils.java index d0fe97034768e1c2256effdc2731b8184d04f80f..4c30fc8e1a3c22f3eb714f69f946049353d1c16f 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/util/LambdaUtils.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/util/LambdaUtils.java @@ -4,11 +4,14 @@ package cn.cliveyuan.robin.base.util; +import cn.cliveyuan.robin.base.annotation.TableField; import cn.cliveyuan.robin.base.support.SFunction; import java.lang.invoke.SerializedLambda; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @@ -28,7 +31,28 @@ public class LambdaUtils { public static String getFieldName(SFunction func) { SerializedLambda serializedLambda = resolveSerializedLambdaCache(func); String getter = serializedLambda.getImplMethodName(); - return resolveFieldName(getter); + return getColumnName(serializedLambda.getImplClass(), resolveFieldName(getter)); + } + + /** + * 通过对象字段名获取表字段 + * + * @param implClassString 对象 + * @param fieldName 字段名 + * @return + */ + private static String getColumnName(String implClassString, String fieldName) { + try { + Class implClass = Class.forName(implClassString.replace('/', '.')); + Field field = implClass.getDeclaredField(fieldName); + TableField tableField = field.getAnnotation(TableField.class); + if (Objects.nonNull(tableField) && RobinStrUtils.isNotBlank(tableField.value())) { + return tableField.value(); + } + } catch (ClassNotFoundException | NoSuchFieldException e) { + throw new RuntimeException(e); + } + return fieldName; } private static SerializedLambda resolveSerializedLambdaCache(SFunction func) { diff --git a/robin-base/src/main/java/cn/cliveyuan/robin/base/util/ReflectUtils.java b/robin-base/src/main/java/cn/cliveyuan/robin/base/util/ReflectUtils.java index d9ff4aa8fa98d8cbf8401c4de0c1a7ee15e56479..a5b3bb61c3e6f3815b90c1a508e2f83f78fb16cb 100644 --- a/robin-base/src/main/java/cn/cliveyuan/robin/base/util/ReflectUtils.java +++ b/robin-base/src/main/java/cn/cliveyuan/robin/base/util/ReflectUtils.java @@ -105,7 +105,7 @@ public class ReflectUtils { // 读取字段 List fields = new ArrayList<>(); reflectEntity.setFields(fields); - List declaredFields = getDeclaredFields(clazz); + List declaredFields = getAllDeclaredFields(clazz); for (Field declaredField : declaredFields) { String name = declaredField.getName(); boolean primaryKey = false; @@ -156,24 +156,34 @@ public class ReflectUtils { * @param 实体对象类 * @return */ - public static Map resolveEntityFieldAndValue(T entity) { - Map fieldValueMap = new HashMap<>(); + public static Map resolveEntityFieldAndValue(T entity) { + Map fieldValueMap = new HashMap<>(); Class entityClass = entity.getClass(); - List declaredFields = getDeclaredFields(entityClass); + List declaredFields = getAllDeclaredFields(entityClass); List fieldNames = declaredFields.stream() .map(Field::getName) .collect(Collectors.toList()); + Map fieldMap = declaredFields.stream().collect(Collectors.toMap(Field::getName, Function.identity())); - Method[] declaredMethods = entityClass.getDeclaredMethods(); - Map getMethodMap = Arrays.stream(declaredMethods).filter(x -> x.getName().startsWith(GET_METHOD_PREFIX)) + List declaredMethods = getAllMethods(entityClass); + Map getMethodMap = declaredMethods.stream().filter(x -> x.getName().startsWith(GET_METHOD_PREFIX)) .collect(Collectors.toMap(Method::getName, Function.identity())); fieldNames.forEach(fieldName -> { + String columnName = fieldName; + Field field = fieldMap.get(fieldName); + TableField tableField = field.getAnnotation(TableField.class); + if (Objects.nonNull(tableField) && RobinStrUtils.isNotBlank(tableField.value())) { + columnName = tableField.value(); + } String methodName = GET_METHOD_PREFIX.concat(SqlUtils.firstToUpperCase(fieldName)); Method method = getMethodMap.get(methodName); + if (Objects.isNull(method)) { + return; + } Object value = methodInvoke(method, entity); if (Objects.nonNull(value)) { - fieldValueMap.put(fieldName, value.toString()); + fieldValueMap.put(columnName, value); } }); return fieldValueMap; @@ -190,25 +200,85 @@ public class ReflectUtils { } public static Method getMethod(Class entityClass, String fieldName) { - try { - return entityClass.getDeclaredMethod(GET_METHOD_PREFIX.concat(SqlUtils.firstToUpperCase(fieldName))); - } catch (NoSuchMethodException e) { - LOGGER.error("getMethod error", e); - throw new RuntimeException(e); + Method method = getMethodRecursion(entityClass, fieldName); + if (Objects.isNull(method)) { + String methodName = GET_METHOD_PREFIX.concat(SqlUtils.firstToUpperCase(fieldName)); + throw new RuntimeException(String.format("NoSuchMethodException: %s.%s()", entityClass, methodName)); + } + return method; + } + + /** + * 递归获取对象get方法 + * + * @param entityClass 对象类 + * @param fieldName 字段名 + * @return + */ + private static Method getMethodRecursion(Class entityClass, String fieldName) { + String methodName = GET_METHOD_PREFIX.concat(SqlUtils.firstToUpperCase(fieldName)); + if ("java.lang.Object".equalsIgnoreCase(entityClass.getName())) { + return null; + } + return Arrays.stream(entityClass.getDeclaredMethods()) + .filter(x -> Objects.equals(x.getName(), methodName)) + .findFirst() + .orElseGet(() -> getMethodRecursion(entityClass.getSuperclass(), fieldName)); + } + + public static List getAllMethods(Class entityClass) { + List list = new ArrayList<>(); + getMethodsRecursion(entityClass, list); + return list; + } + + public static void getMethodsRecursion(Class entityClass, List list) { + if ("java.lang.Object".equalsIgnoreCase(entityClass.getName())) { + return; } + list.addAll(Arrays.stream(entityClass.getDeclaredMethods()).collect(Collectors.toList())); + getMethodsRecursion(entityClass.getSuperclass(), list); } /** - * 获取所有声明字段,且非static修饰 + * 获取当前类声明字段,且非static修饰 * * @param clazz 类对象 * @return */ - private static List getDeclaredFields(Class clazz) { + public static List getDeclaredFields(Class clazz) { Field[] declaredFields = clazz.getDeclaredFields(); return Arrays.stream(declaredFields).filter(x -> !Modifier.isStatic(x.getModifiers())) .collect(Collectors.toList()); + } + /** + * 获取所有声明字段,且非static修饰 (包括父类) + * + * @param clazz 类对象 + * @return + */ + public static List getAllDeclaredFields(Class clazz) { + List list = new ArrayList<>(); + getFieldsRecursion(clazz, list); + return list; + } + + /** + * 递归获取对象字段 + * + * @param entityClass 对象类 + * @param fields 字段列表 + * @return + */ + private static void getFieldsRecursion(Class entityClass, List fields) { + if ("java.lang.Object".equalsIgnoreCase(entityClass.getName())) { + return; + } + Field[] declaredFields = entityClass.getDeclaredFields(); + fields.addAll(Arrays.stream(declaredFields).filter(x -> !Modifier.isStatic(x.getModifiers())) + .collect(Collectors.toList())); + getFieldsRecursion(entityClass.getSuperclass(), fields); } } diff --git a/robin-base/src/test/java/cn/cliveyuan/robin/base/test/ReflectUtilsTest.java b/robin-base/src/test/java/cn/cliveyuan/robin/base/test/ReflectUtilsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..75014b59529c43fcd922f0a4fdfab6e83e17c4d3 --- /dev/null +++ b/robin-base/src/test/java/cn/cliveyuan/robin/base/test/ReflectUtilsTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2021, CliveYuan All rights reserved. + */ + +package cn.cliveyuan.robin.base.test; + +import cn.cliveyuan.robin.base.util.ReflectUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Method; + +/** + * @author Clive Yuan + * @date 2021/06/07 + */ +public class ReflectUtilsTest { + + @Test + public void test() { + Method method = ReflectUtils.getMethod(SpottyDog.class, "name"); + System.out.println(method); + Assert.assertNotNull(method); + } + + @Test + public void test2() { + System.out.println(ReflectUtils.getDeclaredFields(Animal.class)); + System.out.println(ReflectUtils.getAllDeclaredFields(Animal.class)); + System.out.println(ReflectUtils.getDeclaredFields(Dog.class)); + System.out.println(ReflectUtils.getAllDeclaredFields(Dog.class)); + } + + class Animal { + private Long id; + private String name; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + class Dog extends Animal { + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + + class SpottyDog extends Dog { + + } +} diff --git a/robin-generator/pom.xml b/robin-generator/pom.xml index 64a1ebc1c1cc487752c28b75fcbd0c1d2305044d..f6d81c5c4df51cdde985a8b432f87c3b7a938f6d 100644 --- a/robin-generator/pom.xml +++ b/robin-generator/pom.xml @@ -2,13 +2,13 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 robin-generator - 1.2.0 + 1.2.4 jar com.gitee.opensource4clive robin - 1.2.0 + 1.2.3 diff --git a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java index 2e49b8abbc08b5f317ea32aed57669a668073f2a..d1f7b16fad9fa4b9559b0ef904fa39004aae6e1d 100644 --- a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java +++ b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/CodeGeneratorXmlConfig.java @@ -88,10 +88,26 @@ public class CodeGeneratorXmlConfig implements Serializable { @Data @Builder public static class Table { + /** + * 表名 + */ private String tableName; + /** + * 对象名称 + */ private String entityObjectName; + /** + * 忽略字段 + */ private Set ignoreColumns; + /** + * 对象后缀 + */ private String entityObjectSuffix; + /** + * 移除表前缀 + */ + private String removePrefix; } } diff --git a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java index ba51c211e2d66caf4c1614353315e10575e9ada5..51304a40dfa0990ac0912c9508c64f132ce3b3dd 100644 --- a/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java +++ b/robin-generator/src/main/java/cn/cliveyuan/robin/generator/core/GeneratorContextResolver.java @@ -83,7 +83,11 @@ public class GeneratorContextResolver { private Entity table2Entity(CodeGeneratorXmlConfig.Table table) { TableInfo tableInfo = tableIntrospect.introspect(table.getTableName()); Entity entity = new Entity(); - String lowerCamelName = GeneratorUtils.getLowerCamelName(tableInfo.getName()); + String tableName = tableInfo.getName(); + if (StringUtils.isNotBlank(table.getRemovePrefix()) && tableName.startsWith(table.getRemovePrefix())) { + tableName = tableName.replaceFirst(table.getRemovePrefix(), ""); + } + String lowerCamelName = GeneratorUtils.getLowerCamelName(tableName); String upperCamelName = StringUtils.capitalize(lowerCamelName); String entityName = table.getEntityObjectName(); String suffix = StringUtils.isNotBlank(table.getEntityObjectSuffix()) ? table.getEntityObjectSuffix() : ""; @@ -244,6 +248,7 @@ public class GeneratorContextResolver { String createTimeColumn = this.getAttributeValue(tableEls, "createTimeColumn", true); String updateTimeColumn = this.getAttributeValue(tableEls, "updateTimeColumn", true); String entityObjectSuffix = this.getAttributeValue(tableEls, "entityObjectSuffix", true); + String removePrefix = this.getAttributeValue(tableEls, "removePrefix", true); Set globalIgnoreColumnSet = this.getIgnoreColumnSet(tableEls); String primaryKeyColumn = GeneratorConst.PRIMARY_KEY_COL; @@ -273,6 +278,8 @@ public class GeneratorContextResolver { tables.add(CodeGeneratorXmlConfig.Table.builder() .tableName(tableName) .ignoreColumns(globalIgnoreColumnSet) + .removePrefix(removePrefix) + .entityObjectSuffix(entityObjectSuffix) .build()); }); } else { @@ -286,6 +293,7 @@ public class GeneratorContextResolver { .entityObjectName(this.getAttributeValue(tableEl, "entityObjectName", true)) .entityObjectSuffix(entityObjectSuffix) .ignoreColumns(tableIgnoreColumnSet) + .removePrefix(removePrefix) .build()); } } diff --git a/robin-generator/src/main/resources/templates/controller.java.ftl b/robin-generator/src/main/resources/templates/controller.java.ftl index 4f61efe2915da7d8de83a7460f2370a5863cae2b..3c867a1df69bd183220db2ae61be8aa71a336df5 100644 --- a/robin-generator/src/main/resources/templates/controller.java.ftl +++ b/robin-generator/src/main/resources/templates/controller.java.ftl @@ -6,7 +6,7 @@ import ${servicePackage}.${entity.upperCamelName}${serviceSuffix}; import cn.cliveyuan.robin.base.condition.PageQueryExample; import cn.cliveyuan.robin.base.common.PageQueryRequest; import cn.cliveyuan.robin.base.util.BeanCopyUtils; -import cn.cliveyuan.robin.base.common.ApiResponse; +import cn.cliveyuan.robin.base.common.WebApiResponse; import cn.cliveyuan.robin.base.common.Pagination; [#if baseConfig.enableSwagger] @@ -40,31 +40,31 @@ public class ${entity.fileName} { [#if baseConfig.enableSwagger] @ApiOperation("保存") [/#if] - public ApiResponse save([#if baseConfig.enableValidation]@Validated[/#if] ${entity.upperCamelName}${dtoSuffix} request) { - return ApiResponse.success(${entity.lowerCamelName}${serviceSuffix}.save(BeanCopyUtils.copy(request, ${entity.entityName}.class)) > 0); + public WebApiResponse save([#if baseConfig.enableValidation]@Validated[/#if] ${entity.upperCamelName}${dtoSuffix} request) { + return WebApiResponse.success(${entity.lowerCamelName}${serviceSuffix}.save(BeanCopyUtils.copy(request, ${entity.entityName}.class)) > 0); } @PostMapping("delete") [#if baseConfig.enableSwagger] @ApiOperation("删除") [/#if] - public ApiResponse delete(Long id) { - return ApiResponse.success(${entity.lowerCamelName}${serviceSuffix}.delete(id) > 0); + public WebApiResponse delete(Long id) { + return WebApiResponse.success(${entity.lowerCamelName}${serviceSuffix}.delete(id) > 0); } @PostMapping("get") [#if baseConfig.enableSwagger] @ApiOperation("获取") [/#if] - public ApiResponse<${entity.upperCamelName}${dtoSuffix}> get(Long id) { - return ApiResponse.success(BeanCopyUtils.copy(${entity.lowerCamelName}${serviceSuffix}.get(id), ${entity.upperCamelName}${dtoSuffix}.class)); + public WebApiResponse<${entity.upperCamelName}${dtoSuffix}> get(Long id) { + return WebApiResponse.success(BeanCopyUtils.copy(${entity.lowerCamelName}${serviceSuffix}.get(id), ${entity.upperCamelName}${dtoSuffix}.class)); } @PostMapping("page") [#if baseConfig.enableSwagger] @ApiOperation("分页查询") [/#if] - public ApiResponse> page(@RequestBody PageQueryRequest<${entity.upperCamelName}${dtoSuffix}> request) { - return ApiResponse.success(BeanCopyUtils.copyPagination(${entity.lowerCamelName}${serviceSuffix}.page(new PageQueryExample<>(request, ${entity.entityName}.class)), ${entity.upperCamelName}${dtoSuffix}.class)); + public WebApiResponse> page(@RequestBody PageQueryRequest<${entity.upperCamelName}${dtoSuffix}> request) { + return WebApiResponse.success(BeanCopyUtils.copyPagination(${entity.lowerCamelName}${serviceSuffix}.page(new PageQueryExample<>(request, ${entity.entityName}.class)), ${entity.upperCamelName}${dtoSuffix}.class)); } } diff --git a/robin-generator/src/test/resources/code-generator.xml b/robin-generator/src/test/resources/code-generator.xml index 2b3bcfc2e10458b6d6972232361f8364888201e4..e78c180aa6a48de46dc46b3bf99aa6e63f0d638b 100755 --- a/robin-generator/src/test/resources/code-generator.xml +++ b/robin-generator/src/test/resources/code-generator.xml @@ -43,10 +43,10 @@ - + - -
+ diff --git a/update_versions.sh b/update_versions.sh index 9af421c73504fd5379580c38983ae306f675df3a..42769bf8f173b04e0e792b129b82bb144130851a 100755 --- a/update_versions.sh +++ b/update_versions.sh @@ -1,3 +1,3 @@ #!/bin/sh -mvn versions:set -DnewVersion=1.2.0 +mvn versions:set -DnewVersion=1.2.4