Merge branch 'main' of gitee.com:mybatis-flex/mybatis-flex into main

Signed-off-by: 王帅 <1474983351@qq.com>
This commit is contained in:
王帅 2023-07-31 08:17:14 +00:00 committed by Gitee
commit 51ea1a15f6
48 changed files with 408 additions and 269 deletions

View File

@ -17,7 +17,7 @@
- 优化:修改 getPropertySimpleType 方法实现, 防止出现找不到类的问题,感谢 @dcrpp - 优化:修改 getPropertySimpleType 方法实现, 防止出现找不到类的问题,感谢 @dcrpp
- 优化:重构将 assertAreNotNull 从 FlexExceptions 移动到 FlexAssert 中,感谢 @Suomm - 优化:重构将 assertAreNotNull 从 FlexExceptions 移动到 FlexAssert 中,感谢 @Suomm
- 优化:重构 ActiveRecord 的一些方法,避免被 JSON 框架解析,感谢 @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) - 优化Maven 的 "artifact xxx has been relocated" 警告的问题,感谢 [@sppan24](https://github.com/sppan24)
- 优化:优化主键逻辑删除处理器逻辑,感谢 @Suomm - 优化:优化主键逻辑删除处理器逻辑,感谢 @Suomm
- 修复:代码生成器多次调用是出错的问题,感谢 @Suomm - 修复:代码生成器多次调用是出错的问题,感谢 @Suomm
@ -36,9 +36,6 @@
## v1.5.3 20230725: ## v1.5.3 20230725:
- 新增:添加 UpdateChain 方便用于对数据进行更新 - 新增:添加 UpdateChain 方便用于对数据进行更新
- 新增:添加对 ActiveRecord 设计模式的支持,感谢 @Suomm - 新增:添加对 ActiveRecord 设计模式的支持,感谢 @Suomm

View File

@ -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://gitee.com/djxchi/mybatis-flex-code-gen.git
- 视频简介https://www.bilibili.com/video/BV1yV411g7Yd - 视频简介https://www.bilibili.com/video/BV1yV411g7Yd
@ -20,7 +20,7 @@
## 视频教程 ## 视频教程
**课程1《MyBatis-Flex 视频教程》** -- 全网首发(免费)。 **课程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都有非常深入的理解。 > 其无论对 MyBatis 还是 MyBatis-Flex都有非常深入的理解。
课程目录: 课程目录:
@ -49,3 +49,6 @@
- [MyBatis-Flex 视频教程 - 22 @Id 的简单使用](https://www.bilibili.com/video/BV1Hp4y1571K) - [MyBatis-Flex 视频教程 - 22 @Id 的简单使用](https://www.bilibili.com/video/BV1Hp4y1571K)
- [MyBatis-Flex 视频教程 - 23 自定义主键生成器](https://www.bilibili.com/video/BV1eM4y1p72z) - [MyBatis-Flex 视频教程 - 23 自定义主键生成器](https://www.bilibili.com/video/BV1eM4y1p72z)
- [MyBatis-Flex 视频教程 - 24 @Column 注解的简单使用](https://www.bilibili.com/video/BV14c411w7Fr) - [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)

View File

@ -187,7 +187,7 @@ public class ArticleVo {
ArticleVo articleVo = articleService.queryChain() ArticleVo articleVo = articleService.queryChain()
.select( .select(
ARTICLE.ALL_COLUMNS, ARTICLE.ALL_COLUMNS,
max(ARTICLE.comments).as(ArticleVo::maxCommments) max(ARTICLE.comments).as(ArticleVo::maxComments)
).from(ARTICLE) ).from(ARTICLE)
.where(ARTICLE.ID.ge(100)) .where(ARTICLE.ID.ge(100))
.limit(1) .limit(1)

View File

@ -2,7 +2,7 @@
`MyBatisFlexCustomizer` 是 MyBatis-Flex 为了方便 `SpringBoot` 用户对 MyBatis-Flex 进行初始化而产生的接口。 `MyBatisFlexCustomizer` 是 MyBatis-Flex 为了方便 `SpringBoot` 用户对 MyBatis-Flex 进行初始化而产生的接口。
通过在 `@Configuration` 去实现 `MyBatisFlexCustomizer` 接口,我们可以对 MyBatis-Flex 进行一列的初始化配置。这些配置可能包含如下的内容: 通过在 `@Configuration` 去实现 `MyBatisFlexCustomizer` 接口,我们可以对 MyBatis-Flex 进行一列的初始化配置。这些配置可能包含如下的内容:
- 1、FlexGlobalConfig 的全局配置 - 1、FlexGlobalConfig 的全局配置
- 2、自定义主键生成器 - 2、自定义主键生成器

View File

@ -6,8 +6,8 @@
- **`updateByCondition(entity, ignoreNulls, whereConditions)`**:根据查询条件来更新数据。 - **`updateByCondition(entity, ignoreNulls, whereConditions)`**:根据查询条件来更新数据。
- **`updateByQuery(entity, queryWrapper)`**:根据查询条件来更新数据。 - **`updateByQuery(entity, queryWrapper)`**:根据查询条件来更新数据。
- **`updateByQuery(entity, ignoreNulls, queryWrapper)`**:根据查询条件来更新数据。 - **`updateByQuery(entity, ignoreNulls, queryWrapper)`**:根据查询条件来更新数据。
- ~**`updateNumberAddByQuery(fieldName, 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(column, value, queryWrapper)`**~~:执行类似 `update table set field = field + 1 where ... `
的场景。~ 的场景。
- ~**`updateNumberAddByQuery(fn, value, queryWrapper)`**:执行类似 `update table set field = field + 1 where ... ` 的场景。~ - ~~**`updateNumberAddByQuery(fn, value, queryWrapper)`**~~:执行类似 `update table set field = field + 1 where ... ` 的场景。

View File

@ -17,7 +17,7 @@
- 优化:修改 getPropertySimpleType 方法实现, 防止出现找不到类的问题,感谢 @dcrpp - 优化:修改 getPropertySimpleType 方法实现, 防止出现找不到类的问题,感谢 @dcrpp
- 优化:重构将 assertAreNotNull 从 FlexExceptions 移动到 FlexAssert 中,感谢 @Suomm - 优化:重构将 assertAreNotNull 从 FlexExceptions 移动到 FlexAssert 中,感谢 @Suomm
- 优化:重构 ActiveRecord 的一些方法,避免被 JSON 框架解析,感谢 @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) - 优化Maven 的 "artifact xxx has been relocated" 警告的问题,感谢 [@sppan24](https://github.com/sppan24)
- 优化:优化主键逻辑删除处理器逻辑,感谢 @Suomm - 优化:优化主键逻辑删除处理器逻辑,感谢 @Suomm
- 修复:代码生成器多次调用是出错的问题,感谢 @Suomm - 修复:代码生成器多次调用是出错的问题,感谢 @Suomm
@ -36,9 +36,6 @@
## v1.5.3 20230725: ## v1.5.3 20230725:
- 新增:添加 UpdateChain 方便用于对数据进行更新 - 新增:添加 UpdateChain 方便用于对数据进行更新
- 新增:添加对 ActiveRecord 设计模式的支持,感谢 @Suomm - 新增:添加对 ActiveRecord 设计模式的支持,感谢 @Suomm

View File

@ -6,7 +6,7 @@ SQL 审计是一项非常重要的工作,是企业数据安全体系的重要
## 开启审计功能<Badge type="tip" text="^1.0.5" /> ## 开启审计功能<Badge type="tip" text="^1.0.5" />
Mybaits-Flex 的 SQL 审计功能,默认是关闭的,若开启审计功能,添加如下配置。 Mybaits-Flex 的 SQL 审计功能,默认是关闭的,若开启审计功能,添加如下配置。
```java ```java
AuditManager.setAuditEnable(true) AuditManager.setAuditEnable(true)

View File

@ -26,7 +26,15 @@ TableManager.setDynamicTableProcessor(new DynamicTableProcessor() {
在某些情况下,我们临时修改映射关系,而非通过 `DynamicTableProcessor.process` 方法获取,可以通过如下配置: 在某些情况下,我们临时修改映射关系,而非通过 `DynamicTableProcessor.process` 方法获取,可以通过如下配置:
```java ```java
TableManager.setHintTableMapping("tb_account", "tb_account_01") try{
TableManager.setHintTableMapping("tb_account", "tb_account_01")
//这里写您的业务逻辑
}finally{
TableManager.clear()
}
``` ```
那么此时,当前线程不再通过 `DynamicTableProcessor` 去获取。 那么此时,当前线程不再通过 `DynamicTableProcessor` 去获取。
@ -57,13 +65,13 @@ public class MyConfiguration {
DynamicTableProcessor processor = new ....; DynamicTableProcessor processor = new ....;
return processor; return processor;
} }
@Bean @Bean
public DynamicSchemaProcessor dynamicSchemaProcessor(){ public DynamicSchemaProcessor dynamicSchemaProcessor(){
DynamicSchemaProcessor processor = new ....; DynamicSchemaProcessor processor = new ....;
return processor; return processor;
} }
} }
``` ```

View File

@ -70,12 +70,12 @@ QueryWrapper query1 = QueryWrapper.create()
```sql ```sql
SELECT * SELECT *
FROM `tb_account` 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 WHERE `tb_account`.`age` >= 10
AND `tb_account`.`is_delete` = 0 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 示例 2

View File

@ -33,7 +33,9 @@ import org.springframework.context.annotation.Configuration;
@Configuration @Configuration
public class MyBatisFlexConfiguration { 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() { public MyBatisFlexConfiguration() {
//开启审计功能 //开启审计功能
@ -41,17 +43,42 @@ public class MyBatisFlexConfiguration {
//设置 SQL 审计收集器 //设置 SQL 审计收集器
AuditManager.setMessageCollector(auditMessage -> AuditManager.setMessageCollector(auditMessage ->
logger.info("{},{}ms", auditMessage.getFullSql(), auditMessage.getElapsedTime()) logger.info("{},{}ms", auditMessage.getFullSql()
, auditMessage.getElapsedTime())
); );
} }
} }
``` ```
## 注意 ## MyBatis 自带方案
在执行以下语句之后执行的 SQL 才会被打印。如果你发现你有些 SQL 没有打印,则需要自行检查 SQL 执行与以下语句执行的先后顺序。
### 非 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 方案 ## p6spy 方案
@ -59,4 +86,4 @@ AuditManager.setMessageCollector(collector);
我们可以把数据源配置为 p6spy 数据源,使用 p6spy 的 SQL 输出功能进行 SQL 打印。更多文档参考 p6spy 官方文档: 我们可以把数据源配置为 p6spy 数据源,使用 p6spy 的 SQL 输出功能进行 SQL 打印。更多文档参考 p6spy 官方文档:
[https://p6spy.readthedocs.io/en/latest/index.html](https://p6spy.readthedocs.io/en/latest/index.html) [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) 使用 SpringBoot 的情况下,参考文档 [https://github.com/gavlyukovskiy/spring-boot-data-source-decorator](https://github.com/gavlyukovskiy/spring-boot-data-source-decorator)

View File

@ -116,7 +116,7 @@ public @interface RelationOneToMany {
* *
* @return 数据量 * @return 数据量
*/ */
int limit() default 0; long limit() default 0;
/** /**
* 默认使用哪个数据源若系统找不到该指定的数据源时默认使用第一个数据源 * 默认使用哪个数据源若系统找不到该指定的数据源时默认使用第一个数据源

View File

@ -240,7 +240,7 @@ public interface BaseMapper<T> {
* @return 受影响的行数 * @return 受影响的行数
*/ */
default int deleteByMap(Map<String, Object> whereConditions) { default int deleteByMap(Map<String, Object> whereConditions) {
FlexAssert.notEmpty(whereConditions, "deleteByMap is not allow empty map."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return deleteByQuery(QueryWrapper.create().where(whereConditions)); return deleteByQuery(QueryWrapper.create().where(whereConditions));
} }
@ -251,7 +251,7 @@ public interface BaseMapper<T> {
* @return 受影响的行数 * @return 受影响的行数
*/ */
default int deleteByCondition(QueryCondition whereConditions) { default int deleteByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
return deleteByQuery(QueryWrapper.create().where(whereConditions)); return deleteByQuery(QueryWrapper.create().where(whereConditions));
} }
@ -296,7 +296,7 @@ public interface BaseMapper<T> {
* @return 受影响的行数 * @return 受影响的行数
*/ */
default int updateByMap(T entity, Map<String, Object> whereConditions) { default int updateByMap(T entity, Map<String, Object> whereConditions) {
FlexAssert.notEmpty(whereConditions, "updateByMap is not allow empty map."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return updateByQuery(entity, QueryWrapper.create().where(whereConditions)); return updateByQuery(entity, QueryWrapper.create().where(whereConditions));
} }
@ -309,7 +309,7 @@ public interface BaseMapper<T> {
* @return 受影响的行数 * @return 受影响的行数
*/ */
default int updateByMap(T entity, boolean ignoreNulls, Map<String, Object> whereConditions) { default int updateByMap(T entity, boolean ignoreNulls, Map<String, Object> whereConditions) {
FlexAssert.notEmpty(whereConditions, "updateByMap is not allow empty map."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions)); return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions));
} }
@ -321,7 +321,7 @@ public interface BaseMapper<T> {
* @return 受影响的行数 * @return 受影响的行数
*/ */
default int updateByCondition(T entity, QueryCondition whereConditions) { 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)); return updateByQuery(entity, QueryWrapper.create().where(whereConditions));
} }
@ -334,7 +334,7 @@ public interface BaseMapper<T> {
* @return 受影响的行数 * @return 受影响的行数
*/ */
default int updateByCondition(T entity, boolean ignoreNulls, QueryCondition whereConditions) { 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)); return updateByQuery(entity, ignoreNulls, QueryWrapper.create().where(whereConditions));
} }
@ -385,7 +385,7 @@ public interface BaseMapper<T> {
*/ */
@Deprecated @Deprecated
default int updateNumberAddByQuery(QueryColumn column, Number value, QueryWrapper queryWrapper) { 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); return updateNumberAddByQuery(column.getName(), value, queryWrapper);
} }
@ -400,7 +400,7 @@ public interface BaseMapper<T> {
*/ */
@Deprecated @Deprecated
default int updateNumberAddByQuery(LambdaGetter<T> fn, Number value, QueryWrapper queryWrapper) { default int updateNumberAddByQuery(LambdaGetter<T> 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())); TableInfo tableInfo = TableInfoFactory.ofMapperClass(ClassUtil.getUsefulClass(getClass()));
String column = tableInfo.getColumnByProperty(LambdaUtil.getFieldName(fn)); String column = tableInfo.getColumnByProperty(LambdaUtil.getFieldName(fn));
return updateNumberAddByQuery(column, value, queryWrapper); return updateNumberAddByQuery(column, value, queryWrapper);
@ -425,8 +425,8 @@ public interface BaseMapper<T> {
* @return 实体类数据 * @return 实体类数据
*/ */
default T selectOneByMap(Map<String, Object> whereConditions) { default T selectOneByMap(Map<String, Object> whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1)); return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1L));
} }
/** /**
@ -436,8 +436,8 @@ public interface BaseMapper<T> {
* @return 实体类数据 * @return 实体类数据
*/ */
default T selectOneByCondition(QueryCondition whereConditions) { default T selectOneByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1)); return selectOneByQuery(QueryWrapper.create().where(whereConditions).limit(1L));
} }
/** /**
@ -468,8 +468,8 @@ public interface BaseMapper<T> {
* @return 实体类数据 * @return 实体类数据
*/ */
default T selectOneWithRelationsByMap(Map<String, Object> whereConditions) { default T selectOneWithRelationsByMap(Map<String, Object> whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1)); return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1L));
} }
/** /**
@ -479,8 +479,8 @@ public interface BaseMapper<T> {
* @return 实体类数据 * @return 实体类数据
*/ */
default T selectOneWithRelationsByCondition(QueryCondition whereConditions) { default T selectOneWithRelationsByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1)); return selectOneWithRelationsByQuery(QueryWrapper.create().where(whereConditions).limit(1L));
} }
/** /**
@ -545,7 +545,7 @@ public interface BaseMapper<T> {
* @return 数据列表 * @return 数据列表
*/ */
default List<T> selectListByMap(Map<String, Object> whereConditions) { default List<T> selectListByMap(Map<String, Object> whereConditions) {
FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions)); return selectListByQuery(QueryWrapper.create().where(whereConditions));
} }
@ -556,8 +556,8 @@ public interface BaseMapper<T> {
* @param count 数据量 * @param count 数据量
* @return 数据列表 * @return 数据列表
*/ */
default List<T> selectListByMap(Map<String, Object> whereConditions, int count) { default List<T> selectListByMap(Map<String, Object> whereConditions, Long count) {
FlexAssert.notEmpty(whereConditions, "whereConditions map can not be null or empty."); FlexAssert.notEmpty(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count)); return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
} }
@ -568,7 +568,7 @@ public interface BaseMapper<T> {
* @return 数据列表 * @return 数据列表
*/ */
default List<T> selectListByCondition(QueryCondition whereConditions) { default List<T> selectListByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions)); return selectListByQuery(QueryWrapper.create().where(whereConditions));
} }
@ -579,8 +579,8 @@ public interface BaseMapper<T> {
* @param count 数据量 * @param count 数据量
* @return 数据列表 * @return 数据列表
*/ */
default List<T> selectListByCondition(QueryCondition whereConditions, int count) { default List<T> selectListByCondition(QueryCondition whereConditions, Long count) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count)); return selectListByQuery(QueryWrapper.create().where(whereConditions).limit(count));
} }
@ -849,7 +849,7 @@ public interface BaseMapper<T> {
* @return 数据量 * @return 数据量
*/ */
default long selectCountByCondition(QueryCondition whereConditions) { default long selectCountByCondition(QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
return selectCountByQuery(QueryWrapper.create().where(whereConditions)); return selectCountByQuery(QueryWrapper.create().where(whereConditions));
} }
@ -861,7 +861,7 @@ public interface BaseMapper<T> {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginate(int pageNumber, int pageSize, QueryWrapper queryWrapper) { default Page<T> paginate(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
Page<T> page = new Page<>(pageNumber, pageSize); Page<T> page = new Page<>(pageNumber, pageSize);
return paginate(page, queryWrapper); return paginate(page, queryWrapper);
} }
@ -874,7 +874,7 @@ public interface BaseMapper<T> {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginateWithRelations(int pageNumber, int pageSize, QueryWrapper queryWrapper) { default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
Page<T> page = new Page<>(pageNumber, pageSize); Page<T> page = new Page<>(pageNumber, pageSize);
return paginateWithRelations(page, queryWrapper); return paginateWithRelations(page, queryWrapper);
} }
@ -887,7 +887,7 @@ public interface BaseMapper<T> {
* @param whereConditions 条件 * @param whereConditions 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginate(int pageNumber, int pageSize, QueryCondition whereConditions) { default Page<T> paginate(Number pageNumber, Number pageSize, QueryCondition whereConditions) {
Page<T> page = new Page<>(pageNumber, pageSize); Page<T> page = new Page<>(pageNumber, pageSize);
return paginate(page, new QueryWrapper().where(whereConditions)); return paginate(page, new QueryWrapper().where(whereConditions));
} }
@ -900,7 +900,7 @@ public interface BaseMapper<T> {
* @param whereConditions 条件 * @param whereConditions 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginateWithRelations(int pageNumber, int pageSize, QueryCondition whereConditions) { default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, QueryCondition whereConditions) {
Page<T> page = new Page<>(pageNumber, pageSize); Page<T> page = new Page<>(pageNumber, pageSize);
return paginateWithRelations(page, new QueryWrapper().where(whereConditions)); return paginateWithRelations(page, new QueryWrapper().where(whereConditions));
} }
@ -914,7 +914,7 @@ public interface BaseMapper<T> {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginate(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { default Page<T> paginate(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
Page<T> page = new Page<>(pageNumber, pageSize, totalRow); Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
return paginate(page, queryWrapper); return paginate(page, queryWrapper);
} }
@ -928,7 +928,7 @@ public interface BaseMapper<T> {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginateWithRelations(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
Page<T> page = new Page<>(pageNumber, pageSize, totalRow); Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
return paginateWithRelations(page, queryWrapper); return paginateWithRelations(page, queryWrapper);
} }
@ -942,8 +942,8 @@ public interface BaseMapper<T> {
* @param whereConditions 条件 * @param whereConditions 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginate(int pageNumber, int pageSize, int totalRow, QueryCondition whereConditions) { default Page<T> paginate(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
Page<T> page = new Page<>(pageNumber, pageSize, totalRow); Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
return paginate(page, new QueryWrapper().where(whereConditions)); return paginate(page, new QueryWrapper().where(whereConditions));
} }
@ -957,8 +957,8 @@ public interface BaseMapper<T> {
* @param whereConditions 条件 * @param whereConditions 条件
* @return 分页数据 * @return 分页数据
*/ */
default Page<T> paginateWithRelations(int pageNumber, int pageSize, int totalRow, QueryCondition whereConditions) { default Page<T> paginateWithRelations(Number pageNumber, Number pageSize, Number totalRow, QueryCondition whereConditions) {
FlexAssert.notNull(whereConditions, "whereConditions can not be null."); FlexAssert.notNull(whereConditions, "whereConditions");
Page<T> page = new Page<>(pageNumber, pageSize, totalRow); Page<T> page = new Page<>(pageNumber, pageSize, totalRow);
return paginateWithRelations(page, new QueryWrapper().where(whereConditions)); return paginateWithRelations(page, new QueryWrapper().where(whereConditions));
} }
@ -1018,7 +1018,7 @@ public interface BaseMapper<T> {
* @param asType 接收数据类型 * @param asType 接收数据类型
* @return 分页数据 * @return 分页数据
*/ */
default <R> Page<R> paginateAs(int pageNumber, int pageSize, QueryWrapper queryWrapper, Class<R> asType) { default <R> Page<R> paginateAs(Number pageNumber, Number pageSize, QueryWrapper queryWrapper, Class<R> asType) {
Page<R> page = new Page<>(pageNumber, pageSize); Page<R> page = new Page<>(pageNumber, pageSize);
return MapperUtil.doPaginate(this, page, queryWrapper, asType, false); return MapperUtil.doPaginate(this, page, queryWrapper, asType, false);
} }
@ -1033,7 +1033,7 @@ public interface BaseMapper<T> {
* @param asType 接收数据类型 * @param asType 接收数据类型
* @return 分页数据 * @return 分页数据
*/ */
default <R> Page<R> paginateAs(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper, Class<R> asType) { default <R> Page<R> paginateAs(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper, Class<R> asType) {
Page<R> page = new Page<>(pageNumber, pageSize, totalRow); Page<R> page = new Page<>(pageNumber, pageSize, totalRow);
return MapperUtil.doPaginate(this, page, queryWrapper, asType, false); return MapperUtil.doPaginate(this, page, queryWrapper, asType, false);
} }
@ -1072,7 +1072,7 @@ public interface BaseMapper<T> {
* @param asType 接收数据类型 * @param asType 接收数据类型
* @return 分页数据 * @return 分页数据
*/ */
default <R> Page<R> paginateWithRelationsAs(int pageNumber, int pageSize, QueryWrapper queryWrapper, Class<R> asType) { default <R> Page<R> paginateWithRelationsAs(Number pageNumber, Number pageSize, QueryWrapper queryWrapper, Class<R> asType) {
Page<R> page = new Page<>(pageNumber, pageSize); Page<R> page = new Page<>(pageNumber, pageSize);
return MapperUtil.doPaginate(this, page, queryWrapper, asType, true); return MapperUtil.doPaginate(this, page, queryWrapper, asType, true);
} }
@ -1087,7 +1087,7 @@ public interface BaseMapper<T> {
* @param asType 接收数据类型 * @param asType 接收数据类型
* @return 分页数据 * @return 分页数据
*/ */
default <R> Page<R> paginateWithRelationsAs(int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper, Class<R> asType) { default <R> Page<R> paginateWithRelationsAs(Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper, Class<R> asType) {
Page<R> page = new Page<>(pageNumber, pageSize, totalRow); Page<R> page = new Page<>(pageNumber, pageSize, totalRow);
return MapperUtil.doPaginate(this, page, queryWrapper, asType, true); return MapperUtil.doPaginate(this, page, queryWrapper, asType, true);
} }

View File

@ -21,6 +21,7 @@ import com.mybatisflex.annotation.SetListener;
import com.mybatisflex.annotation.UpdateListener; import com.mybatisflex.annotation.UpdateListener;
import com.mybatisflex.core.datasource.FlexDataSource; import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.core.dialect.DbType; import com.mybatisflex.core.dialect.DbType;
import com.mybatisflex.core.exception.FlexAssert;
import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
@ -307,9 +308,7 @@ public class FlexGlobalConfig {
} }
public void setNormalValueOfLogicDelete(Object normalValueOfLogicDelete) { public void setNormalValueOfLogicDelete(Object normalValueOfLogicDelete) {
if (normalValueOfLogicDelete == null) { FlexAssert.notNull(normalValueOfLogicDelete,"normalValueOfLogicDelete");
throw new NullPointerException("normalValueOfLogicDelete can not be null.");
}
this.normalValueOfLogicDelete = normalValueOfLogicDelete; this.normalValueOfLogicDelete = normalValueOfLogicDelete;
} }
@ -318,9 +317,7 @@ public class FlexGlobalConfig {
} }
public void setDeletedValueOfLogicDelete(Object deletedValueOfLogicDelete) { public void setDeletedValueOfLogicDelete(Object deletedValueOfLogicDelete) {
if (deletedValueOfLogicDelete == null) { FlexAssert.notNull(deletedValueOfLogicDelete,"deletedValueOfLogicDelete");
throw new NullPointerException("deletedValueOfLogicDelete can not be null.");
}
this.deletedValueOfLogicDelete = deletedValueOfLogicDelete; this.deletedValueOfLogicDelete = deletedValueOfLogicDelete;
} }

View File

@ -16,6 +16,7 @@
package com.mybatisflex.core; package com.mybatisflex.core;
import com.mybatisflex.core.datasource.FlexDataSource; import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder; import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder;
import com.mybatisflex.core.mybatis.Mappers; import com.mybatisflex.core.mybatis.Mappers;
@ -92,9 +93,8 @@ public class MybatisFlexBootstrap {
public MybatisFlexBootstrap start() { public MybatisFlexBootstrap start() {
if (started.compareAndSet(false, true)) { if (started.compareAndSet(false, true)) {
if (dataSource == null) {
throw new IllegalStateException("dataSource can not be null."); FlexAssert.notNull(dataSource,"dataSource");
}
//init configuration //init configuration
if (configuration == null) { if (configuration == null) {

View File

@ -356,17 +356,17 @@ public abstract class QueryModel<T extends QueryModel<T>> {
return new OrderByBuilder<>((T) this, column); return new OrderByBuilder<>((T) this, column);
} }
public T limit(Integer rows) { public T limit(Number rows) {
queryWrapper().limit(rows); queryWrapper().limit(rows);
return (T) this; return (T) this;
} }
public T offset(Integer offset) { public T offset(Number offset) {
queryWrapper().offset(offset); queryWrapper().offset(offset);
return (T) this; return (T) this;
} }
public T limit(Integer offset, Integer rows) { public T limit(Number offset, Number rows) {
queryWrapper().limit(offset, rows); queryWrapper().limit(offset, rows);
return (T) this; return (T) this;
} }

View File

@ -22,6 +22,9 @@ import com.mybatisflex.core.table.TableManager;
import java.util.List; import java.util.List;
/**
* @author michael
*/
public interface IDialect { public interface IDialect {
String wrap(String keyword); String wrap(String keyword);

View File

@ -39,7 +39,7 @@ public interface LimitOffsetProcessor {
* @param limitRows 用户传入的 limit 参数 可能为 null * @param limitRows 用户传入的 limit 参数 可能为 null
* @param limitOffset 用户传入的 offset 参数可能为 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) -> { LimitOffsetProcessor SQLSERVER_2005 = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null) { if (limitRows != null) {
if (limitOffset == null) { if (limitOffset == null) {
limitOffset = 0; limitOffset = 0L;
} }
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper); List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
@ -196,7 +196,7 @@ public interface LimitOffsetProcessor {
LimitOffsetProcessor ORACLE = (dialect, sql, queryWrapper, limitRows, limitOffset) -> { LimitOffsetProcessor ORACLE = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null) { if (limitRows != null) {
if (limitOffset == null) { if (limitOffset == null) {
limitOffset = 0; limitOffset = 0L;
} }
StringBuilder newSql = new StringBuilder("SELECT * FROM (SELECT TEMP_DATAS.*, ROWNUM RN FROM ("); StringBuilder newSql = new StringBuilder("SELECT * FROM (SELECT TEMP_DATAS.*, ROWNUM RN FROM (");
newSql.append(sql); newSql.append(sql);

View File

@ -382,8 +382,8 @@ public class CommonsDialectImpl implements IDialect {
} }
} }
Integer limitRows = CPI.getLimitRows(queryWrapper); Long limitRows = CPI.getLimitRows(queryWrapper);
Integer limitOffset = CPI.getLimitOffset(queryWrapper); Long limitOffset = CPI.getLimitOffset(queryWrapper);
if (limitRows != null || limitOffset != null) { if (limitRows != null || limitOffset != null) {
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset); sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
} }
@ -418,8 +418,8 @@ public class CommonsDialectImpl implements IDialect {
} }
} }
Integer limitRows = CPI.getLimitRows(queryWrapper); Long limitRows = CPI.getLimitRows(queryWrapper);
Integer limitOffset = CPI.getLimitOffset(queryWrapper); Long limitOffset = CPI.getLimitOffset(queryWrapper);
if (limitRows != null || limitOffset != null) { if (limitRows != null || limitOffset != null) {
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset); sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
} }
@ -782,8 +782,8 @@ public class CommonsDialectImpl implements IDialect {
Set<String> updateColumns = tableInfo.obtainUpdateColumns(entity, ignoreNulls, true); Set<String> updateColumns = tableInfo.obtainUpdateColumns(entity, ignoreNulls, true);
Map<String, RawValue> rawValueMap = tableInfo.obtainUpdateRawValueMap(entity); Map<String, RawValue> rawValueMap = tableInfo.obtainUpdateRawValueMap(entity);
sql.append(UPDATE).append(forHint(CPI.getHint(queryWrapper))) sql.append(UPDATE).append(forHint(CPI.getHint(queryWrapper)));
.append(tableInfo.getWrapSchemaAndTableName(this)).append(SET); sql.append(tableInfo.getWrapSchemaAndTableName(this)).append(SET);
StringJoiner stringJoiner = new StringJoiner(DELIMITER); StringJoiner stringJoiner = new StringJoiner(DELIMITER);
@ -814,7 +814,7 @@ public class CommonsDialectImpl implements IDialect {
//不允许全量更新 //不允许全量更新
if (StringUtil.isBlank(whereConditionSql)) { 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); sql.append(WHERE).append(whereConditionSql);
@ -844,7 +844,7 @@ public class CommonsDialectImpl implements IDialect {
//不允许全量更新 //不允许全量更新
if (StringUtil.isBlank(whereConditionSql)) { 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); sql.append(WHERE).append(whereConditionSql);
@ -993,12 +993,12 @@ public class CommonsDialectImpl implements IDialect {
if (StringUtil.isNotBlank(whereSql)) { if (StringUtil.isNotBlank(whereSql)) {
sqlBuilder.append(WHERE).append(whereSql); sqlBuilder.append(WHERE).append(whereSql);
} else if (!allowNoCondition) { } 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 { } else {
// whereQueryCondition == null // whereQueryCondition == null
if (!allowNoCondition) { 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 的参数 * 构建 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); return limitOffsetProcessor.process(this, sqlBuilder, queryWrapper, limitRows, limitOffset);
} }

View File

@ -16,6 +16,8 @@
package com.mybatisflex.core.exception; package com.mybatisflex.core.exception;
import com.mybatisflex.core.exception.locale.LocalizedFormats;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
@ -23,6 +25,8 @@ import java.util.Map;
* 断言 * 断言
* *
* @author 王帅 * @author 王帅
* @author michael
*
* @since 2023-07-08 * @since 2023-07-08
*/ */
public final class FlexAssert { public final class FlexAssert {
@ -33,26 +37,27 @@ public final class FlexAssert {
/** /**
* 断言对象不为空如果为空抛出异常并指明哪个对象为空 * 断言对象不为空如果为空抛出异常并指明哪个对象为空
* *
* @param obj 对象 * @param obj 对象
* @param message 错误消息 * @param param 错误消息参数
* @throws MybatisFlexException 如果对象为空抛出此异常 * @throws MybatisFlexException 如果对象为空抛出此异常
*/ */
public static void notNull(Object obj, String message) { public static void notNull(Object obj, String param) {
if (obj == null) { if (obj == null) {
throw FlexExceptions.wrap(message); throw FlexExceptions.wrap(LocalizedFormats.OBJECT_NULL, param);
} }
} }
/** /**
* 断言 Map 集合不为 {@code null} 或者空集合如果为空则抛出异常并指明为什么不允许为空集合 * 断言 Map 集合不为 {@code null} 或者空集合如果为空则抛出异常并指明为什么不允许为空集合
* *
* @param map Map 集合 * @param map Map 集合
* @param message 错误消息 * @param param 错误消息参数
* @throws MybatisFlexException 如果集合为空抛出此异常 * @throws MybatisFlexException 如果集合为空抛出此异常
*/ */
public static void notEmpty(Map<?, ?> map, String message) { public static void notEmpty(Map<?, ?> map, String param) {
if (map == null || map.isEmpty()) { 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} 或者空集合如果为空则抛出异常并指明为什么不允许为空集合 * 断言集合不为 {@code null} 或者空集合如果为空则抛出异常并指明为什么不允许为空集合
* *
* @param collection 集合 * @param collection 集合
* @param message 错误消息 * @param param 错误消息参数
* @throws MybatisFlexException 如果集合为空抛出此异常 * @throws MybatisFlexException 如果集合为空抛出此异常
*/ */
public static void notEmpty(Collection<?> collection, String message) { public static void notEmpty(Collection<?> collection, String param) {
if (collection == null || collection.isEmpty()) { if (collection == null || collection.isEmpty()) {
throw FlexExceptions.wrap(message); throw FlexExceptions.wrap(LocalizedFormats.MAP_NULL_OR_EMPTY, param);
} }
} }
/** /**
* 断言数组不为 {@code null} 或者空数组如果为空则抛出异常并指明为什么不允许为空数组 * 断言数组不为 {@code null} 或者空数组如果为空则抛出异常并指明为什么不允许为空数组
* *
* @param array 数组 * @param array 数组
* @param message 错误消息 * @param param 错误消息参数
* @throws MybatisFlexException 如果数组为空抛出此异常 * @throws MybatisFlexException 如果数组为空抛出此异常
*/ */
public static <T> void notEmpty(T[] array, String message) { public static <T> void notEmpty(T[] array, String param) {
if (array == null || array.length == 0) { if (array == null || array.length == 0) {
throw FlexExceptions.wrap(message); throw FlexExceptions.wrap(param);
} }
} }

View File

@ -34,17 +34,22 @@ public enum LocalizedFormats implements Localizable {
* object can not be null * object can not be null
*/ */
OBJECT_NULL("{0} 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_BLANK("The dataSource type can not be null or blank."),
DATASOURCE_TYPE_NOT_FIND("Can not find the dataSource type: {0}"), 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."), DATASOURCE_JDBC_URL("Can not get the dataSource jdbcUrl."),
UPDATE_ONLY_SUPPORT_1_TABLE("\"UpdateByQuery\" only support 1 table."), 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; private final String sourceFormat;

View File

@ -37,9 +37,9 @@ public class PrimaryKeyLogicDeleteProcessor extends NullableColumnLogicDeletePro
@Override @Override
public String buildLogicDeletedSet(String logicColumn, TableInfo tableInfo, IDialect dialect) { public String buildLogicDeletedSet(String logicColumn, TableInfo tableInfo, IDialect dialect) {
List<IdInfo> primaryKeyList = tableInfo.getPrimaryKeyList(); List<IdInfo> primaryKeys = tableInfo.getPrimaryKeyList();
FlexAssert.notEmpty(primaryKeyList, "Entity must have one primary key."); FlexAssert.notEmpty(primaryKeys, "primaryKeys");
String column = primaryKeyList.get(0).getColumn(); String column = primaryKeys.get(0).getColumn();
return dialect.wrap(logicColumn) + EQUALS + dialect.wrap(column); return dialect.wrap(logicColumn) + EQUALS + dialect.wrap(column);
} }

View File

@ -53,7 +53,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class FlexConfiguration extends Configuration { public class FlexConfiguration extends Configuration {
private static Map<String, MappedStatement> dynamicMappedStatementCache = new ConcurrentHashMap<>(); private static final Map<String, MappedStatement> dynamicMappedStatementCache = new ConcurrentHashMap<>();
public FlexConfiguration(Environment environment) { public FlexConfiguration(Environment environment) {
super(environment); super(environment);

View File

@ -23,14 +23,10 @@ import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.util.MapUtil; import org.apache.ibatis.util.MapUtil;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
@ -51,6 +47,7 @@ public class Mappers {
/** /**
* 通过 entity Class 获取 Mapper 对象 * 通过 entity Class 获取 Mapper 对象
*
* @param entityClass * @param entityClass
* @param <Entity> * @param <Entity>
* @return mapper 对象 * @return mapper 对象
@ -58,7 +55,7 @@ public class Mappers {
public static <Entity> BaseMapper<Entity> ofEntityClass(Class<Entity> entityClass) { public static <Entity> BaseMapper<Entity> ofEntityClass(Class<Entity> entityClass) {
Class<?> mapperClass = ENTITY_MAPPER_MAP.get(entityClass); Class<?> mapperClass = ENTITY_MAPPER_MAP.get(entityClass);
if (mapperClass == null) { 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<Entity>) ofMapperClass(mapperClass); return (BaseMapper<Entity>) ofMapperClass(mapperClass);
} }
@ -79,10 +76,8 @@ public class Mappers {
} }
static class MapperHandler implements InvocationHandler { static class MapperHandler implements InvocationHandler {
private static final Set<String> ignoreMethods = new HashSet<>(Arrays.asList("queryChain","updateChain"));
private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
private Class<?> mapperClass; private Class<?> mapperClass;
private final SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getDefaultConfig().getSqlSessionFactory(); private final SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getDefaultConfig().getSqlSessionFactory();
private final ExecutorType executorType = FlexGlobalConfig.getDefaultConfig().getConfiguration().getDefaultExecutorType(); private final ExecutorType executorType = FlexGlobalConfig.getDefaultConfig().getConfiguration().getDefaultExecutorType();

View File

@ -44,12 +44,12 @@ public class Page<T> 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<T> implements Serializable {
* @param <T> 数据类型 * @param <T> 数据类型
* @return 分页对象 * @return 分页对象
*/ */
public static <T> Page<T> of(int pageNumber, int pageSize) { public static <T> Page<T> of(Number pageNumber, Number pageSize) {
return new Page<>(pageNumber, pageSize); return new Page<>(pageNumber, pageSize);
} }
@ -87,7 +87,7 @@ public class Page<T> implements Serializable {
* @param <T> 数据类型 * @param <T> 数据类型
* @return 分页对象 * @return 分页对象
*/ */
public static <T> Page<T> of(int pageNumber, int pageSize, long totalRow) { public static <T> Page<T> of(Number pageNumber, Number pageSize, Number totalRow) {
return new Page<>(pageNumber, pageSize, totalRow); return new Page<>(pageNumber, pageSize, totalRow);
} }
@ -103,7 +103,7 @@ public class Page<T> implements Serializable {
* @param pageNumber 当前页码 * @param pageNumber 当前页码
* @param pageSize 每页数据数量 * @param pageSize 每页数据数量
*/ */
public Page(int pageNumber, int pageSize) { public Page(Number pageNumber, Number pageSize) {
this.setPageNumber(pageNumber); this.setPageNumber(pageNumber);
this.setPageSize(pageSize); this.setPageSize(pageSize);
} }
@ -115,7 +115,7 @@ public class Page<T> implements Serializable {
* @param pageSize 每页数据数量 * @param pageSize 每页数据数量
* @param totalRow 总数居数量 * @param totalRow 总数居数量
*/ */
public Page(int pageNumber, int pageSize, long totalRow) { public Page(Number pageNumber, Number pageSize, Number totalRow) {
this.setPageNumber(pageNumber); this.setPageNumber(pageNumber);
this.setPageSize(pageSize); this.setPageSize(pageSize);
this.setTotalRow(totalRow); this.setTotalRow(totalRow);
@ -129,7 +129,7 @@ public class Page<T> implements Serializable {
* @param pageSize 每页数据数量 * @param pageSize 每页数据数量
* @param totalRow 总数居数量 * @param totalRow 总数居数量
*/ */
public Page(List<T> records, int pageNumber, int pageSize, long totalRow) { public Page(List<T> records, Number pageNumber, Number pageSize, Number totalRow) {
this.setRecords(records); this.setRecords(records);
this.setPageNumber(pageNumber); this.setPageNumber(pageNumber);
this.setPageSize(pageSize); this.setPageSize(pageSize);
@ -162,7 +162,7 @@ public class Page<T> implements Serializable {
* *
* @return 页码 * @return 页码
*/ */
public int getPageNumber() { public long getPageNumber() {
return pageNumber; return pageNumber;
} }
@ -171,11 +171,11 @@ public class Page<T> implements Serializable {
* *
* @param pageNumber 页码 * @param pageNumber 页码
*/ */
public void setPageNumber(int pageNumber) { public void setPageNumber(Number pageNumber) {
if (pageNumber < 1) { if (pageNumber.longValue() < 1) {
throw new IllegalArgumentException("pageNumber must greater than or equal 1current value is: " + pageNumber); throw new IllegalArgumentException("pageNumber must greater than or equal 1current value is: " + pageNumber);
} }
this.pageNumber = pageNumber; this.pageNumber = pageNumber.longValue();
} }
/** /**
@ -183,7 +183,7 @@ public class Page<T> implements Serializable {
* *
* @return 每页数据数量 * @return 每页数据数量
*/ */
public int getPageSize() { public long getPageSize() {
return pageSize; return pageSize;
} }
@ -192,11 +192,11 @@ public class Page<T> implements Serializable {
* *
* @param pageSize 每页数据数量 * @param pageSize 每页数据数量
*/ */
public void setPageSize(int pageSize) { public void setPageSize(Number pageSize) {
if (pageSize < 0) { if (pageSize.longValue() < 0) {
throw new IllegalArgumentException("pageSize must greater than or equal 0current value is: " + pageSize); throw new IllegalArgumentException("pageSize must greater than or equal 0current value is: " + pageSize);
} }
this.pageSize = pageSize; this.pageSize = pageSize.longValue();
this.calcTotalPage(); this.calcTotalPage();
} }
@ -232,8 +232,8 @@ public class Page<T> implements Serializable {
* *
* @param totalRow 数据总数 * @param totalRow 数据总数
*/ */
public void setTotalRow(long totalRow) { public void setTotalRow(Number totalRow) {
this.totalRow = totalRow; this.totalRow = totalRow.longValue();
this.calcTotalPage(); this.calcTotalPage();
} }
@ -280,7 +280,7 @@ public class Page<T> implements Serializable {
* *
* @return 偏移量 * @return 偏移量
*/ */
public int offset() { public long offset() {
return getPageSize() * (getPageNumber() - 1); return getPageSize() * (getPageNumber() - 1);
} }

View File

@ -52,7 +52,7 @@ public class EntitySqlProvider {
public static String insert(Map params, ProviderContext context) { public static String insert(Map params, ProviderContext context) {
Object entity = ProviderUtil.getEntity(params); Object entity = ProviderUtil.getEntity(params);
FlexAssert.notNull(entity, "entity can not be null."); FlexAssert.notNull(entity, "entity");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params); boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
@ -88,7 +88,7 @@ public class EntitySqlProvider {
public static String insertWithPk(Map params, ProviderContext context) { public static String insertWithPk(Map params, ProviderContext context) {
Object entity = ProviderUtil.getEntity(params); Object entity = ProviderUtil.getEntity(params);
FlexAssert.notNull(entity, "entity can not be null."); FlexAssert.notNull(entity, "entity");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params); boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
@ -125,7 +125,7 @@ public class EntitySqlProvider {
public static String insertBatch(Map params, ProviderContext context) { public static String insertBatch(Map params, ProviderContext context) {
List<Object> entities = ProviderUtil.getEntities(params); List<Object> entities = ProviderUtil.getEntities(params);
FlexAssert.notEmpty(entities, "entities can not be null or empty."); FlexAssert.notEmpty(entities, "entities");
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
for (Object entity : entities) { for (Object entity : entities) {
@ -160,7 +160,7 @@ public class EntitySqlProvider {
public static String deleteById(Map params, ProviderContext context) { public static String deleteById(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params); Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); FlexAssert.notEmpty(primaryValues, "primaryValues");
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -182,7 +182,7 @@ public class EntitySqlProvider {
public static String deleteBatchByIds(Map params, ProviderContext context) { public static String deleteBatchByIds(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params); Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); FlexAssert.notEmpty(primaryValues, "primaryValues");
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -322,7 +322,7 @@ public class EntitySqlProvider {
public static String selectOneById(Map params, ProviderContext context) { public static String selectOneById(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params); Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); FlexAssert.notEmpty(primaryValues, "primaryValues");
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -345,7 +345,7 @@ public class EntitySqlProvider {
public static String selectListByIds(Map params, ProviderContext context) { public static String selectListByIds(Map params, ProviderContext context) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(params); Object[] primaryValues = ProviderUtil.getPrimaryValues(params);
FlexAssert.notEmpty(primaryValues, "primaryValues can not be null or empty."); FlexAssert.notEmpty(primaryValues, "primaryValues");
TableInfo tableInfo = ProviderUtil.getTableInfo(context); TableInfo tableInfo = ProviderUtil.getTableInfo(context);

View File

@ -16,7 +16,9 @@
package com.mybatisflex.core.provider; package com.mybatisflex.core.provider;
import com.mybatisflex.core.FlexConsts; import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.exception.locale.LocalizedFormats;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Row; import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfo;
@ -55,7 +57,7 @@ class ProviderUtil {
public static String[] getPrimaryKeys(Map params) { public static String[] getPrimaryKeys(Map params) {
String primaryKey = (String) params.get(FlexConsts.PRIMARY_KEY); String primaryKey = (String) params.get(FlexConsts.PRIMARY_KEY);
if (StringUtil.isBlank(primaryKey)) { 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(","); String[] primaryKeys = primaryKey.split(",");
for (int i = 0; i < primaryKeys.length; i++) { for (int i = 0; i < primaryKeys.length; i++) {
@ -80,9 +82,7 @@ class ProviderUtil {
public static QueryWrapper getQueryWrapper(Map params) { public static QueryWrapper getQueryWrapper(Map params) {
Object queryWrapper = params.get(FlexConsts.QUERY); Object queryWrapper = params.get(FlexConsts.QUERY);
if (queryWrapper == null) { FlexAssert.notNull(queryWrapper,"queryWrapper");
throw new IllegalArgumentException("queryWrapper can not be null.");
}
return (QueryWrapper) queryWrapper; return (QueryWrapper) queryWrapper;
} }

View File

@ -79,7 +79,7 @@ public class RowSqlProvider {
public static String insertBatchWithFirstRowColumns(Map params) { public static String insertBatchWithFirstRowColumns(Map params) {
List<Row> rows = ProviderUtil.getRows(params); List<Row> rows = ProviderUtil.getRows(params);
FlexAssert.notEmpty(rows, "rows can not be null or empty."); FlexAssert.notEmpty(rows, "rows");
String tableName = ProviderUtil.getTableName(params); String tableName = ProviderUtil.getTableName(params);
String schema = ProviderUtil.getSchemaName(params); String schema = ProviderUtil.getSchemaName(params);
@ -109,7 +109,7 @@ public class RowSqlProvider {
public static String deleteById(Map params) { public static String deleteById(Map params) {
Object[] primaryValues = ProviderUtil.getPrimaryValues(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 schema = ProviderUtil.getSchemaName(params);
String tableName = ProviderUtil.getTableName(params); String tableName = ProviderUtil.getTableName(params);
@ -211,7 +211,7 @@ public class RowSqlProvider {
public static String updateBatchById(Map params) { public static String updateBatchById(Map params) {
List<Row> rows = ProviderUtil.getRows(params); List<Row> rows = ProviderUtil.getRows(params);
FlexAssert.notEmpty(rows, "rows can not be null or empty."); FlexAssert.notEmpty(rows, "rows");
String schema = ProviderUtil.getSchemaName(params); String schema = ProviderUtil.getSchemaName(params);
String tableName = ProviderUtil.getTableName(params); String tableName = ProviderUtil.getTableName(params);

View File

@ -40,8 +40,8 @@ public class BaseQueryWrapper<T extends BaseQueryWrapper<T>> implements CloneSup
protected List<UnionWrapper> unions; protected List<UnionWrapper> unions;
protected Integer limitOffset; protected Long limitOffset;
protected Integer limitRows; protected Long limitRows;
protected List<String> endFragments; protected List<String> endFragments;
@ -219,19 +219,19 @@ public class BaseQueryWrapper<T extends BaseQueryWrapper<T>> implements CloneSup
this.unions = unions; this.unions = unions;
} }
protected Integer getLimitOffset() { protected Long getLimitOffset() {
return limitOffset; return limitOffset;
} }
protected void setLimitOffset(Integer limitOffset) { protected void setLimitOffset(Long limitOffset) {
this.limitOffset = limitOffset; this.limitOffset = limitOffset;
} }
protected Integer getLimitRows() { protected Long getLimitRows() {
return limitRows; return limitRows;
} }
protected void setLimitRows(Integer limitRows) { protected void setLimitRows(Long limitRows) {
this.limitRows = limitRows; this.limitRows = limitRows;
} }

View File

@ -167,19 +167,19 @@ public class CPI {
} }
public static Integer getLimitOffset(QueryWrapper queryWrapper) { public static Long getLimitOffset(QueryWrapper queryWrapper) {
return queryWrapper.getLimitOffset(); return queryWrapper.getLimitOffset();
} }
public static void setLimitOffset(QueryWrapper queryWrapper, Integer limitOffset) { public static void setLimitOffset(QueryWrapper queryWrapper, Long limitOffset) {
queryWrapper.setLimitOffset(limitOffset); queryWrapper.setLimitOffset(limitOffset);
} }
public static Integer getLimitRows(QueryWrapper queryWrapper) { public static Long getLimitRows(QueryWrapper queryWrapper) {
return queryWrapper.getLimitRows(); return queryWrapper.getLimitRows();
} }
public static void setLimitRows(QueryWrapper queryWrapper, Integer limitRows) { public static void setLimitRows(QueryWrapper queryWrapper, Long limitRows) {
queryWrapper.setLimitRows(limitRows); queryWrapper.setLimitRows(limitRows);
} }

View File

@ -654,19 +654,27 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
return this; return this;
} }
public QueryWrapper limit(Integer rows) { public QueryWrapper limit(Number rows) {
setLimitRows(rows); if (rows != null) {
setLimitRows(rows.longValue());
}else {
setLimitRows(null);
}
return this; return this;
} }
public QueryWrapper offset(Integer offset) { public QueryWrapper offset(Number offset) {
setLimitOffset(offset); if (offset!= null) {
setLimitOffset(offset.longValue());
}else {
setLimitOffset(null);
}
return this; return this;
} }
public QueryWrapper limit(Integer offset, Integer rows) { public QueryWrapper limit(Number offset, Number rows) {
setLimitOffset(offset); offset(offset);
setLimitRows(rows); limit(rows);
return this; return this;
} }

View File

@ -583,19 +583,19 @@ public class QueryWrapperAdapter<R extends QueryWrapperAdapter<R>> extends Query
} }
@Override @Override
public R limit(Integer rows) { public R limit(Number rows) {
super.limit(rows); super.limit(rows);
return (R) this; return (R) this;
} }
@Override @Override
public R offset(Integer offset) { public R offset(Number offset) {
super.offset(offset); super.offset(offset);
return (R) this; return (R) this;
} }
@Override @Override
public R limit(Integer offset, Integer rows) { public R limit(Number offset, Number rows) {
super.limit(offset, rows); super.limit(offset, rows);
return (R) this; return (R) this;
} }

View File

@ -28,7 +28,7 @@ class ToManyRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
protected String mapKeyField; protected String mapKeyField;
protected FieldWrapper mapKeyFieldWrapper; protected FieldWrapper mapKeyFieldWrapper;
protected String orderBy; protected String orderBy;
protected int limit = 0; protected long limit = 0;
public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField,

View File

@ -610,7 +610,7 @@ public class Db {
* @param whereColumns where条件 * @param whereColumns where条件
*/ */
public static Row selectOneByMap(String schema, String tableName, Map whereColumns) { 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条件 * @param whereColumns where条件
*/ */
public static Row selectOneByMap(String tableName, Map whereColumns) { 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 条件 * @param condition 条件
*/ */
public static Row selectOneByCondition(String schema, String tableName, QueryCondition 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 条件 * @param condition 条件
*/ */
public static Row selectOneByCondition(String tableName, QueryCondition 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 whereColumns 条件
* @param count 数据量 * @param count 数据量
*/ */
public static List<Row> selectListByMap(String schema, String tableName, Map<String, Object> whereColumns, int count) { public static List<Row> selectListByMap(String schema, String tableName, Map<String, Object> whereColumns, Long count) {
return invoker().selectListByQuery(schema, tableName, new QueryWrapper().where(whereColumns).limit(count)); return invoker().selectListByQuery(schema, tableName, new QueryWrapper().where(whereColumns).limit(count));
} }
@ -734,7 +734,7 @@ public class Db {
* @param whereColumns 条件 * @param whereColumns 条件
* @param count 数据量 * @param count 数据量
*/ */
public static List<Row> selectListByMap(String tableName, Map<String, Object> whereColumns, int count) { public static List<Row> selectListByMap(String tableName, Map<String, Object> whereColumns, Long count) {
return invoker().selectListByQuery(null, tableName, new QueryWrapper().where(whereColumns).limit(count)); return invoker().selectListByQuery(null, tableName, new QueryWrapper().where(whereColumns).limit(count));
} }
@ -769,7 +769,7 @@ public class Db {
* @param condition 条件 * @param condition 条件
* @param count 数据量 * @param count 数据量
*/ */
public static List<Row> selectListByCondition(String schema, String tableName, QueryCondition condition, int count) { public static List<Row> selectListByCondition(String schema, String tableName, QueryCondition condition, Long count) {
return invoker().selectListByQuery(schema, tableName, new QueryWrapper().where(condition).limit(count)); return invoker().selectListByQuery(schema, tableName, new QueryWrapper().where(condition).limit(count));
} }
@ -780,7 +780,7 @@ public class Db {
* @param condition 条件 * @param condition 条件
* @param count 数据量 * @param count 数据量
*/ */
public static List<Row> selectListByCondition(String tableName, QueryCondition condition, int count) { public static List<Row> selectListByCondition(String tableName, QueryCondition condition, Long count) {
return invoker().selectListByQuery(null, tableName, new QueryWrapper().where(condition).limit(count)); return invoker().selectListByQuery(null, tableName, new QueryWrapper().where(condition).limit(count));
} }
@ -1012,7 +1012,7 @@ public class Db {
* @param pageSize 每页的数据量 * @param pageSize 每页的数据量
* @param condition 条件 * @param condition 条件
*/ */
public static Page<Row> paginate(String schema, String tableName, int pageNumber, int pageSize, QueryCondition condition) { public static Page<Row> paginate(String schema, String tableName, Number pageNumber, Number pageSize, QueryCondition condition) {
return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition)); return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition));
} }
@ -1025,7 +1025,7 @@ public class Db {
* @param pageSize 每页的数据量 * @param pageSize 每页的数据量
* @param condition 条件 * @param condition 条件
*/ */
public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, QueryCondition condition) { public static Page<Row> paginate(String tableName, Number pageNumber, Number pageSize, QueryCondition condition) {
return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition)); return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition));
} }
@ -1040,7 +1040,7 @@ public class Db {
* @param totalRow 数据总量 * @param totalRow 数据总量
* @param condition 条件 * @param condition 条件
*/ */
public static Page<Row> paginate(String schema, String tableName, int pageNumber, int pageSize, int totalRow, QueryCondition condition) { public static Page<Row> 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)); return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize, totalRow), QueryWrapper.create().where(condition));
} }
@ -1053,7 +1053,7 @@ public class Db {
* @param totalRow 数据总量 * @param totalRow 数据总量
* @param condition 条件 * @param condition 条件
*/ */
public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, int totalRow, QueryCondition condition) { public static Page<Row> 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)); return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize, totalRow), QueryWrapper.create().where(condition));
} }
@ -1067,7 +1067,7 @@ public class Db {
* @param pageSize 每页的数据量 * @param pageSize 每页的数据量
* @param queryWrapper 条件 * @param queryWrapper 条件
*/ */
public static Page<Row> paginate(String schema, String tableName, int pageNumber, int pageSize, QueryWrapper queryWrapper) { public static Page<Row> paginate(String schema, String tableName, Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize), queryWrapper); return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize), queryWrapper);
} }
@ -1079,7 +1079,7 @@ public class Db {
* @param pageSize 每页的数据量 * @param pageSize 每页的数据量
* @param queryWrapper 条件 * @param queryWrapper 条件
*/ */
public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, QueryWrapper queryWrapper) { public static Page<Row> paginate(String tableName, Number pageNumber, Number pageSize, QueryWrapper queryWrapper) {
return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize), queryWrapper); return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize), queryWrapper);
} }
@ -1094,7 +1094,7 @@ public class Db {
* @param totalRow 数据总量 * @param totalRow 数据总量
* @param queryWrapper 条件 * @param queryWrapper 条件
*/ */
public static Page<Row> paginate(String schema, String tableName, int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { public static Page<Row> paginate(String schema, String tableName, Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper); return invoker().paginate(schema, tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper);
} }
@ -1107,7 +1107,7 @@ public class Db {
* @param totalRow 数据总量 * @param totalRow 数据总量
* @param queryWrapper 条件 * @param queryWrapper 条件
*/ */
public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) { public static Page<Row> paginate(String tableName, Number pageNumber, Number pageSize, Number totalRow, QueryWrapper queryWrapper) {
return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper); return invoker().paginate(null, tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper);
} }

View File

@ -289,7 +289,7 @@ public interface RowMapper {
* @return row or null * @return row or null
*/ */
default Row selectOneByQuery(String schema, String tableName, QueryWrapper queryWrapper) { default Row selectOneByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
List<Row> rows = selectListByQuery(schema, tableName, queryWrapper.limit(1)); List<Row> rows = selectListByQuery(schema, tableName, queryWrapper.limit(1L));
if (rows == null || rows.isEmpty()) { if (rows == null || rows.isEmpty()) {
return null; return null;
} else { } else {
@ -384,7 +384,7 @@ public interface RowMapper {
* @return 数据 * @return 数据
*/ */
default Object selectObjectByQuery(String schema, String tableName, QueryWrapper queryWrapper) { default Object selectObjectByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
queryWrapper.limit(1); queryWrapper.limit(1L);
List<Object> objects = selectObjectListByQuery(schema, tableName, queryWrapper); List<Object> objects = selectObjectListByQuery(schema, tableName, queryWrapper);
if (objects == null || objects.isEmpty()) { if (objects == null || objects.isEmpty()) {
return null; return null;

View File

@ -628,9 +628,11 @@ public class TableInfo {
if (value != null) { if (value != null) {
ColumnInfo columnInfo = columnInfoMapping.get(column); ColumnInfo columnInfo = columnInfoMapping.get(column);
TypeHandler typeHandler = columnInfo.buildTypeHandler(); if (columnInfo != null) {
if (typeHandler != null) { TypeHandler typeHandler = columnInfo.buildTypeHandler();
value = new TypeHandlerObject(typeHandler, value, columnInfo.getJdbcType()); if (typeHandler != null) {
value = new TypeHandlerObject(typeHandler, value, columnInfo.getJdbcType());
}
} }
} }

View File

@ -20,6 +20,9 @@ import com.mybatisflex.core.util.StringUtil;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/**
* @author michael
*/
public class TableManager { public class TableManager {
private TableManager() { private TableManager() {
@ -28,8 +31,8 @@ public class TableManager {
private static DynamicTableProcessor dynamicTableProcessor; private static DynamicTableProcessor dynamicTableProcessor;
private static DynamicSchemaProcessor dynamicSchemaProcessor; private static DynamicSchemaProcessor dynamicSchemaProcessor;
private static final ThreadLocal<Map<String, String>> tableNameMappingTL = ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal<Map<String, String>> tableNameMappingTL = new ThreadLocal<>();
private static final ThreadLocal<Map<String, String>> schemaMappingTL = ThreadLocal.withInitial(HashMap::new); private static final ThreadLocal<Map<String, String>> schemaMappingTL = new ThreadLocal<>();
public static DynamicTableProcessor getDynamicTableProcessor() { public static DynamicTableProcessor getDynamicTableProcessor() {
@ -49,7 +52,12 @@ public class TableManager {
} }
public static void setHintTableMapping(String tableName, String mappingTable) { public static void setHintTableMapping(String tableName, String mappingTable) {
tableNameMappingTL.get().put(tableName, mappingTable); Map<String, String> hintTables = tableNameMappingTL.get();
if (hintTables == null) {
hintTables = new HashMap<>();
tableNameMappingTL.set(hintTables);
}
hintTables.put(tableName, mappingTable);
} }
public static String getHintTableMapping(String tableName) { public static String getHintTableMapping(String tableName) {
@ -57,7 +65,12 @@ public class TableManager {
} }
public static void setHintSchemaMapping(String schema, String mappingSchema) { public static void setHintSchemaMapping(String schema, String mappingSchema) {
schemaMappingTL.get().put(schema, mappingSchema); Map<String, String> hintTables = schemaMappingTL.get();
if (hintTables == null) {
hintTables = new HashMap<>();
schemaMappingTL.set(hintTables);
}
hintTables.put(schema, mappingSchema);
} }
public static String getHintSchemaMapping(String schema) { public static String getHintSchemaMapping(String schema) {
@ -66,47 +79,45 @@ public class TableManager {
public static String getRealTable(String tableName) { public static String getRealTable(String tableName) {
Map<String, String> mapping = tableNameMappingTL.get();
if (mapping != null) {
String dynamicTableName = mapping.get(tableName);
if (StringUtil.isNotBlank(dynamicTableName)) {
return dynamicTableName;
}
}
if (dynamicTableProcessor == null) { if (dynamicTableProcessor == null) {
return tableName; return tableName;
} }
Map<String, String> mapping = tableNameMappingTL.get(); String dynamicTableName = dynamicTableProcessor.process(tableName);
return StringUtil.isNotBlank(dynamicTableName) ? dynamicTableName : tableName;
String dynamicTableName = mapping.get(tableName);
if (StringUtil.isNotBlank(dynamicTableName)) {
return dynamicTableName;
}
dynamicTableName = dynamicTableProcessor.process(tableName);
mapping.put(tableName, dynamicTableName);
return dynamicTableName;
} }
public static String getRealSchema(String schema) { public static String getRealSchema(String schema) {
Map<String, String> mapping = schemaMappingTL.get();
if (mapping != null) {
String dynamicSchema = mapping.get(schema);
if (StringUtil.isNotBlank(dynamicSchema)) {
return dynamicSchema;
}
}
if (dynamicSchemaProcessor == null) { if (dynamicSchemaProcessor == null) {
return schema; return schema;
} }
Map<String, String> mapping = schemaMappingTL.get(); String dynamicSchema = dynamicSchemaProcessor.process(schema);
String dynamiSchema = mapping.get(schema); return StringUtil.isNotBlank(dynamicSchema) ? dynamicSchema : schema;
if (StringUtil.isNotBlank(dynamiSchema)) {
return dynamiSchema;
}
dynamiSchema = dynamicSchemaProcessor.process(schema);
mapping.put(schema, dynamiSchema);
return dynamiSchema;
} }
// public static void clear() { public static void clear() {
// if (dynamicTableProcessor != null) { tableNameMappingTL.remove();
// tableNameMappingTL.remove(); schemaMappingTL.remove();
// } }
// if (dynamicSchemaProcessor != null) {
// schemaMappingTL.remove();
// }
// }
} }

View File

@ -25,7 +25,9 @@ import java.util.Map;
class ModifyAttrsRecordHandler implements MethodHandler { class ModifyAttrsRecordHandler implements MethodHandler {
//更新内容 /**
* 更新的字段和内容
*/
private final Map<String, Object> updates = new LinkedHashMap<>(); private final Map<String, Object> updates = new LinkedHashMap<>();
public Map<String, Object> getUpdates() { public Map<String, Object> getUpdates() {

View File

@ -15,47 +15,54 @@
*/ */
package com.mybatisflex.core.update; 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.ProxyFactory;
import org.apache.ibatis.javassist.util.proxy.ProxyObject; import org.apache.ibatis.javassist.util.proxy.ProxyObject;
import org.apache.ibatis.logging.LogFactory; import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.util.MapUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author michael
*/
public class ModifyAttrsRecordProxyFactory { public class ModifyAttrsRecordProxyFactory {
private static final ModifyAttrsRecordProxyFactory instance = new ModifyAttrsRecordProxyFactory(); protected static final Map<Class<?>, Class<?>> CACHE = new ConcurrentHashMap<>();
private static final ModifyAttrsRecordProxyFactory INSTANCE = new ModifyAttrsRecordProxyFactory();
public static ModifyAttrsRecordProxyFactory getInstance() { public static ModifyAttrsRecordProxyFactory getInstance() {
return instance; return INSTANCE;
} }
private ModifyAttrsRecordProxyFactory() { private ModifyAttrsRecordProxyFactory() {
} }
public <T> T get(Class<T> target) { public <T> T get(Class<T> target) {
ProxyFactory factory = new ProxyFactory(); Class<?> proxyClass = MapUtil.computeIfAbsent(CACHE, target, aClass -> {
factory.setSuperclass(target); ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(target);
Class<?>[] interfaces = Arrays.copyOf(target.getInterfaces(), target.getInterfaces().length + 1); Class<?>[] interfaces = Arrays.copyOf(target.getInterfaces(), target.getInterfaces().length + 1);
interfaces[interfaces.length - 1] = UpdateWrapper.class; interfaces[interfaces.length - 1] = UpdateWrapper.class;
factory.setInterfaces(interfaces); factory.setInterfaces(interfaces);
return factory.createClass();
final Class<?> proxyClass = factory.createClass(); });
T proxyObject = null; T proxyObject = null;
try { try {
proxyObject = (T) proxyClass.newInstance(); proxyObject = (T) ClassUtil.newInstance(proxyClass);
((ProxyObject) proxyObject).setHandler(new ModifyAttrsRecordHandler()); ((ProxyObject) proxyObject).setHandler(new ModifyAttrsRecordHandler());
} catch (Throwable e) { } catch (Exception e) {
LogFactory.getLog(ModifyAttrsRecordProxyFactory.class).error(e.toString(), e); LogFactory.getLog(ModifyAttrsRecordProxyFactory.class).error(e.toString(), e);
} }
return proxyObject; return proxyObject;
} }
} }

View File

@ -25,10 +25,7 @@ import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryWrapperAdapter; import com.mybatisflex.core.query.QueryWrapperAdapter;
import com.mybatisflex.core.table.TableInfo; import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory; import com.mybatisflex.core.table.TableInfoFactory;
import com.mybatisflex.core.util.ClassUtil; import com.mybatisflex.core.util.*;
import com.mybatisflex.core.util.LambdaGetter;
import com.mybatisflex.core.util.SqlUtil;
import com.mybatisflex.core.util.UpdateEntity;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -124,6 +121,7 @@ public class UpdateChain<T> extends QueryWrapperAdapter<UpdateChain<T>> {
return SqlUtil.toBool(baseMapper.deleteByQuery(this)); return SqlUtil.toBool(baseMapper.deleteByQuery(this));
} }
public boolean update() { public boolean update() {
return SqlUtil.toBool(baseMapper.updateByQuery(entity, this)); return SqlUtil.toBool(baseMapper.updateByQuery(entity, this));
} }
@ -133,8 +131,12 @@ public class UpdateChain<T> extends QueryWrapperAdapter<UpdateChain<T>> {
public String toSQL() { public String toSQL() {
TableInfo tableInfo = TableInfoFactory.ofMapperClass(baseMapper.getClass()); TableInfo tableInfo = TableInfoFactory.ofMapperClass(baseMapper.getClass());
CPI.setFromIfNecessary(this, tableInfo.getSchema(), tableInfo.getTableName()); CPI.setFromIfNecessary(this, tableInfo.getSchema(), tableInfo.getTableName());
String sql = DialectFactory.getDialect().forUpdateEntityByQuery(tableInfo,entity,true,this); String sql = DialectFactory.getDialect().forUpdateEntityByQuery(tableInfo, entity, true, this);
return SqlUtil.replaceSqlParams(sql, CPI.getValueArray(this));
Object[] values = tableInfo.buildUpdateSqlArgs(entity, true, true);
values = ArrayUtil.concat(values, CPI.getValueArray(this));
return SqlUtil.replaceSqlParams(sql, values);
} }
} }

View File

@ -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 { public class ClassUtil {
private ClassUtil() { private ClassUtil() {
} }
private static final String[] OBJECT_METHODS = new String[]{
"toString",
"getClass",
"equals",
"hashCode",
"wait",
"notify",
"notifyAll",
"clone",
"finalize"
};
//proxy frameworks //proxy frameworks
private static final List<String> PROXY_CLASS_NAMES = Arrays.asList("net.sf.cglib.proxy.Factory" private static final List<String> PROXY_CLASS_NAMES = Arrays.asList("net.sf.cglib.proxy.Factory"
// cglib // cglib
@ -118,7 +133,7 @@ public class ClassUtil {
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : declaredConstructors) { for (Constructor<?> constructor : declaredConstructors) {
if (constructor.getParameterCount() == 0) { if (constructor.getParameterCount() == 0 && Modifier.isPublic(constructor.getModifiers())) {
defaultConstructor = constructor; defaultConstructor = constructor;
} else if (Modifier.isPublic(constructor.getModifiers())) { } else if (Modifier.isPublic(constructor.getModifiers())) {
otherConstructor = constructor; otherConstructor = constructor;
@ -138,6 +153,16 @@ public class ClassUtil {
} }
return (T) otherConstructor.newInstance(parameters); 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."); throw new IllegalArgumentException("the class \"" + clazz.getName() + "\" has no constructor.");
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Can not newInstance class: " + clazz.getName()); 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);
}
} }

View File

@ -28,11 +28,12 @@ public class ConvertUtil {
private ConvertUtil() { private ConvertUtil() {
} }
@SuppressWarnings("rawtypes")
public static Object convert(Object value, Class targetClass) { public static Object convert(Object value, Class targetClass) {
return convert(value, targetClass, false); return convert(value, targetClass, false);
} }
@SuppressWarnings("unchecked") @SuppressWarnings({"unchecked", "rawtypes"})
public static Object convert(Object value, Class targetClass, boolean ignoreConvertError) { public static Object convert(Object value, Class targetClass, boolean ignoreConvertError) {
if (value == null && targetClass.isPrimitive()) { if (value == null && targetClass.isPrimitive()) {
return getPrimitiveDefaultValue(targetClass); return getPrimitiveDefaultValue(targetClass);

View File

@ -1,7 +1,14 @@
OBJECT_NULL={0} \u4E0D\u80FD\u4E3A null \u503C\u3002 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_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_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_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 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_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 ENTITY_VERSION_NULL=\u4e50\u89c2\u9501\u5b9e\u4f53\u7c7b\u5fc5\u987b\u8bbe\u7f6e version \u7684\u503c\uff1a{0}\u3002

View File

@ -16,11 +16,14 @@
package com.mybatisflex.spring.boot; package com.mybatisflex.spring.boot;
import com.mybatisflex.core.datasource.DataSourceBuilder; 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.core.datasource.FlexDataSource;
import com.mybatisflex.spring.datasource.DataSourceAdvice; import com.mybatisflex.spring.datasource.DataSourceAdvice;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.aop.Advisor; import org.springframework.aop.Advisor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -37,6 +40,7 @@ import java.util.Map;
/** /**
* MyBatis-Flex 多数据源的配置支持 * MyBatis-Flex 多数据源的配置支持
*
* @author michael * @author michael
*/ */
@ConditionalOnMybatisFlexDatasource() @ConditionalOnMybatisFlexDatasource()
@ -47,10 +51,18 @@ import java.util.Map;
, name = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure") , name = "com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure")
public class MultiDataSourceAutoConfiguration { public class MultiDataSourceAutoConfiguration {
private final Map<String, Map<String, String>> dataSourceProperties; private final Map<String, Map<String, String>> dataSourceProperties;
public MultiDataSourceAutoConfiguration(MybatisFlexProperties properties) { //数据源解密器
protected final DataSourceDecipher dataSourceDecipher;
public MultiDataSourceAutoConfiguration(MybatisFlexProperties properties
, ObjectProvider<DataSourceDecipher> dataSourceDecipherProvider
) {
dataSourceProperties = properties.getDatasource(); dataSourceProperties = properties.getDatasource();
dataSourceDecipher = dataSourceDecipherProvider.getIfAvailable();
} }
@Bean @Bean
@ -60,6 +72,9 @@ public class MultiDataSourceAutoConfiguration {
FlexDataSource flexDataSource = null; FlexDataSource flexDataSource = null;
if (dataSourceProperties != null && !dataSourceProperties.isEmpty()) { if (dataSourceProperties != null && !dataSourceProperties.isEmpty()) {
DataSourceManager.setDecipher(dataSourceDecipher);
for (Map.Entry<String, Map<String, String>> entry : dataSourceProperties.entrySet()) { for (Map.Entry<String, Map<String, String>> entry : dataSourceProperties.entrySet()) {
DataSource dataSource = new DataSourceBuilder(entry.getValue()).build(); DataSource dataSource = new DataSourceBuilder(entry.getValue()).build();
if (flexDataSource == null) { if (flexDataSource == null) {

View File

@ -18,7 +18,6 @@ package com.mybatisflex.spring.boot;
import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.datasource.DataSourceDecipher; import com.mybatisflex.core.datasource.DataSourceDecipher;
import com.mybatisflex.core.datasource.DataSourceManager; import com.mybatisflex.core.datasource.DataSourceManager;
import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.core.logicdelete.LogicDeleteManager; import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import com.mybatisflex.core.logicdelete.LogicDeleteProcessor; import com.mybatisflex.core.logicdelete.LogicDeleteProcessor;
import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexConfiguration;
@ -71,7 +70,6 @@ import org.springframework.util.StringUtils;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -228,13 +226,6 @@ public class MybatisFlexAutoConfiguration implements InitializingBean {
@ConditionalOnMissingBean @ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
if (dataSource instanceof FlexDataSource && DataSourceManager.getDecipher() != null) {
Map<String, DataSource> dataSourceMap = ((FlexDataSource) dataSource).getDataSourceMap();
for (DataSource ds : dataSourceMap.values()) {
DataSourceManager.decryptDataSource(ds);
}
}
SqlSessionFactoryBean factory = new FlexSqlSessionFactoryBean(); SqlSessionFactoryBean factory = new FlexSqlSessionFactoryBean();
factory.setDataSource(dataSource); factory.setDataSource(dataSource);
if (properties.getConfiguration() == null || properties.getConfiguration().getVfsImpl() == null) { if (properties.getConfiguration() == null || properties.getConfiguration().getVfsImpl() == null) {

View File

@ -25,6 +25,7 @@ import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.DbChain; import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.update.UpdateWrapper; import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.core.util.UpdateEntity; import com.mybatisflex.core.util.UpdateEntity;
import com.mybatisflex.mapper.ArticleMapper;
import org.apache.ibatis.logging.stdout.StdOutImpl; import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
@ -35,11 +36,13 @@ import javax.sql.DataSource;
import java.util.List; import java.util.List;
import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT; import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT;
import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE;
public class AccountTester { public class AccountTester {
static AccountMapper accountMapper; static AccountMapper accountMapper;
static ArticleMapper articleMapper;
@BeforeClass @BeforeClass
public static void init() { public static void init() {
@ -53,6 +56,7 @@ public class AccountTester {
.setDataSource(dataSource) .setDataSource(dataSource)
.setLogImpl(StdOutImpl.class) .setLogImpl(StdOutImpl.class)
.addMapper(AccountMapper.class) .addMapper(AccountMapper.class)
.addMapper(ArticleMapper.class)
.start(); .start();
//开启审计功能 //开启审计功能
@ -64,6 +68,7 @@ public class AccountTester {
accountMapper = bootstrap.getMapper(AccountMapper.class); accountMapper = bootstrap.getMapper(AccountMapper.class);
articleMapper = bootstrap.getMapper(ArticleMapper.class);
} }
@Test @Test
@ -101,6 +106,16 @@ public class AccountTester {
System.out.println(accounts); 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<Article> accounts = articleMapper.selectListByQuery(queryWrapper);
System.out.println(accounts);
}
@Test @Test
public void testSelectAsToDTO() { public void testSelectAsToDTO() {

View File

@ -2,6 +2,7 @@ package com.mybatisflex.test;
import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.core.table.TableManager;
import com.mybatisflex.core.update.UpdateChain; import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.mapper.ArticleMapper; import com.mybatisflex.mapper.ArticleMapper;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
@ -12,16 +13,25 @@ public class MainSqlTest {
public static void main(String[] args) { public static void main(String[] args) {
Environment environment = new Environment("test", new JdbcTransactionFactory(), new HikariDataSource());
FlexConfiguration configuration = new FlexConfiguration(environment);
FlexGlobalConfig globalConfig = FlexGlobalConfig.getDefaultConfig(); FlexGlobalConfig globalConfig = FlexGlobalConfig.getDefaultConfig();
Environment environment = new Environment("test", new JdbcTransactionFactory(), new HikariDataSource());
FlexConfiguration configuration = new FlexConfiguration(environment);
globalConfig.setConfiguration(configuration); globalConfig.setConfiguration(configuration);
FlexGlobalConfig.setConfig("test", globalConfig, true); FlexGlobalConfig.setConfig("test", globalConfig, true);
configuration.addMapper(ArticleMapper.class); configuration.addMapper(ArticleMapper.class);
// ArticleMapper mapper = (ArticleMapper) Proxy.newProxyInstance(MainSqlTest.class.getClassLoader(), // ArticleMapper mapper = (ArticleMapper) Proxy.newProxyInstance(MainSqlTest.class.getClassLoader(),
// new Class[]{ArticleMapper.class}, new InvocationHandler() { // new Class[]{ArticleMapper.class}, new InvocationHandler() {
// @Override // @Override
@ -38,6 +48,9 @@ public class MainSqlTest {
// System.out.println(sql1); // System.out.println(sql1);
TableManager.setHintTableMapping("tb_article","tb_article1");
String sql2 = UpdateChain.of(Article.class) String sql2 = UpdateChain.of(Article.class)
.set("xxxx", "xxxx") .set("xxxx", "xxxx")
.where(Article::getId).ge(100) .where(Article::getId).ge(100)

View File

@ -13,7 +13,7 @@
> MyBatis-Flex 支持 CRUD、分页查询、多表查询、批量操作但不丢失 MyBatis 原有的任何功能。 > MyBatis-Flex 支持 CRUD、分页查询、多表查询、批量操作但不丢失 MyBatis 原有的任何功能。
#### 3、高性能 #### 3、高性能
> MyBatis-Flex 采用独特的技术架构、相比同类框架MyBatis-Flex 的在增删改查等方面的性能均超越其 5~10 倍或以上。 > MyBatis-Flex 采用独特的技术架构、相比许多同类框架MyBatis-Flex 的在增删改查等方面的性能均超越其 5~10 倍或以上。
#### 4、更灵动 #### 4、更灵动
> MyBatis-Flex 支持多主键、多表查询、逻辑删除、乐观锁、数据脱敏、数据加密、多数据源、分库分表、字段权限、 > MyBatis-Flex 支持多主键、多表查询、逻辑删除、乐观锁、数据脱敏、数据加密、多数据源、分库分表、字段权限、