mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-06 16:48:24 +08:00
Merge remote-tracking branch 'origin/main'
# Conflicts: # docs/zh/intro/gradle.md # docs/zh/others/kapt.md
This commit is contained in:
commit
9483ab9dfb
28
changes.md
28
changes.md
@ -1,6 +1,34 @@
|
||||
# MyBatis-Flex ChangeLog
|
||||
|
||||
|
||||
## v1.5.7 20230812:
|
||||
- 新增:QueryWrapper 添加对 delete 和 update 的 left join 支持
|
||||
- 新增:RelationManager.addIgnoreRelations() 添加对 lambda 的支持
|
||||
- 新增:添加 QueryColumnBehavior 用于自定义 QueryColumn 的某些行为特征
|
||||
- 新增:typeHandler 添加对泛型自动支持的功能
|
||||
- 新增:多数据源新增对 Seata 分布式事务的支持,感谢 @lifejwang11
|
||||
- 新增:添加对 Kotlin 的扩展支持,感谢 @kamo-sama
|
||||
- 新增:添加 saveOrUpdateBatch 方法的支持,感谢 @Suomm
|
||||
- 新增:QueryModel 提供 as 方法的支持,感谢 @Suomm
|
||||
- 新增:逻辑删除、乐观锁、多租户添加全局默认自动配置的功能,感谢 @Suomm
|
||||
- 优化:移除 flex 自动把 id 属性设置为主键的功能
|
||||
- 优化:重构链式调用的方法,统一链式调用和 ActiveRecord 的 API,感谢 @Suomm
|
||||
- 优化:UpdateChian 支持设置 left join 的表数据的支持,感谢 @Suomm
|
||||
- 修复:db2 方言的 KeywordWrap 错误的问题
|
||||
- 修复:在某些场景下 count 查询没有被替换的问题,感谢 @Suomm
|
||||
- 修复:QueryWrapper 的 or(consumer, condition) 方法逻辑错误,感谢 @Suomm
|
||||
- 修复:QueryColumn 由于 Predicate 没有类型约束可能导致类型转换异常的问题,感谢 @Suomm
|
||||
- 修复:OSGI 环境下,Lambda 通过 ClassLoader 获取不到类的问题,感谢 @2han9wen71an
|
||||
- 文档:更新视频教程的文档链接
|
||||
- 文档:添加 SpringBoot 最低版本的说明文档,感谢 @Suomm
|
||||
- 文档:Seata 分布式事务的相关文档,感谢 @lifejwang11
|
||||
- 文档:增加了使用gradle构建时的文档说明,感谢 @CloudPlayer
|
||||
- 文档:增加了在Kotlin中使用注解处理器的说明,感谢 @CloudPlayer
|
||||
- 文档:常见问题添加代码生成器获取不到注释说明,感谢 @Suomm
|
||||
- 文档:常见问题添加 Spring Devtools 造成的类转换异常的相关文档
|
||||
- 文档:常见问题添加 Nacos 集成启动出错的相关文档
|
||||
|
||||
|
||||
|
||||
## v1.5.6 20230804:
|
||||
- 新增:代码生成器重构并新增对 Solon 框架的代码生成功能,感谢 @Suomm
|
||||
|
||||
@ -46,6 +46,7 @@ export default defineConfig({
|
||||
{text: 'MyBatis-Flex 是什么', link: '/zh/intro/what-is-mybatisflex'},
|
||||
{text: '快速开始', link: '/zh/intro/getting-started'},
|
||||
{text: 'Maven 依赖', link: '/zh/intro/maven'},
|
||||
{text: 'Gradle 依赖', link: '/zh/intro/gradle'},
|
||||
{text: '和同类框架「功能」对比', link: '/zh/intro/comparison'},
|
||||
{text: '和同类框架「性能」对比', link: '/zh/intro/benchmark'},
|
||||
{text: '使用 Mybatis 原生功能', link: '/zh/intro/use-mybatis-native'},
|
||||
@ -100,6 +101,7 @@ export default defineConfig({
|
||||
items: [
|
||||
{text: '代码生成器', link: '/zh/others/codegen'},
|
||||
{text: 'APT 设置', link: '/zh/others/apt'},
|
||||
{text: 'KAPT 设置', link: '/zh/others/kapt'},
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@ -115,7 +115,7 @@ const {Layout} = DefaultTheme
|
||||
<a href="https://gitee.com/sdyunze/iotlink" target="_blank"><img src="/assets/images/ad/iotlink_20240802.png"></a>
|
||||
</div>
|
||||
<div class="banner">
|
||||
虚以待位
|
||||
<a href="https://eiam.topiam.cn" target="_blank"><img src="/assets/images/ad/topiam_20230909.png" style="width: 105px;height: 50px"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="banner-bottom">
|
||||
|
||||
BIN
docs/assets/images/ad/topiam_20230909.png
Normal file
BIN
docs/assets/images/ad/topiam_20230909.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@ -20,7 +20,7 @@ features:
|
||||
- title: 更轻量
|
||||
details: MyBatis-Flex 除了 MyBatis 本身,再无任何第三方依赖,因此会带来更高的自主性、把控性和稳定性。在任何一个系统中,依赖越多,稳定性越差。
|
||||
- title: 更灵活
|
||||
details: MyBatis-Flex 提供了非常灵活的 QueryWrapper,支持关联查询、多表查询、多主键、逻辑删除、乐观锁更新、数据填充、数据脱敏、等等....
|
||||
details: MyBatis-Flex 提供了非常灵活的 QueryWrapper,支持关联查询、多表查询、多主键、逻辑删除、乐观锁更新、数据填充、数据脱敏等等。
|
||||
- title: 更高的性能
|
||||
details: MyBatis-Flex 通过独特的架构,没有任何 MyBatis 拦截器、在 SQL 执行的过程中,没有任何的 SQL Parse,因此会带来指数级的性能增长。
|
||||
---
|
||||
|
||||
@ -87,6 +87,10 @@
|
||||
- [MyBatis-Flex 视频教程 - 33 关联查询(Field Query)](https://www.bilibili.com/video/BV17k4y1g7vt)
|
||||
- [MyBatis-Flex 视频教程 - 34 关联查询(Relation Query)](https://www.bilibili.com/video/BV1bj411r7A4)
|
||||
- [MyBatis-Flex 视频教程 - 35 关联查询对比](https://www.bilibili.com/video/BV1oF411f7dr)
|
||||
- [MyBatis-Flex 视频教程 - 36 分页查询](https://www.bilibili.com/video/BV1d44y1F7JM)
|
||||
- [MyBatis-Flex 视频教程 - 37 分页查询 count 查询优化](https://www.bilibili.com/video/BV1np4y1G7R9)
|
||||
- [MyBatis-Flex 视频教程 - 38 基于 XML 文件的高性能分页](https://www.bilibili.com/video/BV1Zh4y1D7aj)
|
||||
- [MyBatis-Flex 视频教程 - 39 Db + Row](https://www.bilibili.com/video/BV1wp4y1g7by)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -8,13 +8,15 @@ SpringBoot 配置文件(`application.yml` 等)主要是用于对 MyBatis 原
|
||||
mybatis-flex:
|
||||
#......
|
||||
datasource:
|
||||
#......
|
||||
#......
|
||||
configuration:
|
||||
#......
|
||||
#......
|
||||
global-config:
|
||||
#......
|
||||
#......
|
||||
admin-config:
|
||||
#......
|
||||
#......
|
||||
seata-config:
|
||||
#......
|
||||
```
|
||||
|
||||
## mybatis-flex
|
||||
@ -129,7 +131,28 @@ TypeHandler 扫描路径,如果配置了该属性,SqlSessionFactoryBean 会
|
||||
- 类型:`java.lang.Object`
|
||||
- 默认值:`1`
|
||||
|
||||
逻辑删除数据删除标记值,
|
||||
逻辑删除数据删除标记值。
|
||||
|
||||
### logic-delete-column
|
||||
|
||||
- 类型:`java.lang.String`
|
||||
- 默认值:`del_flag`
|
||||
|
||||
默认的逻辑删除字段。
|
||||
|
||||
### tenant-column
|
||||
|
||||
- 类型:`java.lang.String`
|
||||
- 默认值:`tenant_id`
|
||||
|
||||
默认的多租户字段。
|
||||
|
||||
### version-column
|
||||
|
||||
- 类型:`java.lang.String`
|
||||
- 默认值:`version`
|
||||
|
||||
默认的乐观锁字段。
|
||||
|
||||
## admin-config
|
||||
|
||||
@ -152,4 +175,20 @@ MyBatis-Flex-Admin 连接端点。
|
||||
- 类型:`String`
|
||||
- 默认值:`null`
|
||||
|
||||
MyBatis-Flex-Admin 连接密钥。
|
||||
MyBatis-Flex-Admin 连接密钥。
|
||||
|
||||
## seata-config
|
||||
|
||||
### enable
|
||||
|
||||
- 类型:`boolean`
|
||||
- 默认值:`false`
|
||||
|
||||
是否启用 Seata 代理数据源。
|
||||
|
||||
### seata-mode
|
||||
|
||||
- 类型:`com.mybatisflex.spring.boot.MybatisFlexProperties.SeataMode`
|
||||
- 默认值:`AT`
|
||||
|
||||
使用 Seata AT 模式代理数据源。
|
||||
|
||||
@ -1017,7 +1017,7 @@ QueryWrapper query2 = QueryWrapper.create()
|
||||
在以上的 `query1` 中,由于 `userName` 和 `id` 都为 null,MyBatis-Flex 会自动忽略 null 值的条件,因此,它们构建出来的 SQL 条件是和 `query2` 完全一致的 。
|
||||
|
||||
|
||||
## QueryColumnBehavior <Badge type="tip" text="^ v1.5.6" />
|
||||
## QueryColumnBehavior <Badge type="tip" text="^ v1.5.7" />
|
||||
|
||||
在以上的内容中,我们知道 MyBatis-Flex 会自动忽略 `null` 值的条件,但是在实际开发中,有的开发者希望除了自动忽略 `null`
|
||||
值以外,还可以自动忽略其他值,比如 `空字符串` 等。
|
||||
|
||||
@ -1,6 +1,34 @@
|
||||
# MyBatis-Flex ChangeLog
|
||||
|
||||
|
||||
## v1.5.7 20230812:
|
||||
- 新增:QueryWrapper 添加对 delete 和 update 的 left join 支持
|
||||
- 新增:RelationManager.addIgnoreRelations() 添加对 lambda 的支持
|
||||
- 新增:添加 QueryColumnBehavior 用于自定义 QueryColumn 的某些行为特征
|
||||
- 新增:typeHandler 添加对泛型自动支持的功能
|
||||
- 新增:多数据源新增对 Seata 分布式事务的支持,感谢 @lifejwang11
|
||||
- 新增:添加对 Kotlin 的扩展支持,感谢 @kamo-sama
|
||||
- 新增:添加 saveOrUpdateBatch 方法的支持,感谢 @Suomm
|
||||
- 新增:QueryModel 提供 as 方法的支持,感谢 @Suomm
|
||||
- 新增:逻辑删除、乐观锁、多租户添加全局默认自动配置的功能,感谢 @Suomm
|
||||
- 优化:移除 flex 自动把 id 属性设置为主键的功能
|
||||
- 优化:重构链式调用的方法,统一链式调用和 ActiveRecord 的 API,感谢 @Suomm
|
||||
- 优化:UpdateChian 支持设置 left join 的表数据的支持,感谢 @Suomm
|
||||
- 修复:db2 方言的 KeywordWrap 错误的问题
|
||||
- 修复:在某些场景下 count 查询没有被替换的问题,感谢 @Suomm
|
||||
- 修复:QueryWrapper 的 or(consumer, condition) 方法逻辑错误,感谢 @Suomm
|
||||
- 修复:QueryColumn 由于 Predicate 没有类型约束可能导致类型转换异常的问题,感谢 @Suomm
|
||||
- 修复:OSGI 环境下,Lambda 通过 ClassLoader 获取不到类的问题,感谢 @2han9wen71an
|
||||
- 文档:更新视频教程的文档链接
|
||||
- 文档:添加 SpringBoot 最低版本的说明文档,感谢 @Suomm
|
||||
- 文档:Seata 分布式事务的相关文档,感谢 @lifejwang11
|
||||
- 文档:增加了使用gradle构建时的文档说明,感谢 @CloudPlayer
|
||||
- 文档:增加了在Kotlin中使用注解处理器的说明,感谢 @CloudPlayer
|
||||
- 文档:常见问题添加代码生成器获取不到注释说明,感谢 @Suomm
|
||||
- 文档:常见问题添加 Spring Devtools 造成的类转换异常的相关文档
|
||||
- 文档:常见问题添加 Nacos 集成启动出错的相关文档
|
||||
|
||||
|
||||
|
||||
## v1.5.6 20230804:
|
||||
- 新增:代码生成器重构并新增对 Solon 框架的代码生成功能,感谢 @Suomm
|
||||
|
||||
@ -224,8 +224,14 @@ public void purchase(String userId, String commodityCode, int orderCount) {
|
||||
> 的官方示例快速开始:https://seata.io/zh-cn/docs/user/quickstart.html
|
||||
|
||||
### 注意事项
|
||||
1.使用`seata-spring-boot-starter`的时候请关闭自动代理
|
||||
```yaml
|
||||
seata:
|
||||
enable-auto-data-source-proxy: false
|
||||
```
|
||||
2.使用 `seata-all` 请不要使用 `@EnableAutoDataSourceProxy`
|
||||
|
||||
在使用 Seata 分布式事务时,请注意添加 Seata 的相关 Maven 依赖,例如:
|
||||
3.如果是 SpringBoot 项目需要引入相关 Maven 依赖,例如:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
@ -234,3 +240,7 @@ public void purchase(String userId, String commodityCode, int orderCount) {
|
||||
<version>1.7.0</version>
|
||||
</dependency>
|
||||
```
|
||||
### 示例
|
||||
|
||||
[mybatis-flex-spring-boot-seata-demo](https://gitee.com/mybatis-flex/mybatis-flex-samples/tree/master/mybatis-flex-spring-boot-seata-demo) : Seata 官方 demo 与 flex 结合。
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
# 常见问题
|
||||
|
||||
[[toc]]
|
||||
|
||||
## MyBatis-Flex 没有启动或者启动出错怎么办?
|
||||
|
||||
正常情况下,MyBatis-Flex 在启动时,会在控制台打印如下 Banner 信息,包含版本与官方网址,如果在项目启动中没有发现 MyBatis-Flex 的 Banner 打印,那就说明 MyBatis-Flex 没有被正常加载。
|
||||
@ -21,6 +23,7 @@
|
||||
就可以了,不需要再添加其他 MyBatis 依赖。
|
||||
- 3、是否与 `mybatis-plus-boot-starter` 共用,使 MyBatis 被优先初始化,而导致 MyBatis-Flex 没有被加载。
|
||||
- 4、是否添加了 `pagehelper-spring-boot-starter` 依赖,导致传递了 `mybatis-spring-boot-starter` 依赖。如还想继续使用 pagehelper 插件,点击 [这里](#与-pagehelper-集成出现错误) 查看解决方案。
|
||||
- 5、是否 Spring Boot 版本过低,请使用 Spring Boot 2.2 及其以上版本,点击 [这里](#springboot-项目-启动报错-java-lang-classnotfoundexception-org-springframework-transaction-transactionmanager) 获取详细信息。
|
||||
|
||||
## 示例中的 AccountMapper 和 "ACCOUNT" 在哪里,报错了。
|
||||
|
||||
@ -62,6 +65,11 @@ in alimaven (http://maven.aliyun.com/nexus/content/groups/public/)
|
||||
</mirror>
|
||||
```
|
||||
|
||||
## SpringBoot 项目,启动报错 java.lang.ClassNotFoundException: org.springframework.transaction.TransactionManager
|
||||
|
||||
这个应该是 Spring Boot 版本的问题,`org.springframework.transaction.TransactionManager` 这个类是 Spring Framework 5.2
|
||||
新增的,对应 Spring Boot 的版本应该是 Spring Boot 2.2 及其以上版本,所以应该使用 Spring Boot 2.2 及其以上版本。
|
||||
|
||||
## SpringBoot 项目,启动报错 Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
|
||||
|
||||
如果当前依赖没有连接池相关依赖,则建议添加 HikariCP 依赖。
|
||||
@ -88,6 +96,18 @@ SpringBoot v3.x 添加 hikariCP 的内容如下:
|
||||
|
||||
> 如果使用的是 druid 数据库连接池,则需要添加数据源类型的配置 `spring.datasource.type=com.alibaba.druid.pool.DruidDataSource`。
|
||||
|
||||
## SpringBoot 项目中出现 class "com.xxx" cannot be cast class "com.xxx" 的错误
|
||||
这个问题是由于 Spring 的 devtools 热加载引起的,可以在项目的 `resources/META-INF`
|
||||
目录下创建一个名为 `spring-devtools.properties` 的配置文件,配置内容如下:
|
||||
|
||||
```properties
|
||||
restart.include.mapper=/mapper-[\\w-\\.].jar
|
||||
restart.include.pagehelper=/pagehelper-[\\w-\\.].jar
|
||||
restart.include.mybatis-flex=/mybatis-flex-[\\w-\\.]+jar
|
||||
```
|
||||
相关文档参考 Spring 的官方网站:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using.devtools.restart.customizing-the-classload
|
||||
|
||||
|
||||
## java.sql.SQLException: No value specified for parameter x
|
||||
出现这个问题,原因是 MyBatis-Flex 未能正常启动,SQL 执行没有经过 MyBatis-Flex 导致的。其直接是因为和其他第三方增强框架整合使用了,
|
||||
比如和 MyBatis-Plus、或者 PageHelper 等整合造成的。
|
||||
@ -161,13 +181,29 @@ spring:
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
<version>版本号</version>
|
||||
<version>5.3.3</version>
|
||||
</dependency>
|
||||
```
|
||||
解决方案:https://gitee.com/mybatis-flex/mybatis-flex/issues/I71AUE
|
||||
|
||||
|
||||
## 代码生成器获取不到注释
|
||||
|
||||
如果是 MySQL 数据库的话,可能是因为数据库版本太低,解决办法:MySQL 5.* 需要在 jdbcUrl 设置参数 `useInformationSchema=true` 才能获取到注释。
|
||||
|
||||
例如:`jdbc:mysql://127.0.0.1:3306/mybatis-flex?characterEncoding=UTF-8&useInformationSchema=true`
|
||||
|
||||
## 与 Nacos 集成时出错,无法正常启动 MyBatis-Flex
|
||||
|
||||
一般请看下是缺少 Nacos 的相关 Maven,注意添加如下的 Nacos 依赖:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
<version>2022.0.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## 如何自定义 MyBatis 的 Configuration?
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ VALUES (1, '张三', 18, '2020-01-11'),
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
|
||||
@ -12,12 +12,12 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@ -28,12 +28,12 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
``````
|
||||
@ -44,12 +44,12 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@ -60,7 +60,7 @@
|
||||
|
||||
参考:[APT 设置-和 Lombok、Mapstruct 整合](../others/apt.md)
|
||||
|
||||
> 在Kotlin中使用时,请参考[在Kotlin中使用注解处理器](../kotlin/kapt.md)
|
||||
> 在Kotlin中使用时,请参考[在Kotlin中使用注解处理器](../others/kapt.md)
|
||||
|
||||
```xml
|
||||
<plugin>
|
||||
@ -72,7 +72,7 @@
|
||||
<path>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
|
||||
@ -220,7 +220,7 @@ pom.xml 添加 `annotationProcessorPaths` 配置,
|
||||
```
|
||||
dependencies {
|
||||
...
|
||||
annotationProcessor 'com.mybatis-flex:mybatis-flex-processor:<version>1.5.6</version>'
|
||||
annotationProcessor 'com.mybatis-flex:mybatis-flex-processor:<version>1.5.7</version>'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-codegen</artifactId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -87,6 +87,30 @@ public class #(table.buildServiceImplClassName()) extends #(serviceImplConfig.bu
|
||||
return super.getOneAs(query, asType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
|
||||
public Object getObj(QueryWrapper query) {
|
||||
return super.getObj(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
|
||||
public <R> R getObjAs(QueryWrapper query, Class<R> asType) {
|
||||
return super.getObjAs(query, asType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
|
||||
public List<Object> objList(QueryWrapper query) {
|
||||
return super.objList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
|
||||
public <R> List<R> objListAs(QueryWrapper query, Class<R> asType) {
|
||||
return super.objListAs(query, asType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(key = "#root.methodName + ':' + #query.toSQL()")
|
||||
public List<#(entityClassName)> list(QueryWrapper query) {
|
||||
|
||||
@ -23,7 +23,6 @@ import com.mybatisflex.codegen.config.TableConfig;
|
||||
import com.mybatisflex.codegen.config.TableDefConfig;
|
||||
import com.mybatisflex.codegen.constant.TemplateConst;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
@ -150,7 +149,7 @@ public class GeneratorTest {
|
||||
generator.generate();
|
||||
}
|
||||
|
||||
@Test
|
||||
// @Test
|
||||
public void testCodeGen3() {
|
||||
//配置数据源
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
@ -226,7 +225,7 @@ public class GeneratorTest {
|
||||
return globalConfig;
|
||||
}
|
||||
|
||||
@Test
|
||||
// @Test
|
||||
public void testCodeGen4() {
|
||||
// 配置数据源
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -17,6 +17,9 @@ package com.mybatisflex.core;
|
||||
|
||||
/**
|
||||
* Mybatis-Flex 可能用到的静态常量
|
||||
*
|
||||
* @author michael
|
||||
* @author 王帅
|
||||
*/
|
||||
public class FlexConsts {
|
||||
|
||||
@ -24,9 +27,8 @@ public class FlexConsts {
|
||||
}
|
||||
|
||||
public static final String NAME = "MyBatis-Flex";
|
||||
public static final String VERSION = "1.5.6";
|
||||
public static final String VERSION = "1.5.7";
|
||||
|
||||
public static final String DEFAULT_PRIMARY_FIELD = "id";
|
||||
|
||||
public static final String SQL = "$$sql";
|
||||
public static final String SQL_ARGS = "$$sql_args";
|
||||
|
||||
@ -88,6 +88,21 @@ public class FlexGlobalConfig {
|
||||
*/
|
||||
private int defaultRelationQueryDepth = 2;
|
||||
|
||||
/**
|
||||
* 默认的逻辑删除字段,允许设置 {@code null} 忽略匹配。
|
||||
*/
|
||||
private String logicDeleteColumn = "del_flag";
|
||||
|
||||
/**
|
||||
* 默认的多租户字段,允许设置 {@code null} 忽略匹配。
|
||||
*/
|
||||
private String tenantColumn = "tenant_id";
|
||||
|
||||
/**
|
||||
* 默认的乐观锁字段,允许设置 {@code null} 忽略匹配。
|
||||
*/
|
||||
private String versionColumn = "version";
|
||||
|
||||
public boolean isPrintBanner() {
|
||||
return printBanner;
|
||||
}
|
||||
@ -337,6 +352,30 @@ public class FlexGlobalConfig {
|
||||
this.defaultRelationQueryDepth = defaultRelationQueryDepth;
|
||||
}
|
||||
|
||||
public String getLogicDeleteColumn() {
|
||||
return logicDeleteColumn;
|
||||
}
|
||||
|
||||
public void setLogicDeleteColumn(String logicDeleteColumn) {
|
||||
this.logicDeleteColumn = logicDeleteColumn;
|
||||
}
|
||||
|
||||
public String getTenantColumn() {
|
||||
return tenantColumn;
|
||||
}
|
||||
|
||||
public void setTenantColumn(String tenantColumn) {
|
||||
this.tenantColumn = tenantColumn;
|
||||
}
|
||||
|
||||
public String getVersionColumn() {
|
||||
return versionColumn;
|
||||
}
|
||||
|
||||
public void setVersionColumn(String versionColumn) {
|
||||
this.versionColumn = versionColumn;
|
||||
}
|
||||
|
||||
public FlexDataSource getDataSource() {
|
||||
return (FlexDataSource) getConfiguration().getEnvironment().getDataSource();
|
||||
}
|
||||
|
||||
@ -44,11 +44,20 @@ public abstract class QueryModel<T extends QueryModel<T>> {
|
||||
|
||||
protected QueryWrapper queryWrapper() {
|
||||
if (queryWrapper == null) {
|
||||
queryWrapper = QueryWrapper.create();
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(getClass());
|
||||
QueryTable queryTable = new QueryTable();
|
||||
queryTable.setSchema(tableInfo.getSchema());
|
||||
queryTable.setName(tableInfo.getTableName());
|
||||
queryWrapper = QueryWrapper.create().from(queryTable);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public T as(String alias) {
|
||||
queryWrapper().as(alias);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public T select() {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import com.mybatisflex.core.util.LambdaGetter;
|
||||
import com.mybatisflex.core.util.LambdaUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@ -49,7 +50,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R eq(Object value, Predicate<T> when) {
|
||||
public <T> R eq(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.eq(value, when), connector);
|
||||
}
|
||||
@ -60,8 +61,15 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return eq(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R eq(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return eq(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.eq(LambdaUtil.getQueryColumn(value)).when(when), connector);
|
||||
}
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public R ne(Object value) {
|
||||
@ -71,7 +79,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R ne(Object value, Predicate<T> when) {
|
||||
public <T> R ne(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.ne(value, when), connector);
|
||||
}
|
||||
@ -82,8 +90,15 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return ne(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R ne(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return ne(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.ne(LambdaUtil.getQueryColumn(value)).when(when), connector);
|
||||
}
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public R like(Object value) {
|
||||
@ -93,7 +108,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R like(Object value, Predicate<T> when) {
|
||||
public <T> R like(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.like(value, when), connector);
|
||||
}
|
||||
@ -107,7 +122,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R likeLeft(Object value, Predicate<T> when) {
|
||||
public <T> R likeLeft(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.likeLeft(value, when), connector);
|
||||
}
|
||||
@ -121,7 +136,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R likeRight(Object value, Predicate<T> when) {
|
||||
public <T> R likeRight(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.likeRight(value, when), connector);
|
||||
}
|
||||
@ -135,7 +150,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R gt(Object value, Predicate<T> when) {
|
||||
public <T> R gt(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.gt(value, when), connector);
|
||||
}
|
||||
@ -146,8 +161,15 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return gt(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R gt(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return gt(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.gt(LambdaUtil.getQueryColumn(value)).when(when), connector);
|
||||
}
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public R ge(Object value) {
|
||||
@ -157,7 +179,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R ge(Object value, Predicate<T> when) {
|
||||
public <T> R ge(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.ge(value, when), connector);
|
||||
}
|
||||
@ -168,8 +190,15 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return ge(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R ge(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return ge(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.ge(LambdaUtil.getQueryColumn(value)).when(when), connector);
|
||||
}
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public R lt(Object value) {
|
||||
@ -179,7 +208,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R lt(Object value, Predicate<T> when) {
|
||||
public <T> R lt(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.lt(value, when), connector);
|
||||
}
|
||||
@ -190,8 +219,15 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return lt(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R lt(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return lt(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.lt(LambdaUtil.getQueryColumn(value)).when(when), connector);
|
||||
}
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public R le(Object value) {
|
||||
@ -201,7 +237,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R le(Object value, Predicate<T> when) {
|
||||
public <T> R le(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.le(value, when), connector);
|
||||
}
|
||||
@ -212,8 +248,15 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return le(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R le(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return le(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.le(LambdaUtil.getQueryColumn(value)).when(when), connector);
|
||||
}
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public R isNull() {
|
||||
@ -221,6 +264,10 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R isNull(Predicate<T> when) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.isNull(when), connector);
|
||||
return queryModel;
|
||||
@ -231,6 +278,10 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R isNotNull(Predicate<T> when) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.isNotNull(when), connector);
|
||||
return queryModel;
|
||||
@ -243,7 +294,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R in(Object[] arrays, Predicate<T> when) {
|
||||
public <T> R in(T[] arrays, Predicate<T[]> when) {
|
||||
//忽略 QueryWrapper.in("name", null) 的情况
|
||||
if (arrays != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.in(arrays, when), connector);
|
||||
@ -258,6 +309,10 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return this.queryModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R in(R queryModel, Predicate<T> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.in(queryModel, when), connector);
|
||||
@ -272,7 +327,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R in(Collection<?> collection, Predicate<T> when) {
|
||||
public <T extends Collection<?>> R in(T collection, Predicate<T> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.in(collection, when), connector);
|
||||
}
|
||||
@ -286,7 +341,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R notIn(Object[] arrays, Predicate<T> when) {
|
||||
public <T> R notIn(T[] arrays, Predicate<T[]> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.notIn(arrays, when), connector);
|
||||
}
|
||||
@ -300,7 +355,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R notIn(Collection<?> collection, Predicate<T> when) {
|
||||
public <T extends Collection<?>> R notIn(T collection, Predicate<T> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.notIn(collection, when), connector);
|
||||
}
|
||||
@ -314,6 +369,10 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return this.queryModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> R notIn(R queryModel, Predicate<T> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.notIn(queryModel, when), connector);
|
||||
@ -328,7 +387,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R between(Object start, Object end, Predicate<T> when) {
|
||||
public <S, E> R between(S start, E end, BiPredicate<S, E> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.between(start, end, when), connector);
|
||||
}
|
||||
@ -342,7 +401,7 @@ public class WhereBuilder<R extends QueryModel<R>> {
|
||||
return queryModel;
|
||||
}
|
||||
|
||||
public <T> R notBetween(Object start, Object end, Predicate<T> when) {
|
||||
public <S, E> R notBetween(S start, E end, BiPredicate<S, E> when) {
|
||||
if (queryModel != null) {
|
||||
CPI.addWhereQueryCondition(queryModel.queryWrapper(), queryColumn.notBetween(start, end, when), connector);
|
||||
}
|
||||
|
||||
@ -103,12 +103,13 @@ public class DialectFactory {
|
||||
case GBASE:
|
||||
case OSCAR:
|
||||
case XUGU:
|
||||
case CLICK_HOUSE:
|
||||
case OCEAN_BASE:
|
||||
case CUBRID:
|
||||
case GOLDILOCKS:
|
||||
case CSIIDB:
|
||||
return new CommonsDialectImpl(KeywordWrap.BACK_QUOTE, LimitOffsetProcessor.MYSQL);
|
||||
case CLICK_HOUSE:
|
||||
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.MYSQL);
|
||||
case DM:
|
||||
return new DmDialect();
|
||||
case ORACLE:
|
||||
@ -134,13 +135,13 @@ public class DialectFactory {
|
||||
return new OracleDialect(LimitOffsetProcessor.DERBY);
|
||||
case FIREBIRD:
|
||||
case DB2:
|
||||
return new CommonsDialectImpl(KeywordWrap.DOUBLE_QUOTATION, LimitOffsetProcessor.DERBY);
|
||||
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.DERBY);
|
||||
case SQLSERVER:
|
||||
return new CommonsDialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER);
|
||||
case SQLSERVER_2005:
|
||||
return new CommonsDialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER_2005);
|
||||
case INFORMIX:
|
||||
return new CommonsDialectImpl(KeywordWrap.DOUBLE_QUOTATION, LimitOffsetProcessor.INFORMIX);
|
||||
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.INFORMIX);
|
||||
case SINODB:
|
||||
return new CommonsDialectImpl(KeywordWrap.DOUBLE_QUOTATION, LimitOffsetProcessor.SINODB);
|
||||
case SYBASE:
|
||||
|
||||
@ -242,7 +242,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
|
||||
@Override
|
||||
public String forUpdateByQuery(QueryWrapper queryWrapper, Row row) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
|
||||
Set<String> modifyAttrs = RowCPI.getModifyAttrs(row);
|
||||
Map<String, RawValue> rawValueMap = RowCPI.getRawValueMap(row);
|
||||
@ -254,30 +254,39 @@ public class CommonsDialectImpl implements IDialect {
|
||||
|
||||
//fix: support schema
|
||||
QueryTable queryTable = queryTables.get(0);
|
||||
sql.append(UPDATE).append(queryTable.toSql(this)).append(SET);
|
||||
sqlBuilder.append(UPDATE).append(queryTable.toSql(this)).append(SET);
|
||||
int index = 0;
|
||||
for (String modifyAttr : modifyAttrs) {
|
||||
if (index > 0) {
|
||||
sql.append(DELIMITER);
|
||||
sqlBuilder.append(DELIMITER);
|
||||
}
|
||||
|
||||
sql.append(wrap(modifyAttr));
|
||||
sqlBuilder.append(wrap(modifyAttr));
|
||||
|
||||
if (rawValueMap.containsKey(modifyAttr)) {
|
||||
sql.append(EQUALS).append(rawValueMap.get(modifyAttr).toSql(this));
|
||||
sqlBuilder.append(EQUALS).append(rawValueMap.get(modifyAttr).toSql(this));
|
||||
} else {
|
||||
sql.append(EQUALS_PLACEHOLDER);
|
||||
sqlBuilder.append(EQUALS_PLACEHOLDER);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
String whereConditionSql = buildWhereConditionSql(queryWrapper);
|
||||
if (StringUtil.isNotBlank(whereConditionSql)) {
|
||||
sql.append(WHERE).append(whereConditionSql);
|
||||
buildJoinSql(sqlBuilder, queryWrapper, queryTables);
|
||||
buildWhereSql(sqlBuilder, queryWrapper, queryTables, false);
|
||||
buildGroupBySql(sqlBuilder, queryWrapper, queryTables);
|
||||
buildHavingSql(sqlBuilder, queryWrapper, queryTables);
|
||||
|
||||
//ignore orderBy and limit
|
||||
buildOrderBySql(sqlBuilder, queryWrapper, queryTables);
|
||||
|
||||
Long limitRows = CPI.getLimitRows(queryWrapper);
|
||||
Long limitOffset = CPI.getLimitOffset(queryWrapper);
|
||||
if (limitRows != null || limitOffset != null) {
|
||||
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
|
||||
}
|
||||
|
||||
return sql.toString();
|
||||
return sqlBuilder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -473,8 +482,13 @@ public class CommonsDialectImpl implements IDialect {
|
||||
buildHavingSql(sqlBuilder, queryWrapper, allTables);
|
||||
|
||||
//ignore orderBy and limit
|
||||
//buildOrderBySql(sqlBuilder, queryWrapper)
|
||||
//buildLimitSql(sqlBuilder, queryWrapper)
|
||||
buildOrderBySql(sqlBuilder, queryWrapper, allTables);
|
||||
|
||||
Long limitRows = CPI.getLimitRows(queryWrapper);
|
||||
Long limitOffset = CPI.getLimitOffset(queryWrapper);
|
||||
if (limitRows != null || limitOffset != null) {
|
||||
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
|
||||
}
|
||||
|
||||
List<String> endFragments = CPI.getEndFragments(queryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(endFragments)) {
|
||||
@ -777,13 +791,19 @@ public class CommonsDialectImpl implements IDialect {
|
||||
|
||||
@Override
|
||||
public String forUpdateEntityByQuery(TableInfo tableInfo, Object entity, boolean ignoreNulls, QueryWrapper queryWrapper) {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
|
||||
Set<String> updateColumns = tableInfo.obtainUpdateColumns(entity, ignoreNulls, true);
|
||||
Map<String, RawValue> rawValueMap = tableInfo.obtainUpdateRawValueMap(entity);
|
||||
|
||||
sql.append(UPDATE).append(forHint(CPI.getHint(queryWrapper)));
|
||||
sql.append(tableInfo.getWrapSchemaAndTableName(this)).append(SET);
|
||||
sqlBuilder.append(UPDATE).append(forHint(CPI.getHint(queryWrapper)));
|
||||
sqlBuilder.append(tableInfo.getWrapSchemaAndTableName(this));
|
||||
|
||||
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
|
||||
buildJoinSql(sqlBuilder, queryWrapper, queryTables);
|
||||
|
||||
|
||||
sqlBuilder.append(SET);
|
||||
|
||||
StringJoiner stringJoiner = new StringJoiner(DELIMITER);
|
||||
|
||||
@ -807,26 +827,40 @@ public class CommonsDialectImpl implements IDialect {
|
||||
stringJoiner.add(wrap(versionColumn) + EQUALS + wrap(versionColumn) + " + 1 ");
|
||||
}
|
||||
|
||||
sql.append(stringJoiner);
|
||||
sqlBuilder.append(stringJoiner);
|
||||
|
||||
|
||||
String whereConditionSql = buildWhereConditionSql(queryWrapper);
|
||||
buildWhereSql(sqlBuilder, queryWrapper, queryTables, false);
|
||||
buildGroupBySql(sqlBuilder, queryWrapper, queryTables);
|
||||
buildHavingSql(sqlBuilder, queryWrapper, queryTables);
|
||||
|
||||
//不允许全量更新
|
||||
if (StringUtil.isBlank(whereConditionSql)) {
|
||||
throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW);
|
||||
//ignore orderBy and limit
|
||||
buildOrderBySql(sqlBuilder, queryWrapper, queryTables);
|
||||
|
||||
Long limitRows = CPI.getLimitRows(queryWrapper);
|
||||
Long limitOffset = CPI.getLimitOffset(queryWrapper);
|
||||
if (limitRows != null || limitOffset != null) {
|
||||
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
|
||||
}
|
||||
|
||||
sql.append(WHERE).append(whereConditionSql);
|
||||
|
||||
// String whereConditionSql = buildWhereConditionSql(queryWrapper);
|
||||
//
|
||||
// //不允许全量更新
|
||||
// if (StringUtil.isBlank(whereConditionSql)) {
|
||||
// throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW);
|
||||
// }
|
||||
//
|
||||
// sql.append(WHERE).append(whereConditionSql);
|
||||
|
||||
List<String> endFragments = CPI.getEndFragments(queryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(endFragments)) {
|
||||
for (String endFragment : endFragments) {
|
||||
sql.append(BLANK).append(endFragment);
|
||||
sqlBuilder.append(BLANK).append(endFragment);
|
||||
}
|
||||
}
|
||||
|
||||
return sql.toString();
|
||||
return sqlBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
@ -973,16 +1007,19 @@ public class CommonsDialectImpl implements IDialect {
|
||||
}
|
||||
|
||||
|
||||
protected void buildJoinSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, List<QueryTable> queryTables) {
|
||||
protected boolean buildJoinSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, List<QueryTable> queryTables) {
|
||||
List<Join> joins = CPI.getJoins(queryWrapper);
|
||||
boolean joinSuccess = false;
|
||||
if (joins != null && !joins.isEmpty()) {
|
||||
for (Join join : joins) {
|
||||
if (!join.checkEffective()) {
|
||||
continue;
|
||||
}
|
||||
sqlBuilder.append(join.toSql(queryTables, this));
|
||||
joinSuccess = true;
|
||||
}
|
||||
}
|
||||
return joinSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -17,18 +17,38 @@ package com.mybatisflex.core.handler;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
import com.alibaba.fastjson2.TypeReference;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author michael
|
||||
*/
|
||||
public class Fastjson2TypeHandler extends BaseJsonTypeHandler<Object> {
|
||||
|
||||
private final Class<?> propertyType;
|
||||
private Class<?> genericType;
|
||||
private Type type;
|
||||
|
||||
public Fastjson2TypeHandler(Class<?> type) {
|
||||
this.propertyType = type;
|
||||
public Fastjson2TypeHandler(Class<?> propertyType) {
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
|
||||
|
||||
public Fastjson2TypeHandler(Class<?> propertyType, Class<?> genericType) {
|
||||
this.propertyType = propertyType;
|
||||
this.genericType = genericType;
|
||||
this.type = TypeReference.collectionType((Class<? extends Collection>) propertyType, genericType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object parseJson(String json) {
|
||||
return JSON.parseObject(json, propertyType);
|
||||
if (genericType != null && Collection.class.isAssignableFrom(propertyType)) {
|
||||
return JSON.parseObject(json, type);
|
||||
} else {
|
||||
return JSON.parseObject(json, propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -18,17 +18,37 @@ package com.mybatisflex.core.handler;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author michael
|
||||
*/
|
||||
public class FastjsonTypeHandler extends BaseJsonTypeHandler<Object> {
|
||||
|
||||
private final Class<?> propertyType;
|
||||
private Class<?> genericType;
|
||||
private Type type;
|
||||
|
||||
public FastjsonTypeHandler(Class<?> type) {
|
||||
this.propertyType = type;
|
||||
public FastjsonTypeHandler(Class<?> propertyType) {
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
|
||||
public FastjsonTypeHandler(Class<?> propertyType, Class<?> genericType) {
|
||||
this.propertyType = propertyType;
|
||||
this.genericType = genericType;
|
||||
this.type = new ParameterizedTypeImpl(propertyType, genericType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object parseJson(String json) {
|
||||
return JSON.parseObject(json, propertyType);
|
||||
if (genericType != null && Collection.class.isAssignableFrom(propertyType)) {
|
||||
return JSON.parseObject(json, type);
|
||||
} else {
|
||||
return JSON.parseObject(json, propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -37,4 +57,66 @@ public class FastjsonTypeHandler extends BaseJsonTypeHandler<Object> {
|
||||
SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
|
||||
}
|
||||
|
||||
|
||||
public static class ParameterizedTypeImpl implements ParameterizedType {
|
||||
|
||||
private final Type[] actualTypeArguments;
|
||||
private final Type ownerType;
|
||||
private final Type rawType;
|
||||
|
||||
public ParameterizedTypeImpl(Type rawType, Type... actualTypeArguments) {
|
||||
this.rawType = rawType;
|
||||
this.actualTypeArguments = actualTypeArguments;
|
||||
this.ownerType = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getActualTypeArguments() {
|
||||
return this.actualTypeArguments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getOwnerType() {
|
||||
return this.ownerType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getRawType() {
|
||||
return this.rawType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o != null && this.getClass() == o.getClass()) {
|
||||
ParameterizedTypeImpl that = (ParameterizedTypeImpl) o;
|
||||
if (!Arrays.equals(this.actualTypeArguments, that.actualTypeArguments)) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.ownerType != null) {
|
||||
if (this.ownerType.equals(that.ownerType)) {
|
||||
return this.rawType != null ? this.rawType.equals(that.rawType) : that.rawType == null;
|
||||
}
|
||||
} else if (that.ownerType == null) {
|
||||
return this.rawType != null ? this.rawType.equals(that.rawType) : that.rawType == null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.actualTypeArguments != null ? Arrays.hashCode(this.actualTypeArguments) : 0;
|
||||
result = 31 * result + (this.ownerType != null ? this.ownerType.hashCode() : 0);
|
||||
result = 31 * result + (this.rawType != null ? this.rawType.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -16,19 +16,34 @@
|
||||
package com.mybatisflex.core.handler;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
/**
|
||||
* @author michael
|
||||
*/
|
||||
public class GsonTypeHandler extends BaseJsonTypeHandler<Object> {
|
||||
|
||||
private static Gson gson;
|
||||
private final Class<?> propertyType;
|
||||
private Class<?> genericType;
|
||||
|
||||
public GsonTypeHandler(Class<?> type) {
|
||||
this.propertyType = type;
|
||||
public GsonTypeHandler(Class<?> propertyType) {
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
|
||||
public GsonTypeHandler(Class<?> propertyType, Class<?> genericType) {
|
||||
this.propertyType = propertyType;
|
||||
this.genericType = genericType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object parseJson(String json) {
|
||||
return getGson().fromJson(json, propertyType);
|
||||
if (genericType != null) {
|
||||
TypeToken<?> typeToken = TypeToken.getParameterized(propertyType, genericType);
|
||||
return getGson().fromJson(json, typeToken);
|
||||
} else {
|
||||
return getGson().fromJson(json, propertyType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,24 +16,40 @@
|
||||
package com.mybatisflex.core.handler;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.mybatisflex.core.exception.FlexExceptions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author michael
|
||||
*/
|
||||
public class JacksonTypeHandler extends BaseJsonTypeHandler<Object> {
|
||||
|
||||
private static ObjectMapper objectMapper;
|
||||
private final Class<?> propertyType;
|
||||
private Class<?> genericType;
|
||||
private JavaType javaType;
|
||||
|
||||
public JacksonTypeHandler(Class<?> propertyType) {
|
||||
this.propertyType = propertyType;
|
||||
}
|
||||
|
||||
public JacksonTypeHandler(Class<?> propertyType, Class<?> genericType) {
|
||||
this.propertyType = propertyType;
|
||||
this.genericType = genericType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object parseJson(String json) {
|
||||
try {
|
||||
return getObjectMapper().readValue(json, propertyType);
|
||||
if (genericType != null && Collection.class.isAssignableFrom(propertyType)) {
|
||||
return getObjectMapper().readValue(json, getJavaType());
|
||||
} else {
|
||||
return getObjectMapper().readValue(json, propertyType);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw FlexExceptions.wrap(e, "Can not parseJson by JacksonTypeHandler: " + json);
|
||||
}
|
||||
@ -48,6 +64,14 @@ public class JacksonTypeHandler extends BaseJsonTypeHandler<Object> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public JavaType getJavaType() {
|
||||
if (javaType == null){
|
||||
javaType = getObjectMapper().getTypeFactory().constructCollectionType((Class<? extends Collection>) propertyType, genericType);
|
||||
}
|
||||
return javaType;
|
||||
}
|
||||
|
||||
public static ObjectMapper getObjectMapper() {
|
||||
if (null == objectMapper) {
|
||||
objectMapper = new ObjectMapper();
|
||||
|
||||
@ -261,7 +261,9 @@ public class EntitySqlProvider {
|
||||
FlexAssert.notNull(entity, "entity can not be null");
|
||||
|
||||
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
|
||||
|
||||
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
|
||||
appendTableConditions(context,queryWrapper,false);
|
||||
|
||||
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
|
||||
|
||||
@ -274,9 +276,13 @@ public class EntitySqlProvider {
|
||||
//优先构建 sql,再构建参数
|
||||
String sql = DialectFactory.getDialect().forUpdateEntityByQuery(tableInfo, entity, ignoreNulls, queryWrapper);
|
||||
|
||||
Object[] joinValueArray = CPI.getJoinValueArray(queryWrapper);
|
||||
Object[] values = tableInfo.buildUpdateSqlArgs(entity, ignoreNulls, true);
|
||||
Object[] queryParams = CPI.getValueArray(queryWrapper);
|
||||
ProviderUtil.setSqlArgs(params, ArrayUtil.concat(values, queryParams));
|
||||
Object[] queryParams = CPI.getConditionValueArray(queryWrapper);
|
||||
|
||||
Object[] paramValues = ArrayUtil.concat(joinValueArray,ArrayUtil.concat(values,queryParams));
|
||||
|
||||
ProviderUtil.setSqlArgs(params, paramValues);
|
||||
|
||||
return sql;
|
||||
}
|
||||
|
||||
@ -34,7 +34,15 @@ public class CPI {
|
||||
}
|
||||
|
||||
public static Object[] getValueArray(QueryWrapper queryWrapper) {
|
||||
return queryWrapper.getValueArray();
|
||||
return queryWrapper.getAllValueArray();
|
||||
}
|
||||
|
||||
public static Object[] getJoinValueArray(QueryWrapper queryWrapper) {
|
||||
return queryWrapper.getJoinValueArray();
|
||||
}
|
||||
|
||||
public static Object[] getConditionValueArray(QueryWrapper queryWrapper) {
|
||||
return queryWrapper.getConditionValueArray();
|
||||
}
|
||||
|
||||
public static List<QueryWrapper> getChildSelect(QueryWrapper queryWrapper) {
|
||||
|
||||
@ -45,7 +45,9 @@ public class If {
|
||||
* 查看某个对象是否为空,支持数组、集合、map 等
|
||||
*
|
||||
* @param object
|
||||
* @deprecated 无泛型,多 instanceof 判断
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean notEmpty(Object object) {
|
||||
if (object == null) {
|
||||
return false;
|
||||
@ -74,7 +76,9 @@ public class If {
|
||||
* 查看某个对象是否为空数据 或者 null
|
||||
*
|
||||
* @param object
|
||||
* @deprecated 无泛型,多 instanceof 判断
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isEmpty(Object object) {
|
||||
return !notEmpty(object);
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ public class OperatorSelectCondition extends QueryCondition {
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return queryWrapper.getValueArray();
|
||||
return queryWrapper.getAllValueArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -24,6 +24,7 @@ import com.mybatisflex.core.util.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
@ -147,11 +148,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
}
|
||||
|
||||
|
||||
public <T> QueryCondition eq(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition eq(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.EQUALS, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.EQUALS, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -167,11 +168,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_EQUALS, value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition ne(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition ne(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.NOT_EQUALS, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.NOT_EQUALS, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -187,11 +188,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, "%" + value + "%");
|
||||
}
|
||||
|
||||
public <T> QueryCondition like(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition like(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, "%" + value + "%").when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, "%" + value + "%").when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -202,11 +203,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, value + "%");
|
||||
}
|
||||
|
||||
public <T> QueryCondition likeLeft(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition likeLeft(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, value + "%").when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, value + "%").when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -217,11 +218,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, "%" + value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition likeRight(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition likeRight(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, "%" + value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, "%" + value).when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -232,11 +233,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition likeRaw(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition likeRaw(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.LIKE, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -252,11 +253,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, "%" + value + "%");
|
||||
}
|
||||
|
||||
public <T> QueryCondition notLike(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition notLike(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, "%" + value + "%").when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, "%" + value + "%").when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -267,11 +268,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, value + "%");
|
||||
}
|
||||
|
||||
public <T> QueryCondition notLikeLeft(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition notLikeLeft(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, value + "%").when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, value + "%").when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -282,11 +283,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, "%" + value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition notLikeRight(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition notLikeRight(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, "%" + value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.NOT_LIKE, "%" + value).when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -302,11 +303,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.GT, value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition gt(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition gt(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.GT, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.GT, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,11 +322,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.GE, value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition ge(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition ge(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.GE, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.GE, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -340,11 +341,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.LT, value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition lt(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition lt(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.LT, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.LT, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -359,11 +360,11 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.LE, value);
|
||||
}
|
||||
|
||||
public <T> QueryCondition le(Object value, Predicate<T> fn) {
|
||||
public <T> QueryCondition le(T value, Predicate<T> fn) {
|
||||
if (value == null || QueryColumnBehavior.shouldIgnoreValue(value)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.create(this, SqlConsts.LE, value).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.LE, value).when(fn.test(value));
|
||||
}
|
||||
|
||||
|
||||
@ -376,6 +377,10 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.IS_NULL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> QueryCondition isNull(Predicate<T> fn) {
|
||||
return QueryCondition.create(this, SqlConsts.IS_NULL, null).when(fn);
|
||||
}
|
||||
@ -390,6 +395,10 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.IS_NOT_NULL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> QueryCondition isNotNull(Predicate<T> fn) {
|
||||
return QueryCondition.create(this, SqlConsts.IS_NOT_NULL, null).when(fn);
|
||||
}
|
||||
@ -415,7 +424,7 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
}
|
||||
|
||||
|
||||
public <T> QueryCondition in(Object[] arrays, Predicate<T> fn) {
|
||||
public <T> QueryCondition in(T[] arrays, Predicate<T[]> fn) {
|
||||
//忽略 QueryWrapper.in("name", null) 的情况
|
||||
if (arrays == null || arrays.length == 0 || (arrays.length == 1 && arrays[0] == null) || QueryColumnBehavior.shouldIgnoreValue(arrays)) {
|
||||
return QueryCondition.createEmpty();
|
||||
@ -425,7 +434,7 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.EQUALS, arrays[0]);
|
||||
}
|
||||
|
||||
return QueryCondition.create(this, SqlConsts.IN, arrays).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.IN, arrays).when(fn.test(arrays));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -442,6 +451,10 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> QueryCondition in(QueryWrapper queryWrapper, Predicate<T> fn) {
|
||||
if (queryWrapper == null || QueryColumnBehavior.shouldIgnoreValue(queryWrapper)) {
|
||||
return QueryCondition.createEmpty();
|
||||
@ -457,17 +470,17 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
* @return QueryCondition
|
||||
*/
|
||||
public QueryCondition in(Collection<?> collection) {
|
||||
if (collection != null && !collection.isEmpty() && !QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return in(collection.toArray());
|
||||
if (collection == null || collection.isEmpty() || QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.createEmpty();
|
||||
return in(collection.toArray());
|
||||
}
|
||||
|
||||
public <T> QueryCondition in(Collection<?> collection, Predicate<T> fn) {
|
||||
if (collection != null && !collection.isEmpty() && !QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return in(collection.toArray(), fn);
|
||||
public <T extends Collection<?>> QueryCondition in(T collection, Predicate<T> fn) {
|
||||
if (collection == null || collection.isEmpty() || QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.createEmpty();
|
||||
return in(collection.toArray()).when(fn.test(collection));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -489,7 +502,7 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_IN, arrays);
|
||||
}
|
||||
|
||||
public <T> QueryCondition notIn(Object[] arrays, Predicate<T> fn) {
|
||||
public <T> QueryCondition notIn(T[] arrays, Predicate<T[]> fn) {
|
||||
//忽略 QueryWrapper.notIn("name", null) 的情况
|
||||
if (arrays == null || arrays.length == 0 || (arrays.length == 1 && arrays[0] == null) || QueryColumnBehavior.shouldIgnoreValue(arrays)) {
|
||||
return QueryCondition.createEmpty();
|
||||
@ -499,7 +512,7 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_EQUALS, arrays[0]);
|
||||
}
|
||||
|
||||
return QueryCondition.create(this, SqlConsts.NOT_IN, arrays).when(fn);
|
||||
return QueryCondition.create(this, SqlConsts.NOT_IN, arrays).when(fn.test(arrays));
|
||||
}
|
||||
|
||||
|
||||
@ -510,17 +523,17 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
* @return QueryCondition
|
||||
*/
|
||||
public QueryCondition notIn(Collection<?> collection) {
|
||||
if (collection != null && !collection.isEmpty() && !QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return notIn(collection.toArray());
|
||||
if (collection == null || collection.isEmpty() || QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.createEmpty();
|
||||
return notIn(collection.toArray());
|
||||
}
|
||||
|
||||
public <T> QueryCondition notIn(Collection<?> collection, Predicate<T> fn) {
|
||||
if (collection != null && !collection.isEmpty() && !QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return notIn(collection.toArray(), fn);
|
||||
public <T extends Collection<?>> QueryCondition notIn(T collection, Predicate<T> fn) {
|
||||
if (collection == null || collection.isEmpty() || QueryColumnBehavior.shouldIgnoreValue(collection)) {
|
||||
return QueryCondition.createEmpty();
|
||||
}
|
||||
return QueryCondition.createEmpty();
|
||||
return notIn(collection.toArray()).when(fn.test(collection));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -536,6 +549,10 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> QueryCondition notIn(QueryWrapper queryWrapper, Predicate<T> fn) {
|
||||
if (queryWrapper == null || QueryColumnBehavior.shouldIgnoreValue(queryWrapper)) {
|
||||
return QueryCondition.createEmpty();
|
||||
@ -554,8 +571,8 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end});
|
||||
}
|
||||
|
||||
public <T> QueryCondition between(Object start, Object end, Predicate<T> fn) {
|
||||
return QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end}).when(fn);
|
||||
public <S, E> QueryCondition between(S start, E end, BiPredicate<S, E> fn) {
|
||||
return QueryCondition.create(this, SqlConsts.BETWEEN, new Object[]{start, end}).when(fn.test(start, end));
|
||||
}
|
||||
|
||||
|
||||
@ -569,8 +586,8 @@ public class QueryColumn implements CloneSupport<QueryColumn> {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end});
|
||||
}
|
||||
|
||||
public <T> QueryCondition notBetween(Object start, Object end, Predicate<T> fn) {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end}).when(fn);
|
||||
public <S, E> QueryCondition notBetween(S start, E end, BiPredicate<S, E> fn) {
|
||||
return QueryCondition.create(this, SqlConsts.NOT_BETWEEN, new Object[]{start, end}).when(fn.test(start, end));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -24,8 +24,8 @@ import com.mybatisflex.core.util.ObjectUtil;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class QueryCondition implements CloneSupport<QueryCondition> {
|
||||
|
||||
@ -96,17 +96,44 @@ public class QueryCondition implements CloneSupport<QueryCondition> {
|
||||
this.logic = logic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动态条件构造。
|
||||
*
|
||||
* @param effective 是否启用该条件
|
||||
* @return {@link QueryCondition}
|
||||
*/
|
||||
public QueryCondition when(boolean effective) {
|
||||
this.effective = effective;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void when(Supplier<Boolean> fn) {
|
||||
Boolean effective = fn.get();
|
||||
this.effective = (effective != null && effective);
|
||||
|
||||
/**
|
||||
* 动态条件构造。
|
||||
*
|
||||
* @param fn 是否启用该条件
|
||||
* @return {@link QueryCondition}
|
||||
*/
|
||||
public QueryCondition when(BooleanSupplier fn) {
|
||||
this.effective = fn.getAsBoolean();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>动态条件构造。
|
||||
*
|
||||
* <p>推荐将 {@link Predicate} 推断写在填写的值的后面,以确保泛型对应,例如:
|
||||
* <pre>{@code
|
||||
* ACCOUNT.ID.in(idList, CollectionUtil::isNotEmpty);
|
||||
* }</pre>
|
||||
*
|
||||
* @see #when(boolean)
|
||||
* @see #when(BooleanSupplier)
|
||||
* @deprecated 由于 {@link QueryCondition} 中属性 {@link #value} 的类型为 Object
|
||||
* 类型,没有使用泛型,所以该方法泛型推断可能会出现问题。
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> QueryCondition when(Predicate<T> fn) {
|
||||
Object val = this.value;
|
||||
if ((SqlConsts.LIKE.equals(logic) || SqlConsts.NOT_LIKE.equals(logic))
|
||||
|
||||
@ -19,6 +19,7 @@ import com.mybatisflex.core.util.LambdaGetter;
|
||||
import com.mybatisflex.core.util.LambdaUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
@ -47,7 +48,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
}
|
||||
|
||||
|
||||
public <T> Wrapper eq(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper eq(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.eq(value, when), connector);
|
||||
}
|
||||
@ -59,9 +60,15 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return eq(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper eq(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return eq(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.eq(value).when(when), connector);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +84,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper ne(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper ne(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.ne(value, when), connector);
|
||||
}
|
||||
@ -89,8 +96,15 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper ne(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return ne(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.ne(value).when(when), connector);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
@ -106,7 +120,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper like(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper like(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.like(value, when), connector);
|
||||
}
|
||||
@ -121,7 +135,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper likeLeft(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper likeLeft(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.likeLeft(value, when), connector);
|
||||
}
|
||||
@ -136,7 +150,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper likeRight(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper likeRight(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.likeRight(value, when), connector);
|
||||
}
|
||||
@ -155,7 +169,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper gt(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper gt(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.gt(value, when), connector);
|
||||
}
|
||||
@ -166,9 +180,15 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return gt(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper gt(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return gt(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.gt(value).when(when), connector);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
@ -184,7 +204,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper ge(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper ge(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.ge(value, when), connector);
|
||||
}
|
||||
@ -195,9 +215,15 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return ge(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper ge(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return ge(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.ge(value).when(when), connector);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,7 +238,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper lt(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper lt(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.lt(value, when), connector);
|
||||
}
|
||||
@ -223,9 +249,15 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return lt(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper lt(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return lt(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.lt(value).when(when), connector);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +273,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
}
|
||||
|
||||
|
||||
public <T> Wrapper le(Object value, Predicate<T> when) {
|
||||
public <T> Wrapper le(T value, Predicate<T> when) {
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.le(value, when), connector);
|
||||
}
|
||||
@ -252,9 +284,15 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return le(LambdaUtil.getQueryColumn(value));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated {@link Predicate} 泛型参数无效
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper le(LambdaGetter<T> value, Predicate<T> when) {
|
||||
return le(LambdaUtil.getQueryColumn(value), when);
|
||||
if (value != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.le(value).when(when), connector);
|
||||
}
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
|
||||
@ -268,6 +306,10 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper isNull(Predicate<T> when) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.isNull(when), connector);
|
||||
return queryWrapper;
|
||||
@ -284,6 +326,10 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper isNotNull(Predicate<T> when) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.isNotNull(when), connector);
|
||||
return queryWrapper;
|
||||
@ -303,7 +349,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper in(Object[] arrays, Predicate<T> when) {
|
||||
public <T> Wrapper in(T[] arrays, Predicate<T[]> when) {
|
||||
//忽略 QueryWrapper.in("name", null) 的情况
|
||||
if (arrays != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.in(arrays, when), connector);
|
||||
@ -324,6 +370,10 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return this.queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper in(QueryWrapper queryWrapper, Predicate<T> when) {
|
||||
if (queryWrapper != null) {
|
||||
this.queryWrapper.addWhereQueryCondition(queryColumn.in(queryWrapper, when), connector);
|
||||
@ -345,7 +395,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper in(Collection<?> collection, Predicate<T> when) {
|
||||
public <T extends Collection<?>> Wrapper in(T collection, Predicate<T> when) {
|
||||
if (queryWrapper != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.in(collection, when), connector);
|
||||
}
|
||||
@ -365,7 +415,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper notIn(Object[] arrays, Predicate<T> when) {
|
||||
public <T> Wrapper notIn(T[] arrays, Predicate<T[]> when) {
|
||||
if (queryWrapper != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.notIn(arrays, when), connector);
|
||||
}
|
||||
@ -386,7 +436,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper notIn(Collection<?> collection, Predicate<T> when) {
|
||||
public <T extends Collection<?>> Wrapper notIn(T collection, Predicate<T> when) {
|
||||
if (queryWrapper != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.notIn(collection, when), connector);
|
||||
}
|
||||
@ -405,6 +455,10 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return this.queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 无法推断泛型
|
||||
*/
|
||||
@Deprecated
|
||||
public <T> Wrapper notIn(QueryWrapper queryWrapper, Predicate<T> when) {
|
||||
if (queryWrapper != null) {
|
||||
this.queryWrapper.addWhereQueryCondition(queryColumn.notIn(queryWrapper, when), connector);
|
||||
@ -427,7 +481,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
}
|
||||
|
||||
|
||||
public <T> Wrapper between(Object start, Object end, Predicate<T> when) {
|
||||
public <S, E> Wrapper between(S start, E end, BiPredicate<S, E> when) {
|
||||
if (queryWrapper != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.between(start, end, when), connector);
|
||||
}
|
||||
@ -448,7 +502,7 @@ public class QueryConditionBuilder<Wrapper extends QueryWrapper> {
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
public <T> Wrapper notBetween(Object start, Object end, Predicate<T> when) {
|
||||
public <S, E> Wrapper notBetween(S start, E end, BiPredicate<S, E> when) {
|
||||
if (queryWrapper != null) {
|
||||
queryWrapper.addWhereQueryCondition(queryColumn.notBetween(start, end, when), connector);
|
||||
}
|
||||
|
||||
@ -291,7 +291,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
|
||||
}
|
||||
|
||||
public QueryWrapper or(Consumer<QueryWrapper> consumer, boolean condition) {
|
||||
if (condition) {
|
||||
if (!condition) {
|
||||
return this;
|
||||
}
|
||||
QueryWrapper newWrapper = new QueryWrapper();
|
||||
@ -692,7 +692,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
|
||||
* 获取 queryWrapper 的参数
|
||||
* 在构建 sql 的时候,需要保证 where 在 having 的前面
|
||||
*/
|
||||
Object[] getValueArray() {
|
||||
Object[] getAllValueArray() {
|
||||
|
||||
List<Object> withValues = null;
|
||||
if (with != null) {
|
||||
@ -770,7 +770,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
|
||||
if (CollectionUtil.isNotEmpty(unions)) {
|
||||
for (UnionWrapper union : unions) {
|
||||
QueryWrapper queryWrapper = union.getQueryWrapper();
|
||||
paramValues = ArrayUtil.concat(paramValues, queryWrapper.getValueArray());
|
||||
paramValues = ArrayUtil.concat(paramValues, queryWrapper.getAllValueArray());
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,6 +783,67 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
|
||||
return returnValues;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取 queryWrapper 的参数
|
||||
* 在构建 sql 的时候,需要保证 where 在 having 的前面
|
||||
*/
|
||||
Object[] getJoinValueArray() {
|
||||
//join 子查询的参数:left join (select ...)
|
||||
List<Object> joinValues = null;
|
||||
List<Join> joins = getJoins();
|
||||
if (CollectionUtil.isNotEmpty(joins)) {
|
||||
for (Join join : joins) {
|
||||
QueryTable joinTable = join.getQueryTable();
|
||||
Object[] valueArray = joinTable.getValueArray();
|
||||
if (valueArray.length > 0) {
|
||||
if (joinValues == null) {
|
||||
joinValues = new ArrayList<>(valueArray.length);
|
||||
}
|
||||
joinValues.addAll(Arrays.asList(valueArray));
|
||||
}
|
||||
QueryCondition onCondition = join.getOnCondition();
|
||||
Object[] values = WrapperUtil.getValues(onCondition);
|
||||
if (values.length > 0) {
|
||||
if (joinValues == null) {
|
||||
joinValues = new ArrayList<>(values.length);
|
||||
}
|
||||
joinValues.addAll(Arrays.asList(values));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return joinValues == null ? FlexConsts.EMPTY_ARRAY : joinValues.toArray();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取 queryWrapper 的参数
|
||||
* 在构建 sql 的时候,需要保证 where 在 having 的前面
|
||||
*/
|
||||
Object[] getConditionValueArray() {
|
||||
//where 参数
|
||||
Object[] whereValues = WrapperUtil.getValues(whereQueryCondition);
|
||||
|
||||
//having 参数
|
||||
Object[] havingValues = WrapperUtil.getValues(havingQueryCondition);
|
||||
|
||||
Object[] paramValues = ArrayUtil.concat(whereValues, havingValues);
|
||||
|
||||
//unions 参数
|
||||
if (CollectionUtil.isNotEmpty(unions)) {
|
||||
for (UnionWrapper union : unions) {
|
||||
QueryWrapper queryWrapper = union.getQueryWrapper();
|
||||
paramValues = ArrayUtil.concat(paramValues, queryWrapper.getAllValueArray());
|
||||
}
|
||||
}
|
||||
|
||||
return paramValues;
|
||||
}
|
||||
|
||||
|
||||
List<QueryWrapper> getChildSelect() {
|
||||
|
||||
List<QueryWrapper> tableChildQuery = null;
|
||||
@ -815,7 +876,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
|
||||
|
||||
public String toSQL() {
|
||||
String sql = DialectFactory.getDialect().forSelectByQuery(this);
|
||||
return SqlUtil.replaceSqlParams(sql, getValueArray());
|
||||
return SqlUtil.replaceSqlParams(sql, getAllValueArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -58,7 +58,7 @@ public class SelectQueryColumn extends QueryColumn implements HasParamsColumn {
|
||||
|
||||
@Override
|
||||
public Object[] getParamValues() {
|
||||
return queryWrapper.getValueArray();
|
||||
return queryWrapper.getAllValueArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ public class SelectQueryTable extends QueryTable {
|
||||
|
||||
@Override
|
||||
Object[] getValueArray() {
|
||||
return queryWrapper.getValueArray();
|
||||
return queryWrapper.getAllValueArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -44,7 +44,7 @@ public class WithSelectDetail implements WithDetail {
|
||||
|
||||
@Override
|
||||
public Object[] getParamValues() {
|
||||
return queryWrapper.getValueArray();
|
||||
return queryWrapper.getAllValueArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -57,7 +57,7 @@ public class WithValuesDetail implements WithDetail {
|
||||
|
||||
@Override
|
||||
public Object[] getParamValues() {
|
||||
return queryWrapper.getValueArray();
|
||||
return queryWrapper.getAllValueArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -115,7 +115,7 @@ class WrapperUtil {
|
||||
addParam(paras, Array.get(value, i));
|
||||
}
|
||||
} else if (value instanceof QueryWrapper) {
|
||||
Object[] valueArray = ((QueryWrapper) value).getValueArray();
|
||||
Object[] valueArray = ((QueryWrapper) value).getAllValueArray();
|
||||
paras.addAll(Arrays.asList(valueArray));
|
||||
} else if (value.getClass().isEnum()) {
|
||||
EnumWrapper enumWrapper = EnumWrapper.of(value.getClass());
|
||||
|
||||
@ -46,8 +46,6 @@ public interface IService<T> {
|
||||
|
||||
int DEFAULT_BATCH_SIZE = 1000;
|
||||
|
||||
// ===== 保存(增)操作 =====
|
||||
|
||||
/**
|
||||
* <p>获取对应实体类(Entity)的基础映射类(BaseMapper)。
|
||||
*
|
||||
@ -55,27 +53,18 @@ public interface IService<T> {
|
||||
*/
|
||||
BaseMapper<T> getMapper();
|
||||
|
||||
// ===== 保存(增)操作 =====
|
||||
|
||||
/**
|
||||
* <p>保存实体类对象数据。
|
||||
*
|
||||
* @param entity 实体类对象
|
||||
* @return {@code true} 保存成功,{@code false} 保存失败。
|
||||
* @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略
|
||||
* {@code null} 字段的数据,使数据库配置的默认值生效。
|
||||
* @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略实体类
|
||||
* {@code null} 属性的数据,使数据库配置的默认值生效。
|
||||
*/
|
||||
default boolean save(T entity) {
|
||||
return SqlUtil.toBool(getMapper().insertSelective(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>保存或者更新实体类对象数据。
|
||||
*
|
||||
* @param entity 实体类对象
|
||||
* @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。
|
||||
* @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据。
|
||||
*/
|
||||
default boolean saveOrUpdate(T entity) {
|
||||
return SqlUtil.toBool(getMapper().insertOrUpdate(entity, true));
|
||||
return SqlUtil.toBool(getMapper().insert(entity, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,6 +72,8 @@ public interface IService<T> {
|
||||
*
|
||||
* @param entities 实体类对象
|
||||
* @return {@code true} 保存成功,{@code false} 保存失败。
|
||||
* @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略实体类
|
||||
* {@code null} 属性的数据,使数据库配置的默认值生效。
|
||||
*/
|
||||
default boolean saveBatch(Collection<T> entities) {
|
||||
return saveBatch(entities, DEFAULT_BATCH_SIZE);
|
||||
@ -94,10 +85,12 @@ public interface IService<T> {
|
||||
* @param entities 实体类对象
|
||||
* @param batchSize 每次保存切分的数量
|
||||
* @return {@code true} 保存成功,{@code false} 保存失败。
|
||||
* @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略实体类
|
||||
* {@code null} 属性的数据,使数据库配置的默认值生效。
|
||||
*/
|
||||
default boolean saveBatch(Collection<T> entities, int batchSize) {
|
||||
Class<BaseMapper<T>> usefulClass = (Class<BaseMapper<T>>) ClassUtil.getUsefulClass(getMapper().getClass());
|
||||
return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insert));
|
||||
return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insertSelective));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,7 +98,10 @@ public interface IService<T> {
|
||||
*
|
||||
* @param entities 实体类对象
|
||||
* @return {@code true} 保存成功,{@code false} 保存失败。
|
||||
* @deprecated 为保持 Service 层 API 一致性,默认方法都是忽略实体类 {@code null} 属性的数据。
|
||||
* 另外,该方法将在 1.6.0 版本被移除。
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean saveBatchSelective(Collection<T> entities) {
|
||||
return saveBatchSelective(entities, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
@ -116,12 +112,53 @@ public interface IService<T> {
|
||||
* @param entities 实体类对象
|
||||
* @param batchSize 每次保存切分的数量
|
||||
* @return {@code true} 保存成功,{@code false} 保存失败。
|
||||
* @deprecated 为保持 Service 层 API 一致性,默认方法都是忽略实体类 {@code null} 属性的数据。
|
||||
* 另外,该方法将在 1.6.0 版本被移除。
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean saveBatchSelective(Collection<T> entities, int batchSize) {
|
||||
Class<BaseMapper<T>> usefulClass = (Class<BaseMapper<T>>) ClassUtil.getUsefulClass(getMapper().getClass());
|
||||
return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insertSelective));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>保存或者更新实体类对象数据。
|
||||
*
|
||||
* @param entity 实体类对象
|
||||
* @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。
|
||||
* @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据,无论新增还是更新都会忽略实体类
|
||||
* {@code null} 属性的数据。
|
||||
*/
|
||||
default boolean saveOrUpdate(T entity) {
|
||||
return SqlUtil.toBool(getMapper().insertOrUpdate(entity, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>保存或者更新实体类对象数据。
|
||||
*
|
||||
* @param entities 实体类对象
|
||||
* @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。
|
||||
* @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据,无论新增还是更新都会忽略实体类
|
||||
* {@code null} 属性的数据。
|
||||
*/
|
||||
default boolean saveOrUpdateBatch(Collection<T> entities) {
|
||||
return saveOrUpdateBatch(entities, DEFAULT_BATCH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>保存或者更新实体类对象数据。
|
||||
*
|
||||
* @param entities 实体类对象
|
||||
* @param batchSize 每次操作切分的数量
|
||||
* @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。
|
||||
* @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据,无论新增还是更新都会忽略实体类
|
||||
* {@code null} 属性的数据。
|
||||
*/
|
||||
default boolean saveOrUpdateBatch(Collection<T> entities, int batchSize) {
|
||||
Class<BaseMapper<T>> usefulClass = (Class<BaseMapper<T>>) ClassUtil.getUsefulClass(getMapper().getClass());
|
||||
return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insertOrUpdateSelective));
|
||||
}
|
||||
|
||||
// ===== 删除(删)操作 =====
|
||||
|
||||
/**
|
||||
@ -167,8 +204,6 @@ public interface IService<T> {
|
||||
return SqlUtil.toBool(getMapper().deleteBatchByIds(ids));
|
||||
}
|
||||
|
||||
// ===== 更新(改)操作 =====
|
||||
|
||||
/**
|
||||
* <p>根据 {@link Map} 构建查询条件删除数据。
|
||||
*
|
||||
@ -183,6 +218,8 @@ public interface IService<T> {
|
||||
return remove(query().where(query));
|
||||
}
|
||||
|
||||
// ===== 更新(改)操作 =====
|
||||
|
||||
/**
|
||||
* <p>根据数据主键更新数据。
|
||||
*
|
||||
@ -211,6 +248,7 @@ public interface IService<T> {
|
||||
* @param entity 实体类对象
|
||||
* @param query 查询条件
|
||||
* @return {@code true} 更新成功,{@code false} 更新失败。
|
||||
* @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。
|
||||
*/
|
||||
default boolean update(T entity, Map<String, Object> query) {
|
||||
return update(entity, query().where(query));
|
||||
@ -222,6 +260,7 @@ public interface IService<T> {
|
||||
* @param entity 实体类对象
|
||||
* @param query 查询条件
|
||||
* @return {@code true} 更新成功,{@code false} 更新失败。
|
||||
* @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。
|
||||
*/
|
||||
default boolean update(T entity, QueryWrapper query) {
|
||||
return SqlUtil.toBool(getMapper().updateByQuery(entity, query));
|
||||
@ -233,6 +272,7 @@ public interface IService<T> {
|
||||
* @param entity 实体类对象
|
||||
* @param condition 查询条件
|
||||
* @return {@code true} 更新成功,{@code false} 更新失败。
|
||||
* @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。
|
||||
*/
|
||||
default boolean update(T entity, QueryCondition condition) {
|
||||
return update(entity, query().where(condition));
|
||||
@ -243,6 +283,7 @@ public interface IService<T> {
|
||||
*
|
||||
* @param entities 实体类对象集合
|
||||
* @return boolean {@code true} 更新成功,{@code false} 更新失败。
|
||||
* @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。
|
||||
*/
|
||||
default boolean updateBatch(Collection<T> entities) {
|
||||
return updateBatch(entities, DEFAULT_BATCH_SIZE);
|
||||
@ -254,13 +295,13 @@ public interface IService<T> {
|
||||
* @param entities 实体类对象集合
|
||||
* @param batchSize 每批次更新数量
|
||||
* @return {@code true} 更新成功,{@code false} 更新失败。
|
||||
* @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。
|
||||
*/
|
||||
default boolean updateBatch(Collection<T> entities, int batchSize) {
|
||||
Class<BaseMapper<T>> usefulClass = (Class<BaseMapper<T>>) ClassUtil.getUsefulClass(getMapper().getClass());
|
||||
return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::update));
|
||||
}
|
||||
|
||||
|
||||
// ===== 查询(查)操作 =====
|
||||
|
||||
/**
|
||||
@ -349,6 +390,70 @@ public interface IService<T> {
|
||||
return Optional.ofNullable(getOne(condition));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询结果集中第一列,且第一条数据。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 数据值
|
||||
*/
|
||||
default Object getObj(QueryWrapper query) {
|
||||
return getMapper().selectObjectByQuery(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询结果集中第一列,且第一条数据,并封装为 {@link Optional} 返回。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 数据值
|
||||
*/
|
||||
default Optional<Object> getObjOpt(QueryWrapper query) {
|
||||
return Optional.ofNullable(getObj(query));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询结果集中第一列,且第一条数据,并转换为指定类型,比如 {@code Long}, {@code String} 等。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param asType 接收的数据类型
|
||||
* @return 数据值
|
||||
*/
|
||||
default <R> R getObjAs(QueryWrapper query, Class<R> asType) {
|
||||
return getMapper().selectObjectByQueryAs(query, asType);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询结果集中第一列,且第一条数据,并转换为指定类型,比如 {@code Long}, {@code String}
|
||||
* 等,封装为 {@link Optional} 返回。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param asType 接收的数据类型
|
||||
* @return 数据值
|
||||
*/
|
||||
default <R> Optional<R> getObjAsOpt(QueryWrapper query, Class<R> asType) {
|
||||
return Optional.ofNullable(getObjAs(query, asType));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询结果集中第一列所有数据。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @return 数据列表
|
||||
*/
|
||||
default List<Object> objList(QueryWrapper query) {
|
||||
return getMapper().selectObjectListByQuery(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询结果集中第一列所有数据,并转换为指定类型,比如 {@code Long}, {@code String} 等。
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param asType 接收的数据类型
|
||||
* @return 数据列表
|
||||
*/
|
||||
default <R> List<R> objListAs(QueryWrapper query, Class<R> asType) {
|
||||
return getMapper().selectObjectListByQueryAs(query, asType);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>查询所有数据。
|
||||
*
|
||||
@ -428,7 +533,7 @@ public interface IService<T> {
|
||||
* @return {@code true} 数据存在,{@code false} 数据不存在。
|
||||
*/
|
||||
default boolean exists(QueryCondition condition) {
|
||||
return CollectionUtil.isNotEmpty(getMapper().selectListByCondition(condition,1L));
|
||||
return CollectionUtil.isNotEmpty(getMapper().selectListByCondition(condition, 1L));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -45,21 +45,6 @@ public class IdInfo extends ColumnInfo {
|
||||
private Boolean before;
|
||||
|
||||
|
||||
public IdInfo(ColumnInfo columnInfo) {
|
||||
this.setColumn(columnInfo.getColumn());
|
||||
this.setAlias(columnInfo.getAlias());
|
||||
this.setProperty(columnInfo.getProperty());
|
||||
this.setPropertyType(columnInfo.getPropertyType());
|
||||
|
||||
//当 id 的类型为数值时,默认设置为自增的方式
|
||||
if (Number.class.isAssignableFrom(columnInfo.getPropertyType())) {
|
||||
keyType = KeyType.Auto;
|
||||
} else {
|
||||
initDefaultKeyType();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IdInfo(Id id) {
|
||||
this.keyType = id.keyType();
|
||||
this.value = id.value();
|
||||
|
||||
@ -376,7 +376,7 @@ public class TableInfo {
|
||||
primaryColumns[i] = idInfo.getColumn();
|
||||
|
||||
if (idInfo.getKeyType() != KeyType.Auto
|
||||
|| (idInfo.getBefore() != null && idInfo.getBefore())
|
||||
&& (idInfo.getBefore() != null && idInfo.getBefore())
|
||||
) {
|
||||
insertIdFields.add(idInfo.getColumn());
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@ package com.mybatisflex.core.table;
|
||||
|
||||
import com.mybatisflex.annotation.*;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.mybatisflex.core.FlexConsts;
|
||||
import com.mybatisflex.core.FlexGlobalConfig;
|
||||
import com.mybatisflex.core.exception.FlexExceptions;
|
||||
import com.mybatisflex.core.util.ClassUtil;
|
||||
@ -28,10 +27,7 @@ import org.apache.ibatis.io.ResolverUtil;
|
||||
import org.apache.ibatis.reflection.Reflector;
|
||||
import org.apache.ibatis.reflection.TypeParameterResolver;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
import org.apache.ibatis.type.TypeHandlerRegistry;
|
||||
import org.apache.ibatis.type.UnknownTypeHandler;
|
||||
import org.apache.ibatis.type.*;
|
||||
import org.apache.ibatis.util.MapUtil;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
@ -179,7 +175,7 @@ public class TableInfoFactory {
|
||||
List<ColumnInfo> columnInfoList = new ArrayList<>();
|
||||
List<IdInfo> idInfos = new ArrayList<>();
|
||||
|
||||
Field idField = null;
|
||||
// Field idField = null;
|
||||
|
||||
String logicDeleteColumn = null;
|
||||
String versionColumn = null;
|
||||
@ -200,6 +196,8 @@ public class TableInfoFactory {
|
||||
|
||||
List<Field> entityFields = getColumnFields(entityClass);
|
||||
|
||||
FlexGlobalConfig config = FlexGlobalConfig.getDefaultConfig();
|
||||
|
||||
for (Field field : entityFields) {
|
||||
|
||||
Column column = field.getAnnotation(Column.class);
|
||||
@ -219,7 +217,7 @@ public class TableInfoFactory {
|
||||
Type genericType = TypeParameterResolver.resolveFieldType(field, entityClass);
|
||||
if (genericType instanceof ParameterizedType) {
|
||||
Type actualTypeArgument = ((ParameterizedType) genericType).getActualTypeArguments()[0];
|
||||
if (actualTypeArgument instanceof Class){
|
||||
if (actualTypeArgument instanceof Class) {
|
||||
tableInfo.addCollectionType(field, (Class<?>) actualTypeArgument);
|
||||
}
|
||||
}
|
||||
@ -237,7 +235,8 @@ public class TableInfoFactory {
|
||||
String columnName = getColumnName(tableInfo.isCamelToUnderline(), field, column);
|
||||
|
||||
//逻辑删除字段
|
||||
if (column != null && column.isLogicDelete()) {
|
||||
if ((column != null && column.isLogicDelete())
|
||||
|| columnName.equals(config.getLogicDeleteColumn())) {
|
||||
if (logicDeleteColumn == null) {
|
||||
logicDeleteColumn = columnName;
|
||||
} else {
|
||||
@ -246,7 +245,8 @@ public class TableInfoFactory {
|
||||
}
|
||||
|
||||
//乐观锁版本字段
|
||||
if (column != null && column.version()) {
|
||||
if ((column != null && column.version())
|
||||
|| columnName.equals(config.getVersionColumn())) {
|
||||
if (versionColumn == null) {
|
||||
versionColumn = columnName;
|
||||
} else {
|
||||
@ -255,7 +255,8 @@ public class TableInfoFactory {
|
||||
}
|
||||
|
||||
//租户ID 字段
|
||||
if (column != null && column.tenantId()) {
|
||||
if ((column != null && column.tenantId())
|
||||
|| columnName.equals(config.getTenantColumn())) {
|
||||
if (tenantIdColumn == null) {
|
||||
tenantIdColumn = columnName;
|
||||
} else {
|
||||
@ -311,10 +312,22 @@ public class TableInfoFactory {
|
||||
columnInfo.setPropertyType(fieldType);
|
||||
|
||||
if (column != null && column.typeHandler() != UnknownTypeHandler.class) {
|
||||
Class<?> typeHandlerClass = column.typeHandler();
|
||||
Configuration configuration = FlexGlobalConfig.getDefaultConfig().getConfiguration();
|
||||
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
||||
TypeHandler<?> typeHandler = typeHandlerRegistry.getInstance(columnInfo.getPropertyType(), typeHandlerClass);
|
||||
TypeHandler<?> typeHandler;
|
||||
|
||||
// 集合类型,传入泛型
|
||||
// fixed https://gitee.com/mybatis-flex/mybatis-flex/issues/I7S2YE
|
||||
if (Collection.class.isAssignableFrom(fieldType)) {
|
||||
typeHandler = createCollectionTypeHandler(entityClass, field, column.typeHandler(), fieldType);
|
||||
}
|
||||
|
||||
//非集合类型
|
||||
else {
|
||||
Class<?> typeHandlerClass = column.typeHandler();
|
||||
Configuration configuration = FlexGlobalConfig.getDefaultConfig().getConfiguration();
|
||||
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
||||
typeHandler = typeHandlerRegistry.getInstance(columnInfo.getPropertyType(), typeHandlerClass);
|
||||
}
|
||||
|
||||
columnInfo.setTypeHandler(typeHandler);
|
||||
}
|
||||
|
||||
@ -330,27 +343,9 @@ public class TableInfoFactory {
|
||||
columnInfo.setJdbcType(column.jdbcType());
|
||||
}
|
||||
|
||||
if (FlexConsts.DEFAULT_PRIMARY_FIELD.equals(field.getName())) {
|
||||
idField = field;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (idInfos.isEmpty() && idField != null) {
|
||||
int index = -1;
|
||||
for (int i = 0; i < columnInfoList.size(); i++) {
|
||||
ColumnInfo columnInfo = columnInfoList.get(i);
|
||||
if (FlexConsts.DEFAULT_PRIMARY_FIELD.equals(columnInfo.getProperty())) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index >= 0) {
|
||||
ColumnInfo removedColumnInfo = columnInfoList.remove(index);
|
||||
idInfos.add(new IdInfo(removedColumnInfo));
|
||||
}
|
||||
}
|
||||
|
||||
tableInfo.setLogicDeleteColumn(logicDeleteColumn);
|
||||
tableInfo.setVersionColumn(versionColumn);
|
||||
tableInfo.setTenantIdColumn(tenantIdColumn);
|
||||
@ -378,6 +373,48 @@ public class TableInfoFactory {
|
||||
return tableInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 typeHandler
|
||||
* 参考 {@link TypeHandlerRegistry#getInstance(Class, Class)}
|
||||
*
|
||||
* @param entityClass
|
||||
* @param field
|
||||
* @param typeHandlerClass
|
||||
* @param fieldType
|
||||
*/
|
||||
private static TypeHandler<?> createCollectionTypeHandler(Class<?> entityClass, Field field, Class<?> typeHandlerClass, Class<?> fieldType) {
|
||||
Class<?> genericClass = null;
|
||||
Type genericType = TypeParameterResolver.resolveFieldType(field, entityClass);
|
||||
if (genericType instanceof ParameterizedType) {
|
||||
Type actualTypeArgument = ((ParameterizedType) genericType).getActualTypeArguments()[0];
|
||||
if (actualTypeArgument instanceof Class) {
|
||||
genericClass = (Class<?>) actualTypeArgument;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Constructor<?> constructor = typeHandlerClass.getConstructor(Class.class, Class.class);
|
||||
return (TypeHandler<?>) constructor.newInstance(fieldType, genericClass);
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
} catch (Exception e) {
|
||||
throw new TypeException("Failed invoking constructor for handler " + typeHandlerClass, e);
|
||||
}
|
||||
try {
|
||||
Constructor<?> constructor = typeHandlerClass.getConstructor(Class.class);
|
||||
return (TypeHandler<?>) constructor.newInstance(fieldType);
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
} catch (Exception e) {
|
||||
throw new TypeException("Failed invoking constructor for handler " + typeHandlerClass, e);
|
||||
}
|
||||
try {
|
||||
Constructor<?> c = typeHandlerClass.getConstructor();
|
||||
return (TypeHandler<?>) c.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new TypeException("Unable to find a usable constructor for " + typeHandlerClass, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static String getColumnName(boolean isCamelToUnderline, Field field, Column column) {
|
||||
if (column != null && StringUtil.isNotBlank(column.value())) {
|
||||
return column.value();
|
||||
|
||||
@ -92,12 +92,12 @@ public class UpdateChain<T> extends QueryWrapperAdapter<UpdateChain<T>> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateChain<T> set(LambdaGetter<T> getter, Object value, boolean condition) {
|
||||
public <L> UpdateChain<T> set(LambdaGetter<L> getter, Object value, boolean condition) {
|
||||
entityWrapper.set(getter, value, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateChain<T> set(LambdaGetter<T> getter, Object value) {
|
||||
public <L> UpdateChain<T> set(LambdaGetter<L> getter, Object value) {
|
||||
entityWrapper.set(getter, value);
|
||||
return this;
|
||||
}
|
||||
@ -123,12 +123,12 @@ public class UpdateChain<T> extends QueryWrapperAdapter<UpdateChain<T>> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateChain<T> setRaw(LambdaGetter<T> getter, Object value, boolean condition) {
|
||||
public <L> UpdateChain<T> setRaw(LambdaGetter<L> getter, Object value, boolean condition) {
|
||||
entityWrapper.setRaw(getter, value, condition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateChain<T> setRaw(LambdaGetter<T> getter, Object value) {
|
||||
public <L> UpdateChain<T> setRaw(LambdaGetter<L> getter, Object value) {
|
||||
entityWrapper.setRaw(getter, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ public class LambdaUtil {
|
||||
|
||||
public static <T> Class<?> getImplClass(LambdaGetter<T> getter) {
|
||||
SerializedLambda lambda = getSerializedLambda(getter);
|
||||
return getImplClass(lambda);
|
||||
return getImplClass(lambda, getter.getClass().getClassLoader());
|
||||
}
|
||||
|
||||
|
||||
@ -56,9 +56,10 @@ public class LambdaUtil {
|
||||
|
||||
|
||||
public static <T> QueryColumn getQueryColumn(LambdaGetter<T> getter) {
|
||||
ClassLoader classLoader = getter.getClass().getClassLoader();
|
||||
SerializedLambda lambda = getSerializedLambda(getter);
|
||||
String methodName = lambda.getImplMethodName();
|
||||
Class<?> entityClass = getImplClass(lambda);
|
||||
Class<?> entityClass = getImplClass(lambda, classLoader);
|
||||
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
|
||||
return tableInfo.getQueryColumnByProperty(PropertyNamer.methodToProperty(methodName));
|
||||
}
|
||||
@ -77,11 +78,11 @@ public class LambdaUtil {
|
||||
}
|
||||
|
||||
|
||||
private static Class<?> getImplClass(SerializedLambda lambda) {
|
||||
private static Class<?> getImplClass(SerializedLambda lambda, ClassLoader classLoader) {
|
||||
String implClass = getImplClassName(lambda);
|
||||
return MapUtil.computeIfAbsent(classMap, implClass, s -> {
|
||||
try {
|
||||
return Class.forName(s.replace("/", "."));
|
||||
return Class.forName(s.replace("/", "."), true, classLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw FlexExceptions.wrap(e);
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ package com.mybatisflex.core.util;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.regex.Matcher;
|
||||
@ -146,7 +147,7 @@ public class SqlUtil {
|
||||
if (value == null) {
|
||||
return "null";
|
||||
}
|
||||
// number
|
||||
// number or bool
|
||||
else if (value instanceof Number || value instanceof Boolean) {
|
||||
return value.toString();
|
||||
}
|
||||
@ -165,7 +166,7 @@ public class SqlUtil {
|
||||
if (value instanceof Date) {
|
||||
sb.append(DateUtil.toDateTimeString((Date) value));
|
||||
} else if (value instanceof LocalDateTime) {
|
||||
sb.append(DateUtil.toDateTimeString(DateUtil.toDate((LocalDateTime) value)));
|
||||
sb.append(((LocalDateTime) value).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
} else {
|
||||
sb.append(value);
|
||||
}
|
||||
|
||||
@ -359,6 +359,21 @@ public class AccountSqlTester {
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testJoin4Sql() {
|
||||
QueryWrapper query = QueryWrapper.create()
|
||||
.select(ACCOUNT.ALL_COLUMNS,
|
||||
column("bui.user_code"),
|
||||
column("bui.user_name"),
|
||||
column("burmc.user_name as created_by_name"))
|
||||
.from(ACCOUNT).as("burm")
|
||||
.leftJoin("base_admin_user_info").as("bui").on("bui.user_id = burm.user_id")
|
||||
.leftJoin("base_admin_user_info").as("burmc").on("burmc.user_id = burm.created_by")
|
||||
.where("bui.is_valid = ?", 3);
|
||||
System.out.println(query.toSQL());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinSelf() {
|
||||
QueryWrapper queryWrapper = QueryWrapper.create()
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.coretest;
|
||||
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.util.CollectionUtil;
|
||||
import com.mybatisflex.core.util.StringUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT;
|
||||
|
||||
/**
|
||||
* 动态条件测试。
|
||||
*
|
||||
* @author 王帅
|
||||
* @since 2023-08-10
|
||||
*/
|
||||
public class DynamicConditionTest {
|
||||
|
||||
@Test
|
||||
public void test01() {
|
||||
String sql = QueryWrapper.create()
|
||||
.from(ACCOUNT)
|
||||
.where(ACCOUNT.AGE.ge(18))
|
||||
.or(qw -> qw.where(ACCOUNT.ID.eq(1)), false)
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test02() {
|
||||
List<Integer> idList = Arrays.asList(1, 2, 3);
|
||||
|
||||
String sql = QueryWrapper.create()
|
||||
.from(ACCOUNT)
|
||||
.where(ACCOUNT.ID.in(idList).when(false))
|
||||
.where(ACCOUNT.ID.in(idList, CollectionUtil::isNotEmpty))
|
||||
.where(ACCOUNT.ID.in(idList).when(idList::isEmpty))
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03() {
|
||||
String sql = QueryWrapper.create()
|
||||
.from(ACCOUNT)
|
||||
.where(ACCOUNT.ID.eq("1", StringUtil::isNumeric))
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04() {
|
||||
String sql = QueryWrapper.create()
|
||||
.from(ACCOUNT)
|
||||
.where(ACCOUNT.ID.between('1', '2', (start, end) -> start < end))
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
}
|
||||
@ -52,4 +52,27 @@ public class FunctionSqlTest {
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test03() {
|
||||
String sql = QueryWrapper.create()
|
||||
.select()
|
||||
.from(ACCOUNT)
|
||||
.where(upper(ACCOUNT.USER_NAME).likeRaw(raw("UPPER('ws')")))
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04() {
|
||||
String sql = QueryWrapper.create()
|
||||
.select()
|
||||
.from(ACCOUNT)
|
||||
// .where("FIND_IN_SET(?, `id`)", 100)
|
||||
.where(findInSet(number(100), ACCOUNT.ID).eq(true))
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
72
mybatis-flex-kotlin/pom.xml
Executable file
72
mybatis-flex-kotlin/pom.xml
Executable file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mybatis-flex-kotlin</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<kotlin.version>1.9.0</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>${mybatis-flex.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<configuration>
|
||||
<args>
|
||||
<arg>-Xjvm-default=all</arg>
|
||||
</args>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>process-sources</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.db
|
||||
|
||||
import java.util.NoSuchElementException
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* 数据库配置对象,暂时未启用
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
object DbConfig {
|
||||
|
||||
var url: String by IfNullVar { "" }
|
||||
var username: String by IfNullVar { "" }
|
||||
var password: String by IfNullVar { "" }
|
||||
|
||||
|
||||
}
|
||||
|
||||
class IfNullVar<T : Any>(private var init: (() -> T)?) : ReadWriteProperty<Any?, T> {
|
||||
private var _value: T? = null
|
||||
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||
if (_value == null && init != null) {
|
||||
synchronized(this) {
|
||||
if (_value == null) {
|
||||
_value = init?.invoke()
|
||||
//释放引用
|
||||
init = null
|
||||
}
|
||||
}
|
||||
}
|
||||
return this._value?:throw NoSuchElementException()
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||
_value = value
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.entry
|
||||
|
||||
import com.mybatisflex.core.dialect.DialectFactory
|
||||
import com.mybatisflex.core.row.Db.*
|
||||
import com.mybatisflex.core.table.TableInfoFactory
|
||||
import com.mybatisflex.core.util.ArrayUtil
|
||||
import java.io.Serializable
|
||||
/**
|
||||
* 实体类父类,继承该类后将赋予实体简单增删改操作
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
open class Entry :Serializable{
|
||||
|
||||
fun save(ignoreNulls: Boolean = true): Boolean {
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(this.javaClass)
|
||||
//设置乐观锁版本字段的初始化数据
|
||||
tableInfo.initVersionValueIfNecessary(this)
|
||||
//设置租户ID
|
||||
tableInfo.initTenantIdIfNecessary(this)
|
||||
//设置逻辑删除字段的出初始化数据
|
||||
tableInfo.initLogicDeleteValueIfNecessary(this)
|
||||
//执行 onInsert 监听器
|
||||
tableInfo.invokeOnInsertListener(this)
|
||||
val values = tableInfo.buildInsertSqlArgs(this, ignoreNulls)
|
||||
val sql = DialectFactory.getDialect().forInsertEntity(tableInfo, this, ignoreNulls)
|
||||
return insertBySql(sql, *values) == 1
|
||||
}
|
||||
|
||||
fun update(ignoreNulls: Boolean = true): Boolean {
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(this.javaClass)
|
||||
//执行 onUpdate 监听器
|
||||
tableInfo.invokeOnUpdateListener(this)
|
||||
val updateValues = tableInfo.buildUpdateSqlArgs(this, ignoreNulls, false)
|
||||
val primaryValues = tableInfo.buildPkSqlArgs(this)
|
||||
val tenantIdArgs = tableInfo.buildTenantIdArgs()
|
||||
val sql = DialectFactory.getDialect().forUpdateEntity(tableInfo, this, ignoreNulls)
|
||||
return updateBySql(sql, *ArrayUtil.concat(updateValues, primaryValues, tenantIdArgs)) == 1
|
||||
}
|
||||
|
||||
fun deleteById(): Boolean {
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(this.javaClass)
|
||||
val primaryValues = tableInfo.buildPkSqlArgs(this)
|
||||
val allValues = ArrayUtil.concat(primaryValues, tableInfo.buildTenantIdArgs())
|
||||
val sql = DialectFactory.getDialect().forDeleteEntityById(tableInfo)
|
||||
return deleteBySql(sql, *allValues) == 1
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.extensions.db
|
||||
|
||||
import com.mybatisflex.core.BaseMapper
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap
|
||||
import com.mybatisflex.core.query.QueryColumn
|
||||
import com.mybatisflex.core.query.QueryCondition
|
||||
import com.mybatisflex.core.row.Db.selectListByQuery
|
||||
import com.mybatisflex.core.row.Db.selectOneByQuery
|
||||
import com.mybatisflex.core.row.Row
|
||||
import com.mybatisflex.core.table.TableDef
|
||||
import com.mybatisflex.core.table.TableInfoFactory
|
||||
import com.mybatisflex.kotlin.extensions.entry.filter
|
||||
import com.mybatisflex.kotlin.extensions.entry.toEntities
|
||||
import com.mybatisflex.kotlin.scope.QueryScope
|
||||
import com.mybatisflex.kotlin.scope.queryScope
|
||||
|
||||
|
||||
/**
|
||||
* 数据库简单操作扩展
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
inline fun <reified M : BaseMapper<*>> mapper(): M = MybatisFlexBootstrap.getInstance().getMapper(M::class.java)
|
||||
|
||||
inline fun <reified T : Any> queryOne(
|
||||
vararg columns: QueryColumn,
|
||||
schema: String? = null,
|
||||
tableName: String? = null,
|
||||
noinline init: QueryScope.() -> Unit
|
||||
): T = queryRow(schema = schema, tableName = tableName, columns = columns, init = init).toEntity(T::class.java)
|
||||
|
||||
|
||||
fun queryRow(
|
||||
vararg columns: QueryColumn?,
|
||||
schema: String? = null,
|
||||
tableName: String? = null,
|
||||
init: QueryScope.() -> Unit
|
||||
): Row =
|
||||
selectOneByQuery(
|
||||
schema,
|
||||
tableName,
|
||||
queryScope(columns = columns, init = init)
|
||||
)
|
||||
|
||||
|
||||
inline fun <reified T> query(
|
||||
vararg columns: QueryColumn?,
|
||||
schema: String? = null,
|
||||
tableName: String? = null,
|
||||
noinline init: QueryScope.() -> Unit
|
||||
): List<T> =
|
||||
queryRows(schema = schema, tableName = tableName, columns = columns, init = init)
|
||||
.toEntities()
|
||||
|
||||
fun queryRows(
|
||||
vararg columns: QueryColumn?,
|
||||
schema: String? = null,
|
||||
tableName: String? = null,
|
||||
init: QueryScope.() -> Unit
|
||||
): List<Row> = selectListByQuery(
|
||||
schema,tableName,queryScope(columns = columns, init = init)
|
||||
)
|
||||
|
||||
// filter-----------
|
||||
inline fun <reified E> filter(
|
||||
tableName: String,
|
||||
schema: String,
|
||||
vararg columns: QueryColumn?,
|
||||
queryCondition: QueryCondition = QueryCondition.createEmpty()
|
||||
): List<E> = selectListByQuery(
|
||||
schema,
|
||||
tableName,
|
||||
queryScope(*columns).where(queryCondition)
|
||||
).toEntities()
|
||||
|
||||
inline fun <reified E> filter(
|
||||
vararg columns: QueryColumn?,
|
||||
init: () -> QueryCondition
|
||||
): List<E> {
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(E::class.java)
|
||||
return filter<E>(
|
||||
columns = columns,
|
||||
schema = tableInfo.schema,
|
||||
tableName = tableInfo.tableName,
|
||||
queryCondition = init()
|
||||
)
|
||||
}
|
||||
|
||||
inline fun <reified E, T : TableDef> filter(
|
||||
tableDef: T,
|
||||
vararg columns: QueryColumn?,
|
||||
init: T.() -> QueryCondition
|
||||
): List<E> = tableDef.filter(columns = columns, init = init)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.extensions.entry
|
||||
|
||||
import com.mybatisflex.core.FlexConsts
|
||||
import com.mybatisflex.core.dialect.DialectFactory
|
||||
import com.mybatisflex.core.query.QueryColumn
|
||||
import com.mybatisflex.core.query.QueryCondition
|
||||
import com.mybatisflex.core.row.Db.*
|
||||
import com.mybatisflex.kotlin.extensions.db.*
|
||||
import com.mybatisflex.core.row.Row
|
||||
import com.mybatisflex.core.row.RowUtil
|
||||
import com.mybatisflex.core.table.TableDef
|
||||
import com.mybatisflex.core.table.TableInfoFactory
|
||||
import com.mybatisflex.core.util.ArrayUtil
|
||||
import com.mybatisflex.kotlin.entry.Entry
|
||||
import com.mybatisflex.kotlin.scope.QueryScope
|
||||
import java.util.Arrays
|
||||
|
||||
/*
|
||||
* 实体操作扩展
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
|
||||
infix fun <T> Row.to(entryClass: Class<T>): T {
|
||||
return RowUtil.toEntity(this, entryClass)
|
||||
}
|
||||
|
||||
inline fun <reified E, T : TableDef> T.filter(
|
||||
vararg columns: QueryColumn?,
|
||||
init: T.() -> QueryCondition
|
||||
): List<E> {
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(E::class.java)
|
||||
return filter<E>(
|
||||
columns = columns,
|
||||
schema = tableInfo.schema,
|
||||
tableName = tableInfo.tableName,
|
||||
queryCondition = init()
|
||||
)
|
||||
}
|
||||
|
||||
inline fun <reified E> TableDef.query(
|
||||
vararg columns: QueryColumn?,
|
||||
noinline init: QueryScope.() -> Unit
|
||||
): List<E> {
|
||||
return query<E>(
|
||||
columns = columns,
|
||||
schema = this.schema,
|
||||
tableName = this.tableName,
|
||||
init = init
|
||||
)
|
||||
}
|
||||
|
||||
inline fun <reified E> TableDef.all(): List<E> = selectAll(schema, tableName).toEntities()
|
||||
|
||||
inline fun <reified E> Collection<Row>.toEntities() = map { it to E::class.java }.toList()
|
||||
|
||||
inline fun<reified E:Entry> List<E>.batchInsert(): Boolean {
|
||||
val entities = this
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(E::class.java)
|
||||
for (entity in entities) {
|
||||
tableInfo.initVersionValueIfNecessary(entity)
|
||||
tableInfo.initTenantIdIfNecessary(entity)
|
||||
tableInfo.initLogicDeleteValueIfNecessary(entity)
|
||||
//执行 onInsert 监听器
|
||||
tableInfo.invokeOnInsertListener(entity)
|
||||
}
|
||||
var allValues = FlexConsts.EMPTY_ARRAY
|
||||
for (entity in entities) {
|
||||
allValues = ArrayUtil.concat(allValues, tableInfo.buildInsertSqlArgs(entity, false))
|
||||
}
|
||||
val sql = DialectFactory.getDialect().forInsertEntityBatch(tableInfo, entities)
|
||||
return insertBySql(sql,*allValues) > 1
|
||||
}
|
||||
|
||||
|
||||
fun< E:Entry> List<E>.batchUpdate(): Boolean = all(Entry::update)
|
||||
|
||||
inline fun<reified E:Entry> List<E>. batchDeleteById(): Boolean {
|
||||
val tableInfo = TableInfoFactory.ofEntityClass(E::class.java)
|
||||
val primaryValues = this.map { tableInfo.buildPkSqlArgs(it) }.stream().flatMap(Arrays::stream).toArray()
|
||||
val tenantIdArgs = tableInfo.buildTenantIdArgs()
|
||||
val sql = DialectFactory.getDialect().forDeleteEntityBatchByIds(tableInfo, primaryValues)
|
||||
return deleteBySql(sql,*ArrayUtil.concat(primaryValues, tenantIdArgs)) > 1
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.extensions.mapper
|
||||
|
||||
import com.mybatisflex.core.BaseMapper
|
||||
import com.mybatisflex.core.query.QueryCondition
|
||||
import com.mybatisflex.kotlin.scope.QueryScope
|
||||
import com.mybatisflex.kotlin.scope.queryScope
|
||||
/*
|
||||
* 映射器操作扩展
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
fun <T> BaseMapper<*>.queryList(init: (QueryScope.() -> Unit)? = null): List<T> =
|
||||
this.selectListByQuery(queryScope(init = init)) as List<T>
|
||||
|
||||
fun <T> BaseMapper<T>.update(entity: T, init: () -> QueryCondition): Int =
|
||||
this.updateByCondition(entity, init())
|
||||
|
||||
fun <T> BaseMapper<T>.delete(init: (QueryScope.() -> Unit)? = null): Int =
|
||||
this.deleteByQuery(queryScope(init = init))
|
||||
|
||||
fun <T> BaseMapper<T>.delete1(init: () -> QueryCondition): Int =
|
||||
this.deleteByCondition(init())
|
||||
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.extensions.sql
|
||||
|
||||
import com.mybatisflex.core.query.Joiner
|
||||
import com.mybatisflex.core.query.QueryColumn
|
||||
import com.mybatisflex.core.query.QueryCondition
|
||||
import com.mybatisflex.core.query.QueryWrapper
|
||||
import java.util.function.Consumer
|
||||
/*
|
||||
* sql操作扩展
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
infix fun QueryColumn.eq(value: Any?): QueryCondition {
|
||||
return this.eq(value)
|
||||
}
|
||||
|
||||
inline fun QueryCondition.andIf(test: Boolean, block: () -> QueryCondition): QueryCondition {
|
||||
if (test) {
|
||||
this.and(block())
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
inline fun QueryCondition.orIf(test: Boolean, block: () -> QueryCondition): QueryCondition {
|
||||
if (test) {
|
||||
this.or(block())
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
inline fun `if`(test: Boolean, block: () -> QueryCondition): QueryCondition {
|
||||
if (test) {
|
||||
return block()
|
||||
}
|
||||
return QueryCondition.createEmpty()
|
||||
}
|
||||
|
||||
infix fun QueryColumn.like(value: String): QueryCondition = this.like(value)
|
||||
|
||||
infix fun QueryCondition.and(other: QueryCondition): QueryCondition = this.and(other)
|
||||
|
||||
infix fun QueryCondition.or(other: QueryCondition): QueryCondition = this.or(other)
|
||||
|
||||
infix fun QueryColumn.`=`(value: Any?): QueryCondition = this.eq(value)
|
||||
|
||||
infix fun QueryColumn.`in`(value: Collection<Any>): QueryCondition = this.`in`(value)
|
||||
|
||||
fun QueryColumn.`in`(vararg values: Array<Any>): QueryCondition = this.`in`(values.asList())
|
||||
|
||||
infix fun QueryWrapper.`as`(alias: String) = this.`as`(alias)
|
||||
|
||||
infix fun <M> Joiner<M>.`as`(alias: String?): Joiner<M> = this.`as`(alias)
|
||||
|
||||
infix fun <M> Joiner<M>.on(on: String?): M = this.on(on)
|
||||
|
||||
infix fun <M> Joiner<M>.on(on: QueryCondition?): M = this.on(on)
|
||||
|
||||
infix fun <M> Joiner<M>.on(consumer: Consumer<QueryWrapper?>): M = this.on(consumer)
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package com.mybatisflex.kotlin.scope
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap
|
||||
import javax.sql.DataSource
|
||||
|
||||
class BootstrapScope(private val instant: MybatisFlexBootstrap = MybatisFlexBootstrap.getInstance()) {
|
||||
|
||||
fun dataSources(dataSourceScope: DataSourceScope.() -> Unit) =
|
||||
dataSourceScope(DataSourceScope(instant))
|
||||
|
||||
|
||||
operator fun <T> Class<T>.unaryPlus(): MybatisFlexBootstrap =
|
||||
instant.addMapper(this)
|
||||
|
||||
operator fun DataSource.unaryPlus(): MybatisFlexBootstrap =
|
||||
instant.setDataSource(this)
|
||||
|
||||
infix fun String.of(dataSource: DataSource): MybatisFlexBootstrap =
|
||||
instant.setDataSource(this, dataSource)
|
||||
|
||||
}
|
||||
|
||||
class DataSourceScope(private val bootstrap: MybatisFlexBootstrap) {
|
||||
|
||||
|
||||
fun dataSource(dataSourceKey: String, dataSource: DataSource) =
|
||||
bootstrap.addDataSource(dataSourceKey, dataSource)
|
||||
|
||||
// infix fun String.of(dataSource: DataSource) =
|
||||
// bootstrap.addDataSource(this, dataSource)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun buildBootstrap(
|
||||
instant: MybatisFlexBootstrap = MybatisFlexBootstrap.getInstance(),
|
||||
scope: BootstrapScope.(MybatisFlexBootstrap) -> Unit
|
||||
): MybatisFlexBootstrap {
|
||||
scope(BootstrapScope(instant), instant)
|
||||
return instant
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.kotlin.scope
|
||||
|
||||
import com.mybatisflex.core.query.QueryColumn
|
||||
import com.mybatisflex.core.query.QueryCondition
|
||||
import com.mybatisflex.core.query.QueryWrapper
|
||||
import com.mybatisflex.core.table.TableDef
|
||||
/**
|
||||
* 查询作用域
|
||||
* @author 卡莫sama(yuanjiashuai)
|
||||
* @date 2023/8/7
|
||||
*/
|
||||
class QueryScope :QueryWrapper() {
|
||||
companion object CurrentQueryScope : ThreadLocal<QueryScope>()
|
||||
|
||||
fun from(init: (QueryScope.() -> Unit)? = null): QueryWrapper = this.from(queryScope(init = init))
|
||||
|
||||
fun <T : TableDef> where(tableDef: T, build: T.() -> QueryCondition): QueryWrapper = this.where(build(tableDef))
|
||||
|
||||
fun where(build: QueryScope.() -> QueryCondition): QueryWrapper = this.where(build(this))
|
||||
|
||||
operator fun String.get(name: String): QueryColumn = QueryColumn(this, name)
|
||||
|
||||
operator fun String.unaryMinus(): QueryColumn = QueryColumn(this)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun queryScope(vararg columns: QueryColumn?, init: (QueryScope.() -> Unit)? = null): QueryWrapper {
|
||||
val builder = QueryScope()
|
||||
|
||||
if (columns.isNotEmpty()) {
|
||||
builder.select(*columns)
|
||||
}
|
||||
//用于嵌套查询拿到上层查询包装对象
|
||||
init?.also {
|
||||
val prentQueryScope = QueryScope.get()
|
||||
QueryScope.set(builder)
|
||||
it(builder)
|
||||
QueryScope.set(prentQueryScope)
|
||||
}
|
||||
|
||||
return builder
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -95,6 +95,7 @@
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-rm-datasource</artifactId>
|
||||
<version>1.7.0</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
@ -86,7 +86,7 @@ public class MultiDataSourceAutoConfiguration {
|
||||
DataSourceManager.decryptDataSource(dataSource);
|
||||
|
||||
if (seataConfig != null && seataConfig.isEnable()) {
|
||||
if (seataConfig.getSeataMode() == SeataMode.XA) {
|
||||
if (seataConfig.getSeataMode() == MybatisFlexProperties.SeataMode.XA) {
|
||||
dataSource = new DataSourceProxyXA(dataSource);
|
||||
} else {
|
||||
dataSource = new DataSourceProxy(dataSource);
|
||||
|
||||
@ -41,6 +41,7 @@ import java.util.stream.Stream;
|
||||
/**
|
||||
* Mybatis-Flex 的配置属性。
|
||||
* 参考:https://github.com/mybatis/spring-boot-starter/blob/master/mybatis-spring-boot-autoconfigure/src/main/java/org/mybatis/spring/boot/autoconfigure/MybatisProperties.java
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Kazuki Shimizu
|
||||
* @author micahel
|
||||
@ -777,22 +778,36 @@ public class MybatisFlexProperties {
|
||||
private Object normalValueOfLogicDelete = FlexConsts.LOGIC_DELETE_NORMAL;
|
||||
|
||||
/**
|
||||
* 逻辑删除数据删除标记值,
|
||||
* 逻辑删除数据删除标记值。
|
||||
*/
|
||||
private Object deletedValueOfLogicDelete = FlexConsts.LOGIC_DELETE_DELETED;
|
||||
|
||||
|
||||
/**
|
||||
* 默认的分页查询时的每页数据量
|
||||
* 默认的分页查询时的每页数据量。
|
||||
*/
|
||||
private int defaultPageSize = 10;
|
||||
|
||||
|
||||
/**
|
||||
* 默认的 Relation 注解查询深度
|
||||
* 默认的 Relation 注解查询深度。
|
||||
*/
|
||||
private int defaultRelationQueryDepth = 2;
|
||||
|
||||
/**
|
||||
* 默认的逻辑删除字段。
|
||||
*/
|
||||
private String logicDeleteColumn = "del_flag";
|
||||
|
||||
/**
|
||||
* 默认的多租户字段。
|
||||
*/
|
||||
private String tenantColumn = "tenant_id";
|
||||
|
||||
/**
|
||||
* 默认的乐观锁字段。
|
||||
*/
|
||||
private String versionColumn = "version";
|
||||
|
||||
public boolean isPrintBanner() {
|
||||
return printBanner;
|
||||
@ -842,6 +857,30 @@ public class MybatisFlexProperties {
|
||||
this.defaultRelationQueryDepth = defaultRelationQueryDepth;
|
||||
}
|
||||
|
||||
public String getLogicDeleteColumn() {
|
||||
return logicDeleteColumn;
|
||||
}
|
||||
|
||||
public void setLogicDeleteColumn(String logicDeleteColumn) {
|
||||
this.logicDeleteColumn = logicDeleteColumn;
|
||||
}
|
||||
|
||||
public String getTenantColumn() {
|
||||
return tenantColumn;
|
||||
}
|
||||
|
||||
public void setTenantColumn(String tenantColumn) {
|
||||
this.tenantColumn = tenantColumn;
|
||||
}
|
||||
|
||||
public String getVersionColumn() {
|
||||
return versionColumn;
|
||||
}
|
||||
|
||||
public void setVersionColumn(String versionColumn) {
|
||||
this.versionColumn = versionColumn;
|
||||
}
|
||||
|
||||
void applyTo(FlexGlobalConfig target) {
|
||||
PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||
mapper.from(isPrintBanner()).to(target::setPrintBanner);
|
||||
@ -850,6 +889,9 @@ public class MybatisFlexProperties {
|
||||
mapper.from(getDeletedValueOfLogicDelete()).to(target::setDeletedValueOfLogicDelete);
|
||||
mapper.from(getDefaultPageSize()).to(target::setDefaultPageSize);
|
||||
mapper.from(getDefaultRelationQueryDepth()).to(target::setDefaultRelationQueryDepth);
|
||||
mapper.from(getLogicDeleteColumn()).to(target::setLogicDeleteColumn);
|
||||
mapper.from(getVersionColumn()).to(target::setVersionColumn);
|
||||
mapper.from(getTenantColumn()).to(target::setTenantColumn);
|
||||
}
|
||||
|
||||
}
|
||||
@ -908,7 +950,7 @@ public class MybatisFlexProperties {
|
||||
*
|
||||
* @author life
|
||||
*/
|
||||
public static class SeataConfig{
|
||||
public static class SeataConfig {
|
||||
|
||||
/**
|
||||
* 是否开启
|
||||
@ -935,6 +977,18 @@ public class MybatisFlexProperties {
|
||||
public void setSeataMode(SeataMode seataMode) {
|
||||
this.seataMode = seataMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @author life
|
||||
*/
|
||||
public enum SeataMode {
|
||||
|
||||
XA,
|
||||
|
||||
AT
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -39,8 +39,6 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@ -88,6 +88,6 @@ public class FlexSpringTransaction implements Transaction {
|
||||
|
||||
@Override
|
||||
public Integer getTimeout() throws SQLException {
|
||||
return getConnection().getNetworkTimeout();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,6 @@ import org.apache.ibatis.session.Configuration;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
|
||||
import org.apache.ibatis.transaction.TransactionFactory;
|
||||
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
import org.mybatis.logging.Logger;
|
||||
import org.mybatis.logging.LoggerFactory;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ public class Account extends BaseEntity implements Serializable, AgeAware {
|
||||
@Column(typeHandler = Fastjson2TypeHandler.class)
|
||||
private Map<String, Object> options;
|
||||
|
||||
@Column(isLogicDelete = true)
|
||||
// @Column(isLogicDelete = true)
|
||||
private Boolean isDelete;
|
||||
|
||||
private List<Article> articles;
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.FlexGlobalConfig;
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
@ -23,6 +24,7 @@ import com.mybatisflex.core.mybatis.Mappers;
|
||||
import com.mybatisflex.core.query.If;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.row.DbChain;
|
||||
import com.mybatisflex.core.update.UpdateChain;
|
||||
import com.mybatisflex.core.update.UpdateWrapper;
|
||||
import com.mybatisflex.core.util.UpdateEntity;
|
||||
import com.mybatisflex.mapper.ArticleMapper;
|
||||
@ -52,6 +54,9 @@ public class AccountTester {
|
||||
.addScript("data.sql")
|
||||
.build();
|
||||
|
||||
FlexGlobalConfig.getDefaultConfig()
|
||||
.setLogicDeleteColumn("is_delete");
|
||||
|
||||
MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance()
|
||||
.setDataSource(dataSource)
|
||||
.setLogImpl(StdOutImpl.class)
|
||||
@ -71,6 +76,11 @@ public class AccountTester {
|
||||
articleMapper = bootstrap.getMapper(ArticleMapper.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogicDelete() {
|
||||
accountMapper.selectAll().forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExecutor() {
|
||||
DbChain.create()
|
||||
@ -139,7 +149,7 @@ public class AccountTester {
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
public void testUpdate1() {
|
||||
List<Account> accounts = accountMapper.selectAll();
|
||||
System.out.println(accounts);
|
||||
|
||||
@ -154,7 +164,25 @@ public class AccountTester {
|
||||
|
||||
accounts = accountMapper.selectAll();
|
||||
System.out.println(accounts);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testUpdate2() {
|
||||
List<Account> accounts = accountMapper.selectAll();
|
||||
System.out.println(accounts);
|
||||
|
||||
|
||||
UpdateChain.of(Account.class)
|
||||
.set(Account::getUserName,"zhangsan123")
|
||||
// .leftJoin(ARTICLE).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID))
|
||||
.where(Account::getId).eq(1)
|
||||
// .and(ARTICLE.ID.ge(0))
|
||||
.limit(1)
|
||||
.remove();
|
||||
|
||||
accounts = accountMapper.selectAll();
|
||||
System.out.println(accounts);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.audit.MessageCollector;
|
||||
import com.mybatisflex.core.row.Db;
|
||||
import com.mybatisflex.mapper.ArticleMapper;
|
||||
import org.apache.ibatis.logging.nologging.NoLoggingImpl;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author 王帅
|
||||
* @since 2023-08-10
|
||||
*/
|
||||
public class ArticleTester {
|
||||
|
||||
static ArticleMapper articleMapper;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
DataSource dataSource = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("schema.sql")
|
||||
.addScript("data.sql")
|
||||
.build();
|
||||
|
||||
MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance()
|
||||
.setDataSource(dataSource)
|
||||
.setLogImpl(NoLoggingImpl.class)
|
||||
.addMapper(ArticleMapper.class)
|
||||
.start();
|
||||
|
||||
//开启审计功能
|
||||
AuditManager.setAuditEnable(true);
|
||||
|
||||
//设置 SQL 审计收集器
|
||||
MessageCollector collector = new ConsoleMessageCollector();
|
||||
AuditManager.setMessageCollector(collector);
|
||||
|
||||
|
||||
articleMapper = bootstrap.getMapper(ArticleMapper.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBatch() {
|
||||
int count = 10;
|
||||
|
||||
Collection<Article> articles = new ArrayList<>(count);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Article article = new Article();
|
||||
article.setTitle("title" + i);
|
||||
articles.add(article);
|
||||
}
|
||||
|
||||
Db.executeBatch(articles, ArticleMapper.class, ArticleMapper::insertOrUpdateSelective);
|
||||
|
||||
articleMapper.selectAll().forEach(System.out::println);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.util.ClassUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class LambdaTester {
|
||||
|
||||
static Function<Account, List<Article>> getArticles = Account::getArticles;
|
||||
static BiConsumer<Account, List<Article>> setArticles = Account::setArticles;
|
||||
|
||||
static Map<String,Function<?,?>> getters = new HashMap<>();
|
||||
{
|
||||
getters.put("getArticles",getArticles);
|
||||
}
|
||||
static Map<String,BiConsumer<?,?>> setters = new HashMap<>();
|
||||
{
|
||||
setters.put("setArticles",setArticles);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
LambdaTester a = new LambdaTester();
|
||||
|
||||
// Function getArticles = JavaTester.getArticles;
|
||||
Function getArticles =getters.get("getArticles");
|
||||
|
||||
Account account = new Account();
|
||||
|
||||
Method method = ClassUtil.getFirstMethod(Account.class, method1 -> "getArticles".equals(method1.getName()));
|
||||
|
||||
|
||||
method.invoke(account);
|
||||
List<Article> apply = ( List<Article>)getArticles.apply(account);
|
||||
|
||||
|
||||
long timeMillis = System.currentTimeMillis();
|
||||
for (int i = 0; i < 100000000; i++) {
|
||||
List<Article> apply1 = (List<Article>) method.invoke(account);
|
||||
}
|
||||
|
||||
System.out.println(">>>>> invoke: " +(System.currentTimeMillis() - timeMillis));
|
||||
|
||||
timeMillis = System.currentTimeMillis();
|
||||
for (int i = 0; i < 100000000; i++) {
|
||||
List<Article> apply2 = ( List<Article>)getArticles.apply(account);
|
||||
}
|
||||
|
||||
System.out.println(">>>>> apply: " +(System.currentTimeMillis() - timeMillis));
|
||||
}
|
||||
|
||||
|
||||
// public static interface FlexFunction<T,R>{
|
||||
// R apply(T t);
|
||||
// }
|
||||
|
||||
}
|
||||
@ -16,7 +16,10 @@
|
||||
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.annotation.*;
|
||||
import com.mybatisflex.annotation.ColumnMask;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import com.mybatisflex.core.mask.Masks;
|
||||
|
||||
import java.util.Date;
|
||||
@ -34,7 +37,7 @@ public class TenantAccount {
|
||||
|
||||
private Date birthday;
|
||||
|
||||
@Column(tenantId = true)
|
||||
// @Column(tenantId = true)
|
||||
private Long tenantId;
|
||||
|
||||
public Long getId() {
|
||||
|
||||
@ -18,8 +18,6 @@ package com.mybatisflex.test;
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.tenant.TenantFactory;
|
||||
import com.mybatisflex.core.tenant.TenantManager;
|
||||
import com.mybatisflex.mapper.TenantAccountMapper;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
@ -27,10 +25,6 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import static com.mybatisflex.core.query.QueryMethods.select;
|
||||
import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT;
|
||||
import static com.mybatisflex.test.table.TenantAccountTableDef.TENANT_ACCOUNT;
|
||||
|
||||
public class TenantTester {
|
||||
|
||||
public static void main(String[] args) {
|
||||
@ -52,24 +46,22 @@ public class TenantTester {
|
||||
AuditManager.setMessageCollector(new ConsoleMessageCollector());
|
||||
|
||||
//配置 tenantFactory
|
||||
TenantManager.setTenantFactory(new TenantFactory() {
|
||||
@Override
|
||||
public Object[] getTenantIds() {
|
||||
return new Object[]{1, 2};
|
||||
}
|
||||
});
|
||||
TenantManager.setTenantFactory(() -> new Object[]{1, 2});
|
||||
|
||||
TenantAccountMapper mapper = MybatisFlexBootstrap.getInstance().getMapper(TenantAccountMapper.class);
|
||||
TenantAccountMapper mapper = MybatisFlexBootstrap.getInstance()
|
||||
.getMapper(TenantAccountMapper.class);
|
||||
|
||||
mapper.selectListByQuery(QueryWrapper.create()
|
||||
.select(TENANT_ACCOUNT.ALL_COLUMNS)
|
||||
.from(TENANT_ACCOUNT.as("c"), ACCOUNT.as("b"))
|
||||
.where(TENANT_ACCOUNT.ID.eq(ACCOUNT.ID))
|
||||
.and(TENANT_ACCOUNT.ID.eq(1))
|
||||
.unionAll(select(TENANT_ACCOUNT.ALL_COLUMNS).from(TENANT_ACCOUNT)
|
||||
.where(TENANT_ACCOUNT.ID.eq(2))
|
||||
)
|
||||
);
|
||||
mapper.selectAll().forEach(System.out::println);
|
||||
|
||||
// mapper.selectListByQuery(QueryWrapper.create()
|
||||
// .select(TENANT_ACCOUNT.ALL_COLUMNS)
|
||||
// .from(TENANT_ACCOUNT.as("c"), ACCOUNT.as("b"))
|
||||
// .where(TENANT_ACCOUNT.ID.eq(ACCOUNT.ID))
|
||||
// .and(TENANT_ACCOUNT.ID.eq(1))
|
||||
// .unionAll(select(TENANT_ACCOUNT.ALL_COLUMNS).from(TENANT_ACCOUNT)
|
||||
// .where(TENANT_ACCOUNT.ID.eq(2))
|
||||
// )
|
||||
// );
|
||||
|
||||
// mapper.deleteBatchByIds(Arrays.asList(1, 2));
|
||||
|
||||
|
||||
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
@ -15,6 +31,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT;
|
||||
import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE;
|
||||
|
||||
public class UpdateChainTest {
|
||||
|
||||
@ -69,4 +86,17 @@ public class UpdateChainTest {
|
||||
.list()
|
||||
.forEach(System.out::println);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateChainToSql() {
|
||||
String sql = UpdateChain.of(Account.class)
|
||||
.set(ACCOUNT.AGE, 18)
|
||||
.set(Article::getAccountId, 4, 1 == 1)
|
||||
.leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
|
||||
.where(ACCOUNT.ID.eq(4))
|
||||
.toSQL();
|
||||
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,5 +4,5 @@ CREATE TABLE IF NOT EXISTS `tb_account`
|
||||
`user_name` VARCHAR(100),
|
||||
`age` INTEGER,
|
||||
`birthday` DATETIME,
|
||||
`tenant_id` INTEGER(11)
|
||||
);
|
||||
`tenant_id` INTEGER
|
||||
);
|
||||
|
||||
@ -0,0 +1 @@
|
||||
processor.mapper.generateEnable=true
|
||||
67
mybatis-flex-test/mybatis-flex-seata-test/pom.xml
Normal file
67
mybatis-flex-test/mybatis-flex-seata-test/pom.xml
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mybatis-flex-seata-test</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>${mybatis-flex.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.32</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.2.18</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-spring-boot-starter</artifactId>
|
||||
<version>1.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.mybatisflex.test.mapper")
|
||||
public class MybatisFlexSpringBootSeataApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MybatisFlexSpringBootSeataApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test.controller;
|
||||
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.audit.MessageCollector;
|
||||
import com.mybatisflex.test.service.TestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class TestController {
|
||||
|
||||
|
||||
@Autowired
|
||||
TestService testService;
|
||||
|
||||
@RequestMapping("buy")
|
||||
public String buy() {
|
||||
//开启审计功能
|
||||
AuditManager.setAuditEnable(true);
|
||||
//设置 SQL 审计收集器
|
||||
MessageCollector collector = new ConsoleMessageCollector();
|
||||
AuditManager.setMessageCollector(collector);
|
||||
return String.valueOf(testService.buy());
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,13 +1,26 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
@ -1,13 +1,26 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
@ -1,13 +1,26 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
|
||||
import java.io.Serializable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
@ -1,23 +1,37 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.service;
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.test.service;
|
||||
|
||||
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.AccountTbl;
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.OrderTbl;
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.StockTbl;
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.table.AccountTblTableDef;
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.AccountTblMapper;
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.OrderTblMapper;
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.StockTblMapper;
|
||||
import com.mybatisflex.core.datasource.DataSourceKey;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.test.entity.AccountTbl;
|
||||
import com.mybatisflex.test.entity.OrderTbl;
|
||||
import com.mybatisflex.test.entity.StockTbl;
|
||||
import com.mybatisflex.test.entity.table.AccountTblTableDef;
|
||||
import com.mybatisflex.test.mapper.AccountTblMapper;
|
||||
import com.mybatisflex.test.mapper.OrderTblMapper;
|
||||
import com.mybatisflex.test.mapper.StockTblMapper;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.spring.annotation.GlobalTransactional;
|
||||
import org.mybatis.logging.Logger;
|
||||
import org.mybatis.logging.LoggerFactory;
|
||||
import org.mybatis.spring.SqlSessionFactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class TestService {
|
||||
@ -33,12 +47,12 @@ public class TestService {
|
||||
@Autowired
|
||||
StockTblMapper stockTblMapper;
|
||||
|
||||
// @Transactional
|
||||
// @Transactional
|
||||
@GlobalTransactional
|
||||
public boolean buy() {
|
||||
// DataSourceKey.use("accountdb");
|
||||
LOGGER.warn(() -> "xid:"+RootContext.getXID());
|
||||
QueryWrapper account =new QueryWrapper();
|
||||
LOGGER.warn(() -> "xid:" + RootContext.getXID());
|
||||
QueryWrapper account = new QueryWrapper();
|
||||
account.where(AccountTblTableDef.ACCOUNT_TBL.USER_ID.eq("1001"));
|
||||
AccountTbl accountTbl = accountTblMapper.selectOneByQuery(account);
|
||||
accountTbl.setMoney(accountTbl.getMoney() - 5);
|
||||
@ -59,4 +73,5 @@ public class TestService {
|
||||
orderTblMapper.insert(orderTbl);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -13,14 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.spring.boot;
|
||||
|
||||
/**
|
||||
* @author life
|
||||
*/
|
||||
public enum SeataMode {
|
||||
package com.mybatisflex.test;
|
||||
|
||||
XA,
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class MybatisFlexSpringBootSeataApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
AT
|
||||
}
|
||||
@ -1,155 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
</parent>
|
||||
<groupId>com.mybatisfle.test</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-seata</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>mybatis-flex-spring-boot-seata</name>
|
||||
<description>mybatis-flex-spring-boot-seata</description>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>${mybatis-flex.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-codegen</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.32</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>1.2.18</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
|
||||
<!-- <version>2.7.9</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework</groupId>-->
|
||||
<!-- <artifactId>spring-jdbc</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.h2database</groupId>-->
|
||||
<!-- <artifactId>h2</artifactId>-->
|
||||
<!-- <version>2.1.214</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.yaml</groupId>-->
|
||||
<!-- <artifactId>snakeyaml</artifactId>-->
|
||||
<!-- <version>1.33</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>RELEASE</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-spring-boot-starter</artifactId>
|
||||
<version>1.7.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
</project>
|
||||
@ -1,15 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@MapperScan("com.mybatisfle.test.mybatisflexspringbootseata")
|
||||
@SpringBootApplication
|
||||
public class MybatisFlexSpringBootSeataApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MybatisFlexSpringBootSeataApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.controller;
|
||||
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.service.TestService;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.audit.MessageCollector;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
public class TestController {
|
||||
|
||||
|
||||
@Autowired
|
||||
TestService testService;
|
||||
|
||||
@RequestMapping("buy")
|
||||
public String buy(){
|
||||
//开启审计功能
|
||||
AuditManager.setAuditEnable(true);
|
||||
//设置 SQL 审计收集器
|
||||
MessageCollector collector = new ConsoleMessageCollector();
|
||||
AuditManager.setMessageCollector(collector);
|
||||
String flag =String.valueOf(testService.buy());
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
|
||||
|
||||
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.AccountTbl;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
*
|
||||
* @author life
|
||||
* @since 2023-08-03
|
||||
*/
|
||||
public interface AccountTblMapper extends BaseMapper<AccountTbl> {
|
||||
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
|
||||
|
||||
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.OrderTbl;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
*
|
||||
* @author life
|
||||
* @since 2023-08-03
|
||||
*/
|
||||
public interface OrderTblMapper extends BaseMapper<OrderTbl> {
|
||||
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
|
||||
|
||||
|
||||
import com.mybatisfle.test.mybatisflexspringbootseata.entity.StockTbl;
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
|
||||
/**
|
||||
* 映射层。
|
||||
*
|
||||
* @author life
|
||||
* @since 2023-08-03
|
||||
*/
|
||||
public interface StockTblMapper extends BaseMapper<StockTbl> {
|
||||
|
||||
}
|
||||
@ -1,88 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata.utils;
|
||||
|
||||
import com.mybatisflex.codegen.Generator;
|
||||
import com.mybatisflex.codegen.config.ColumnConfig;
|
||||
import com.mybatisflex.codegen.config.GlobalConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
public class Codegen {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//配置数据源
|
||||
HikariDataSource dataSource = new HikariDataSource();
|
||||
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/db_stock?characterEncoding=utf-8");
|
||||
dataSource.setUsername("root");
|
||||
dataSource.setPassword("131496");
|
||||
|
||||
//创建配置内容,两种风格都可以。
|
||||
GlobalConfig globalConfig = createGlobalConfigUseStyle1();
|
||||
//GlobalConfig globalConfig = createGlobalConfigUseStyle2();
|
||||
|
||||
//通过 datasource 和 globalConfig 创建代码生成器
|
||||
Generator generator = new Generator(dataSource, globalConfig);
|
||||
|
||||
//生成代码
|
||||
generator.generate();
|
||||
}
|
||||
|
||||
public static GlobalConfig createGlobalConfigUseStyle1() {
|
||||
//创建配置内容
|
||||
GlobalConfig globalConfig = new GlobalConfig();
|
||||
|
||||
//设置根包
|
||||
globalConfig.setBasePackage("com.mybatisfle.test.mybatisflexspringbootseata");
|
||||
|
||||
//设置表前缀和只生成哪些表
|
||||
globalConfig.setGenerateSchema("db_stock");
|
||||
// globalConfig.setTablePrefix("tb_");
|
||||
globalConfig.setGenerateTable("stock_tbl");
|
||||
|
||||
//设置生成 entity 并启用 Lombok
|
||||
globalConfig.setEntityGenerateEnable(true);
|
||||
globalConfig.setEntityWithLombok(true);
|
||||
|
||||
//设置生成 mapper
|
||||
globalConfig.setMapperGenerateEnable(true);
|
||||
|
||||
//可以单独配置某个列
|
||||
// ColumnConfig columnConfig = new ColumnConfig();
|
||||
// columnConfig.setColumnName("tenant_id");
|
||||
// columnConfig.setLarge(true);
|
||||
// columnConfig.setVersion(true);
|
||||
// globalConfig.setColumnConfig("account", columnConfig);
|
||||
|
||||
return globalConfig;
|
||||
}
|
||||
|
||||
public static GlobalConfig createGlobalConfigUseStyle2() {
|
||||
//创建配置内容
|
||||
GlobalConfig globalConfig = new GlobalConfig();
|
||||
|
||||
//设置根包
|
||||
globalConfig.getPackageConfig()
|
||||
.setBasePackage("com.test");
|
||||
|
||||
//设置表前缀和只生成哪些表,setGenerateTable 未配置时,生成所有表
|
||||
globalConfig.getStrategyConfig()
|
||||
.setGenerateSchema("schema")
|
||||
.setTablePrefix("tb_")
|
||||
.setGenerateTable("account", "account_session");
|
||||
|
||||
//设置生成 entity 并启用 Lombok
|
||||
globalConfig.enableEntity()
|
||||
.setWithLombok(true);
|
||||
|
||||
//设置生成 mapper
|
||||
globalConfig.enableMapper();
|
||||
|
||||
//可以单独配置某个列
|
||||
ColumnConfig columnConfig = new ColumnConfig();
|
||||
columnConfig.setColumnName("tenant_id");
|
||||
columnConfig.setLarge(true);
|
||||
columnConfig.setVersion(true);
|
||||
globalConfig.getStrategyConfig()
|
||||
.setColumnConfig("account", columnConfig);
|
||||
|
||||
return globalConfig;
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
package com.mybatisfle.test.mybatisflexspringbootseata;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class MybatisFlexSpringBootSeataApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.5.6</version>
|
||||
<version>1.5.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user