diff --git a/changes.md b/changes.md index 849cf14f..83c788dc 100644 --- a/changes.md +++ b/changes.md @@ -17,7 +17,7 @@ - 优化:修改 getPropertySimpleType 方法实现, 防止出现找不到类的问题,感谢 @dcrpp - 优化:重构将 assertAreNotNull 从 FlexExceptions 移动到 FlexAssert 中,感谢 @Suomm - 优化:重构 ActiveRecord 的一些方法,避免被 JSON 框架解析,感谢 @Suomm -- 优化:BaseMapper.updateNumberAddByQuery() 为删除,在未来 v1.6.0 将会从项目里删除 +- 优化:标记 BaseMapper.updateNumberAddByQuery() 为删除,在未来 v1.6.0 将会从项目里删除 - 优化:Maven 的 "artifact xxx has been relocated" 警告的问题,感谢 [@sppan24](https://github.com/sppan24) - 优化:优化主键逻辑删除处理器逻辑,感谢 @Suomm - 修复:代码生成器多次调用是出错的问题,感谢 @Suomm @@ -36,9 +36,6 @@ - - - ## v1.5.3 20230725: - 新增:添加 UpdateChain 方便用于对数据进行更新 - 新增:添加对 ActiveRecord 设计模式的支持,感谢 @Suomm diff --git a/docs/zh/awesome-things.md b/docs/zh/awesome-things.md index 7f70816c..e2be073c 100644 --- a/docs/zh/awesome-things.md +++ b/docs/zh/awesome-things.md @@ -10,9 +10,9 @@ ## 开发插件 -**Mybatis-Flex IDEA** +**Mybatis-Flex-Helper** -这是一款高度自定义的 Mybatis-Flex IDEA 代码生成插件: +这是一款高度自定义的 Mybatis-Flex IDEA 插件(idea 开发工具可以直接搜索安装): - 开源地址:https://gitee.com/djxchi/mybatis-flex-code-gen.git - 视频简介:https://www.bilibili.com/video/BV1yV411g7Yd @@ -20,7 +20,7 @@ ## 视频教程 **课程1:《MyBatis-Flex 视频教程》** -- 全网首发(免费)。 -> 课程简介:该课程由 [王帅](https://gitee.com/Suomm) 老师录制主讲, [王帅](https://gitee.com/Suomm) 老师 也是除了作者以外,对 MyBatis-Flex 代码贡献最大的 committer。 +> 课程简介:该课程由 [王帅](https://gitee.com/Suomm) 老师录制主讲, [王帅](https://gitee.com/Suomm) 老师也是除了作者以外,对 MyBatis-Flex 代码贡献最大的 committer。 > 其无论对 MyBatis 还是 MyBatis-Flex,都有非常深入的理解。 课程目录: @@ -49,3 +49,6 @@ - [MyBatis-Flex 视频教程 - 22 @Id 的简单使用](https://www.bilibili.com/video/BV1Hp4y1571K) - [MyBatis-Flex 视频教程 - 23 自定义主键生成器](https://www.bilibili.com/video/BV1eM4y1p72z) - [MyBatis-Flex 视频教程 - 24 @Column 注解的简单使用](https://www.bilibili.com/video/BV14c411w7Fr) +- [MyBatis-Flex 视频教程 - 25 isLogicDelete 逻辑删除的简单使用](https://www.bilibili.com/video/BV1K94y1e7X7) +- [MyBatis-Flex 视频教程 - 26 自定义逻辑删除处理器](https://www.bilibili.com/video/BV1oP411z7uu) +- [MyBatis-Flex 视频教程 - 27 version 乐观锁的简单使用](https://www.bilibili.com/video/BV1Rc411F7wp) diff --git a/docs/zh/base/chain.md b/docs/zh/base/chain.md index 1b6db4ba..0206b97a 100644 --- a/docs/zh/base/chain.md +++ b/docs/zh/base/chain.md @@ -187,7 +187,7 @@ public class ArticleVo { ArticleVo articleVo = articleService.queryChain() .select( ARTICLE.ALL_COLUMNS, - max(ARTICLE.comments).as(ArticleVo::maxCommments) + max(ARTICLE.comments).as(ArticleVo::maxComments) ).from(ARTICLE) .where(ARTICLE.ID.ge(100)) .limit(1) diff --git a/docs/zh/base/mybatis-flex-customizer.md b/docs/zh/base/mybatis-flex-customizer.md index b1b8d658..cceebf6e 100644 --- a/docs/zh/base/mybatis-flex-customizer.md +++ b/docs/zh/base/mybatis-flex-customizer.md @@ -2,7 +2,7 @@ `MyBatisFlexCustomizer` 是 MyBatis-Flex 为了方便 `SpringBoot` 用户对 MyBatis-Flex 进行初始化而产生的接口。 -通过在 `@Configuration` 去实现 `MyBatisFlexCustomizer` 接口,我们可以对 MyBatis-Flex 进行一些列的初始化配置。这些配置可能包含如下的内容: +通过在 `@Configuration` 去实现 `MyBatisFlexCustomizer` 接口,我们可以对 MyBatis-Flex 进行一系列的初始化配置。这些配置可能包含如下的内容: - 1、FlexGlobalConfig 的全局配置 - 2、自定义主键生成器 diff --git a/docs/zh/base/parts/base-mapper-update-methods.md b/docs/zh/base/parts/base-mapper-update-methods.md index 1d7f3217..31a52e85 100644 --- a/docs/zh/base/parts/base-mapper-update-methods.md +++ b/docs/zh/base/parts/base-mapper-update-methods.md @@ -6,8 +6,8 @@ - **`updateByCondition(entity, ignoreNulls, whereConditions)`**:根据查询条件来更新数据。 - **`updateByQuery(entity, queryWrapper)`**:根据查询条件来更新数据。 - **`updateByQuery(entity, ignoreNulls, queryWrapper)`**:根据查询条件来更新数据。 -- ~**`updateNumberAddByQuery(fieldName, value, queryWrapper)`**:执行类似 `update table set field = field + 1 where ... ` - 的场景。~ -- ~**`updateNumberAddByQuery(column, value, queryWrapper)`**:执行类似 `update table set field = field + 1 where ... ` - 的场景。~ -- ~**`updateNumberAddByQuery(fn, value, queryWrapper)`**:执行类似 `update table set field = field + 1 where ... ` 的场景。~ +- ~~**`updateNumberAddByQuery(fieldName, value, queryWrapper)`**~~:执行类似 `update table set field = field + 1 where ... ` + 的场景。 +- ~~**`updateNumberAddByQuery(column, value, queryWrapper)`**~~:执行类似 `update table set field = field + 1 where ... ` + 的场景。 +- ~~**`updateNumberAddByQuery(fn, value, queryWrapper)`**~~:执行类似 `update table set field = field + 1 where ... ` 的场景。 diff --git a/docs/zh/changes.md b/docs/zh/changes.md index 849cf14f..83c788dc 100644 --- a/docs/zh/changes.md +++ b/docs/zh/changes.md @@ -17,7 +17,7 @@ - 优化:修改 getPropertySimpleType 方法实现, 防止出现找不到类的问题,感谢 @dcrpp - 优化:重构将 assertAreNotNull 从 FlexExceptions 移动到 FlexAssert 中,感谢 @Suomm - 优化:重构 ActiveRecord 的一些方法,避免被 JSON 框架解析,感谢 @Suomm -- 优化:BaseMapper.updateNumberAddByQuery() 为删除,在未来 v1.6.0 将会从项目里删除 +- 优化:标记 BaseMapper.updateNumberAddByQuery() 为删除,在未来 v1.6.0 将会从项目里删除 - 优化:Maven 的 "artifact xxx has been relocated" 警告的问题,感谢 [@sppan24](https://github.com/sppan24) - 优化:优化主键逻辑删除处理器逻辑,感谢 @Suomm - 修复:代码生成器多次调用是出错的问题,感谢 @Suomm @@ -36,9 +36,6 @@ - - - ## v1.5.3 20230725: - 新增:添加 UpdateChain 方便用于对数据进行更新 - 新增:添加对 ActiveRecord 设计模式的支持,感谢 @Suomm diff --git a/docs/zh/core/audit.md b/docs/zh/core/audit.md index 59d46870..90985962 100644 --- a/docs/zh/core/audit.md +++ b/docs/zh/core/audit.md @@ -6,7 +6,7 @@ SQL 审计是一项非常重要的工作,是企业数据安全体系的重要 ## 开启审计功能 -Mybaits-Flex 的 SQL 审计功能,默认是关闭的,若开启审计功能,许添加如下配置。 +Mybaits-Flex 的 SQL 审计功能,默认是关闭的,若开启审计功能,需添加如下配置。 ```java AuditManager.setAuditEnable(true) diff --git a/docs/zh/core/dynamic-table.md b/docs/zh/core/dynamic-table.md index e617877d..955b16d6 100644 --- a/docs/zh/core/dynamic-table.md +++ b/docs/zh/core/dynamic-table.md @@ -26,7 +26,15 @@ TableManager.setDynamicTableProcessor(new DynamicTableProcessor() { 在某些情况下,我们临时修改映射关系,而非通过 `DynamicTableProcessor.process` 方法获取,可以通过如下配置: ```java -TableManager.setHintTableMapping("tb_account", "tb_account_01") +try{ + TableManager.setHintTableMapping("tb_account", "tb_account_01") + + //这里写您的业务逻辑 + +}finally{ + TableManager.clear() +} + ``` 那么此时,当前线程不再通过 `DynamicTableProcessor` 去获取。 @@ -57,13 +65,13 @@ public class MyConfiguration { DynamicTableProcessor processor = new ....; return processor; } - - + + @Bean public DynamicSchemaProcessor dynamicSchemaProcessor(){ DynamicSchemaProcessor processor = new ....; return processor; } - + } -``` \ No newline at end of file +``` diff --git a/docs/zh/core/logic-delete.md b/docs/zh/core/logic-delete.md index 6994d313..9b243248 100644 --- a/docs/zh/core/logic-delete.md +++ b/docs/zh/core/logic-delete.md @@ -70,12 +70,12 @@ QueryWrapper query1 = QueryWrapper.create() ```sql SELECT * FROM `tb_account` - LEFT JOIN `tb_article` AS `a` ON `tb_account`.`id` = `a`.`account_id` + LEFT JOIN `tb_article` AS `a` + ON `a`.`is_delete` = 0 and `tb_account`.`id` = `a`.`account_id` WHERE `tb_account`.`age` >= 10 AND `tb_account`.`is_delete` = 0 - AND `a`.`is_delete` = 0 ``` -自动添加上 `tb_account.is_delete = 0 AND a.is_delete = 0` 条件。 +在 `left join on` 条件自动添加:`a.is_delete = 0`,并在 where 条件添加上 `tb_account.is_delete = 0`。 示例 2: diff --git a/docs/zh/core/sql-print.md b/docs/zh/core/sql-print.md index 3c47b169..a8b410b9 100644 --- a/docs/zh/core/sql-print.md +++ b/docs/zh/core/sql-print.md @@ -33,7 +33,9 @@ import org.springframework.context.annotation.Configuration; @Configuration public class MyBatisFlexConfiguration { - private static final Logger logger = LoggerFactory.getLogger("mybatis-flex-sql"); + private static final Logger logger = LoggerFactory + .getLogger("mybatis-flex-sql"); + public MyBatisFlexConfiguration() { //开启审计功能 @@ -41,17 +43,42 @@ public class MyBatisFlexConfiguration { //设置 SQL 审计收集器 AuditManager.setMessageCollector(auditMessage -> - logger.info("{},{}ms", auditMessage.getFullSql(), auditMessage.getElapsedTime()) + logger.info("{},{}ms", auditMessage.getFullSql() + , auditMessage.getElapsedTime()) ); } } ``` -## 注意 -在执行以下语句之后执行的 SQL 才会被打印。如果你发现你有些 SQL 没有打印,则需要自行检查 SQL 执行与以下语句执行的先后顺序。 +## MyBatis 自带方案 + +### 非 Spring 项目 + +通过 `bootstrap.setLogImpl()` 方法来指定 MyBatis 输出日志: + +```java 5 +DataSource dataSource = ...; + +MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance() + .setDataSource(dataSource) + .setLogImpl(StdOutImpl.class) + .addMapper(AccountMapper.class) + .start(); ``` -AuditManager.setAuditEnable(true); -AuditManager.setMessageCollector(collector); + +### SpringBoot 项目 + +通过自定义 `ConfigurationCustomizer` 来为 `configuration` 配置 `LogImpl`: + +```java +@Configuration +public class MyConfigurationCustomizer implements ConfigurationCustomizer { + + @Override + public void customize(FlexConfiguration configuration) { + configuration.setLogImpl(StdOutImpl.class); + } +} ``` ## p6spy 方案 @@ -59,4 +86,4 @@ AuditManager.setMessageCollector(collector); 我们可以把数据源配置为 p6spy 数据源,使用 p6spy 的 SQL 输出功能进行 SQL 打印。更多文档参考 p6spy 官方文档: [https://p6spy.readthedocs.io/en/latest/index.html](https://p6spy.readthedocs.io/en/latest/index.html) -使用 SpringBoot 的情况下,参考文档 [https://github.com/gavlyukovskiy/spring-boot-data-source-decorator](https://github.com/gavlyukovskiy/spring-boot-data-source-decorator) \ No newline at end of file +使用 SpringBoot 的情况下,参考文档 [https://github.com/gavlyukovskiy/spring-boot-data-source-decorator](https://github.com/gavlyukovskiy/spring-boot-data-source-decorator) diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java index 9fefdf44..eeafeb08 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java @@ -116,7 +116,7 @@ public @interface RelationOneToMany { * * @return 数据量 */ - int limit() default 0; + long limit() default 0; /** * 默认使用哪个数据源,若系统找不到该指定的数据源时,默认使用第一个数据源。 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java index 0d7dba30..4413d60a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/BaseMapper.java @@ -240,7 +240,7 @@ public interface BaseMapper { * @return 受影响的行数 */ default int deleteByMap(Map whereConditions) { - FlexAssert.notEmpty(whereConditions, "deleteByMap is not allow empty map."); + FlexAssert.notEmpty(whereConditions, "whereConditions"); return deleteByQuery(QueryWrapper.create().where(whereConditions)); } @@ -251,7 +251,7 @@ public interface BaseMapper { * @return 受影响的行数 */ default int deleteByCondition(QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + FlexAssert.notNull(whereConditions, "whereConditions"); return deleteByQuery(QueryWrapper.create().where(whereConditions)); } @@ -296,7 +296,7 @@ public interface BaseMapper { * @return 受影响的行数 */ default int updateByMap(T entity, Map whereConditions) { - FlexAssert.notEmpty(whereConditions, "updateByMap is not allow empty map."); + FlexAssert.notEmpty(whereConditions, "whereConditions"); return updateByQuery(entity, QueryWrapper.create().where(whereConditions)); } @@ -309,7 +309,7 @@ public interface BaseMapper { * @return 受影响的行数 */ default int updateByMap(T entity, boolean ignoreNulls, Map whereConditions) { - FlexAssert.notEmpty(whereConditions, "updateByMap is not allow empty map."); + FlexAssert.notEmpty(whereConditions, "whereConditions"); return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions)); } @@ -321,7 +321,7 @@ public interface BaseMapper { * @return 受影响的行数 */ default int updateByCondition(T entity, QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + FlexAssert.notNull(whereConditions, "whereConditions"); return updateByQuery(entity, QueryWrapper.create().where(whereConditions)); } @@ -334,7 +334,7 @@ public interface BaseMapper { * @return 受影响的行数 */ default int updateByCondition(T entity, boolean ignoreNulls, QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + FlexAssert.notNull(whereConditions, "whereConditions"); return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions)); } @@ -385,7 +385,7 @@ public interface BaseMapper { */ @Deprecated default int updateNumberAddByQuery(QueryColumn column, Number value, QueryWrapper queryWrapper) { - FlexAssert.notNull(value, "add value can not be null."); + FlexAssert.notNull(value, "value"); return updateNumberAddByQuery(column.getName(), value, queryWrapper); } @@ -400,7 +400,7 @@ public interface BaseMapper { */ @Deprecated default int updateNumberAddByQuery(LambdaGetter fn, Number value, QueryWrapper queryWrapper) { - FlexAssert.notNull(value, "add value can not be null."); + FlexAssert.notNull(value, "value"); TableInfo tableInfo = TableInfoFactory.ofMapperClass(ClassUtil.getUsefulClass(getClass())); String column = tableInfo.getColumnByProperty(LambdaUtil.getFieldName(fn)); return updateNumberAddByQuery(column, value, queryWrapper); @@ -425,8 +425,8 @@ public interface BaseMapper { * @return 实体类数据 */ default T selectOneByMap(Map whereConditions) { - FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); - return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1)); + FlexAssert.notEmpty(whereConditions, "whereConditions"); + return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1L)); } /** @@ -436,8 +436,8 @@ public interface BaseMapper { * @return 实体类数据 */ default T selectOneByCondition(QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); - return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1)); + FlexAssert.notNull(whereConditions, "whereConditions"); + return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1L)); } /** @@ -468,8 +468,8 @@ public interface BaseMapper { * @return 实体类数据 */ default T selectOneWithRelationsByMap(Map whereConditions) { - FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); - return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1)); + FlexAssert.notEmpty(whereConditions, "whereConditions"); + return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1L)); } /** @@ -479,8 +479,8 @@ public interface BaseMapper { * @return 实体类数据 */ default T selectOneWithRelationsByCondition(QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); - return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1)); + FlexAssert.notNull(whereConditions, "whereConditions"); + return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1L)); } /** @@ -545,7 +545,7 @@ public interface BaseMapper { * @return 数据列表 */ default List selectListByMap(Map whereConditions) { - FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); + FlexAssert.notEmpty(whereConditions, "whereConditions"); return selectListByQuery(QueryWrapper.create().where(whereConditions)); } @@ -556,8 +556,8 @@ public interface BaseMapper { * @param count 数据量 * @return 数据列表 */ - default List selectListByMap(Map whereConditions, int count) { - FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); + default List selectListByMap(Map whereConditions, Long count) { + FlexAssert.notEmpty(whereConditions, "whereConditions"); return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count)); } @@ -568,7 +568,7 @@ public interface BaseMapper { * @return 数据列表 */ default List selectListByCondition(QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + FlexAssert.notNull(whereConditions, "whereConditions"); return selectListByQuery(QueryWrapper.create().where(whereConditions)); } @@ -579,8 +579,8 @@ public interface BaseMapper { * @param count 数据量 * @return 数据列表 */ - default List selectListByCondition(QueryCondition whereConditions, int count) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + default List selectListByCondition(QueryCondition whereConditions, Long count) { + FlexAssert.notNull(whereConditions, "whereConditions"); return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count)); } @@ -849,7 +849,7 @@ public interface BaseMapper { * @return 数据量 */ default long selectCountByCondition(QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + FlexAssert.notNull(whereConditions, "whereConditions"); return selectCountByQuery(QueryWrapper.create().where(whereConditions)); } @@ -861,7 +861,7 @@ public interface BaseMapper { * @param queryWrapper 条件 * @return 分页数据 */ - default Page paginate(int pageNumber, int pageSize, QueryWrapper queryWrapper) { + default Page paginate(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) { Page page = new Page<>(pageNumber, pageSize); return paginate(page, queryWrapper); } @@ -874,7 +874,7 @@ public interface BaseMapper { * @param queryWrapper 条件 * @return 分页数据 */ - default Page paginateWithRelations(int pageNumber, int pageSize, QueryWrapper queryWrapper) { + default Page paginateWithRelations(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) { Page page = new Page<>(pageNumber, pageSize); return paginateWithRelations(page, queryWrapper); } @@ -887,7 +887,7 @@ public interface BaseMapper { * @param whereConditions 条件 * @return 分页数据 */ - default Page paginate(int pageNumber, int pageSize, QueryCondition whereConditions) { + default Page paginate(Number pageNumber, Number pageSize, QueryCondition whereConditions) { Page page = new Page<>(pageNumber, pageSize); return paginate(page, new QueryWrapper().where(whereConditions)); } @@ -900,7 +900,7 @@ public interface BaseMapper { * @param whereConditions 条件 * @return 分页数据 */ - default Page paginateWithRelations(int pageNumber, int pageSize, QueryCondition whereConditions) { + default Page paginateWithRelations(Number pageNumber, Number pageSize, QueryCondition whereConditions) { Page page = new Page<>(pageNumber, pageSize); return paginateWithRelations(page, new QueryWrapper().where(whereConditions)); } @@ -914,7 +914,7 @@ public interface BaseMapper { * @param queryWrapper 条件 * @return 分页数据 */ - default Page paginate(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { + default Page paginate(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) { Page page = new Page<>(pageNumber, pageSize, totalRow); return paginate(page, queryWrapper); } @@ -928,7 +928,7 @@ public interface BaseMapper { * @param queryWrapper 条件 * @return 分页数据 */ - default Page paginateWithRelations(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { + default Page paginateWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) { Page page = new Page<>(pageNumber, pageSize, totalRow); return paginateWithRelations(page, queryWrapper); } @@ -942,8 +942,8 @@ public interface BaseMapper { * @param whereConditions 条件 * @return 分页数据 */ - default Page paginate(int pageNumber, int pageSize, int totalRow, QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + default Page paginate(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) { + FlexAssert.notNull(whereConditions, "whereConditions"); Page page = new Page<>(pageNumber, pageSize, totalRow); return paginate(page, new QueryWrapper().where(whereConditions)); } @@ -957,8 +957,8 @@ public interface BaseMapper { * @param whereConditions 条件 * @return 分页数据 */ - default Page paginateWithRelations(int pageNumber, int pageSize, int totalRow, QueryCondition whereConditions) { - FlexAssert.notNull(whereConditions, "whereConditions can not be null."); + default Page paginateWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) { + FlexAssert.notNull(whereConditions, "whereConditions"); Page page = new Page<>(pageNumber, pageSize, totalRow); return paginateWithRelations(page, new QueryWrapper().where(whereConditions)); } @@ -1018,7 +1018,7 @@ public interface BaseMapper { * @param asType 接收数据类型 * @return 分页数据 */ - default Page paginateAs(int pageNumber, int pageSize, QueryWrapper queryWrapper, Class asType) { + default Page paginateAs(Number pageNumber, Number pageSize, QueryWrapper queryWrapper, Class asType) { Page page = new Page<>(pageNumber, pageSize); return MapperUtil.doPaginate(this, page, queryWrapper, asType, false); } @@ -1033,7 +1033,7 @@ public interface BaseMapper { * @param asType 接收数据类型 * @return 分页数据 */ - default Page paginateAs(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper, Class asType) { + default Page paginateAs(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper, Class asType) { Page page = new Page<>(pageNumber, pageSize, totalRow); return MapperUtil.doPaginate(this, page, queryWrapper, asType, false); } @@ -1072,7 +1072,7 @@ public interface BaseMapper { * @param asType 接收数据类型 * @return 分页数据 */ - default Page paginateWithRelationsAs(int pageNumber, int pageSize, QueryWrapper queryWrapper, Class asType) { + default Page paginateWithRelationsAs(Number pageNumber, Number pageSize, QueryWrapper queryWrapper, Class asType) { Page page = new Page<>(pageNumber, pageSize); return MapperUtil.doPaginate(this, page, queryWrapper, asType, true); } @@ -1087,7 +1087,7 @@ public interface BaseMapper { * @param asType 接收数据类型 * @return 分页数据 */ - default Page paginateWithRelationsAs(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper, Class asType) { + default Page paginateWithRelationsAs(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper, Class asType) { Page page = new Page<>(pageNumber, pageSize, totalRow); return MapperUtil.doPaginate(this, page, queryWrapper, asType, true); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexGlobalConfig.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexGlobalConfig.java index 16aeebcd..0e4f5901 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexGlobalConfig.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/FlexGlobalConfig.java @@ -21,6 +21,7 @@ import com.mybatisflex.annotation.SetListener; import com.mybatisflex.annotation.UpdateListener; import com.mybatisflex.core.datasource.FlexDataSource; import com.mybatisflex.core.dialect.DbType; +import com.mybatisflex.core.exception.FlexAssert; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.SqlSessionFactory; @@ -307,9 +308,7 @@ public class FlexGlobalConfig { } public void setNormalValueOfLogicDelete(Object normalValueOfLogicDelete) { - if (normalValueOfLogicDelete == null) { - throw new NullPointerException("normalValueOfLogicDelete can not be null."); - } + FlexAssert.notNull(normalValueOfLogicDelete,"normalValueOfLogicDelete"); this.normalValueOfLogicDelete = normalValueOfLogicDelete; } @@ -318,9 +317,7 @@ public class FlexGlobalConfig { } public void setDeletedValueOfLogicDelete(Object deletedValueOfLogicDelete) { - if (deletedValueOfLogicDelete == null) { - throw new NullPointerException("deletedValueOfLogicDelete can not be null."); - } + FlexAssert.notNull(deletedValueOfLogicDelete,"deletedValueOfLogicDelete"); this.deletedValueOfLogicDelete = deletedValueOfLogicDelete; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/MybatisFlexBootstrap.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/MybatisFlexBootstrap.java index 87c80fd0..5817a037 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/MybatisFlexBootstrap.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/MybatisFlexBootstrap.java @@ -16,6 +16,7 @@ package com.mybatisflex.core; import com.mybatisflex.core.datasource.FlexDataSource; +import com.mybatisflex.core.exception.FlexAssert; import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder; import com.mybatisflex.core.mybatis.Mappers; @@ -92,9 +93,8 @@ public class MybatisFlexBootstrap { public MybatisFlexBootstrap start() { if (started.compareAndSet(false, true)) { - if (dataSource == null) { - throw new IllegalStateException("dataSource can not be null."); - } + + FlexAssert.notNull(dataSource,"dataSource"); //init configuration if (configuration == null) { diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/QueryModel.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/QueryModel.java index cfa2ac2a..ceb382f6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/QueryModel.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/activerecord/query/QueryModel.java @@ -356,17 +356,17 @@ public abstract class QueryModel> { return new OrderByBuilder<>((T) this, column); } - public T limit(Integer rows) { + public T limit(Number rows) { queryWrapper().limit(rows); return (T) this; } - public T offset(Integer offset) { + public T offset(Number offset) { queryWrapper().offset(offset); return (T) this; } - public T limit(Integer offset, Integer rows) { + public T limit(Number offset, Number rows) { queryWrapper().limit(offset, rows); return (T) this; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java index d122038f..1403c4ee 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/IDialect.java @@ -22,6 +22,9 @@ import com.mybatisflex.core.table.TableManager; import java.util.List; +/** + * @author michael + */ public interface IDialect { String wrap(String keyword); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java index 34d3b081..21f79b45 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java @@ -39,7 +39,7 @@ public interface LimitOffsetProcessor { * @param limitRows 用户传入的 limit 参数 可能为 null * @param limitOffset 用户传入的 offset 参数,可能为 null */ - StringBuilder process(IDialect dialect, StringBuilder sql, QueryWrapper queryWrapper, Integer limitRows, Integer limitOffset); + StringBuilder process(IDialect dialect, StringBuilder sql, QueryWrapper queryWrapper, Long limitRows, Long limitOffset); /** @@ -110,7 +110,7 @@ public interface LimitOffsetProcessor { LimitOffsetProcessor SQLSERVER_2005 = (dialect, sql, queryWrapper, limitRows, limitOffset) -> { if (limitRows != null) { if (limitOffset == null) { - limitOffset = 0; + limitOffset = 0L; } List queryTables = CPI.getQueryTables(queryWrapper); @@ -196,7 +196,7 @@ public interface LimitOffsetProcessor { LimitOffsetProcessor ORACLE = (dialect, sql, queryWrapper, limitRows, limitOffset) -> { if (limitRows != null) { if (limitOffset == null) { - limitOffset = 0; + limitOffset = 0L; } StringBuilder newSql = new StringBuilder("SELECT * FROM (SELECT TEMP_DATAS.*, ROWNUM RN FROM ("); newSql.append(sql); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java index 15604172..5067e4ea 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java @@ -382,8 +382,8 @@ public class CommonsDialectImpl implements IDialect { } } - Integer limitRows = CPI.getLimitRows(queryWrapper); - Integer limitOffset = CPI.getLimitOffset(queryWrapper); + Long limitRows = CPI.getLimitRows(queryWrapper); + Long limitOffset = CPI.getLimitOffset(queryWrapper); if (limitRows != null || limitOffset != null) { sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset); } @@ -418,8 +418,8 @@ public class CommonsDialectImpl implements IDialect { } } - Integer limitRows = CPI.getLimitRows(queryWrapper); - Integer limitOffset = CPI.getLimitOffset(queryWrapper); + Long limitRows = CPI.getLimitRows(queryWrapper); + Long limitOffset = CPI.getLimitOffset(queryWrapper); if (limitRows != null || limitOffset != null) { sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset); } @@ -782,8 +782,8 @@ public class CommonsDialectImpl implements IDialect { Set updateColumns = tableInfo.obtainUpdateColumns(entity, ignoreNulls, true); Map rawValueMap = tableInfo.obtainUpdateRawValueMap(entity); - sql.append(UPDATE).append(forHint(CPI.getHint(queryWrapper))) - .append(tableInfo.getWrapSchemaAndTableName(this)).append(SET); + sql.append(UPDATE).append(forHint(CPI.getHint(queryWrapper))); + sql.append(tableInfo.getWrapSchemaAndTableName(this)).append(SET); StringJoiner stringJoiner = new StringJoiner(DELIMITER); @@ -814,7 +814,7 @@ public class CommonsDialectImpl implements IDialect { //不允许全量更新 if (StringUtil.isBlank(whereConditionSql)) { - throw new IllegalArgumentException("Not allowed UPDATE a table without where condition."); + throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW); } sql.append(WHERE).append(whereConditionSql); @@ -844,7 +844,7 @@ public class CommonsDialectImpl implements IDialect { //不允许全量更新 if (StringUtil.isBlank(whereConditionSql)) { - throw new IllegalArgumentException("Not allowed UPDATE a table without where condition."); + throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW); } sql.append(WHERE).append(whereConditionSql); @@ -993,12 +993,12 @@ public class CommonsDialectImpl implements IDialect { if (StringUtil.isNotBlank(whereSql)) { sqlBuilder.append(WHERE).append(whereSql); } else if (!allowNoCondition) { - throw new IllegalArgumentException("Not allowed DELETE or UPDATE a table without where condition."); + throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW); } } else { // whereQueryCondition == null if (!allowNoCondition) { - throw new IllegalArgumentException("Not allowed DELETE or UPDATE a table without where condition."); + throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW); } } } @@ -1051,7 +1051,7 @@ public class CommonsDialectImpl implements IDialect { /** * 构建 limit 和 offset 的参数 */ - protected StringBuilder buildLimitOffsetSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, Integer limitRows, Integer limitOffset) { + protected StringBuilder buildLimitOffsetSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, Long limitRows, Long limitOffset) { return limitOffsetProcessor.process(this, sqlBuilder, queryWrapper, limitRows, limitOffset); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java index a329919a..59bd3a34 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/FlexAssert.java @@ -16,6 +16,8 @@ package com.mybatisflex.core.exception; +import com.mybatisflex.core.exception.locale.LocalizedFormats; + import java.util.Collection; import java.util.Map; @@ -23,6 +25,8 @@ import java.util.Map; * 断言。 * * @author 王帅 + * @author michael + * * @since 2023-07-08 */ public final class FlexAssert { @@ -33,26 +37,27 @@ public final class FlexAssert { /** * 断言对象不为空,如果为空抛出异常,并指明哪个对象为空。 * - * @param obj 对象 - * @param message 错误消息 + * @param obj 对象 + * @param param 错误消息参数 * @throws MybatisFlexException 如果对象为空,抛出此异常。 */ - public static void notNull(Object obj, String message) { + public static void notNull(Object obj, String param) { if (obj == null) { - throw FlexExceptions.wrap(message); + throw FlexExceptions.wrap(LocalizedFormats.OBJECT_NULL, param); } } + /** * 断言 Map 集合不为 {@code null} 或者空集合,如果为空则抛出异常,并指明为什么不允许为空集合。 * - * @param map Map 集合 - * @param message 错误消息 + * @param map Map 集合 + * @param param 错误消息参数 * @throws MybatisFlexException 如果集合为空,抛出此异常。 */ - public static void notEmpty(Map map, String message) { + public static void notEmpty(Map map, String param) { if (map == null || map.isEmpty()) { - throw FlexExceptions.wrap(message); + throw FlexExceptions.wrap(LocalizedFormats.MAP_NULL_OR_EMPTY, param); } } @@ -60,25 +65,25 @@ public final class FlexAssert { * 断言集合不为 {@code null} 或者空集合,如果为空则抛出异常,并指明为什么不允许为空集合。 * * @param collection 集合 - * @param message 错误消息 + * @param param 错误消息参数 * @throws MybatisFlexException 如果集合为空,抛出此异常。 */ - public static void notEmpty(Collection collection, String message) { + public static void notEmpty(Collection collection, String param) { if (collection == null || collection.isEmpty()) { - throw FlexExceptions.wrap(message); + throw FlexExceptions.wrap(LocalizedFormats.MAP_NULL_OR_EMPTY, param); } } /** * 断言数组不为 {@code null} 或者空数组,如果为空则抛出异常,并指明为什么不允许为空数组。 * - * @param array 数组 - * @param message 错误消息 + * @param array 数组 + * @param param 错误消息参数 * @throws MybatisFlexException 如果数组为空,抛出此异常。 */ - public static void notEmpty(T[] array, String message) { + public static void notEmpty(T[] array, String param) { if (array == null || array.length == 0) { - throw FlexExceptions.wrap(message); + throw FlexExceptions.wrap(param); } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.java index f8e1d059..e3848311 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/exception/locale/LocalizedFormats.java @@ -34,17 +34,22 @@ public enum LocalizedFormats implements Localizable { * object can not be null */ OBJECT_NULL("{0} can not be null."), + OBJECT_NULL_OR_BLANK("{0} can not be null or blank."), + MAP_NULL_OR_EMPTY("{0} can not be null or empty."), + ARRAY_NULL_OR_EMPTY("{0} array can not be null or empty."), DATASOURCE_TYPE_BLANK("The dataSource type can not be null or blank."), DATASOURCE_TYPE_NOT_FIND("Can not find the dataSource type: {0}"), - DATASOURCE_CAN_NOT_INSTANCE("Can not new instance dataSource object by class: {0}"), + DATASOURCE_CAN_NOT_INSTANCE("Can not new instance dataSource object by class: {0}"), DATASOURCE_JDBC_URL("Can not get the dataSource jdbcUrl."), UPDATE_ONLY_SUPPORT_1_TABLE("\"UpdateByQuery\" only support 1 table."), + UPDATE_OR_DELETE_NOT_ALLOW("Not allowed \"UPDATE\" or \"DELETE\" a table without where condition."), - ENTITY_VERSION_NULL("The version value of entity[{0}] must not be null."), + + ENTITY_VERSION_NULL("The version value of entity \"{0}\" must not be null."), ; private final String sourceFormat; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java index d9a8739a..d4943f4c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/impl/PrimaryKeyLogicDeleteProcessor.java @@ -37,9 +37,9 @@ public class PrimaryKeyLogicDeleteProcessor extends NullableColumnLogicDeletePro @Override public String buildLogicDeletedSet(String logicColumn, TableInfo tableInfo, IDialect dialect) { - List primaryKeyList = tableInfo.getPrimaryKeyList(); - FlexAssert.notEmpty(primaryKeyList, "Entity must have one primary key."); - String column = primaryKeyList.get(0).getColumn(); + List primaryKeys = tableInfo.getPrimaryKeyList(); + FlexAssert.notEmpty(primaryKeys, "primaryKeys"); + String column = primaryKeys.get(0).getColumn(); return dialect.wrap(logicColumn) + EQUALS + dialect.wrap(column); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java index c364091d..8727d865 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/FlexConfiguration.java @@ -53,7 +53,7 @@ import java.util.concurrent.ConcurrentHashMap; public class FlexConfiguration extends Configuration { - private static Map dynamicMappedStatementCache = new ConcurrentHashMap<>(); + private static final Map dynamicMappedStatementCache = new ConcurrentHashMap<>(); public FlexConfiguration(Environment environment) { super(environment); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/Mappers.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/Mappers.java index dda16903..1efb8a73 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/Mappers.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/mybatis/Mappers.java @@ -23,14 +23,10 @@ import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.util.MapUtil; -import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.Arrays; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** @@ -51,6 +47,7 @@ public class Mappers { /** * 通过 entity Class 获取 Mapper 对象 + * * @param entityClass * @param * @return mapper 对象 @@ -58,7 +55,7 @@ public class Mappers { public static BaseMapper ofEntityClass(Class entityClass) { Class mapperClass = ENTITY_MAPPER_MAP.get(entityClass); if (mapperClass == null) { - throw FlexExceptions.wrap("Can not find MapperClass by entity: " + entityClass); + throw FlexExceptions.wrap("Can not find MapperClass by entity: " + entityClass.getName()); } return (BaseMapper) ofMapperClass(mapperClass); } @@ -79,10 +76,8 @@ public class Mappers { } - static class MapperHandler implements InvocationHandler { - private static final Set ignoreMethods = new HashSet<>(Arrays.asList("queryChain","updateChain")); - private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); + private Class mapperClass; private final SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getDefaultConfig().getSqlSessionFactory(); private final ExecutorType executorType = FlexGlobalConfig.getDefaultConfig().getConfiguration().getDefaultExecutorType(); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/Page.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/Page.java index d14b50bc..8592e53e 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/Page.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/paginate/Page.java @@ -44,12 +44,12 @@ public class Page implements Serializable { /** * 当前页码。 */ - private int pageNumber = 1; + private long pageNumber = 1; /** * 每页数据数量。 */ - private int pageSize = FlexGlobalConfig.getDefaultConfig().getDefaultPageSize(); + private long pageSize = FlexGlobalConfig.getDefaultConfig().getDefaultPageSize(); /** * 总页数。 @@ -74,7 +74,7 @@ public class Page implements Serializable { * @param 数据类型 * @return 分页对象 */ - public static Page of(int pageNumber, int pageSize) { + public static Page of(Number pageNumber, Number pageSize) { return new Page<>(pageNumber, pageSize); } @@ -87,7 +87,7 @@ public class Page implements Serializable { * @param 数据类型 * @return 分页对象 */ - public static Page of(int pageNumber, int pageSize, long totalRow) { + public static Page of(Number pageNumber, Number pageSize, Number totalRow) { return new Page<>(pageNumber, pageSize, totalRow); } @@ -103,7 +103,7 @@ public class Page implements Serializable { * @param pageNumber 当前页码 * @param pageSize 每页数据数量 */ - public Page(int pageNumber, int pageSize) { + public Page(Number pageNumber, Number pageSize) { this.setPageNumber(pageNumber); this.setPageSize(pageSize); } @@ -115,7 +115,7 @@ public class Page implements Serializable { * @param pageSize 每页数据数量 * @param totalRow 总数居数量 */ - public Page(int pageNumber, int pageSize, long totalRow) { + public Page(Number pageNumber, Number pageSize, Number totalRow) { this.setPageNumber(pageNumber); this.setPageSize(pageSize); this.setTotalRow(totalRow); @@ -129,7 +129,7 @@ public class Page implements Serializable { * @param pageSize 每页数据数量 * @param totalRow 总数居数量 */ - public Page(List records, int pageNumber, int pageSize, long totalRow) { + public Page(List records, Number pageNumber, Number pageSize, Number totalRow) { this.setRecords(records); this.setPageNumber(pageNumber); this.setPageSize(pageSize); @@ -162,7 +162,7 @@ public class Page implements Serializable { * * @return 页码 */ - public int getPageNumber() { + public long getPageNumber() { return pageNumber; } @@ -171,11 +171,11 @@ public class Page implements Serializable { * * @param pageNumber 页码 */ - public void setPageNumber(int pageNumber) { - if (pageNumber < 1) { + public void setPageNumber(Number pageNumber) { + if (pageNumber.longValue() < 1) { throw new IllegalArgumentException("pageNumber must greater than or equal 1,current value is: " + pageNumber); } - this.pageNumber = pageNumber; + this.pageNumber = pageNumber.longValue(); } /** @@ -183,7 +183,7 @@ public class Page implements Serializable { * * @return 每页数据数量 */ - public int getPageSize() { + public long getPageSize() { return pageSize; } @@ -192,11 +192,11 @@ public class Page implements Serializable { * * @param pageSize 每页数据数量 */ - public void setPageSize(int pageSize) { - if (pageSize < 0) { + public void setPageSize(Number pageSize) { + if (pageSize.longValue() < 0) { throw new IllegalArgumentException("pageSize must greater than or equal 0,current value is: " + pageSize); } - this.pageSize = pageSize; + this.pageSize = pageSize.longValue(); this.calcTotalPage(); } @@ -232,8 +232,8 @@ public class Page implements Serializable { * * @param totalRow 数据总数 */ - public void setTotalRow(long totalRow) { - this.totalRow = totalRow; + public void setTotalRow(Number totalRow) { + this.totalRow = totalRow.longValue(); this.calcTotalPage(); } @@ -280,7 +280,7 @@ public class Page implements Serializable { * * @return 偏移量 */ - public int offset() { + public long offset() { return getPageSize() * (getPageNumber() - 1); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java index 4661d83f..c77cf81b 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/EntitySqlProvider.java @@ -52,7 +52,7 @@ public class EntitySqlProvider { public static String insert(Map params, ProviderContext context) { Object entity = ProviderUtil.getEntity(params); - FlexAssert.notNull(entity, "entity can not be null."); + FlexAssert.notNull(entity, "entity"); boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params); @@ -88,7 +88,7 @@ public class EntitySqlProvider { public static String insertWithPk(Map params, ProviderContext context) { Object entity = ProviderUtil.getEntity(params); - FlexAssert.notNull(entity, "entity can not be null."); + FlexAssert.notNull(entity, "entity"); boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params); @@ -125,7 +125,7 @@ public class EntitySqlProvider { public static String insertBatch(Map params, ProviderContext context) { List entities = ProviderUtil.getEntities(params); - FlexAssert.notEmpty(entities, "entities can not be null or empty."); + FlexAssert.notEmpty(entities, "entities"); TableInfo tableInfo = ProviderUtil.getTableInfo(context); for (Object entity : entities) { @@ -160,7 +160,7 @@ public class EntitySqlProvider { public static String deleteById(Map params, ProviderContext context) { Object[] primaryValues = ProviderUtil.getPrimaryValues(params); - FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); + FlexAssert.notEmpty(primaryValues, "primaryValues"); TableInfo tableInfo = ProviderUtil.getTableInfo(context); @@ -182,7 +182,7 @@ public class EntitySqlProvider { public static String deleteBatchByIds(Map params, ProviderContext context) { Object[] primaryValues = ProviderUtil.getPrimaryValues(params); - FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); + FlexAssert.notEmpty(primaryValues, "primaryValues"); TableInfo tableInfo = ProviderUtil.getTableInfo(context); @@ -322,7 +322,7 @@ public class EntitySqlProvider { public static String selectOneById(Map params, ProviderContext context) { Object[] primaryValues = ProviderUtil.getPrimaryValues(params); - FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); + FlexAssert.notEmpty(primaryValues, "primaryValues"); TableInfo tableInfo = ProviderUtil.getTableInfo(context); @@ -345,7 +345,7 @@ public class EntitySqlProvider { public static String selectListByIds(Map params, ProviderContext context) { Object[] primaryValues = ProviderUtil.getPrimaryValues(params); - FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); + FlexAssert.notEmpty(primaryValues, "primaryValues"); TableInfo tableInfo = ProviderUtil.getTableInfo(context); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/ProviderUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/ProviderUtil.java index 34a75207..99662c72 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/ProviderUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/ProviderUtil.java @@ -16,7 +16,9 @@ package com.mybatisflex.core.provider; import com.mybatisflex.core.FlexConsts; +import com.mybatisflex.core.exception.FlexAssert; import com.mybatisflex.core.exception.FlexExceptions; +import com.mybatisflex.core.exception.locale.LocalizedFormats; import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.row.Row; import com.mybatisflex.core.table.TableInfo; @@ -55,7 +57,7 @@ class ProviderUtil { public static String[] getPrimaryKeys(Map params) { String primaryKey = (String) params.get(FlexConsts.PRIMARY_KEY); if (StringUtil.isBlank(primaryKey)) { - throw FlexExceptions.wrap("primaryKey can not be null or blank."); + throw FlexExceptions.wrap(LocalizedFormats.OBJECT_NULL_OR_BLANK, "primaryKey"); } String[] primaryKeys = primaryKey.split(","); for (int i = 0; i < primaryKeys.length; i++) { @@ -80,9 +82,7 @@ class ProviderUtil { public static QueryWrapper getQueryWrapper(Map params) { Object queryWrapper = params.get(FlexConsts.QUERY); - if (queryWrapper == null) { - throw new IllegalArgumentException("queryWrapper can not be null."); - } + FlexAssert.notNull(queryWrapper,"queryWrapper"); return (QueryWrapper) queryWrapper; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java index 21d7dba6..0e4d42ff 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/provider/RowSqlProvider.java @@ -79,7 +79,7 @@ public class RowSqlProvider { public static String insertBatchWithFirstRowColumns(Map params) { List rows = ProviderUtil.getRows(params); - FlexAssert.notEmpty(rows, "rows can not be null or empty."); + FlexAssert.notEmpty(rows, "rows"); String tableName = ProviderUtil.getTableName(params); String schema = ProviderUtil.getSchemaName(params); @@ -109,7 +109,7 @@ public class RowSqlProvider { public static String deleteById(Map params) { Object[] primaryValues = ProviderUtil.getPrimaryValues(params); - FlexAssert.notEmpty(primaryValues, "primaryValue can not be null or empty."); + FlexAssert.notEmpty(primaryValues, "primaryValues"); String schema = ProviderUtil.getSchemaName(params); String tableName = ProviderUtil.getTableName(params); @@ -211,7 +211,7 @@ public class RowSqlProvider { public static String updateBatchById(Map params) { List rows = ProviderUtil.getRows(params); - FlexAssert.notEmpty(rows, "rows can not be null or empty."); + FlexAssert.notEmpty(rows, "rows"); String schema = ProviderUtil.getSchemaName(params); String tableName = ProviderUtil.getTableName(params); diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/BaseQueryWrapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/BaseQueryWrapper.java index 1198fa65..8f30df24 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/BaseQueryWrapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/BaseQueryWrapper.java @@ -40,8 +40,8 @@ public class BaseQueryWrapper> implements CloneSup protected List unions; - protected Integer limitOffset; - protected Integer limitRows; + protected Long limitOffset; + protected Long limitRows; protected List endFragments; @@ -219,19 +219,19 @@ public class BaseQueryWrapper> implements CloneSup this.unions = unions; } - protected Integer getLimitOffset() { + protected Long getLimitOffset() { return limitOffset; } - protected void setLimitOffset(Integer limitOffset) { + protected void setLimitOffset(Long limitOffset) { this.limitOffset = limitOffset; } - protected Integer getLimitRows() { + protected Long getLimitRows() { return limitRows; } - protected void setLimitRows(Integer limitRows) { + protected void setLimitRows(Long limitRows) { this.limitRows = limitRows; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java index 3a8a3ba7..7ffdc962 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/CPI.java @@ -167,19 +167,19 @@ public class CPI { } - public static Integer getLimitOffset(QueryWrapper queryWrapper) { + public static Long getLimitOffset(QueryWrapper queryWrapper) { return queryWrapper.getLimitOffset(); } - public static void setLimitOffset(QueryWrapper queryWrapper, Integer limitOffset) { + public static void setLimitOffset(QueryWrapper queryWrapper, Long limitOffset) { queryWrapper.setLimitOffset(limitOffset); } - public static Integer getLimitRows(QueryWrapper queryWrapper) { + public static Long getLimitRows(QueryWrapper queryWrapper) { return queryWrapper.getLimitRows(); } - public static void setLimitRows(QueryWrapper queryWrapper, Integer limitRows) { + public static void setLimitRows(QueryWrapper queryWrapper, Long limitRows) { queryWrapper.setLimitRows(limitRows); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java index bc82cb23..6017a491 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapper.java @@ -654,19 +654,27 @@ public class QueryWrapper extends BaseQueryWrapper { return this; } - public QueryWrapper limit(Integer rows) { - setLimitRows(rows); + public QueryWrapper limit(Number rows) { + if (rows != null) { + setLimitRows(rows.longValue()); + }else { + setLimitRows(null); + } return this; } - public QueryWrapper offset(Integer offset) { - setLimitOffset(offset); + public QueryWrapper offset(Number offset) { + if (offset!= null) { + setLimitOffset(offset.longValue()); + }else { + setLimitOffset(null); + } return this; } - public QueryWrapper limit(Integer offset, Integer rows) { - setLimitOffset(offset); - setLimitRows(rows); + public QueryWrapper limit(Number offset, Number rows) { + offset(offset); + limit(rows); return this; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapperAdapter.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapperAdapter.java index 8d859f92..d1576cbc 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapperAdapter.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryWrapperAdapter.java @@ -583,19 +583,19 @@ public class QueryWrapperAdapter> extends Query } @Override - public R limit(Integer rows) { + public R limit(Number rows) { super.limit(rows); return (R) this; } @Override - public R offset(Integer offset) { + public R offset(Number offset) { super.offset(offset); return (R) this; } @Override - public R limit(Integer offset, Integer rows) { + public R limit(Number offset, Number rows) { super.limit(offset, rows); return (R) this; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java index 95bac0a1..694c3ca6 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java @@ -28,7 +28,7 @@ class ToManyRelation extends AbstractRelation { protected String mapKeyField; protected FieldWrapper mapKeyFieldWrapper; protected String orderBy; - protected int limit = 0; + protected long limit = 0; public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java index c83b41d4..52ab0b9e 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java @@ -610,7 +610,7 @@ public class Db { * @param whereColumns where条件 */ public static Row selectOneByMap(String schema, String tableName, Map whereColumns) { - return invoker().selectOneByQuery(schema, tableName, new QueryWrapper().where(whereColumns).limit(1)); + return invoker().selectOneByQuery(schema, tableName, new QueryWrapper().where(whereColumns).limit(1L)); } @@ -621,7 +621,7 @@ public class Db { * @param whereColumns where条件 */ public static Row selectOneByMap(String tableName, Map whereColumns) { - return invoker().selectOneByQuery(null, tableName, new QueryWrapper().where(whereColumns).limit(1)); + return invoker().selectOneByQuery(null, tableName, new QueryWrapper().where(whereColumns).limit(1L)); } /** @@ -632,7 +632,7 @@ public class Db { * @param condition 条件 */ public static Row selectOneByCondition(String schema, String tableName, QueryCondition condition) { - return invoker().selectOneByQuery(schema, tableName, new QueryWrapper().where(condition).limit(1)); + return invoker().selectOneByQuery(schema, tableName, new QueryWrapper().where(condition).limit(1L)); } /** @@ -642,7 +642,7 @@ public class Db { * @param condition 条件 */ public static Row selectOneByCondition(String tableName, QueryCondition condition) { - return invoker().selectOneByQuery(null, tableName, new QueryWrapper().where(condition).limit(1)); + return invoker().selectOneByQuery(null, tableName, new QueryWrapper().where(condition).limit(1L)); } @@ -723,7 +723,7 @@ public class Db { * @param whereColumns 条件 * @param count 数据量 */ - public static List selectListByMap(String schema, String tableName, Map whereColumns, int count) { + public static List selectListByMap(String schema, String tableName, Map whereColumns, Long count) { return invoker().selectListByQuery(schema, tableName, new QueryWrapper().where(whereColumns).limit(count)); } @@ -734,7 +734,7 @@ public class Db { * @param whereColumns 条件 * @param count 数据量 */ - public static List selectListByMap(String tableName, Map whereColumns, int count) { + public static List selectListByMap(String tableName, Map whereColumns, Long count) { return invoker().selectListByQuery(null, tableName, new QueryWrapper().where(whereColumns).limit(count)); } @@ -769,7 +769,7 @@ public class Db { * @param condition 条件 * @param count 数据量 */ - public static List selectListByCondition(String schema, String tableName, QueryCondition condition, int count) { + public static List selectListByCondition(String schema, String tableName, QueryCondition condition, Long count) { return invoker().selectListByQuery(schema, tableName, new QueryWrapper().where(condition).limit(count)); } @@ -780,7 +780,7 @@ public class Db { * @param condition 条件 * @param count 数据量 */ - public static List selectListByCondition(String tableName, QueryCondition condition, int count) { + public static List selectListByCondition(String tableName, QueryCondition condition, Long count) { return invoker().selectListByQuery(null, tableName, new QueryWrapper().where(condition).limit(count)); } @@ -1012,7 +1012,7 @@ public class Db { * @param pageSize 每页的数据量 * @param condition 条件 */ - public static Page paginate(String schema, String tableName, int pageNumber, int pageSize, QueryCondition condition) { + public static Page paginate(String schema, String tableName, Number pageNumber, Number pageSize, QueryCondition condition) { return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition)); } @@ -1025,7 +1025,7 @@ public class Db { * @param pageSize 每页的数据量 * @param condition 条件 */ - public static Page paginate(String tableName, int pageNumber, int pageSize, QueryCondition condition) { + public static Page paginate(String tableName, Number pageNumber, Number pageSize, QueryCondition condition) { return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition)); } @@ -1040,7 +1040,7 @@ public class Db { * @param totalRow 数据总量 * @param condition 条件 */ - public static Page paginate(String schema, String tableName, int pageNumber, int pageSize, int totalRow, QueryCondition condition) { + public static Page paginate(String schema, String tableName, Number pageNumber, Number pageSize, Number totalRow, QueryCondition condition) { return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize, totalRow), QueryWrapper.create().where(condition)); } @@ -1053,7 +1053,7 @@ public class Db { * @param totalRow 数据总量 * @param condition 条件 */ - public static Page paginate(String tableName, int pageNumber, int pageSize, int totalRow, QueryCondition condition) { + public static Page paginate(String tableName, Number pageNumber, Number pageSize, Number totalRow, QueryCondition condition) { return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize, totalRow), QueryWrapper.create().where(condition)); } @@ -1067,7 +1067,7 @@ public class Db { * @param pageSize 每页的数据量 * @param queryWrapper 条件 */ - public static Page paginate(String schema, String tableName, int pageNumber, int pageSize, QueryWrapper queryWrapper) { + public static Page paginate(String schema, String tableName, Number pageNumber, Number pageSize, QueryWrapper queryWrapper) { return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize), queryWrapper); } @@ -1079,7 +1079,7 @@ public class Db { * @param pageSize 每页的数据量 * @param queryWrapper 条件 */ - public static Page paginate(String tableName, int pageNumber, int pageSize, QueryWrapper queryWrapper) { + public static Page paginate(String tableName, Number pageNumber, Number pageSize, QueryWrapper queryWrapper) { return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize), queryWrapper); } @@ -1094,7 +1094,7 @@ public class Db { * @param totalRow 数据总量 * @param queryWrapper 条件 */ - public static Page paginate(String schema, String tableName, int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { + public static Page paginate(String schema, String tableName, Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) { return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper); } @@ -1107,7 +1107,7 @@ public class Db { * @param totalRow 数据总量 * @param queryWrapper 条件 */ - public static Page paginate(String tableName, int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { + public static Page paginate(String tableName, Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) { return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java index 6ed9d166..356e34f0 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/RowMapper.java @@ -289,7 +289,7 @@ public interface RowMapper { * @return row or null */ default Row selectOneByQuery(String schema, String tableName, QueryWrapper queryWrapper) { - List rows = selectListByQuery(schema, tableName, queryWrapper.limit(1)); + List rows = selectListByQuery(schema, tableName, queryWrapper.limit(1L)); if (rows == null || rows.isEmpty()) { return null; } else { @@ -384,7 +384,7 @@ public interface RowMapper { * @return 数据 */ default Object selectObjectByQuery(String schema, String tableName, QueryWrapper queryWrapper) { - queryWrapper.limit(1); + queryWrapper.limit(1L); List objects = selectObjectListByQuery(schema, tableName, queryWrapper); if (objects == null || objects.isEmpty()) { return null; diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java index 7ad205ae..07ff2b66 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java @@ -628,9 +628,11 @@ public class TableInfo { if (value != null) { ColumnInfo columnInfo = columnInfoMapping.get(column); - TypeHandler typeHandler = columnInfo.buildTypeHandler(); - if (typeHandler != null) { - value = new TypeHandlerObject(typeHandler, value, columnInfo.getJdbcType()); + if (columnInfo != null) { + TypeHandler typeHandler = columnInfo.buildTypeHandler(); + if (typeHandler != null) { + value = new TypeHandlerObject(typeHandler, value, columnInfo.getJdbcType()); + } } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java index b0328564..ab41fe03 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableManager.java @@ -20,6 +20,9 @@ import com.mybatisflex.core.util.StringUtil; import java.util.HashMap; import java.util.Map; +/** + * @author michael + */ public class TableManager { private TableManager() { @@ -28,8 +31,8 @@ public class TableManager { private static DynamicTableProcessor dynamicTableProcessor; private static DynamicSchemaProcessor dynamicSchemaProcessor; - private static final ThreadLocal> tableNameMappingTL = ThreadLocal.withInitial(HashMap::new); - private static final ThreadLocal> schemaMappingTL = ThreadLocal.withInitial(HashMap::new); + private static final ThreadLocal> tableNameMappingTL = new ThreadLocal<>(); + private static final ThreadLocal> schemaMappingTL = new ThreadLocal<>(); public static DynamicTableProcessor getDynamicTableProcessor() { @@ -49,7 +52,12 @@ public class TableManager { } public static void setHintTableMapping(String tableName, String mappingTable) { - tableNameMappingTL.get().put(tableName, mappingTable); + Map hintTables = tableNameMappingTL.get(); + if (hintTables == null) { + hintTables = new HashMap<>(); + tableNameMappingTL.set(hintTables); + } + hintTables.put(tableName, mappingTable); } public static String getHintTableMapping(String tableName) { @@ -57,7 +65,12 @@ public class TableManager { } public static void setHintSchemaMapping(String schema, String mappingSchema) { - schemaMappingTL.get().put(schema, mappingSchema); + Map hintTables = schemaMappingTL.get(); + if (hintTables == null) { + hintTables = new HashMap<>(); + schemaMappingTL.set(hintTables); + } + hintTables.put(schema, mappingSchema); } public static String getHintSchemaMapping(String schema) { @@ -66,47 +79,45 @@ public class TableManager { public static String getRealTable(String tableName) { + + Map mapping = tableNameMappingTL.get(); + if (mapping != null) { + String dynamicTableName = mapping.get(tableName); + if (StringUtil.isNotBlank(dynamicTableName)) { + return dynamicTableName; + } + } + if (dynamicTableProcessor == null) { return tableName; } - Map mapping = tableNameMappingTL.get(); - - String dynamicTableName = mapping.get(tableName); - if (StringUtil.isNotBlank(dynamicTableName)) { - return dynamicTableName; - } - - dynamicTableName = dynamicTableProcessor.process(tableName); - mapping.put(tableName, dynamicTableName); - return dynamicTableName; + String dynamicTableName = dynamicTableProcessor.process(tableName); + return StringUtil.isNotBlank(dynamicTableName) ? dynamicTableName : tableName; } public static String getRealSchema(String schema) { + Map mapping = schemaMappingTL.get(); + if (mapping != null) { + String dynamicSchema = mapping.get(schema); + if (StringUtil.isNotBlank(dynamicSchema)) { + return dynamicSchema; + } + } + if (dynamicSchemaProcessor == null) { return schema; } - Map mapping = schemaMappingTL.get(); - String dynamiSchema = mapping.get(schema); - if (StringUtil.isNotBlank(dynamiSchema)) { - return dynamiSchema; - } - - dynamiSchema = dynamicSchemaProcessor.process(schema); - mapping.put(schema, dynamiSchema); - return dynamiSchema; + String dynamicSchema = dynamicSchemaProcessor.process(schema); + return StringUtil.isNotBlank(dynamicSchema) ? dynamicSchema : schema; } -// public static void clear() { -// if (dynamicTableProcessor != null) { -// tableNameMappingTL.remove(); -// } -// if (dynamicSchemaProcessor != null) { -// schemaMappingTL.remove(); -// } -// } + public static void clear() { + tableNameMappingTL.remove(); + schemaMappingTL.remove(); + } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordHandler.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordHandler.java index d76b083d..6f5e4c2c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordHandler.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordHandler.java @@ -25,7 +25,9 @@ import java.util.Map; class ModifyAttrsRecordHandler implements MethodHandler { - //更新内容 + /** + * 更新的字段和内容 + */ private final Map updates = new LinkedHashMap<>(); public Map getUpdates() { diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordProxyFactory.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordProxyFactory.java index 29d65d6f..aac36f31 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordProxyFactory.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/ModifyAttrsRecordProxyFactory.java @@ -15,47 +15,54 @@ */ package com.mybatisflex.core.update; +import com.mybatisflex.core.util.ClassUtil; import org.apache.ibatis.javassist.util.proxy.ProxyFactory; import org.apache.ibatis.javassist.util.proxy.ProxyObject; import org.apache.ibatis.logging.LogFactory; +import org.apache.ibatis.util.MapUtil; import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +/** + * @author michael + */ public class ModifyAttrsRecordProxyFactory { - private static final ModifyAttrsRecordProxyFactory instance = new ModifyAttrsRecordProxyFactory(); + protected static final Map, Class> CACHE = new ConcurrentHashMap<>(); + private static final ModifyAttrsRecordProxyFactory INSTANCE = new ModifyAttrsRecordProxyFactory(); public static ModifyAttrsRecordProxyFactory getInstance() { - return instance; + return INSTANCE; } private ModifyAttrsRecordProxyFactory() { } public T get(Class target) { - ProxyFactory factory = new ProxyFactory(); - factory.setSuperclass(target); + Class proxyClass = MapUtil.computeIfAbsent(CACHE, target, aClass -> { + ProxyFactory factory = new ProxyFactory(); + factory.setSuperclass(target); - Class[] interfaces = Arrays.copyOf(target.getInterfaces(), target.getInterfaces().length + 1); - interfaces[interfaces.length - 1] = UpdateWrapper.class; - factory.setInterfaces(interfaces); + Class[] interfaces = Arrays.copyOf(target.getInterfaces(), target.getInterfaces().length + 1); + interfaces[interfaces.length - 1] = UpdateWrapper.class; + factory.setInterfaces(interfaces); - - final Class proxyClass = factory.createClass(); + return factory.createClass(); + }); T proxyObject = null; try { - proxyObject = (T) proxyClass.newInstance(); + proxyObject = (T) ClassUtil.newInstance(proxyClass); ((ProxyObject) proxyObject).setHandler(new ModifyAttrsRecordHandler()); - } catch (Throwable e) { + } catch (Exception e) { LogFactory.getLog(ModifyAttrsRecordProxyFactory.class).error(e.toString(), e); } return proxyObject; } - - } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/UpdateChain.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/UpdateChain.java index efaf64e4..8e756aae 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/UpdateChain.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/update/UpdateChain.java @@ -25,10 +25,7 @@ import com.mybatisflex.core.query.QueryColumn; import com.mybatisflex.core.query.QueryWrapperAdapter; import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfoFactory; -import com.mybatisflex.core.util.ClassUtil; -import com.mybatisflex.core.util.LambdaGetter; -import com.mybatisflex.core.util.SqlUtil; -import com.mybatisflex.core.util.UpdateEntity; +import com.mybatisflex.core.util.*; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -124,6 +121,7 @@ public class UpdateChain extends QueryWrapperAdapter> { return SqlUtil.toBool(baseMapper.deleteByQuery(this)); } + public boolean update() { return SqlUtil.toBool(baseMapper.updateByQuery(entity, this)); } @@ -133,8 +131,12 @@ public class UpdateChain extends QueryWrapperAdapter> { public String toSQL() { TableInfo tableInfo = TableInfoFactory.ofMapperClass(baseMapper.getClass()); CPI.setFromIfNecessary(this, tableInfo.getSchema(), tableInfo.getTableName()); - String sql = DialectFactory.getDialect().forUpdateEntityByQuery(tableInfo,entity,true,this); - return SqlUtil.replaceSqlParams(sql, CPI.getValueArray(this)); + String sql = DialectFactory.getDialect().forUpdateEntityByQuery(tableInfo, entity, true, this); + + Object[] values = tableInfo.buildUpdateSqlArgs(entity, true, true); + values = ArrayUtil.concat(values, CPI.getValueArray(this)); + + return SqlUtil.replaceSqlParams(sql, values); } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java index 98926274..ceae089d 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ClassUtil.java @@ -24,13 +24,28 @@ import java.util.function.Predicate; /** * 类实例创建者创建者 - * Created by michael on 17/3/21. + * + * @author michael + * @date 17/3/21 */ +@SuppressWarnings("unchecked") public class ClassUtil { private ClassUtil() { } + private static final String[] OBJECT_METHODS = new String[]{ + "toString", + "getClass", + "equals", + "hashCode", + "wait", + "notify", + "notifyAll", + "clone", + "finalize" + }; + //proxy frameworks private static final List PROXY_CLASS_NAMES = Arrays.asList("net.sf.cglib.proxy.Factory" // cglib @@ -118,7 +133,7 @@ public class ClassUtil { Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); for (Constructor constructor : declaredConstructors) { - if (constructor.getParameterCount() == 0) { + if (constructor.getParameterCount() == 0 && Modifier.isPublic(constructor.getModifiers())) { defaultConstructor = constructor; } else if (Modifier.isPublic(constructor.getModifiers())) { otherConstructor = constructor; @@ -138,6 +153,16 @@ public class ClassUtil { } return (T) otherConstructor.newInstance(parameters); } + // 没有任何构造函数的情况下,去查找 static 工厂方法,满足 lombok 注解的需求 + else { + Method factoryMethod = ClassUtil.getFirstMethod(clazz, m -> m.getParameterCount() == 0 + && clazz == m.getReturnType() + && Modifier.isPublic(m.getModifiers()) + && Modifier.isStatic(m.getModifiers())); + if (factoryMethod != null) { + return (T) factoryMethod.invoke(null); + } + } throw new IllegalArgumentException("the class \"" + clazz.getName() + "\" has no constructor."); } catch (Exception e) { throw new RuntimeException("Can not newInstance class: " + clazz.getName()); @@ -289,4 +314,8 @@ public class ClassUtil { } } + public static boolean isObjectMethod(String methodName) { + return ArrayUtil.contains(OBJECT_METHODS, methodName); + } + } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java index 0bea9d08..47d15cc9 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/ConvertUtil.java @@ -28,11 +28,12 @@ public class ConvertUtil { private ConvertUtil() { } + @SuppressWarnings("rawtypes") public static Object convert(Object value, Class targetClass) { return convert(value, targetClass, false); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public static Object convert(Object value, Class targetClass, boolean ignoreConvertError) { if (value == null && targetClass.isPrimitive()) { return getPrimitiveDefaultValue(targetClass); diff --git a/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties index e6ad24ae..e69de29b 100644 --- a/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties +++ b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_en.properties @@ -1 +0,0 @@ -OBJECT_NULL={0} can not be null. diff --git a/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties index ee1b038b..5ac56e73 100644 --- a/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties +++ b/mybatis-flex-core/src/main/resources/assets/com/mybatisflex/core/exception/locale/LocalizedFormats_zh.properties @@ -1,7 +1,14 @@ OBJECT_NULL={0} \u4E0D\u80FD\u4E3A null \u503C\u3002 +OBJECT_NULL_OR_BLANK={0} \u4e0d\u80fd\u4e3a null \u503c\u6216\u8005\u7a7a\u5b57\u7b26\u4e32\u3002 +MAP_NULL_OR_EMPTY={0} \u4e0d\u80fd\u4e3a null \u503c\u6216\u8005\u7a7a\u5143\u7d20\u3002 +ARRAY_NULL_OR_EMPTY={0} \u6570\u7ec4\u4e0d\u80fd\u4e3a null \u503c\u6216\u8005\u7a7a\u5143\u7d20\u3002 + DATASOURCE_TYPE_BLANK=\u6570\u636e\u6e90\u7684\u7c7b\u578b\u4e0d\u80fd\u4e3a null \u6216\u8005\u7a7a\u5b57\u7b26\u4e32\u3002 DATASOURCE_TYPE_NOT_FIND=\u65e0\u6cd5\u627e\u5230\u6570\u636e\u6e90\u7c7b\u578b\uff1a {0} DATASOURCE_CAN_NOT_INSTANCE=\u65e0\u6cd5\u6839\u636e\u7c7b\uff1a {0} \u521b\u5efa\u6570\u636e\u6e90\u3002 DATASOURCE_JDBC_URL=\u65e0\u6cd5\u83b7\u53d6\u6570\u636e\u6e90\u7c7b\u7684 jdbcUrl \u914d\u7f6e\u3002 + UPDATE_ONLY_SUPPORT_1_TABLE=\"UpdateByQuery\" \u4ec5\u652f\u6301\u4f20\u5165 1 \u5f20\u8868\u3002 +UPDATE_OR_DELETE_NOT_ALLOW=\u6267\u884c "update" \u6216\u8005 "delete" \u7684 SQL \u65f6\uff0c\u4e0d\u5141\u8bb8\u5168\u8868\u64cd\u4f5c\uff0c\u5fc5\u987b\u8981\u6709 where \u6761\u4ef6\u3002 + ENTITY_VERSION_NULL=\u4e50\u89c2\u9501\u5b9e\u4f53\u7c7b\u5fc5\u987b\u8bbe\u7f6e version \u7684\u503c\uff1a{0}\u3002 diff --git a/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MultiDataSourceAutoConfiguration.java b/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MultiDataSourceAutoConfiguration.java index 80d429b2..f111cca4 100644 --- a/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MultiDataSourceAutoConfiguration.java +++ b/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MultiDataSourceAutoConfiguration.java @@ -16,11 +16,14 @@ package com.mybatisflex.spring.boot; import com.mybatisflex.core.datasource.DataSourceBuilder; +import com.mybatisflex.core.datasource.DataSourceDecipher; +import com.mybatisflex.core.datasource.DataSourceManager; import com.mybatisflex.core.datasource.FlexDataSource; import com.mybatisflex.spring.datasource.DataSourceAdvice; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.aop.Advisor; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -37,6 +40,7 @@ import java.util.Map; /** * MyBatis-Flex 多数据源的配置支持。 + * * @author michael */ @ConditionalOnMybatisFlexDatasource() @@ -47,10 +51,18 @@ import java.util.Map; , name = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure") public class MultiDataSourceAutoConfiguration { + private final Map> dataSourceProperties; - public MultiDataSourceAutoConfiguration(MybatisFlexProperties properties) { + //数据源解密器 + protected final DataSourceDecipher dataSourceDecipher; + + + public MultiDataSourceAutoConfiguration(MybatisFlexProperties properties + , ObjectProvider dataSourceDecipherProvider + ) { dataSourceProperties = properties.getDatasource(); + dataSourceDecipher = dataSourceDecipherProvider.getIfAvailable(); } @Bean @@ -60,6 +72,9 @@ public class MultiDataSourceAutoConfiguration { FlexDataSource flexDataSource = null; if (dataSourceProperties != null && !dataSourceProperties.isEmpty()) { + + DataSourceManager.setDecipher(dataSourceDecipher); + for (Map.Entry> entry : dataSourceProperties.entrySet()) { DataSource dataSource = new DataSourceBuilder(entry.getValue()).build(); if (flexDataSource == null) { diff --git a/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MybatisFlexAutoConfiguration.java b/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MybatisFlexAutoConfiguration.java index caf7b5fc..be082ebe 100644 --- a/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MybatisFlexAutoConfiguration.java +++ b/mybatis-flex-spring-boot-starter/src/main/java/com/mybatisflex/spring/boot/MybatisFlexAutoConfiguration.java @@ -18,7 +18,6 @@ package com.mybatisflex.spring.boot; import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.datasource.DataSourceDecipher; import com.mybatisflex.core.datasource.DataSourceManager; -import com.mybatisflex.core.datasource.FlexDataSource; import com.mybatisflex.core.logicdelete.LogicDeleteManager; import com.mybatisflex.core.logicdelete.LogicDeleteProcessor; import com.mybatisflex.core.mybatis.FlexConfiguration; @@ -71,7 +70,6 @@ import org.springframework.util.StringUtils; import javax.sql.DataSource; import java.beans.PropertyDescriptor; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -228,13 +226,6 @@ public class MybatisFlexAutoConfiguration implements InitializingBean { @ConditionalOnMissingBean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { - if (dataSource instanceof FlexDataSource && DataSourceManager.getDecipher() != null) { - Map dataSourceMap = ((FlexDataSource) dataSource).getDataSourceMap(); - for (DataSource ds : dataSourceMap.values()) { - DataSourceManager.decryptDataSource(ds); - } - } - SqlSessionFactoryBean factory = new FlexSqlSessionFactoryBean(); factory.setDataSource(dataSource); if (properties.getConfiguration() == null || properties.getConfiguration().getVfsImpl() == null) { diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountTester.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountTester.java index 5c5601eb..0987ddae 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountTester.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/AccountTester.java @@ -25,6 +25,7 @@ import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.row.DbChain; import com.mybatisflex.core.update.UpdateWrapper; import com.mybatisflex.core.util.UpdateEntity; +import com.mybatisflex.mapper.ArticleMapper; import org.apache.ibatis.logging.stdout.StdOutImpl; import org.junit.BeforeClass; import org.junit.Test; @@ -35,11 +36,13 @@ import javax.sql.DataSource; import java.util.List; import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT; +import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE; public class AccountTester { static AccountMapper accountMapper; + static ArticleMapper articleMapper; @BeforeClass public static void init() { @@ -53,6 +56,7 @@ public class AccountTester { .setDataSource(dataSource) .setLogImpl(StdOutImpl.class) .addMapper(AccountMapper.class) + .addMapper(ArticleMapper.class) .start(); //开启审计功能 @@ -64,6 +68,7 @@ public class AccountTester { accountMapper = bootstrap.getMapper(AccountMapper.class); + articleMapper = bootstrap.getMapper(ArticleMapper.class); } @Test @@ -101,6 +106,16 @@ public class AccountTester { System.out.println(accounts); } + @Test + public void testLeftJoinForLogicDelete() { + QueryWrapper queryWrapper = QueryWrapper.create(); + queryWrapper.from(ARTICLE) + .leftJoin(ACCOUNT).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID)) + .where(ARTICLE.ID.ge(1)); + List
accounts = articleMapper.selectListByQuery(queryWrapper); + System.out.println(accounts); + } + @Test public void testSelectAsToDTO() { diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/MainSqlTest.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/MainSqlTest.java index 0482590a..7760bb1f 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/MainSqlTest.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/MainSqlTest.java @@ -2,6 +2,7 @@ package com.mybatisflex.test; import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.mybatis.FlexConfiguration; +import com.mybatisflex.core.table.TableManager; import com.mybatisflex.core.update.UpdateChain; import com.mybatisflex.mapper.ArticleMapper; import com.zaxxer.hikari.HikariDataSource; @@ -12,16 +13,25 @@ public class MainSqlTest { public static void main(String[] args) { - Environment environment = new Environment("test", new JdbcTransactionFactory(), new HikariDataSource()); - FlexConfiguration configuration = new FlexConfiguration(environment); + + FlexGlobalConfig globalConfig = FlexGlobalConfig.getDefaultConfig(); + + + Environment environment = new Environment("test", new JdbcTransactionFactory(), new HikariDataSource()); + FlexConfiguration configuration = new FlexConfiguration(environment); globalConfig.setConfiguration(configuration); FlexGlobalConfig.setConfig("test", globalConfig, true); + configuration.addMapper(ArticleMapper.class); + + + + // ArticleMapper mapper = (ArticleMapper) Proxy.newProxyInstance(MainSqlTest.class.getClassLoader(), // new Class[]{ArticleMapper.class}, new InvocationHandler() { // @Override @@ -38,6 +48,9 @@ public class MainSqlTest { // System.out.println(sql1); + TableManager.setHintTableMapping("tb_article","tb_article1"); + + String sql2 = UpdateChain.of(Article.class) .set("xxxx", "xxxx") .where(Article::getId).ge(100) diff --git a/readme_zh.md b/readme_zh.md index 58219d09..95f0cc35 100644 --- a/readme_zh.md +++ b/readme_zh.md @@ -13,7 +13,7 @@ > MyBatis-Flex 支持 CRUD、分页查询、多表查询、批量操作,但不丢失 MyBatis 原有的任何功能。 #### 3、高性能 -> MyBatis-Flex 采用独特的技术架构、相比同类框架,MyBatis-Flex 的在增删改查等方面的性能均超越其 5~10 倍或以上。 +> MyBatis-Flex 采用独特的技术架构、相比许多同类框架,MyBatis-Flex 的在增删改查等方面的性能均超越其 5~10 倍或以上。 #### 4、更灵动 > MyBatis-Flex 支持多主键、多表查询、逻辑删除、乐观锁、数据脱敏、数据加密、多数据源、分库分表、字段权限、