Compare commits

...

391 Commits

Author SHA1 Message Date
yulichang
1b72884fcb fix https://github.com/yulichang/mybatis-plus-join/issues/283 2025-06-26 23:23:34 +08:00
dependabot[bot]
9463cb6437 chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.5.0 to 3.5.3.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.5.0...v3.5.3)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-version: 3.5.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-24 22:03:06 +08:00
dependabot[bot]
7614007346 chore(deps): bump org.noear:solon from 3.3.2 to 3.3.3
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.3.2...v3.3.3)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.3.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-24 22:02:26 +08:00
dependabot[bot]
5c3cd62a5f chore(deps): bump org.noear:solon from 3.3.1 to 3.3.2
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/commits)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-12 08:22:49 +08:00
dependabot[bot]
a8b4f77753 chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.4.5 to 3.5.0.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.5...v3.5.0)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-07 01:11:49 +08:00
dependabot[bot]
0ffac304b9 chore(deps): bump org.noear:solon from 3.3.0 to 3.3.1
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.3.0...v3.3.1)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-07 01:05:35 +08:00
yulichang
399609c9fb
Update maven.yml 2025-05-28 14:29:20 +08:00
yulichang
28392edd61 升级依赖 2025-05-21 19:05:45 +08:00
yulichang
8e8eb6afdd fix https://gitee.com/best_handsome/mybatis-plus-join/issues/IC8VI5 2025-05-21 18:17:43 +08:00
dependabot[bot]
0356b4c201 chore(deps): bump org.noear:solon from 3.2.1 to 3.3.0
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.2.1 to 3.3.0.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.2.1...v3.3.0)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-15 18:06:02 +08:00
dependabot[bot]
6d847adce5 chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.4.4 to 3.4.5.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.4...v3.4.5)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-version: 3.4.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-29 23:33:48 +08:00
dependabot[bot]
65e466c0e7 chore(deps): bump org.noear:solon from 3.2.0 to 3.2.1
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.2.0...v3.2.1)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-29 17:34:44 +08:00
dependabot[bot]
91e0528da5 chore(deps): bump org.noear:solon from 3.1.2 to 3.2.0
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.1.2...v3.2.0)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-22 15:13:13 +08:00
dependabot[bot]
a1c309949a chore(deps): bump org.noear:solon from 3.1.1 to 3.1.2
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.1.1 to 3.1.2.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.1.1...v3.1.2)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-version: 3.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-08 11:54:59 +08:00
dependabot[bot]
683d640d81 chore(deps): bump org.noear:solon from 3.1.0 to 3.1.1
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 06:16:47 +08:00
dependabot[bot]
7b03ca05d4 chore(deps): bump ognl:ognl from 3.4.6 to 3.4.7
Bumps [ognl:ognl](https://github.com/orphan-oss/ognl) from 3.4.6 to 3.4.7.
- [Release notes](https://github.com/orphan-oss/ognl/releases)
- [Commits](https://github.com/orphan-oss/ognl/commits)

---
updated-dependencies:
- dependency-name: ognl:ognl
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 06:16:37 +08:00
yulichang
3bd8a78e6b 1.5.3 2025-03-26 02:20:03 +08:00
dependabot[bot]
c056475a12 chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.4.3 to 3.4.4.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.3...v3.4.4)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-26 02:09:10 +08:00
yulichang
cd82858357 升级mybatis-plus版本 2025-03-26 01:44:28 +08:00
yulichang
20b21c6d9d 升级mybatis-plus版本 2025-03-26 01:24:59 +08:00
yulichang
cbedb2f58c Merge branch 'v' 2025-03-26 01:11:51 +08:00
yulichang
0b9577e7c4 升级mybatis-plus版本 2025-03-26 01:10:14 +08:00
dependabot[bot]
bb2c8115e0 chore(deps): bump org.noear:solon from 3.0.9 to 3.1.0
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.9 to 3.1.0.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.9...v3.1.0)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 16:58:27 +08:00
dependabot[bot]
6a314b1b70 chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.13.0 to 3.14.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.13.0...maven-compiler-plugin-3.14.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-26 00:56:15 +08:00
dependabot[bot]
d27318503e chore(deps): bump ognl:ognl from 3.4.5 to 3.4.6
Bumps [ognl:ognl](https://github.com/orphan-oss/ognl) from 3.4.5 to 3.4.6.
- [Release notes](https://github.com/orphan-oss/ognl/releases)
- [Commits](https://github.com/orphan-oss/ognl/commits)

---
updated-dependencies:
- dependency-name: ognl:ognl
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-26 00:54:25 +08:00
dependabot[bot]
44e5a5e79d chore(deps): bump org.noear:solon from 3.0.8 to 3.0.9
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.8 to 3.0.9.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.8...v3.0.9)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-26 00:54:15 +08:00
dependabot[bot]
609234dd2e chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.4.2 to 3.4.3.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.2...v3.4.3)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-26 00:54:04 +08:00
yulichang
40b6eff2cc
Update pom.xml 2025-02-19 18:40:49 +08:00
dependabot[bot]
9eb7aac005 chore(deps): bump org.noear:solon from 3.0.7 to 3.0.8
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.7 to 3.0.8.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.7...v3.0.8)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-19 03:47:46 +08:00
yulichang
08d3b1cf9b Merge branch 'refs/heads/master1' 2025-02-17 18:46:55 +08:00
yulichang
b029065187 升级mybatis-plus版本 2025-02-17 18:42:44 +08:00
dependabot[bot]
46a23bfb99 chore(deps): bump org.noear:solon from 3.0.6 to 3.0.7
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.6 to 3.0.7.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.6...v3.0.7)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-04 18:57:28 +08:00
dependabot[bot]
6327dcd15e chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.4.1 to 3.4.2.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.1...v3.4.2)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-04 18:57:17 +08:00
dependabot[bot]
c50da64608 chore(deps): bump org.noear:solon from 3.0.5 to 3.0.6
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.5 to 3.0.6.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.5...v3.0.6)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-15 23:34:27 +08:00
dependabot[bot]
e93b72bad7 chore(deps): bump ognl:ognl from 3.4.4 to 3.4.5
Bumps [ognl:ognl](https://github.com/orphan-oss/ognl) from 3.4.4 to 3.4.5.
- [Release notes](https://github.com/orphan-oss/ognl/releases)
- [Commits](https://github.com/orphan-oss/ognl/commits)

---
updated-dependencies:
- dependency-name: ognl:ognl
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-07 18:02:08 +08:00
dependabot[bot]
93c81ab043 chore(deps): bump ognl:ognl from 3.4.3 to 3.4.4
Bumps [ognl:ognl](https://github.com/orphan-oss/ognl) from 3.4.3 to 3.4.4.
- [Release notes](https://github.com/orphan-oss/ognl/releases)
- [Commits](https://github.com/orphan-oss/ognl/commits)

---
updated-dependencies:
- dependency-name: ognl:ognl
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 09:04:51 +08:00
dependabot[bot]
9f2a79693e chore(deps): bump org.noear:solon from 3.0.4.1 to 3.0.5
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.4.1 to 3.0.5.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.4.1...v3.0.5)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-01 09:03:19 +08:00
dependabot[bot]
5067324103 chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.4.0...v3.4.1)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-24 19:22:19 +08:00
dependabot[bot]
b3f56f9292 chore(deps): bump org.noear:solon from 3.0.4 to 3.0.4.1
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.4 to 3.0.4.1.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.4...v3.0.4.1)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-18 19:00:16 +08:00
dependabot[bot]
0b065266a1 chore(deps): bump org.noear:solon from 3.0.3 to 3.0.4
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.3 to 3.0.4.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.3...v3.0.4)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-10 15:23:16 +08:00
dependabot[bot]
7c8afeaa98 chore(deps): bump org.springframework.boot:spring-boot-dependencies
Bumps [org.springframework.boot:spring-boot-dependencies](https://github.com/spring-projects/spring-boot) from 3.3.5 to 3.4.0.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.5...v3.4.0)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-dependencies
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-27 03:16:06 +08:00
yulichang
0353f972e7 子查询添加union 2024-11-19 21:41:31 +08:00
yulichang
4401ad8ca6 调整 2024-11-13 17:17:42 +08:00
yulichang
42a63cf4d1 依赖调整为 com.baomidou:mybatis-plus-solon-plugin 2024-11-12 17:42:21 +08:00
dependabot[bot]
9dd1cfbde7 chore(deps): bump org.noear:solon from 3.0.2 to 3.0.3
Bumps [org.noear:solon](https://github.com/noear/solon) from 3.0.2 to 3.0.3.
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v3.0.2...v3.0.3)

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-12 17:13:39 +08:00
yulichang
9173f6e5c8 add brackets option 2024-11-12 17:10:57 +08:00
yulichang
6abb21a5ee 调整 2024-11-05 12:24:09 +08:00
yulichang
d7f7f19fac fix: applyFunc 子查询异常 2024-11-01 16:24:40 +08:00
yulichang
8ecc698723 调整 2024-10-31 18:25:49 +08:00
yulichang
6e1c7945c6 调整 2024-10-31 18:09:36 +08:00
yulichang
3db7995d34 调整 2024-10-31 17:27:43 +08:00
yulichang
34d920196f 调整 2024-10-31 14:20:33 +08:00
yulichang
2c5b8678d6 调整 2024-10-31 13:56:51 +08:00
yulichang
5d16d68d4e 1.5.2 2024-10-31 13:51:09 +08:00
yulichang
0ed4bb2278 调整 2024-10-31 13:50:43 +08:00
yulichang
034c341f5c feat: join string sql support param 2024-10-31 10:03:54 +08:00
yulichang
ce3548c7d2 调整 2024-10-30 21:13:53 +08:00
yulichang
eb3cecf626 Merge branch 'refs/heads/master' into snapshot
# Conflicts:
#	pom.xml
2024-10-30 16:01:34 +08:00
yulichang
5b61dfedd8 add repository test 2024-10-30 15:59:53 +08:00
yulichang
effdc96299 feat: wrapper ext 2024-10-30 15:46:06 +08:00
yulichang
720934500f fix: https://gitee.com/best_handsome/mybatis-plus-join/issues/IB0OUN 2024-10-30 10:44:57 +08:00
yulichang
56ef6c57f7 调整 2024-10-30 10:44:19 +08:00
yulichang
4d38516ea2 调整 2024-10-30 10:43:56 +08:00
yulichang
30629ee12a 调整 2024-10-29 16:11:37 +08:00
yulichang
117f465646 调整 2024-10-29 16:08:57 +08:00
yulichang
f2b3308d53 pom 调整 2024-10-29 16:06:15 +08:00
yulichang
1f3a73056d 代码调整 2024-10-29 09:57:16 +08:00
yulichang
14ea2c45b0 调整名称 2024-10-27 21:45:32 +08:00
yulichang
9e65e33301 添加 deploy action 2024-10-27 17:36:58 +08:00
yulichang
b4ce33141d 添加子查询 2024-10-26 21:08:37 +08:00
yulichang
0a05f48032 调整pom 2024-10-25 10:34:16 +08:00
yulichang
15ec4b86b1
Create maven.yml 2024-10-25 10:14:19 +08:00
yulichang
4c4fae44a1 Merge branch 'master' of https://github.com/yulichang/mybatis-plus-join 2024-10-24 14:44:20 +08:00
yulichang
7ee3f52d95 MP 升级 3.5.9 2024-10-24 14:43:14 +08:00
dependabot[bot]
cc08e57540 chore(deps): bump com.mysql:mysql-connector-j from 9.0.0 to 9.1.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 9.0.0 to 9.1.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/9.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/9.0.0...9.1.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-24 14:11:16 +08:00
dependabot[bot]
e562c159d1 chore(deps): bump org.springframework:spring-jdbc from 6.1.13 to 6.1.14
Bumps [org.springframework:spring-jdbc](https://github.com/spring-projects/spring-framework) from 6.1.13 to 6.1.14.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.13...v6.1.14)

---
updated-dependencies:
- dependency-name: org.springframework:spring-jdbc
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-24 14:11:08 +08:00
dependabot[bot]
7abd8550a3 chore(deps): bump org.springframework:spring-aop from 6.1.13 to 6.1.14
Bumps [org.springframework:spring-aop](https://github.com/spring-projects/spring-framework) from 6.1.13 to 6.1.14.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.13...v6.1.14)

---
updated-dependencies:
- dependency-name: org.springframework:spring-aop
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-24 14:11:01 +08:00
yulichang
3c27dc921c fix: https://github.com/yulichang/mybatis-plus-join/issues/212 2024-10-22 08:53:04 +08:00
dependabot[bot]
484eb831dc chore(deps): bump org.jetbrains.kotlin:kotlin-stdlib-jdk8
Bumps [org.jetbrains.kotlin:kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 2.0.20 to 2.0.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v2.0.21/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.0.20...v2.0.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-16 18:08:38 +08:00
dependabot[bot]
bac3938b11 chore(deps-dev): bump org.jetbrains.kotlin:kotlin-test-junit
Bumps [org.jetbrains.kotlin:kotlin-test-junit](https://github.com/JetBrains/kotlin) from 2.0.20 to 2.0.21.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v2.0.21/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.0.20...v2.0.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-test-junit
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-16 18:08:29 +08:00
dependabot[bot]
c2dfbf29b4 chore(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin
Bumps org.jetbrains.kotlin:kotlin-maven-plugin from 2.0.20 to 2.0.21.

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-16 18:08:20 +08:00
yulichang
7e4b778f79 feat: join support wrapper 2024-10-16 17:58:26 +08:00
yulichang
047faf4891 feat: selectFunc support Object param 2024-10-16 17:58:24 +08:00
yulichang
51f39d1129 fix: setParamAlias 2024-10-12 17:08:12 +08:00
dependabot[bot]
951316e84f chore(deps): bump solon.version from 2.9.4 to 3.0.1
Bumps `solon.version` from 2.9.4 to 3.0.1.

Updates `org.noear:solon` from 2.9.4 to 3.0.1
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/commits)

Updates `org.noear:mybatis-solon-plugin` from 2.9.4 to 3.0.1

Updates `org.noear:mybatis-plus-extension-solon-plugin` from 2.9.4 to 3.0.1

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: org.noear:mybatis-solon-plugin
  dependency-type: direct:production
  update-type: version-update:semver-major
- dependency-name: org.noear:mybatis-plus-extension-solon-plugin
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-08 13:35:32 +08:00
yulichang
7e3ee68d73 1.5.1 2024-10-08 10:56:13 +08:00
yulichang
6a5983aad4 优化代码 2024-10-07 17:10:41 +08:00
dependabot[bot]
8495c7c153 chore(deps): bump com.fasterxml.jackson.core:jackson-databind
Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.17.2 to 2.18.0.
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-04 22:23:49 +08:00
yulichang
5fd49c83e7 feat: selectSub add String alias 2024-10-04 22:21:05 +08:00
yulichang
5a7416345a Merge branch 'refs/heads/proce'
# Conflicts:
#	plugin/mybatis-plus-join-processor/pom.xml
2024-10-04 13:12:56 +08:00
yulichang
6947d89697 add enable 2024-10-04 13:09:21 +08:00
yulichang
5c587a3bfe add scan 2024-10-04 11:19:33 +08:00
yulichang
27444dda74 feat: add fill 2024-10-01 19:06:43 +08:00
yulichang
52a0eb3cc9 fix https://github.com/yulichang/mybatis-plus-join/issues/205 2024-09-30 19:10:17 +08:00
yulichang
543c987983 修改pom 2024-09-24 10:09:50 +08:00
yulichang
ec56620e4d 修改pom 2024-09-24 10:06:44 +08:00
yulichang
81013e34b7 修改pom 2024-09-24 10:04:05 +08:00
dependabot[bot]
280e9901ed chore(deps): bump solon.varrsion from 2.9.3 to 2.9.4
Bumps `solon.varrsion` from 2.9.3 to 2.9.4.

Updates `org.noear:solon` from 2.9.3 to 2.9.4
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/commits)

Updates `org.noear:mybatis-solon-plugin` from 2.9.3 to 2.9.4

Updates `org.noear:mybatis-plus-extension-solon-plugin` from 2.9.3 to 2.9.4

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.noear:mybatis-solon-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.noear:mybatis-plus-extension-solon-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 04:28:31 +08:00
dependabot[bot]
b6d04d5ea4 chore(deps): bump org.springframework.boot:spring-boot-configuration-processor
Bumps [org.springframework.boot:spring-boot-configuration-processor](https://github.com/spring-projects/spring-boot) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.3...v3.3.4)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-configuration-processor
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 04:28:24 +08:00
dependabot[bot]
7e30322e2b chore(deps): bump org.springframework.boot:spring-boot-starter-parent
Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 3.3.3 to 3.3.4.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.3...v3.3.4)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-starter-parent
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 04:28:16 +08:00
yulichang
bee3f83dea 同步mp相关代码 2024-09-20 13:54:44 +08:00
yulichang
0519bd47ee 添加返回MP实体的join方法 2024-09-20 12:23:24 +08:00
yulichang
31662a6e9e 移除Map代码 2024-09-20 11:21:23 +08:00
yulichang
d604be19ac update mybatis plus version to 3.5.8 2024-09-19 10:09:42 +08:00
yulichang
5269f3a535 update maven plugin 2024-09-17 13:33:30 +08:00
dependabot[bot]
ae6116ce95 chore(deps): bump com.h2database:h2 from 2.2.220 to 2.3.232
Bumps [com.h2database:h2](https://github.com/h2database/h2database) from 2.2.220 to 2.3.232.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.2.220...version-2.3.232)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-15 01:04:38 +08:00
dependabot[bot]
646fefaada chore(deps): bump com.mysql:mysql-connector-j from 8.2.0 to 9.0.0
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.2.0 to 9.0.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/9.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.2.0...9.0.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-15 01:04:30 +08:00
dependabot[bot]
754cf726fd chore(deps): bump org.springframework:spring-aop from 5.3.36 to 6.1.13
Bumps [org.springframework:spring-aop](https://github.com/spring-projects/spring-framework) from 5.3.36 to 6.1.13.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.36...v6.1.13)

---
updated-dependencies:
- dependency-name: org.springframework:spring-aop
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-15 01:04:23 +08:00
dependabot[bot]
c898aa56c4 chore(deps-dev): bump org.jetbrains.kotlin:kotlin-test-junit
Bumps [org.jetbrains.kotlin:kotlin-test-junit](https://github.com/JetBrains/kotlin) from 1.8.21 to 2.0.20.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.21...v2.0.20)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-test-junit
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-15 01:04:15 +08:00
dependabot[bot]
7a05056e6f chore(deps): bump org.jetbrains.kotlin:kotlin-stdlib-jdk8
Bumps [org.jetbrains.kotlin:kotlin-stdlib-jdk8](https://github.com/JetBrains/kotlin) from 1.8.21 to 2.0.20.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.8.21...v2.0.20)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-15 01:02:56 +08:00
yulichang
8bc94f2038 update dependabot.yml 2024-09-15 00:51:26 +08:00
yulichang
fd0e559c3a update dependabot.yml 2024-09-14 23:56:35 +08:00
yulichang
fa95c33847 Revert "chore(deps): bump mpj.mybatis.plus.version from 3.3.0 to 3.5.7"
This reverts commit 33e35ee1fbdf5884654cfef2e8cc126b5b96361d.
2024-09-14 23:16:58 +08:00
yulichang
369ec8db05
Merge pull request #177 from yulichang/dependabot/maven/mpj.mybatis.plus.version-3.5.7
chore(deps): bump mpj.mybatis.plus.version from 3.3.0 to 3.5.7
2024-09-14 23:03:31 +08:00
yulichang
01043008f9
Merge pull request #178 from yulichang/dependabot/maven/org.springframework.boot-spring-boot-configuration-processor-3.3.3
chore(deps): bump org.springframework.boot:spring-boot-configuration-processor from 2.7.18 to 3.3.3
2024-09-14 23:03:19 +08:00
yulichang
9794aa3545
Merge pull request #179 from yulichang/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.13.0
chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.8.1 to 3.13.0
2024-09-14 23:03:11 +08:00
yulichang
3558d94c68
Merge pull request #180 from yulichang/dependabot/maven/org.jetbrains.kotlin-kotlin-maven-plugin-2.0.20
chore(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin from 1.8.21 to 2.0.20
2024-09-14 23:03:02 +08:00
yulichang
9c683963cb
Merge pull request #181 from yulichang/dependabot/maven/com.fasterxml.jackson.core-jackson-databind-2.17.2
chore(deps): bump com.fasterxml.jackson.core:jackson-databind from 2.14.2 to 2.17.2
2024-09-14 23:02:49 +08:00
dependabot[bot]
108ed07bd6
chore(deps): bump com.fasterxml.jackson.core:jackson-databind
Bumps [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) from 2.14.2 to 2.17.2.
- [Commits](https://github.com/FasterXML/jackson/commits)

---
updated-dependencies:
- dependency-name: com.fasterxml.jackson.core:jackson-databind
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 14:59:10 +00:00
dependabot[bot]
ab92b9811f
chore(deps): bump org.jetbrains.kotlin:kotlin-maven-plugin
Bumps org.jetbrains.kotlin:kotlin-maven-plugin from 1.8.21 to 2.0.20.

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 14:59:08 +00:00
dependabot[bot]
2ee52e39a6
chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin
Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.8.1 to 3.13.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.8.1...maven-compiler-plugin-3.13.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 14:59:06 +00:00
dependabot[bot]
5767ad4b1e
chore(deps): bump org.springframework.boot:spring-boot-configuration-processor
Bumps [org.springframework.boot:spring-boot-configuration-processor](https://github.com/spring-projects/spring-boot) from 2.7.18 to 3.3.3.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.18...v3.3.3)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-configuration-processor
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 14:59:03 +00:00
dependabot[bot]
33e35ee1fb
chore(deps): bump mpj.mybatis.plus.version from 3.3.0 to 3.5.7
Bumps `mpj.mybatis.plus.version` from 3.3.0 to 3.5.7.

Updates `com.baomidou:mybatis-plus-boot-starter` from 3.3.0 to 3.5.7
- [Release notes](https://github.com/baomidou/mybatis-plus/releases)
- [Changelog](https://github.com/baomidou/mybatis-plus/blob/3.0/CHANGELOG.md)
- [Commits](https://github.com/baomidou/mybatis-plus/compare/v3.3.0...v3.5.7)

Updates `com.baomidou:mybatis-plus-extension` from 3.5.7 to 3.5.7
- [Release notes](https://github.com/baomidou/mybatis-plus/releases)
- [Changelog](https://github.com/baomidou/mybatis-plus/blob/3.0/CHANGELOG.md)
- [Commits](https://github.com/baomidou/mybatis-plus/compare/v3.5.7...v3.5.7)

Updates `com.baomidou:mybatis-plus-core` from 3.5.5 to 3.5.7
- [Release notes](https://github.com/baomidou/mybatis-plus/releases)
- [Changelog](https://github.com/baomidou/mybatis-plus/blob/3.0/CHANGELOG.md)
- [Commits](https://github.com/baomidou/mybatis-plus/compare/v3.5.5...v3.5.7)

---
updated-dependencies:
- dependency-name: com.baomidou:mybatis-plus-boot-starter
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.baomidou:mybatis-plus-extension
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.baomidou:mybatis-plus-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 14:58:58 +00:00
yulichang
19329cfb28 update jdk to 17 2024-09-14 22:54:52 +08:00
yulichang
b252c474a1
Merge pull request #172 from yulichang/dependabot/maven/solon.varrsion-2.9.3
chore(deps): bump solon.varrsion from 2.8.0 to 2.9.3
2024-09-14 22:32:31 +08:00
yulichang
1a82b74952
Merge pull request #173 from yulichang/dependabot/maven/org.codehaus.mojo-flatten-maven-plugin-1.6.0
chore(deps): bump org.codehaus.mojo:flatten-maven-plugin from 1.5.0 to 1.6.0
2024-09-14 22:32:20 +08:00
yulichang
e3d5187c35
Merge pull request #174 from yulichang/dependabot/maven/org.springframework.boot-spring-boot-starter-parent-3.3.3
chore(deps): bump org.springframework.boot:spring-boot-starter-parent from 2.7.14 to 3.3.3
2024-09-14 22:32:10 +08:00
yulichang
d291edf026
Merge pull request #175 from yulichang/dependabot/maven/org.springframework-spring-jdbc-6.1.13
chore(deps): bump org.springframework:spring-jdbc from 5.3.4 to 6.1.13
2024-09-14 22:31:57 +08:00
yulichang
7e03776471
Merge pull request #176 from yulichang/dependabot/maven/org.projectlombok-lombok-1.18.34
chore(deps): bump org.projectlombok:lombok from 1.18.30 to 1.18.34
2024-09-14 22:31:45 +08:00
dependabot[bot]
9f4a7a0ea0
chore(deps): bump org.projectlombok:lombok from 1.18.30 to 1.18.34
Bumps [org.projectlombok:lombok](https://github.com/projectlombok/lombok) from 1.18.30 to 1.18.34.
- [Changelog](https://github.com/projectlombok/lombok/blob/master/doc/changelog.markdown)
- [Commits](https://github.com/projectlombok/lombok/compare/v1.18.30...v1.18.34)

---
updated-dependencies:
- dependency-name: org.projectlombok:lombok
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 13:14:49 +00:00
dependabot[bot]
cde5c86518
chore(deps): bump org.springframework:spring-jdbc from 5.3.4 to 6.1.13
Bumps [org.springframework:spring-jdbc](https://github.com/spring-projects/spring-framework) from 5.3.4 to 6.1.13.
- [Release notes](https://github.com/spring-projects/spring-framework/releases)
- [Commits](https://github.com/spring-projects/spring-framework/compare/v5.3.4...v6.1.13)

---
updated-dependencies:
- dependency-name: org.springframework:spring-jdbc
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 13:14:46 +00:00
dependabot[bot]
879cecaca9
chore(deps): bump org.springframework.boot:spring-boot-starter-parent
Bumps [org.springframework.boot:spring-boot-starter-parent](https://github.com/spring-projects/spring-boot) from 2.7.14 to 3.3.3.
- [Release notes](https://github.com/spring-projects/spring-boot/releases)
- [Commits](https://github.com/spring-projects/spring-boot/compare/v2.7.14...v3.3.3)

---
updated-dependencies:
- dependency-name: org.springframework.boot:spring-boot-starter-parent
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 13:14:42 +00:00
dependabot[bot]
ad878e454f
chore(deps): bump org.codehaus.mojo:flatten-maven-plugin
Bumps [org.codehaus.mojo:flatten-maven-plugin](https://github.com/mojohaus/flatten-maven-plugin) from 1.5.0 to 1.6.0.
- [Release notes](https://github.com/mojohaus/flatten-maven-plugin/releases)
- [Commits](https://github.com/mojohaus/flatten-maven-plugin/compare/1.5.0...1.6.0)

---
updated-dependencies:
- dependency-name: org.codehaus.mojo:flatten-maven-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 13:14:37 +00:00
dependabot[bot]
bb2b322246
chore(deps): bump solon.varrsion from 2.8.0 to 2.9.3
Bumps `solon.varrsion` from 2.8.0 to 2.9.3.

Updates `org.noear:solon` from 2.8.0 to 2.9.3
- [Release notes](https://github.com/noear/solon/releases)
- [Commits](https://github.com/noear/solon/compare/v2.8.0...v2.9.3)

Updates `org.noear:mybatis-solon-plugin` from 2.8.0 to 2.9.3

Updates `org.noear:mybatis-plus-extension-solon-plugin` from 2.8.0 to 2.9.3

---
updated-dependencies:
- dependency-name: org.noear:solon
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.noear:mybatis-solon-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: org.noear:mybatis-plus-extension-solon-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 13:14:34 +00:00
yulichang
c32988d4b6
Create dependabot.yml 2024-09-14 21:14:10 +08:00
yulichang
6fb8e958f5
Merge pull request #170 from yulichang/dependabot/maven/mybatis-plus-join-test/com.h2database-h2-2.2.220
chore(deps): bump com.h2database:h2 from 2.1.214 to 2.2.220 in /mybatis-plus-join-test
2024-09-14 21:00:15 +08:00
yulichang
5c76932fdc
Merge pull request #171 from yulichang/dependabot/maven/mybatis-plus-join-test/test-kotlin/com.mysql-mysql-connector-j-8.2.0
chore(deps): bump com.mysql:mysql-connector-j from 8.0.32 to 8.2.0 in /mybatis-plus-join-test/test-kotlin
2024-09-14 20:59:55 +08:00
dependabot[bot]
5582305376
chore(deps): bump com.h2database:h2 in /mybatis-plus-join-test
Bumps [com.h2database:h2](https://github.com/h2database/h2database) from 2.1.214 to 2.2.220.
- [Release notes](https://github.com/h2database/h2database/releases)
- [Commits](https://github.com/h2database/h2database/compare/version-2.1.214...version-2.2.220)

---
updated-dependencies:
- dependency-name: com.h2database:h2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 12:55:41 +00:00
dependabot[bot]
1673cfe4c0
chore(deps): bump com.mysql:mysql-connector-j
Bumps [com.mysql:mysql-connector-j](https://github.com/mysql/mysql-connector-j) from 8.0.32 to 8.2.0.
- [Changelog](https://github.com/mysql/mysql-connector-j/blob/release/9.x/CHANGES)
- [Commits](https://github.com/mysql/mysql-connector-j/compare/8.0.32...8.2.0)

---
updated-dependencies:
- dependency-name: com.mysql:mysql-connector-j
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-14 12:55:41 +00:00
yulichang
24b1d51155 处理idea代码警告 2024-09-14 20:23:21 +08:00
yulichang
f319e4b7a1 1.5.0 2024-09-14 15:07:04 +08:00
yulichang
be34118e9d adapter 2024-09-14 14:16:27 +08:00
yulichang
18b2394e7e feat: updateWrapper add setApply api 2024-09-14 11:23:52 +08:00
yulichang
24212523d7 chain add map api 2024-09-14 11:23:18 +08:00
yulichang
110e0cf8a3 update pom 2024-09-14 11:22:30 +08:00
yulichang
1ca477a61a remove mybatis-plus-join 2024-09-14 10:07:04 +08:00
yulichang
7f8723bf0f 修改模板 2024-09-14 10:06:45 +08:00
yulichang
6be7f0bc21 简化代码 2024-09-11 17:45:04 +08:00
yulichang
1b3f294645 优化代码 2024-09-10 01:14:26 +08:00
yulichang
0df22e3adf 优化代码 2024-09-10 01:14:00 +08:00
yulichang
69713b1c39 优化分页 2024-09-09 14:09:26 +08:00
yulichang
064f5ccaa9 优化first 2024-08-25 21:17:00 +08:00
yulichang
42211407cd 修改文档地址 2024-08-21 09:53:56 +08:00
yulichang
ff63c3c141 修改文档地址 2024-08-20 23:09:57 +08:00
yulichang
adada6870c 修改文档地址 2024-08-20 23:05:23 +08:00
yulichang
de49069ccc feat func(condition, consumer , else consumer); 2024-08-17 13:24:09 +08:00
yulichang
a3340741f1 fix https://github.com/yulichang/mybatis-plus-join/issues/163 2024-08-13 14:33:08 +08:00
yulichang
c6b781fc72 调整文件目录 2024-08-10 15:33:57 +08:00
yulichang
99a5190f43 style https://gitee.com/best_handsome/mybatis-plus-join/issues/IAJ3AE 2024-08-10 13:33:41 +08:00
yulichang
ad4df5b939 first 添加分页 2024-08-01 06:46:35 +08:00
yulichang
17936814b0 fix https://github.com/yulichang/mybatis-plus-join/issues/160 2024-07-31 21:18:54 +08:00
yulichang
45b68607a2 fix first npe 2024-07-30 16:09:21 +08:00
yulichang
e92df45f88 Merge branch 'refs/heads/1.5'
# Conflicts:
#	mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/segments/Select.java
#	mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/segments/SelectLabel.java
2024-07-30 15:55:43 +08:00
yulichang
30924c4810 添加 SuppressWarnings 2024-07-30 05:40:45 +08:00
yulichang
4f3f6dac3f 添加缓存 2024-07-30 05:37:03 +08:00
yulichang
19d67fd1a8 简化代码 2024-07-22 03:01:08 +08:00
yulichang
049e54d023 简化代码 2024-07-21 21:50:14 +08:00
yulichang
a3de7ec409 简化代码 2024-07-21 21:13:51 +08:00
yulichang
ac635a91db 简化代码 2024-07-21 20:38:58 +08:00
yulichang
2ee265c213 feat: apt 配置文件 2024-07-19 18:09:24 +08:00
yulichang
7cd632f1ad feat: apt ognl 2024-07-17 02:55:03 +08:00
yulichang
30377e4f5e 调整目录 2024-07-16 03:50:41 +08:00
yulichang
658bb2bb59 fix: 修复apt问题 2024-07-16 03:43:20 +08:00
yulichang
f8e51aa958 fix: 修复apt问题 2024-07-16 01:02:44 +08:00
yulichang
326bd68ade fix: https://github.com/yulichang/mybatis-plus-join/issues/155 2024-07-15 18:12:13 +08:00
yulichang
9d37dd4d7c apt 2024-07-15 02:22:07 +08:00
yulichang
de3504ed5e 简化代码 2024-07-06 23:56:40 +08:00
yulichang
7db13fd882 添加日志 2024-06-26 15:37:27 +08:00
yulichang
f861b9df9c fix: 适配错误 2024-06-19 01:07:26 +08:00
yulichang
dd35dce49f fix: https://github.com/yulichang/mybatis-plus-join/issues/148 2024-06-18 22:56:58 +08:00
yulichang
22ad7c4232 fix: isSelect导致条件查询NPE 2024-06-17 19:03:09 +08:00
yulichang
266d71293f fix: selectSub配置无效 2024-06-16 20:18:20 +08:00
yulichang
86888633f6 chore: update mybatis-plus version 2024-06-11 12:10:43 +08:00
yulichang
f15d94885a docs: readme 2024-06-01 07:55:10 +08:00
yulichang
2838731d29 1.4.13 2024-06-01 07:00:34 +08:00
yulichang
9500ff6d66 feat: selectAll(class,...exclude) 查询全部并排除部分字段 2024-06-01 06:36:15 +08:00
yulichang
f249368ba7 1.4.13 2024-06-01 05:57:53 +08:00
yulichang
629101a774 test: 代码调整 2024-05-31 08:52:15 +08:00
yulichang
79e875f8d1 style: 简化代码 2024-05-31 06:19:46 +08:00
yulichang
7a1afacfcb style: 简化代码 2024-05-28 10:54:31 +08:00
yulichang
c8a21424af style: 简化代码 2024-05-28 10:51:20 +08:00
yulichang
a500230a6b fix: https://gitee.com/best_handsome/mybatis-plus-join/issues/I9GBZI 2024-05-28 07:28:08 +08:00
yulichang
d40c0d46d0 style: 优化代码格式 2024-05-28 05:19:39 +08:00
yulichang
fddb12b943 test: 完善测试代码 2024-05-28 05:01:33 +08:00
yulichang
e93fbe968f fix: https://github.com/yulichang/mybatis-plus-join/issues/127 2024-05-25 08:08:08 +08:00
yulichang
56d60031e8 fix: https://github.com/yulichang/mybatis-plus-join/issues/127 2024-05-25 07:50:40 +08:00
yulichang
5a29504927 fix: https://github.com/yulichang/mybatis-plus-join/issues/127 2024-05-25 06:24:58 +08:00
yulichang
cace18d3bb feat: updateJoin set值支持其他字段 https://gitee.com/best_handsome/mybatis-plus-join/issues/I9G29I 2024-05-25 00:58:37 +08:00
yulichang
321abffa01 feat: 添加 applyFunc(), apply形式的"selectFunc" 2024-05-24 06:03:33 +08:00
yulichang
93d3ab6e1c feat: 添加 applyFunc(), apply形式的"selectFunc" 2024-05-24 05:38:33 +08:00
yulichang
6224140cc1 style: 简化代码 2024-05-24 04:09:00 +08:00
yulichang
42bb8eef3b docs: update solon readme 2024-05-24 02:18:02 +08:00
yulichang
20edf9e822 fix: https://gitee.com/best_handsome/mybatis-plus-join/issues/I9RN5N 2024-05-24 02:01:05 +08:00
yulichang
08e4b70a02 fix: https://github.com/yulichang/mybatis-plus-join/issues/140 2024-05-22 05:19:51 +08:00
yulichang
4d1ad0d26e fix:https://github.com/yulichang/mybatis-plus-join/issues/135 2024-05-18 05:24:23 +08:00
yulichang
4e284e504a readme 2024-05-18 01:53:29 +08:00
yulichang
ad40b925da orderBy支持resultType字段 2024-05-18 00:53:25 +08:00
yulichang
da15b11833 orderBy支持resultType字段 2024-05-18 00:51:07 +08:00
赵志正
54f890f0de feat(inner join): inner join两个表支持别名 2024-05-14 12:24:02 +08:00
yulichang
3d68c143d9 修改文档地址 2024-05-07 13:50:46 +08:00
yulichang
8bd81a368c 修改文档地址 2024-05-07 13:48:45 +08:00
yulichang
0877317078 添加adapter设置 2024-05-04 01:13:02 +08:00
yulichang
57715b11a1 merge PR[80] 2024-04-16 17:10:00 +08:00
yulichang
198736a970
Merge pull request #80 from luckey-ke/master
select为 false 不加入 select 查询范围
2024-04-16 17:00:43 +08:00
yueke
52982356a3
Merge branch 'master' into master 2024-04-11 08:52:36 +08:00
yulichang
84a1cb19a5 1.4.12 2024-04-10 11:24:51 +08:00
yulichang
cbc3709156 添加 字段自增 setIncrBy 自减 setDecrBy 方法 2024-04-10 11:22:02 +08:00
yulichang
67aa1b106a 添加 eqSql api 2024-04-10 10:17:13 +08:00
yulichang
7eb5605fff mp -> 3.5.6 & 适配jsqlparser 2024-04-10 09:38:18 +08:00
yulichang
cd68b2e25d fix [115](https://github.com/yulichang/mybatis-plus-join/issues/115) 2024-04-09 06:47:12 +08:00
yulichang
152cd6c11c fix [115](https://github.com/yulichang/mybatis-plus-join/issues/115) 2024-04-09 06:47:02 +08:00
yulichang
5c57a0aa6e https://github.com/yulichang/mybatis-plus-join/issues/120 2024-03-20 17:37:28 +08:00
yulichang
86d94a0264 1.4.11 2024-03-02 23:59:54 +08:00
yulichang
75f497fd29 添加around 2024-03-02 23:34:21 +08:00
yulichang
44a726ace8 添加around 2024-03-01 17:12:40 +08:00
yulichang
750b216156 fix https://github.com/yulichang/mybatis-plus-join/issues/110 2024-01-30 20:50:45 +08:00
yulichang
a0c8d9c797 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I84S1N https://gitee.com/best_handsome/mybatis-plus-join/issues/I7B6DT https://github.com/yulichang/mybatis-plus-join/issues/73 2024-01-20 15:03:13 +08:00
yulichang
db0d197226 SelectFunc 字段别名 2024-01-19 22:51:22 +08:00
yulichang
f45a807339 SelectFunc 字段别名 2024-01-19 22:51:03 +08:00
yulichang
0db41de3da fix on 配置问题 2024-01-18 13:25:48 +08:00
yulichang
fe3e139826 readme 2024-01-18 11:54:24 +08:00
yulichang
321747ecba readme 2024-01-18 11:53:00 +08:00
yulichang
0a6d71a328 1.4.10 2024-01-17 19:10:24 +08:00
yulichang
3ed76b8ca0 update和delete添加链式调用 2024-01-17 17:05:13 +08:00
yulichang
34e4acdc6a update和delete添加链式调用 2024-01-17 16:48:51 +08:00
yulichang
fde21a04dd 简化代码 2024-01-17 16:34:55 +08:00
yulichang
39942b28ce ifPresent -> ifExists 2024-01-17 14:21:01 +08:00
yulichang
c7ea5485fd 版本升级 2024-01-17 14:12:26 +08:00
yulichang
5acf97e08a solon 2024-01-17 02:20:09 +08:00
yulichang
0475d410d0 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I8WPCL https://gitee.com/best_handsome/mybatis-plus-join/issues/I8WP8Q https://gitee.com/best_handsome/mybatis-plus-join/issues/I83IEV https://github.com/yulichang/mybatis-plus-join/issues/89 2024-01-17 02:17:26 +08:00
yulichang
48c1b6e8a1 solon 2024-01-16 19:38:45 +08:00
yulichang
185d92f054 solon 2024-01-16 13:10:19 +08:00
yulichang
fbce257571 https://gitee.com/best_handsome/mybatis-plus-join/issues/I7OLR3#note_24413498_link 2024-01-16 13:08:23 +08:00
yulichang
05baec13a9 Merge branch 'master' of https://github.com/yulichang/mybatis-plus-join 2024-01-15 13:49:55 +08:00
jera
dfc883eb1a
Merge pull request #104 from tuine/add_check_join
feat: 增加检测表是否已连接
2024-01-15 13:47:55 +08:00
yulichang
a286bf811d solon 2024-01-15 01:13:00 +08:00
yulichang
15fefbd458 注释更正 2024-01-15 00:41:22 +08:00
yulichang
01e12d6a6f 注释更正 2024-01-15 00:29:31 +08:00
tuine
7f859b78d7
feat: 增加检测表是否已连接 2024-01-10 18:02:43 +08:00
yulichang
fb3bf66545 升级springboot版本 2024-01-05 12:37:33 +08:00
yulichang
8a347e4a23 ifPresent 2024-01-05 11:57:07 +08:00
yulichang
26d7ff580b solon 2024-01-05 11:17:12 +08:00
yulichang
aee5f54559 solon 2023-12-31 11:49:50 +08:00
yulichang
f038a10e1e 1.4.9 2023-12-30 15:03:55 +08:00
yulichang
75fc373f2c solon-plugin 2023-12-30 14:52:32 +08:00
yulichang
e021c8281b solon-plugin 2023-12-30 14:30:37 +08:00
yulichang
63e5c3787e 修改类名 2023-12-29 21:33:36 +08:00
yulichang
dbdea7b592 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I8RE0R 2023-12-27 14:55:56 +08:00
yulichang
3d3762f470 MP -> 3.5.5 2023-12-25 23:52:50 +08:00
yulichang
6a6b6415ef MP -> 3.5.5 2023-12-25 23:38:24 +08:00
yulichang
ef3301e7eb 添加notLikeLeft和notLikeRight 2023-12-25 00:57:04 +08:00
yulichang
a2bdce7614 添加ifAbsent 2023-12-24 23:37:14 +08:00
yulichang
a2756a9dde 添加ifAbsent 2023-12-24 23:13:50 +08:00
yulichang
eda25c23f8 添加ifAbsent 2023-12-23 17:00:59 +08:00
yulichang
665e433051 添加ifAbsent 2023-12-23 16:55:51 +08:00
yulichang
a822c4f78e 添加配置方式 2023-12-22 05:01:47 +08:00
yulichang
d0774a06f1 添加配置方式 2023-12-22 03:37:13 +08:00
yulichang
3fbeb1c84a 优化 mapper not find 2023-12-21 06:40:07 +08:00
yulichang
72f155319f 优化 mapper not find 2023-12-18 23:57:52 +08:00
yulichang
d8fa7ddf30 1.4.8.1 2023-12-12 19:44:30 +08:00
yulichang
b8fbc6fc04 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I8NTF1 2023-12-12 19:39:00 +08:00
yulichang
69f673f531 1.4.8 2023-12-11 04:09:02 +08:00
yulichang
2b42b33f41 逻辑删除调整 2023-12-11 04:06:13 +08:00
yulichang
9ce2b519b1 别名优化 2023-12-11 03:42:50 +08:00
yulichang
25b3df16cf 优化idea代码警告 2023-12-10 05:45:42 +08:00
yulichang
8170305daf 字段自定义前缀 2023-12-07 02:08:20 +08:00
yulichang
aa0f9e87bf fix selectSub多次调用报错和优化union 2023-11-17 23:41:14 +08:00
yulichang
630c320cd3 sql换行 2023-11-17 07:19:52 +08:00
yulichang
7b33070fa4 优化字段获取 2023-11-17 06:54:58 +08:00
yulichang
40006863f6 添加模板 2023-11-17 04:18:01 +08:00
yulichang
ab27be7f81 fix https://github.com/yulichang/mybatis-plus-join/issues/92 2023-11-16 20:29:41 +08:00
yulichang
064c0e3bd2 fix https://github.com/yulichang/mybatis-plus-join/issues/91 2023-11-16 01:56:27 +08:00
yulichang
818fdb9191 1.4.7.2 2023-11-16 00:23:13 +08:00
yulichang
0269e57a17 pom调整 2023-11-15 22:44:36 +08:00
yulichang
7ca1b4fad7 1.4.7.2 2023-11-15 20:33:49 +08:00
yulichang
5a7d561367 test 2023-11-15 20:31:27 +08:00
yulichang
5251af216e 升级MP 2023-11-15 20:30:59 +08:00
yulichang
6e06a04fd9 fix 移除union all泛型限制 2023-11-15 20:30:28 +08:00
yulichang
7c9e77f828 新增toChildren方法 2023-11-15 20:29:48 +08:00
yulichang
b6098167c6 升级MP -> 3.5.4.1 2023-11-15 20:27:55 +08:00
yulichang
863ab1942e pom调整 2023-11-15 20:22:54 +08:00
yulichang
6a721e9dc0 readme 2023-11-02 10:04:35 +08:00
yulichang
c9e735522c readme 2023-11-02 10:03:08 +08:00
yulichang
b83963a61c https://github.com/yulichang/mybatis-plus-join/issues/84 2023-11-02 01:08:57 +08:00
yulichang
289127c0f6 优化原生方法别名支持 2023-11-01 23:27:06 +08:00
yulichang
4bf4d25c9c 1.4.7.1 2023-11-01 12:20:05 +08:00
yulichang
fbb7f05fcb fix MP多租户sqlParse解析异常 https://gitee.com/best_handsome/mybatis-plus-join/issues/I8CAGY 2023-10-31 23:27:05 +08:00
yulichang
51f2231e9d fix union逻辑删除问题
https://gitee.com/best_handsome/mybatis-plus-join/issues/I8C2QR
2023-10-31 01:55:08 +08:00
yulichang
bb93df99b4 fix union条件嵌套参数名问题
https://github.com/yulichang/mybatis-plus-join/issues/87
https://gitee.com/best_handsome/mybatis-plus-join/issues/I8C2QR
2023-10-31 01:38:06 +08:00
yulichang
91c67c5e82 1.4.7 2023-10-23 18:37:04 +08:00
yulichang
bc59b2329a 1.4.7 2023-10-23 16:56:25 +08:00
yulichang
46e04953bf 1.4.7 2023-10-23 16:51:45 +08:00
yulichang
1ce8f68f29 MP升级3.5.4 2023-10-23 15:20:49 +08:00
yulichang
c60e89ea79 fix select子查询参数问题 2023-10-23 00:28:13 +08:00
yulichang
468a28f836 fix select子查询参数问题 2023-10-23 00:15:25 +08:00
yueke
b8c3b1caf6
select为 false 不加入 select 查询范围
select为 false 不加入 select 查询范围,结果忽略select 标识的字段
2023-09-19 14:13:50 +08:00
yulichang
fcfbef0139 1.4.6 2023-08-13 05:24:59 +08:00
yulichang
9340e5e38f 升级MP依赖3.5.3.2 & 同步新版功能及代码 2023-08-13 04:24:06 +08:00
yulichang
a8b91edb6b 同步 MP 3.5.3.2 sql注入检查代码
https://gitee.com/baomidou/mybatis-plus/issues/I7OCM4
2023-08-13 02:54:25 +08:00
yulichang
026c64ee59 代码调整 2023-08-07 16:35:39 +08:00
yulichang
cc1b03ad3c fix https://github.com/yulichang/mybatis-plus-join/issues/61 2023-07-15 12:15:29 +08:00
yulichang
05191f49b2 fix https://github.com/yulichang/mybatis-plus-join/issues/65 2023-07-15 11:40:43 +08:00
yulichang
832f0cc704 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I7BLZ6 2023-07-15 11:10:06 +08:00
yulichang
473ec1d052 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I7A3N8 2023-06-06 01:02:05 +08:00
yulichang
1f0ada7593 pom 2023-05-30 11:35:15 +08:00
yulichang
48b12a324c pom 2023-05-29 17:22:07 +08:00
yulichang
d4d531f688 kt 2023-05-29 17:05:31 +08:00
yulichang
14a616a9da kt 2023-05-29 17:03:28 +08:00
yulichang
11791c60d5 kt 2023-05-29 17:02:53 +08:00
yulichang
ed0af0f42c fix https://github.com/yulichang/mybatis-plus-join/issues/46 2023-05-17 18:00:40 +08:00
yulichang
e8f0910049 check 2023-05-15 10:25:04 +08:00
yulichang
e53386a8e1 版本 2023-05-10 21:29:37 +08:00
yulichang
4b4f0a2016 test 2023-05-10 17:43:50 +08:00
yulichang
7555326847 调整banner 2023-05-10 17:09:02 +08:00
yulichang
dd5003427d 优化代码 2023-05-10 17:03:22 +08:00
yulichang
ef520f3944 修改注解名称 2023-05-10 16:08:26 +08:00
yulichang
df769aa863 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I6ZANZ 2023-05-10 10:23:26 +08:00
yulichang
69fa6a8bc2 添加union方法 2023-05-09 18:33:29 +08:00
yulichang
2d481241c4 添加子查询 2023-05-09 17:42:50 +08:00
yulichang
679c647253 注解映射优化 2023-05-09 14:42:37 +08:00
yulichang
c5573a39cd 注解映射重构 2023-05-09 11:01:30 +08:00
yulichang
14d7e954b0 项目结构调整 2023-05-08 13:49:12 +08:00
yulichang
d2084ba1ae idea代码检查 2023-05-05 18:08:46 +08:00
yulichang
17fbae01b6 idea代码检查 2023-05-05 18:07:59 +08:00
yulichang
ed3c33db42 优化wrapper 2023-05-05 18:04:05 +08:00
yulichang
90941058ce fix https://github.com/yulichang/mybatis-plus-join/issues/41 2023-04-29 12:16:47 +08:00
yulichang
8b1362eefa Revert "添加注释"
This reverts commit 6efc10b5c7ad6fcb3b5d2dc17e95f5874f1b01db.
2023-04-20 17:06:44 +08:00
yulichang
6efc10b5c7 添加注释 2023-04-20 17:05:22 +08:00
yulichang
ee35e934b4 添加注释 2023-04-20 11:49:00 +08:00
yulichang
25bc045f66 添加注释 2023-04-20 11:41:04 +08:00
yulichang
30ba7ac06c 条件别名优化 2023-04-19 23:35:15 +08:00
yulichang
e4914429fe 优化 2023-04-18 11:34:10 +08:00
yulichang
e4f0b4314b 版本 2023-04-16 01:52:28 +08:00
yulichang
e8d92f10e1 优化别名 2023-04-14 16:59:32 +08:00
yulichang
59a85f6414 映射过滤 2023-04-11 18:11:21 +08:00
yulichang
5b1031b2e1 fix lambda string join npe 2023-04-06 16:32:47 +08:00
yulichang
6fa3db2df4 优化异常提示 2023-04-04 16:22:18 +08:00
yulichang
7c6173d3d2 优化异常提示 2023-04-04 16:13:23 +08:00
yulichang
a74c07f059 删除没有使用的 import 2023-03-30 17:45:48 +08:00
yulichang
38bcaee07e 异常信息修改 2023-03-30 17:43:58 +08:00
yulichang
1bdb91325a orderBy兼容 2023-03-28 18:36:40 +08:00
yulichang
dfa9baea93 类名修改 2023-03-27 19:12:50 +08:00
yulichang
3c3fb3272c 添加实现 2023-03-27 11:19:12 +08:00
yulichang
b6dcc7c1c6 泛型优化 2023-03-27 10:59:46 +08:00
yulichang
a229521dd7 优化 2023-03-17 22:22:28 +08:00
yulichang
a8a790e3ac 版本 2023-03-17 22:21:56 +08:00
yulichang
c1463c9c9c 添加注释以及test 2023-03-17 15:11:21 +08:00
yulichang
740c19511c test 2023-03-17 11:34:11 +08:00
yulichang
bf56112b05 低版本错误 2023-03-16 22:52:52 +08:00
yulichang
14ae83aff5 代码优化 2023-03-16 19:58:28 +08:00
yulichang
4211d02855 兼容 2023-03-16 19:18:46 +08:00
yulichang
943c48b801 添加不限制类型的映射方法 2023-03-16 19:13:24 +08:00
yulichang
f46422882d 代码注释 2023-03-16 14:15:33 +08:00
yulichang
8a209a7595 链式调用 2023-03-15 19:56:48 +08:00
yulichang
79de988db6 添加逻辑删除位置配置 2023-03-15 16:13:09 +08:00
yulichang
7d616e0d6c 动态表名 2023-03-13 14:24:14 +08:00
yulichang
3211eba2d5 Merge branch 'master' into 1.4 2023-03-13 11:20:17 +08:00
yulichang
a20c6b483e 动态表名 2023-03-13 11:20:10 +08:00
yulichang
02f9368ada fix selectFunc别名带点 2023-03-03 12:29:19 +08:00
yulichang
37cac33e44 版本 2023-03-02 22:35:08 +08:00
yulichang
ac6445390c fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I6J2YN 2023-03-02 16:35:33 +08:00
yulichang
d06c770492 版本 2023-02-27 22:32:59 +08:00
yulichang
516c6a24d6 fix https://gitee.com/best_handsome/mybatis-plus-join/issues/I6I09Y 2023-02-27 17:54:59 +08:00
yulichang
d75144e57a 简化代码 2023-02-27 09:14:51 +08:00
yulichang
ff1378a410 版本号 2023-02-24 16:11:12 +08:00
yulichang
71796252ad 优化测试代码 2023-02-24 14:11:30 +08:00
yulichang
c5a1ec397e 优化测试代码 2023-02-23 17:06:26 +08:00
yulichang
bb5c5df261 优化 2023-02-23 14:41:16 +08:00
yulichang
bfab4f289e fix 对一查询参数类型错误 2023-02-23 14:18:30 +08:00
yulichang
11db738c62 MPJLambdaWrapper兼容单表update和delete 2023-02-22 18:00:40 +08:00
yulichang
1cce8e8e10 优化 2023-02-11 16:15:00 +08:00
yulichang
4459f484d9 fix https://github.com/yulichang/mybatis-plus-join/issues/27 2023-01-14 14:17:56 +08:00
yulichang
eb479a7d59 readme 2023-01-12 16:39:05 +08:00
yulichang
fb18d0e707 readme 2023-01-12 16:35:48 +08:00
yulichang
32fabe6c7f readme 2023-01-12 16:34:45 +08:00
yulichang
3d33afc08d 分页参数优化 2023-01-12 10:04:47 +08:00
yulichang
b80b747e07 test 模块 2023-01-11 10:45:29 +08:00
yulichang
6086dbae45 test 模块 2023-01-11 10:43:34 +08:00
yulichang
656e325276 test 模块 2023-01-11 10:11:17 +08:00
yulichang
b45094d1ea 注释 2023-01-10 17:42:58 +08:00
yulichang
83585c075f 优化 test 2023-01-10 15:27:14 +08:00
405 changed files with 32912 additions and 4218 deletions

45
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: 错误报告
description: File a bug report.
title: "[错误报告]: 描述"
labels: [""]
body:
- type: markdown
attributes:
value: |
请确认以下信息:
1. 请按此模板提交issues, 不按模板提交的问题将直接关闭
2. 如果你的问题与该仓库无关或者可以直接在以往 issue 中找到, 那么你的 issue 将会被直接关闭
3. 提交问题务必描述清楚、附上日志, 描述不清导致无法理解和分析的问题会被直接关闭
- type: checkboxes
id: confirm
attributes:
label: 确认
description: 在提交 issue 之前,请确认你已经阅读并确认以下内容
options:
- label: 我的版本是最新版本, 我的版本号与 [version](https://central.sonatype.com/search?q=g:com.github.yulichang%20%20a:mybatis-plus-join-boot-starter&smo=true) 相同, 并且项目里无依赖冲突
required: true
- label: 我已经在 [issue](https://github.com/yulichang/mybatis-plus-join/issues) 中搜索过, 确认问题没有被提出过
required: true
- label: 我已经修改标题, 将标题中的 描述 替换为遇到的问题
required: true
- type: input
id: version
attributes:
label: 当前程序版本
description: 遇到问题时程序所在的版本号
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: 问题描述
description: 请详细描述你碰到的问题
placeholder: "问题描述"
validations:
required: true
- type: textarea
id: logs
attributes:
label: 详细堆栈日志
description: 问题出现时,程序错误堆栈日志。
render: bash

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: 官网
url: https://mybatis-plus-join.github.io/
about: document.

View File

@ -0,0 +1,35 @@
name: 功能改进
description: Feature Request
title: "[功能改进]: 描述"
labels: [""]
body:
- type: markdown
attributes:
value: |
请说明你希望添加的功能。
- type: checkboxes
id: confirm
attributes:
label: 确认
description: 在提交 issue 之前,请确认你已经阅读并确认以下内容
options:
- label: 我的版本是最新版本, 我的版本号与 [version](https://central.sonatype.com/search?q=g:com.github.yulichang%20%20a:mybatis-plus-join-boot-starter&smo=true) 相同, 并且项目里无依赖冲突
required: true
- label: 我已经在 [issue](https://github.com/yulichang/mybatis-plus-join/issues) 中搜索过, 确认问题没有被提出过
required: true
- label: 我已经修改标题, 将标题中的 描述 替换为遇到的问题
required: true
- type: textarea
id: feature-request
attributes:
label: 功能改进
description: 请详细描述需要改进或者添加的功能。
placeholder: "功能改进"
validations:
required: true
- type: textarea
id: references
attributes:
label: 参考资料
description: 可以列举一些参考资料,但是不要引用同类但商业化软件的任何内容。
placeholder: "参考资料"

13
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,13 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "maven" # See documentation for possible values
directory: "/"
schedule:
interval: "weekly"
ignore:
- dependency-name: "com.baomidou:mybatis-plus*"

39
.github/workflows/depoly.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Maven Package
on:
push:
tags:
- '*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Set up Apache Maven Central
uses: actions/setup-java@v4
with: # running setup-java again overwrites the settings.xml
distribution: 'temurin'
java-version: '17'
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: Publish to Apache Maven Central
run: mvn com.github.yulichang:pom-maven-plugin:pom && mvn clean deploy
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

31
.github/workflows/maven.yml vendored Normal file
View File

@ -0,0 +1,31 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Java CI with Maven
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml

39
.github/workflows/snapshot.yml vendored Normal file
View File

@ -0,0 +1,39 @@
name: Maven Package
on:
push:
branches:
- snapshot
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
- name: Build with Maven
run: mvn -B package --file pom.xml
- name: Set up Apache Maven Central
uses: actions/setup-java@v4
with: # running setup-java again overwrites the settings.xml
distribution: 'temurin'
java-version: '17'
server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml
server-username: MAVEN_USERNAME # env variable for username in deploy
server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy
gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} # Value of the GPG private key to import
gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase
- name: Publish to Apache Maven Central
run: mvn com.github.yulichang:pom-maven-plugin:pom -Dprofile=snapshot && mvn clean deploy
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}

View File

@ -1,113 +0,0 @@
# mybatis-plus-join
#### @EntityMapping@FieldMapping 注解
UserDO.java
```java
@Data
@TableName("user")
public class UserDO {
@TableId
private Integer id;
private Integer pid;//父id
/* 其他属性略 */
/**
* 查询上级 一对一
*/
@TableField(exist = false)
@EntityMapping(thisField = "pid", joinField = "id")
private UserDO pUser;
/**
* 查询下级 一对多
*/
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "pid")
private List<UserDO> childUser;
/**
* 带条件的查询下级 一对多
*/
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "pid",
condition = {
@MPJMappingCondition(column = "sex", value = "0"),//sex = '0' 默认条件是等于
@MPJMappingCondition(column = "name", value = "张三", keyWord = SqlKeyword.LIKE)//name like '%a%'
},
apply = @MPJMappingApply(value = "id between 1 and 20"))//拼接sql 同 wrapper.apply()
private List<UserDO> childUserCondition;
/**
* 查询地址 (一对多)
*/
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "userId")
private List<UserAddressDO> addressList;
/**
* 绑定字段 (一对多)
*/
@TableField(exist = false)
@FieldMapping(tag = UserDO.class, thisField = "id", joinField = "pid", select = "id")
private List<Integer> childIds;
}
```
使用
```java
/**
* 一对一,一对多关系映射查询
* 映射只对以Deep结尾有效比如 getByIdDeep listByIdsDeep 等
* 如果不需要关系映射就使用mybatis plus原生方法即可比如 getById listByIds 等
*
* 注意关系映射不会去关联查询而是执行多次单表查询对结果汇总后使用in语句查询,再对结果进行匹配)
*/
@SpringBootTest
class MappingTest {
@Resource
private UserMapper userMapper;
@Test
void test1() {
UserDO deep = userMapper.selectByIdDeep(2);
System.out.println(deep);
}
@Test
void test2() {
List<UserDO> list = userMapper.selectListDeep(Wrappers.emptyWrapper());
list.forEach(System.out::println);
}
@Test
void test3() {
Page<UserDO> page = userMapper.selectPageDeep(new Page<>(2, 2), Wrappers.emptyWrapper());
page.getRecords().forEach(System.out::println);
}
/**
* 更多方法请查阅 MPJDeepMapper 或者 MPJDeepService
* 使用方式与 mybatis plus 一致
*/
}
```
MPJMapping 说明:
* @EntityMapping / @FieldMapping tag 关联实体类
* @EntityMapping / @FieldMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键
* @EntityMapping / @FieldMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键
* @EntityMapping / @FieldMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据
*
更多功能请看代码注释 [EntityMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/EntityMapping.java)
[FieldMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/FieldMapping.java)

119
README-zh.md Normal file
View File

@ -0,0 +1,119 @@
<!--suppress HtmlDeprecatedAttribute -->
<p align="center">
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img alt="Mybatis-Plus-Join-Logo" src="https://foruda.gitee.com/images/1714756037858567246/8b0258f5_2020985.png">
</a>
</p>
<h1 align="center">MyBatis-Plus-Join</h1>
<p align="center">
为简化开发工作、提高生产率而生
</p>
<p align="center">
<a href="https://central.sonatype.com/artifact/com.github.yulichang/mybatis-plus-join-boot-starter">
<img alt="Maven central" src="https://img.shields.io/maven-central/v/com.github.yulichang/mybatis-plus-join-boot-starter.svg?style=flat-square">
</a>
<a href="https://www.apache.org/licenses/LICENSE-2.0">
<img alt="code style" src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square">
</a>
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img src="https://img.shields.io/github/stars/yulichang/mybatis-plus-join.svg?style=social&label=Stars" alt=""/>
</a>
<a href="https://gitee.com/best_handsome/mybatis-plus-join" target="_blank">
<img src="https://gitee.com/best_handsome/mybatis-plus-join/badge/star.svg?theme=dark" alt=""/>
</a>
</p>
<p align="center">
<a href="https://gitee.com/baomidou/mybatis-plus" target="_blank">MyBatis-Plus</a> 多表查询的扩展 |
<a href="https://gitee.com/best_handsome/mybatis-plus-join-demo" target="_blank">演示工程</a> |
<a href="https://mybatis-plus-join.github.io" target="_blank">使用文档</a> |
点个Star支持一下吧 (☆▽☆)
</p>
<p align="center">
<a href="https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M" target="_blank">添加作者微信备注MPJ加入微信群</a>
<br/>
<img width="200px" height="200px" src="https://foruda.gitee.com/images/1714756135330585984/bcc86eb0_2020985.png" alt="添加作者微信备注MPJ加入微信群"/>
</p>
### <a href="https://mybatis-plus-join.github.io" target="_blank">使用文档WIKI</a>
## 使用方法
### 安装
- Maven
```xml
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.5.4</version>
</dependency>
```
- Gradle
```
implementation 'com.github.yulichang:mybatis-plus-join-boot-starter:1.5.4'
```
或者clone代码到本地执行 `mvn install`, 再引入以上依赖
<br>
注意: MyBatis Plus版本需要3.1.2+
<br>
### 使用
* mapper继承MPJBaseMapper
### Lambda形式用法MPJLambdaWrapper
#### 简单的连表查询
```java
class test {
@Resource
private UserMapper userMapper;
void testJoin() {
//和Mybatis plus一致MPJLambdaWrapper的泛型必须是主表的泛型并且要用主表的Mapper来调用
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)//查询user表全部字段
.select(UserAddressDO::getTel)//查询user_address tel 字段
.selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress)//别名
.select(AreaDO::getProvince, AreaDO::getCity)
.leftJoin(UserAddressDO.class, UserAddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, UserAddressDO::getAreaId)
.eq(UserDO::getId, 1)
.like(UserAddressDO::getTel, "1")
.gt(UserDO::getId, 5);
//连表查询 返回自定义ResultType
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
//分页查询 (需要启用 mybatis plus 分页插件)
Page<UserDTO> listPage = userMapper.selectJoinPage(new Page<>(2, 10), UserDTO.class, wrapper);
}
}
```
对应sql
```
SELECT
t.id, t.name, t.sex, t.head_img,
t1.tel, t1.address AS userAddress,
t2.province, t2.city
FROM
user t
LEFT JOIN user_address t1 ON t1.user_id = t.id
LEFT JOIN area t2 ON t2.id = t1.area_id
WHERE (
t.id = ?
AND t1.tel LIKE ?
AND t.id > ?)
```
# <a href="https://mybatis-plus-join.github.io" target="_blank">完整使用文档 wiki</a>
# 用爱发电
<a href="https://mybatis-plus-join.github.io/pages/quickstart/support.html" target="_blank">
<img alt="支持一下mybatis-plus-join" src="https://foruda.gitee.com/images/1717191488951888381/8463cfcd_2020985.png">
</a>

237
README.md
View File

@ -1,13 +1,41 @@
# mybatis-plus-join
<!--suppress HtmlDeprecatedAttribute -->
<p align="center">
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img alt="Mybatis-Plus-Join-Logo" src="https://github.com/yulichang/mybatis-plus-join/assets/33247410/f61a92d0-dc6e-463d-b431-61f469bd35f8">
</a>
</p>
<h1 align="center">MyBatis-Plus-Join</h1>
<p align="center">
为简化开发工作、提高生产率而生
</p>
<p align="center">
<a href="https://central.sonatype.com/artifact/com.github.yulichang/mybatis-plus-join-boot-starter">
<img alt="Maven central" src="https://img.shields.io/maven-central/v/com.github.yulichang/mybatis-plus-join-boot-starter.svg?style=flat-square">
</a>
<a href="https://www.apache.org/licenses/LICENSE-2.0">
<img alt="code style" src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square">
</a>
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img src="https://img.shields.io/github/stars/yulichang/mybatis-plus-join.svg?style=social&label=Stars" alt=""/>
</a>
<a href="https://gitee.com/best_handsome/mybatis-plus-join" target="_blank">
<img src="https://gitee.com/best_handsome/mybatis-plus-join/badge/star.svg?theme=dark" alt=""/>
</a>
</p>
<p align="center">
<a href="https://github.com/baomidou/mybatis-plus" target="_blank">MyBatis-Plus</a> 多表查询的扩展 |
<a href="https://github.com/yulichang/mybatis-plus-join-demo" target="_blank">演示工程</a> |
<a href="https://mybatis-plus-join.github.io" target="_blank">使用文档</a> |
点个Star支持一下吧 (☆▽☆)
</p>
* 对 [mybatis-plus](https://gitee.com/baomidou/mybatis-plus) 多表查询的扩展
* [演示工程](https://gitee.com/best_handsome/mybatis-plus-join-demo)
* 点个Star支持一下吧 :)
<p align="center">
<a href="https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M" target="_blank">添加作者微信备注MPJ加入微信群</a>
<br/>
<img width="200px" height="200px" src="https://github.com/yulichang/mybatis-plus-join/assets/33247410/6a2aedfa-c67d-4691-9441-204f28b6c73d" alt="添加作者微信备注MPJ加入微信群"/>
</p>
QQ群:1022221898
[加入微信群](https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M)
### [文档](https://ylctmh.com)
### <a href="https://mybatis-plus-join.github.io" target="_blank">使用文档WIKI</a>
## 使用方法
@ -18,23 +46,21 @@ QQ群:1022221898
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.2.2</version>
<version>1.5.4</version>
</dependency>
```
- Gradle
```
implementation 'com.github.yulichang:mybatis-plus-join-boot-starter:1.4.2.2'
implementation 'com.github.yulichang:mybatis-plus-join-boot-starter:1.5.4'
```
或者clone代码到本地执行 mvn install, 再引入以上依赖
或者clone代码到本地执行 `mvn install`, 再引入以上依赖
<br>
注意: mybatis plus version >= 3.4.0
注意: MyBatis Plus版本需要3.1.2+
<br>
### 使用
* mapper继承MPJBaseMapper (必选)
* service继承MPJBaseService (可选)
* serviceImpl继承MPJBaseServiceImpl (可选)
* mapper继承MPJBaseMapper
### Lambda形式用法MPJLambdaWrapper
@ -47,10 +73,10 @@ class test {
void testJoin() {
//和Mybatis plus一致MPJLambdaWrapper的泛型必须是主表的泛型并且要用主表的Mapper来调用
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)//查询user表全部字段
.select(UserAddressDO::getTel)//查询user_address tel 字段
.selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress)//别名 t.address AS userAddress
.selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress)//别名
.select(AreaDO::getProvince, AreaDO::getCity)
.leftJoin(UserAddressDO.class, UserAddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, UserAddressDO::getAreaId)
@ -84,175 +110,8 @@ WHERE (
AND t.id > ?)
```
说明:
* UserDTO.class 查询结果返回类(resultType)
* selectAll() 查询指定实体类的全部字段
* select() 查询指定的字段,支持可变参数,同一个select只能查询相同表的字段
* selectAs() 字段别名查询,用于数据库字段与业务实体类属性名不一致时使用
* leftJoin() 参数说明
第一个参数: 参与连表的实体类class
第二个参数: 连表的ON字段,这个属性必须是第一个参数实体类的属性
第三个参数: 参与连表的ON的另一个实体类属性
* 默认主表别名是t,其他的表别名以先后调用的顺序使用t1,t2,t3....
* 条件查询,可以查询主表以及参与连接的所有表的字段,全部调用mp原生的方法,正常使用没有sql注入风险
#### 一对多查询
```java
class test {
@Resource
private UserMapper userMapper;
@Test
void testResultMap() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
//对多查询
.selectCollection(AddressDO.class, UesrDTO::getAddressList)
//对一查询
.selectAssociation(AddressDO.class, UesrDTO::getAddress)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId);
List<UserDTO> dtoList = userMapper.selectJoinList(UserDTO.class, wrapper);
//关于对多分页查询
//由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
}
}
```
等效于ResultMap
```xml
<resultMap id="xxxxxxxx" type="com.github.yulichang.join.dto.UserDTO">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--其他属性省略-->
<collection property="addressList" javaType="java.util.List"
ofType="com.github.yulichang.join.entity.UserAddressDO">
<id property="id" column="mpj_id"/>
<result property="address" column="address"/>
<result property="userId" column="user_id"/>
<!--其他属性省略-->
</collection>
</resultMap>
```
MPJLambdaWrapper其他功能
* [一对一,一对多使用](https://gitee.com/best_handsome/mybatis-plus-join/wikis/MyLambdaWrapper/selectCollection()?sort_id=6509590)
* [简单的SQL函数使用](https://gitee.com/best_handsome/mybatis-plus-join/wikis/selectFunc()?sort_id=4082479)
* [ON语句多条件支持](https://gitee.com/best_handsome/mybatis-plus-join/wikis/leftJoin?sort_id=3496671)
### String形式用法MPJQueryWrapper
#### 简单的连表查询
```java
class test {
@Resource
private UserMapper userMapper;
void testJoin() {
MPJQueryWrapper wrapper = new MPJQueryWrapper<UserDO>()
.selectAll(UserDO.class)
.select("addr.tel", "addr.address", "a.province")
.leftJoin("user_address addr on t.id = addr.user_id")
.rightJoin("area a on addr.area_id = a.id")
.like("addr.tel", "1")
.le("a.province", "1");
//列表查询
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
//分页查询 (需要启用 mybatis plus 分页插件)
Page<UserDTO> listPage = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper);
}
}
```
对应sql
```
SELECT
t.id,
t.name,
t.sex,
t.head_img,
addr.tel,
addr.address,
a.province
FROM
user t
LEFT JOIN user_address addr on t.id = addr.user_id
RIGHT JOIN area a on addr.area_id = a.id
WHERE (
addr.tel LIKE ?
AND a.province <= ?)
```
说明:
* UserDTO.class 查询结果类(resultType)
* selectAll(UserDO.class) 查询主表全部字段(主表实体类)默认主表别名 "t"
* select() mp的select策略是覆盖,以最后一次为准,这里的策略是追加,可以一直select
主表字段可以用lambda,会自动添加表别名,主表别名默认是 t ,非主表字段必须带别名查询
* leftJoin() rightJoin() innerJoin() 传sql片段 格式 (表 + 别名 + 关联条件)
* 条件查询,可以查询主表以及参与连接的所有表的字段,全部调用mp原生的方法,正常使用没有sql注入风险
#### 还可以这么操作,但不建议
```java
class test {
@Resource
private UserMapper userMapper;
void testJoin() {
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class,
new MPJQueryWrapper<UserDO>()
.selectAll(UserDO.class)
.select("addr.tel", "addr.address")
//行列转换
.select("CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex")
//求和函数
.select("sum(a.province) AS province")
//自定义数据集
.leftJoin("(select * from user_address) addr on t.id = addr.user_id")
.rightJoin("area a on addr.area_id = a.id")
.like("addr.tel", "1")
.le("a.province", "1")
.orderByDesc("addr.id"));
}
}
```
对应sql
```
SELECT
t.id,
t.name,
t.sex,
t.head_img,
addr.tel,
addr.address,
CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex,
sum(a.province) AS province
FROM
user t
LEFT JOIN (select * from user_address) addr on t.id = addr.user_id
RIGHT JOIN area a on addr.area_id = a.id
WHERE (
addr.tel LIKE ?
AND a.province <= ?)
ORDER BY
addr.id DESC
```
# [wiki](https://ylctmh.com)
# <a href="https://mybatis-plus-join.github.io" target="_blank">完整使用文档 wiki</a>
# 用爱发电
<a href="https://mybatis-plus-join.github.io/pages/quickstart/support.html" target="_blank">
<img alt="支持一下mybatis-plus-join" src="https://mybatis-plus-join.github.io/support.png">
</a>

View File

@ -0,0 +1,46 @@
<?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.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>mybatis-plus-join-adapter-jsqlparser-v46</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-jsqlparser-v46</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.5.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,63 @@
package com.github.yulichang.adapter.jsqlparser.v46;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*;
import java.util.function.Consumer;
/**
* 字段解析
*
* @author yulichang
* @since 1.4.12
*/
public class JSqlParserHelperV46 {
public static void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
try {
boolean parser = false;
Statement statement = CCJSqlParserUtil.parse(String.format("SELECT %s FROM table %s %s", selectSql, alias, from));
if (statement instanceof Select) {
Select select = (Select) statement;
SelectBody selectBody = select.getSelectBody();
if (selectBody instanceof PlainSelect) {
PlainSelect plainSelect = (PlainSelect) selectBody;
if (CollectionUtils.isNotEmpty(plainSelect.getSelectItems())) {
for (SelectItem item : plainSelect.getSelectItems()) {
if (item instanceof SelectExpressionItem) {
String col;
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) item;
if (null == selectExpressionItem.getAlias()) {
if (selectExpressionItem.getExpression() instanceof Column) {
col = ((Column) selectExpressionItem.getExpression()).getColumnName();
} else {
col = selectExpressionItem.getExpression().toString();
}
} else {
col = selectExpressionItem.getAlias().getName();
}
if (isNotBlank(col)) {
columConsumer.accept(col);
}
}
}
parser = true;
}
}
if (!parser)
throw ExceptionUtils.mpe("JSqlParser parser error <%s>", selectSql);
}
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
public static boolean isNotBlank(String str) {
return str != null && !str.trim().isEmpty();
}
}

View File

@ -0,0 +1,53 @@
<?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.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>mybatis-plus-join-adapter-jsqlparser</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-jsqlparser</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,57 @@
package com.github.yulichang.adapter.jsqlparser;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectItem;
import java.util.function.Consumer;
/**
* 字段解析
*
* @author yulichang
* @since 1.4.12
*/
public class JSqlParserHelper {
public static void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
try {
boolean parser = false;
Statement statement = CCJSqlParserUtil.parse(String.format("SELECT %s FROM table %s %s", selectSql, alias, from));
if (statement instanceof PlainSelect) {
PlainSelect plainSelect = (PlainSelect) statement;
if (CollectionUtils.isNotEmpty(plainSelect.getSelectItems())) {
for (SelectItem<?> item : plainSelect.getSelectItems()) {
String col;
if (item.getAlias() == null) {
if (item.getExpression() instanceof Column) {
Column column = (Column) item.getExpression();
col = column.getColumnName();
} else {
col = item.getExpression().toString();
}
} else {
col = item.getAlias().getName();
}
if (isNotBlank(col)) {
columConsumer.accept(col);
}
}
parser = true;
}
}
if (!parser)
throw ExceptionUtils.mpe("JSqlParser parser error <%s>", selectSql);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
public static boolean isNotBlank(String str) {
return str != null && !str.trim().isEmpty();
}
}

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-base</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-jsqlparser</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-jsqlparser-v46</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,110 @@
package com.github.yulichang.adapter.base;
import com.baomidou.mybatisplus.core.handlers.IJsonTypeHandler;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.MybatisUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.jsqlparser.JSqlParserHelper;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.ibatis.type.UnknownTypeHandler;
import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.3
*/
public interface IAdapter {
default boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isWithLogicDelete();
}
default boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.isPrimitive();
}
default boolean isWithUpdateFill(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.isWithUpdateFill();
}
default String mpjMapping(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.getMapping();
}
default TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getLogicDeleteFieldInfo();
}
default boolean mpjHasPK(TableInfo tableInfo) {
return tableInfo.havePK();
}
default Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
default Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return fieldInfo.getField();
}
default List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
return tableInfo.getOrderByFields().stream().map(f ->
new OrderFieldInfo(f.getColumn(), f.getType(), f.getSort())).collect(Collectors.toList());
}
default void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelper.parserColum(alias, from, selectSql, columConsumer);
}
default TypeHandler<?> getTypeHandler(Configuration configuration, Class<?> propertyType, Class<? extends TypeHandler<?>> typeHandlerClass, Field field) {
TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(typeHandlerClass);
if (typeHandlerClass != null && typeHandlerClass != UnknownTypeHandler.class) {
if (IJsonTypeHandler.class.isAssignableFrom(typeHandlerClass)) {
// 保证每次实例化
typeHandler = MybatisUtils.newJsonTypeHandler(typeHandlerClass, propertyType, field);
} else {
if (typeHandler == null) {
typeHandler = registry.getInstance(propertyType, typeHandlerClass);
}
}
}
return typeHandler;
}
default void wrapperInnerPage(Interceptor interceptor, Predicate<Object> predicate, Function<Object, Object> function) {
if (interceptor instanceof MybatisPlusInterceptor) {
MybatisPlusInterceptor mybatisPlusInterceptor = (MybatisPlusInterceptor) interceptor;
try {
Field field = MybatisPlusInterceptor.class.getDeclaredField("interceptors");
field.setAccessible(true);
@SuppressWarnings("unchecked")
List<InnerInterceptor> interceptors = (List<InnerInterceptor>) field.get(mybatisPlusInterceptor);
interceptors.replaceAll(i -> {
if (i instanceof PaginationInnerInterceptor && !predicate.test(i)) {
return (InnerInterceptor) function.apply(i);
}
return i;
});
} catch (Exception e) {
throw ExceptionUtils.mpe(e);
}
}
}
}

View File

@ -0,0 +1,35 @@
package com.github.yulichang.adapter.base.metadata;
import lombok.Data;
/**
* 兼容MP 3.5.4
* copy {@link com.baomidou.mybatisplus.core.metadata.OrderFieldInfo}
*
* @since 1.4.7
*/
@Data
public class OrderFieldInfo {
/**
* 字段
*/
private String column;
/**
* 排序类型
*/
private String type;
/**
* 排序顺序
*/
private short sort;
public OrderFieldInfo(String column, String type, short orderBySort) {
this.column = column;
this.type = type;
this.sort = orderBySort;
}
}

View File

@ -0,0 +1,12 @@
package com.github.yulichang.adapter.base.tookit;
public class CharSequenceUtils {
public static boolean isBlank(String str) {
return str == null || str.trim().isEmpty();
}
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
}

View File

@ -0,0 +1,71 @@
package com.github.yulichang.adapter.base.tookit;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
/**
* 版本工具类
*
* @author yulichang
* @since 1.4.4
*/
public class VersionUtils {
public static String version = MybatisPlusVersion.getVersion();
@SuppressWarnings("unused")
public static void setMybatisPlusVersion(String version) {
VersionUtils.version = version;
}
public static String getVersion() {
if (version != null) {
return version;
} else {
throw ExceptionUtils.mpe("mybatis-plus version is blank, " +
"please add VersionUtils.setMybatisPlusVersion(?) code before running application");
}
}
public static int compare(String v1, String v2) {
String[] v1s = v1.split("-")[0].split("\\.");
String[] v2s = v2.split("\\.");
String[] vs = v1s.length > v2s.length ? v2s : v1s;
for (int i = 0; i < vs.length; i++) {
int compareV = compareV(v1s[i], v2s[i]);
if (compareV != 0) {
return compareV;
}
}
if (v1s.length == v2s.length) {
return 0;
}
return v1s.length > v2s.length ? 1 : -1;
}
private static int compareV(String v1, String v2) {
if (isNumber(v1)) {
if (isNumber(v2)) {
return Integer.valueOf(v1).compareTo(Integer.valueOf(v2));
} else {
return 1;
}
} else {
if (isNumber(v2)) {
return -1;
} else {
return v1.compareTo(v2);
}
}
}
private static boolean isNumber(String str) {
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e2) {
return false;
}
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v312</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v312</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,98 @@
package com.github.yulichang.adapter.v312;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.CharSequenceUtils;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* @author yulichang
* @since 1.4.3
*/
public class Adapter312 implements IAdapter {
@Override
public boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isLogicDelete();
}
@Override
public boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.getPropertyType().isPrimitive();
}
@Override
public boolean isWithUpdateFill(TableFieldInfo tableFieldInfo) {
return false;
}
@Override
public String mpjMapping(TableFieldInfo tableFieldInfo) {
String el = tableFieldInfo.getEl();
if (el != null && el.contains(StringPool.COMMA)) {
return el.substring(el.indexOf(StringPool.COMMA) + 1);
}
return null;
}
@Override
public TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getFieldList().stream().filter(f -> Objects.nonNull(f.getLogicDeleteValue())
|| Objects.nonNull(f.getLogicNotDeleteValue())).findFirst().orElse(null);
}
@Override
public boolean mpjHasPK(TableInfo tableInfo) {
return CharSequenceUtils.isNotBlank(tableInfo.getKeyProperty()) ||
CharSequenceUtils.isNotBlank(tableInfo.getKeyColumn());
}
@Override
public Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
@Override
public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return supplier.get();
}
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
throw new UnsupportedOperationException("不支持排序");
}
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
@Override
public TypeHandler<?> getTypeHandler(Configuration configuration, Class<?> propertyType, Class<? extends TypeHandler<?>> typeHandlerClass, Field field) {
TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(typeHandlerClass);
if (typeHandler == null) {
typeHandler = registry.getInstance(propertyType, typeHandlerClass);
}
return typeHandler;
}
@Override
public void wrapperInnerPage(Interceptor interceptor, Predicate<Object> predicate, Function<Object, Object> function) {
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v33x</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v33x</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,96 @@
package com.github.yulichang.adapter.v33x;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.CharSequenceUtils;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* @author yulichang
* @since 1.4.3
*/
public class Adapter33x implements IAdapter {
private static final boolean is330 = VersionUtils.compare(VersionUtils.getVersion(), "3.3.0") == 0;
@Override
public boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isLogicDelete();
}
@Override
public boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.getPropertyType().isPrimitive();
}
@Override
public String mpjMapping(TableFieldInfo tableFieldInfo) {
String el = tableFieldInfo.getEl();
if (el != null && el.contains(StringPool.COMMA)) {
return el.substring(el.indexOf(StringPool.COMMA) + 1);
}
return null;
}
@Override
public TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getFieldList().stream().filter(f -> Objects.nonNull(f.getLogicDeleteValue())
|| Objects.nonNull(f.getLogicNotDeleteValue())).findFirst().orElse(null);
}
@Override
public boolean mpjHasPK(TableInfo tableInfo) {
return CharSequenceUtils.isNotBlank(tableInfo.getKeyProperty()) ||
CharSequenceUtils.isNotBlank(tableInfo.getKeyColumn());
}
@Override
public Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
@Override
public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return is330 ? supplier.get() : IAdapter.super.mpjGetField(fieldInfo, null);
}
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
throw new UnsupportedOperationException("不支持排序");
}
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
@Override
public TypeHandler<?> getTypeHandler(Configuration configuration, Class<?> propertyType, Class<? extends TypeHandler<?>> typeHandlerClass, Field field) {
TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(typeHandlerClass);
if (typeHandler == null) {
typeHandler = registry.getInstance(propertyType, typeHandlerClass);
}
return typeHandler;
}
@Override
public void wrapperInnerPage(Interceptor interceptor, Predicate<Object> predicate, Function<Object, Object> function) {
}
}

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress VulnerableLibrariesLocal -->
<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>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v3431</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v3431</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package com.github.yulichang.adapter.v3431;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
import java.util.List;
/**
* @author yulichang
* @since 1.4.5
*/
public class AbstractMethodV3431 {
public static List<AbstractMethod> getMethod(AbstractSqlInjector sqlInjector, Class<?> clazz) {
return sqlInjector.getMethodList(clazz);
}
}

View File

@ -0,0 +1,68 @@
package com.github.yulichang.adapter.v3431;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import lombok.AllArgsConstructor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.7
*/
@AllArgsConstructor
public class Adapter3431 implements IAdapter {
private static final boolean v = VersionUtils.compare(VersionUtils.getVersion(), "3.4.3") < 0;
@Override
public String mpjMapping(TableFieldInfo tableFieldInfo) {
if (v) {
String el = tableFieldInfo.getEl();
if (el != null && el.contains(StringPool.COMMA)) {
return el.substring(el.indexOf(StringPool.COMMA) + 1);
}
return null;
}
return IAdapter.super.mpjMapping(tableFieldInfo);
}
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
return v ? null : tableInfo.getOrderByFields().stream().map(f ->
new OrderFieldInfo(f.getColumn(), f.getOrderByType(), f.getOrderBySort())).collect(Collectors.toList());
}
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
@Override
public TypeHandler<?> getTypeHandler(Configuration configuration, Class<?> propertyType, Class<? extends TypeHandler<?>> typeHandlerClass, Field field) {
TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(typeHandlerClass);
if (typeHandler == null) {
typeHandler = registry.getInstance(propertyType, typeHandlerClass);
}
return typeHandler;
}
@Override
public void wrapperInnerPage(Interceptor interceptor, Predicate<Object> predicate, Function<Object, Object> function) {
}
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress VulnerableLibrariesLocal -->
<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>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v352</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v352</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,21 @@
package com.github.yulichang.adapter.v352;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
/**
* @author yulichang
* @since 1.4.3
*/
public abstract class AbstractMethod352 extends AbstractMethod {
@Deprecated
public AbstractMethod352() {
super();
}
public AbstractMethod352(String methodName) {
super(methodName);
}
}

View File

@ -0,0 +1,50 @@
<?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.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v355</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v355</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.5.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package com.github.yulichang.adapter.v355;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import java.lang.reflect.Field;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* @author yulichang
* @since 1.4.12
*/
public class Adapter355 implements IAdapter {
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
@Override
public TypeHandler<?> getTypeHandler(Configuration configuration, Class<?> propertyType, Class<? extends TypeHandler<?>> typeHandlerClass, Field field) {
TypeHandlerRegistry registry = configuration.getTypeHandlerRegistry();
TypeHandler<?> typeHandler = registry.getMappingTypeHandler(typeHandlerClass);
if (typeHandler == null) {
typeHandler = registry.getInstance(propertyType, typeHandlerClass);
}
return typeHandler;
}
@Override
public void wrapperInnerPage(Interceptor interceptor, Predicate<Object> predicate, Function<Object, Object> function) {
}
}

View File

@ -0,0 +1,54 @@
<?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>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>${revision}</version>
</parent>
<packaging>pom</packaging>
<version>${revision}</version>
<artifactId>mybatis-plus-join-adapter</artifactId>
<name>mybatis-plus-join-adapter</name>
<modules>
<module>mybatis-plus-join-adapter-base</module>
<module>mybatis-plus-join-adapter-v312</module>
<module>mybatis-plus-join-adapter-v33x</module>
<module>mybatis-plus-join-adapter-v3431</module>
<module>mybatis-plus-join-adapter-v352</module>
<module>mybatis-plus-join-adapter-v355</module>
<module>jsqlparser/mybatis-plus-join-adapter-jsqlparser</module>
<module>jsqlparser/mybatis-plus-join-adapter-jsqlparser-v46</module>
</modules>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -7,9 +7,9 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.2.2</version>
<version>${revision}</version>
</parent>
<version>1.4.2.2</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-annotation</artifactId>
<name>mybatis-plus-join-annotation</name>
@ -33,22 +33,4 @@
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.5.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -8,7 +8,7 @@ package com.github.yulichang.annotation;
* @since 1.2.0
*/
@SuppressWarnings("unused")
public @interface MPJMappingApply {
public @interface Apply {
/**
* sql片段

View File

@ -1,6 +1,7 @@
package com.github.yulichang.annotation;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.github.yulichang.annotation.enums.SqlKeyword;
/**
* 映射表条件
@ -9,7 +10,7 @@ import com.baomidou.mybatisplus.core.enums.SqlKeyword;
* @since 1.2.0
*/
@SuppressWarnings("unused")
public @interface MPJMappingCondition {
public @interface Condition {
/**
* 条件枚举

View File

@ -0,0 +1,18 @@
package com.github.yulichang.annotation;
import java.lang.annotation.*;
/**
* 动态表名注解
* <p>
* 1.5.2及以后无需添加此注解就可实现动态表名
*
* @author yulichang
* @since 1.4.4
*/
@Deprecated
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DynamicTableName {
}

View File

@ -12,7 +12,7 @@ import java.lang.annotation.*;
@Documented
@SuppressWarnings("unused")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Target(ElementType.FIELD)
public @interface EntityMapping {
/**
@ -41,29 +41,11 @@ public @interface EntityMapping {
boolean isThrowExp() default true;
/**
* 针对查询结果map的时候使用<br/>
* 默认为thisField对应的数据库列名<br/>
* <p>
* 如果此类是以map方式查询的<br/>
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
*/
String thisMapKey() default "";
/**
* isMap为true时生效<br/>
* 针对查询结果map的时候使用<br/>
* 默认为joinField对应的数据库列名<br/>
* <p>
* 如果此类是以map方式查询的<br/>
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
*/
String joinMapKey() default "";
/**
* 注意!!! 属性名
* 映射表查询条件之 select<br/>
* 等效于 Wrappers.<T>query().select(xxx);
*/
String select() default "";
String[] select() default "";
/**
* 映射表查询条件之 first<br/>
@ -75,24 +57,24 @@ public @interface EntityMapping {
* 映射表查询条件之 apply<br/>
* 等效于 Wrappers.<T>query().apply(xxx);
*/
MPJMappingApply[] apply() default {};
Apply[] apply() default {};
/**
* 映射表查询条件
*/
MPJMappingCondition[] condition() default {};
Condition[] condition() default {};
/**
* 映射表查询条件之 orderBy<br/>
* 等效于 Wrappers.<T>query().orderByAsc(xxx);
*/
String orderByAsc() default "";
String[] orderByAsc() default "";
/**
* 映射表查询条件之 orderByDesc<br/>
* 等效于 Wrappers.<T>query().orderByDesc(xxx);
*/
String orderByDesc() default "";
String[] orderByDesc() default "";
/**
* 映射表查询条件之 last<br/>

View File

@ -12,7 +12,7 @@ import java.lang.annotation.*;
@Documented
@SuppressWarnings("unused")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Target(ElementType.FIELD)
public @interface FieldMapping {
/**
@ -45,25 +45,6 @@ public @interface FieldMapping {
*/
String select();
/**
* 针对查询结果map的时候使用<br/>
* 默认为thisField对应的数据库列名<br/>
* <p>
* 如果此类是以map方式查询的<br/>
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
*/
String thisMapKey() default "";
/**
* isMap为true时生效<br/>
* 针对查询结果map的时候使用<br/>
* 默认为joinField对应的数据库列名<br/>
* <p>
* 如果此类是以map方式查询的<br/>
* 并且查询出来的map的key不是thisField对应的数据库列名就需要设置<br/>
*/
String joinMapKey() default "";
/**
* 映射表查询条件之 first<br/>
* 等效于 Wrappers.<T>query().first(xxx);
@ -74,24 +55,24 @@ public @interface FieldMapping {
* 映射表查询条件之 apply<br/>
* 等效于 Wrappers.<T>query().apply(xxx);
*/
MPJMappingApply[] apply() default {};
Apply[] apply() default {};
/**
* 映射表查询条件
*/
MPJMappingCondition[] condition() default {};
Condition[] condition() default {};
/**
* 映射表查询条件之 orderBy<br/>
* 等效于 Wrappers.<T>query().orderByAsc(xxx);
*/
String orderByAsc() default "";
String[] orderByAsc() default "";
/**
* 映射表查询条件之 orderByDesc<br/>
* 等效于 Wrappers.<T>query().orderByDesc(xxx);
*/
String orderByDesc() default "";
String[] orderByDesc() default "";
/**
* 映射表查询条件之 last<br/>

View File

@ -0,0 +1,89 @@
package com.github.yulichang.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* apt注解
* <p>
* 默认为String.format
* <p>
* 举例
* <ul>
* <li>全大写 %S</li>
* <li>加APT后缀 %sAPT</li>
* <li>加APT前缀 APT%s</li>
* <li>加APT后缀并且大写 %SAPT</li>
* </ul>
* <p>
* 支持Ognl语法,字段说明<br/>
* Ognl上下文
* <ul>
* <li>className 类名</li>
* <li>classPackage 包名</li>
* <li>
* util 工具类 OgnlUtil {@link com.github.yulichang.processor.utils.OgnlUtil} ,
* <a href="https://github.com/yulichang/mybatis-plus-join/tree/master/plugin/mybatis-plus-join-processor/src/main/java/com/github/yulichang/processor/utils/OgnlUtil.java">
* github link
* </a>
* </li>
* </ul>
* 指定开头 Ognl# 这不是ognl语法这是MPJ规定的 用于区分 ognl还是String.format
* <p>
* 举例
* <ul>
* <li>去掉3长度的后缀并且大写 Ognl#className.substring(0, className.length() - 3).toUpperCase() </li>
* <li>APT结尾 Ognl#className + 'APT'</li>
* <li>全大写并且以APT结尾 Ognl#className.toUpperCase() + 'APT' </li>
* <li>"PO"结尾替换为APT且全大写 Ognl#util.replaceSuffix(className, 'PO', 'APT').toUpperCase() </li>
* </ul>
* <p>
* 支持 三元运算 String所有方法 如lastIndexOf subString toUpperCase等 Ognl语法<p>
*
* @author yulichang
* @since 1.5.0
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface Table {
/**
* APT类名
* <p>
* 支持Ognl 默认使用String.format()
*/
String value() default "%sCol";
/**
* 生成类的包名
* <p>
* 支持Ognl 默认使用String.format()
*/
String classPackage() default "%s.apt";
/**
* 是否在Tables中生成对应的类字段
*/
boolean genTables() default true;
/**
* Tables中的字段名 默认大写的类名
* <p>
* 支持Ognl 默认使用String.format()
*/
String tablesClassPackage() default "%s.tables";
/**
* Tables中的字段名 默认大写的类名
* <p>
* 支持Ognl 默认使用String.format()
*/
String tablesClassName() default "%S";
/**
* 是否缓存
*/
boolean cache() default true;
}

View File

@ -0,0 +1,27 @@
package com.github.yulichang.annotation.enums;
/**
* @author yulichang
* @since 1.4.5
*/
public enum SqlKeyword {
NOT,
IN,
NOT_IN,
LIKE,
NOT_LIKE,
EQ,
NE,
GT,
GE,
LT,
LE,
IS_NULL,
IS_NOT_NULL,
BETWEEN,
NOT_BETWEEN,
;
SqlKeyword() {
}
}

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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">
@ -7,9 +6,9 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.2.2</version>
<version>${revision}</version>
</parent>
<version>1.4.2.2</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<name>mybatis-plus-join-boot-starter</name>
@ -34,37 +33,26 @@
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-core</artifactId>
<version>1.4.2.2</version>
<artifactId>mybatis-plus-join-extension</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -1,19 +1,27 @@
package com.github.yulichang.autoconfigure;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration;
import com.baomidou.mybatisplus.core.injector.AbstractSqlInjector;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.github.yulichang.autoconfigure.conditional.JoinSqlInjectorCondition;
import com.github.yulichang.autoconfigure.consumer.MybatisPlusJoinIfExistsConsumer;
import com.github.yulichang.autoconfigure.consumer.MybatisPlusJoinPropertiesConsumer;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.config.MPJInterceptorConfig;
import com.github.yulichang.extension.mapping.config.MappingConfig;
import com.github.yulichang.injector.MPJSqlInjector;
import com.github.yulichang.interceptor.MPJInterceptor;
import com.github.yulichang.toolkit.SpringContentUtils;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.interfaces.MBiPredicate;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -27,11 +35,13 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import javax.sql.DataSource;
import java.util.List;
import java.util.Optional;
/**
* springboot 自动配置类
@ -39,33 +49,41 @@ import java.util.List;
* @author yulichang
* @since 1.3.7
*/
@SuppressWarnings("ALL")
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisPlusJoinProperties.class)
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisPlusLanguageDriverAutoConfiguration.class})
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisPlusJoinAutoConfiguration {
private static final Logger logger = LoggerFactory.getLogger(MybatisPlusJoinAutoConfiguration.class);
@SuppressWarnings("FieldCanBeLocal")
private final MybatisPlusJoinProperties properties;
public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties) {
this.properties = properties;
ConfigProperties.subTableLogic = properties.getSubTableLogic();
ConfigProperties.msCache = properties.isMsCache();
ConfigProperties.tableAlias = properties.getTableAlias();
ConfigProperties.joinPrefix = properties.getJoinPrefix();
public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties,
ObjectProvider<MybatisPlusJoinPropertiesConsumer> propertiesConsumers,
ObjectProvider<MybatisPlusJoinIfExistsConsumer> IfExistsConsumers) {
this.properties = Optional.ofNullable(propertiesConsumers.getIfAvailable()).map(c -> c.config(properties)).orElse(properties);
ConfigProperties.banner = this.properties.getBanner();
ConfigProperties.msCache = this.properties.isMsCache();
ConfigProperties.tableAlias = this.properties.getTableAlias();
ConfigProperties.joinPrefix = this.properties.getJoinPrefix();
ConfigProperties.logicDelType = this.properties.getLogicDelType();
ConfigProperties.subQueryAlias = this.properties.getSubQueryAlias();
ConfigProperties.subTableLogic = this.properties.getSubTableLogic();
ConfigProperties.mappingMaxCount = this.properties.getMappingMaxCount();
ConfigProperties.Convert.IfExists = this.properties.getIfExists();
ConfigProperties.ifExists = Optional.ofNullable(IfExistsConsumers.getIfAvailable())
.map(m -> (MBiPredicate<Object, IfExistsSqlKeyWordEnum>) m)
.orElse((val, key) -> ConfigProperties.Convert.IfExists.test(val));
info("mybatis plus join properties config complete");
}
/**
* mybatis plus join 拦截器
*/
@Bean
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJInterceptor mpjInterceptor() {
return new MPJInterceptor();
}
@ -74,7 +92,8 @@ public class MybatisPlusJoinAutoConfiguration {
* mybatis plus 拦截器配置
*/
@Bean
@ConditionalOnBean(SqlSessionFactory.class)
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJInterceptorConfig mpjInterceptorConfig(List<SqlSessionFactory> sqlSessionFactoryList) {
return new MPJInterceptorConfig(sqlSessionFactoryList, properties.getBanner());
}
@ -83,48 +102,90 @@ public class MybatisPlusJoinAutoConfiguration {
* mybatis plus join 自定义方法
*/
@Bean
@Primary
@JoinSqlInjectorCondition
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnMissingBean({DefaultSqlInjector.class, AbstractSqlInjector.class, ISqlInjector.class})
public MPJSqlInjector mpjSqlInjector() {
logger.info("MPJSqlInjector init");
return new MPJSqlInjector();
@ConditionalOnBean(ISqlInjector.class)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJSqlInjector mpjSqlInjector(ISqlInjector sqlInjector) {
info("mybatis plus join SqlInjector init");
return new MPJSqlInjector(sqlInjector);
}
/**
* springboot content 工具类
* mybatis plus join 自定义方法
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SpringContentUtils springContentUtils(SpringContext springContext) {
return new SpringContentUtils(springContext);
@ConditionalOnMissingBean(ISqlInjector.class)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJSqlInjector mpjSqlInjectorOnMiss() {
info("mybatis plus join SqlInjector init");
return new MPJSqlInjector();
}
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnBean(SqlSessionFactory.class)
public static class MappingConfig implements ApplicationListener<ApplicationReadyEvent> {
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public static class MPJMappingConfig implements ApplicationListener<ApplicationReadyEvent> {
@Override
@SuppressWarnings("NullableProblems")
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
new com.github.yulichang.config.MappingConfig();
MappingConfig.init();
}
}
private static void info(String info) {
if (ConfigProperties.banner) {
logger.info(info);
}
}
@Configuration
@ConditionalOnBean(SqlSessionFactory.class)
public static class SpringContext implements SpringContentUtils.SpringContext, ApplicationContextAware {
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public static class MPJSpringContext implements SpringContentUtils.SpringContext, BeanFactoryPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
private ListableBeanFactory listableBeanFactory;
@Override
public <T> T getBean(Class<T> clazz) {
return this.applicationContext.getBean(clazz);
return getBeanFactory().getBean(clazz);
}
@Override
public <T> void getBeansOfType(Class<T> clazz) {
getBeanFactory().getBeansOfType(clazz);
}
private ListableBeanFactory getBeanFactory() {
return applicationContext == null ? listableBeanFactory : applicationContext;
}
@Override
@SuppressWarnings("NullableProblems")
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
SpringContentUtils.setSpringContext(this);
}
@Override
@SuppressWarnings("NullableProblems")
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.listableBeanFactory = beanFactory;
SpringContentUtils.setSpringContext(this);
try {
String[] names = beanFactory.getBeanNamesForType(SqlSessionFactory.class);
for (String name : names) {
BeanDefinition definition = beanFactory.getBeanDefinition(name);
info(String.format("MPJ SqlSessionFactory bean definition: %s factoryBeanName: %s factoryMethodName: %s source: %s",
name, definition.getFactoryBeanName(), definition.getFactoryMethodName(), definition.getSource()));
}
} catch (Exception ignore) {
}
}
}
}

View File

@ -1,5 +1,7 @@
package com.github.yulichang.autoconfigure;
import com.github.yulichang.config.enums.IfExistsEnum;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -39,4 +41,30 @@ public class MybatisPlusJoinProperties {
* 连表查询重复字段名前缀
*/
private String joinPrefix = "join";
/**
* 逻辑删除类型 支持 where on
*/
private LogicDelTypeEnum logicDelType = LogicDelTypeEnum.ON;
/**
* 映射查询最大深度
*/
private int mappingMaxCount = 5;
/**
* 子查询别名
*/
private String subQueryAlias = "st";
/**
* Wrapper IfExists 判断策略
* <p>
* NOT_NULL 非null
* <p>
* NOT_EMPTY 非空字符串 "" -> false, " " -> true ...
* <p>
* NOT_BLANK 非空白字符串 "" -> false, " " -> false, "\r" -> false, "abc" -> true ...
*/
private IfExistsEnum IfExists = IfExistsEnum.NOT_EMPTY;
}

View File

@ -0,0 +1,17 @@
package com.github.yulichang.autoconfigure.conditional;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
/**
* @author yulichang
* @since 1.4.5
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(OnSqlInjectorCondition.class)
public @interface JoinSqlInjectorCondition {
}

View File

@ -0,0 +1,46 @@
package com.github.yulichang.autoconfigure.conditional;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.MethodMetadata;
import java.lang.annotation.Annotation;
import java.util.Objects;
/**
* @author yulichang
* @since 1.4.5
*/
public class OnSqlInjectorCondition implements Condition {
@Override
@SuppressWarnings("NullableProblems")
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
if (Objects.nonNull(conditionContext.getBeanFactory())) {
String[] names = conditionContext.getBeanFactory().getBeanNamesForType(ISqlInjector.class);
for (String name : names) {
BeanDefinition definition = conditionContext.getBeanFactory().getBeanDefinition(name);
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annotatedBeanDefinition = (AnnotatedBeanDefinition) definition;
MethodMetadata metadata = annotatedBeanDefinition.getFactoryMethodMetadata();
if (Objects.nonNull(metadata)) {
MergedAnnotations annotations = metadata.getAnnotations();
for (MergedAnnotation<Annotation> it : annotations) {
if (Objects.equals(it.getType(), Primary.class)) {
return false;
}
}
}
}
}
}
return true;
}
}

View File

@ -0,0 +1,13 @@
package com.github.yulichang.autoconfigure.consumer;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.interfaces.MBiPredicate;
/**
* 自定义IfExists策略
*
* @author yulichang
* @since 1.4.9
*/
public interface MybatisPlusJoinIfExistsConsumer extends MBiPredicate<Object, IfExistsSqlKeyWordEnum> {
}

View File

@ -0,0 +1,20 @@
package com.github.yulichang.autoconfigure.consumer;
import com.github.yulichang.autoconfigure.MybatisPlusJoinProperties;
/**
* 自定义配置
*
* @author yulichang
* @since 1.4.9
*/
public interface MybatisPlusJoinPropertiesConsumer {
/**
* 自定义配置此方法会覆盖配置文件中的MPJ配置
*
* @param properties 配置文件里的配置
* @return 修改后的配置
*/
MybatisPlusJoinProperties config(MybatisPlusJoinProperties properties);
}

View File

@ -3,7 +3,8 @@
{
"sourceType": "com.github.yulichang.autoconfigure.MybatisPlusJoinProperties",
"name": "mybatis-plus-join",
"type": "com.github.yulichang.autoconfigure.MybatisPlusJoinProperties"
"type": "com.github.yulichang.autoconfigure.MybatisPlusJoinProperties",
"description": "mybatis-plus-join configure."
}
],
"properties": [
@ -33,9 +34,33 @@
},
{
"name": "mybatis-plus-join.join-prefix",
"defaultValue": "t",
"defaultValue": "join",
"type": "java.lang.String",
"description": "重复字段前缀."
},
{
"name": "mybatis-plus-join.logic-del-type",
"defaultValue": "com.github.yulichang.config.enums.LogicDelTypeEnum.ON",
"type": "com.github.yulichang.config.enums.LogicDelTypeEnum",
"description": "逻辑删除的位置支持where和on两个."
},
{
"name": "mybatis-plus-join.mapping-max-count",
"defaultValue": 5,
"type": "java.lang.Integer",
"description": "映射查询最大深度."
},
{
"name": "mybatis-plus-join.sub-query-alias",
"defaultValue": "st",
"type": "java.lang.String",
"description": "子查询表别名."
},
{
"name": "mybatis-plus-join.if-exist",
"defaultValue": "com.github.yulichang.config.enums.IfExistsEnum.NOT_EMPTY",
"type": "com.github.yulichang.config.enums.IfExistsEnum",
"description": "IfExists方法判断策略,如需自定义请用@Bean形式MybatisPlusJoinIfExistsConsumer."
}
]
}

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress VulnerableLibrariesLocal -->
<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">
@ -7,9 +6,9 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.2.2</version>
<version>${revision}</version>
</parent>
<version>1.4.2.2</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-core</artifactId>
<name>mybatis-plus-join-core</name>
@ -34,38 +33,90 @@
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-annotation</artifactId>
<version>1.4.2.2</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v312</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v33x</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v3431</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v352</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v355</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-wrapper-ext</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.5.2</version>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring</artifactId>
<version>${mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.23</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
package com.github.yulichang.adapter;
import com.github.yulichang.adapter.base.IAdapter;
/**
* @author yulichang
* @since 1.4.3
*/
public class Adapter implements IAdapter {
}

View File

@ -0,0 +1,42 @@
package com.github.yulichang.adapter;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.v312.Adapter312;
import com.github.yulichang.adapter.v33x.Adapter33x;
import com.github.yulichang.adapter.v3431.Adapter3431;
import com.github.yulichang.adapter.v355.Adapter355;
import lombok.Getter;
/**
* @author yulichang
* @since 1.4.3
*/
public class AdapterHelper {
@Getter
private static IAdapter adapter;
static {
String version = VersionUtils.getVersion();
if (VersionUtils.compare(version, "3.5.6") >= 0) {
adapter = new Adapter();
} else if (VersionUtils.compare(version, "3.5.4") >= 0) {
adapter = new Adapter355();
} else if (VersionUtils.compare(version, "3.4.0") >= 0) {
adapter = new Adapter3431();
} else if (VersionUtils.compare(version, "3.3.0") >= 0) {
adapter = new Adapter33x();
} else if (VersionUtils.compare(version, "3.1.2") >= 0) {
adapter = new Adapter312();
} else {
throw ExceptionUtils.mpe("MPJ需要MP版本3.1.2+当前MP版本%s", version);
}
}
public static void setAdapter(IAdapter adapter) {
AdapterHelper.adapter = adapter;
}
}

View File

@ -0,0 +1,137 @@
package com.github.yulichang.base;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.toolkit.Constant;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* join相关方法
*
* @author yulichang
*/
public interface JoinMapper<T> {
/**
* 根据 Wrapper 条件连表删除
*
* @param wrapper joinWrapper
*/
int deleteJoin(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 根据 whereEntity 条件更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param wrapper 实体对象封装操作类可以为 null,里面的 entity 用于生成 where 语句
*/
int updateJoin(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 根据 whereEntity 条件更新记录 (null字段也会更新 !!!)
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param wrapper 实体对象封装操作类可以为 null,里面的 entity 用于生成 where 语句
*/
int updateJoinAndNull(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 根据 Wrapper 条件查询总记录数
*
* @param wrapper joinWrapper
*/
Long selectJoinCount(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回一条记录
*
* @param wrapper joinWrapper
* @return T
*/
default T selectJoinOne(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper) {
return selectJoinOne(null, wrapper);
}
/**
* 连表查询返回一条记录
*
* @param wrapper joinWrapper
* @param clazz resultType
*/
<DTO> DTO selectJoinOne(@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map
*
* @param wrapper joinWrapper
*/
default Map<String, Object> selectJoinMap(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper) {
//noinspection unchecked
return selectJoinOne(Map.class, wrapper);
}
/**
* 连表查询返回记录集合
*
* @param wrapper joinWrapper
* @return List&lt;T&gt;
*/
default List<T> selectJoinList(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper) {
return selectJoinList(null, wrapper);
}
/**
* 连表查询返回记录集合
*
* @param wrapper joinWrapper
* @param clazz resultType
*/
<DTO> List<DTO> selectJoinList(@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map集合
*
* @param wrapper joinWrapper
*/
default List<Map<String, Object>> selectJoinMaps(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper) {
//noinspection unchecked
return (List<Map<String, Object>>) ((Object) selectJoinList(Map.class, wrapper));
}
/**
* 连表查询返回记录集合并分页
*
* @param wrapper joinWrapper
*/
default <P extends IPage<T>> P selectJoinPage(P page, @Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper) {
return selectJoinPage(page, null, wrapper);
}
/**
* 连表查询返回记录集合并分页
*
* @param wrapper joinWrapper
* @param clazz resultType
* @param <DTO> 分页返回对象
*/
<DTO, P extends IPage<DTO>> P selectJoinPage(P page,
@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map集合并分页
*
* @param wrapper joinWrapper
*/
default <P extends IPage<Map<String, Object>>> P selectJoinMapsPage(P page,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper) {
//noinspection unchecked,rawtypes
return (P) selectJoinPage((IPage) page, Map.class, wrapper);
}
}

View File

@ -0,0 +1,93 @@
package com.github.yulichang.base;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.github.yulichang.interfaces.MPJBaseJoin;
import java.util.List;
import java.util.Map;
@SuppressWarnings({"unchecked", "unused"})
public interface JoinService<T> {
BaseMapper<T> getBaseMapper();
/**
* 根据 Wrapper 条件连表删除
*
* @param wrapper joinWrapper
*/
default boolean deleteJoin(MPJBaseJoin<T> wrapper) {
return SqlHelper.retBool(((JoinMapper<T>) getBaseMapper()).deleteJoin(wrapper));
}
/**
* 根据 whereEntity 条件更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param wrapper 实体对象封装操作类可以为 null,里面的 entity 用于生成 where 语句
*/
default boolean updateJoin(T entity, MPJBaseJoin<T> wrapper) {
return SqlHelper.retBool(((JoinMapper<T>) getBaseMapper()).updateJoin(entity, wrapper));
}
/**
* 根据 whereEntity 条件更新记录 (null字段也会更新 !!!)
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param wrapper 实体对象封装操作类可以为 null,里面的 entity 用于生成 where 语句
*/
default boolean updateJoinAndNull(T entity, MPJBaseJoin<T> wrapper) {
return SqlHelper.retBool(((JoinMapper<T>) getBaseMapper()).updateJoinAndNull(entity, wrapper));
}
/**
* 根据 Wrapper 条件查询总记录数
*/
default Long selectJoinCount(MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinCount(wrapper);
}
/**
* 连接查询返回一条记录
*/
default <DTO> DTO selectJoinOne(Class<DTO> clazz, MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinOne(clazz, wrapper);
}
/**
* 连接查询返回集合
*/
default <DTO> List<DTO> selectJoinList(Class<DTO> clazz, MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinList(clazz, wrapper);
}
/**
* 连接查询返回集合并分页
*/
default <DTO, P extends IPage<DTO>> P selectJoinListPage(P page, Class<DTO> clazz, MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinPage(page, clazz, wrapper);
}
/**
* 连接查询返回Map
*/
default Map<String, Object> selectJoinMap(MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinMap(wrapper);
}
/**
* 连接查询返回Map集合
*/
default List<Map<String, Object>> selectJoinMaps(MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinMaps(wrapper);
}
/**
* 连接查询返回Map集合并分页
*/
default <P extends IPage<Map<String, Object>>> P selectJoinMapsPage(P page, MPJBaseJoin<T> wrapper) {
return ((JoinMapper<T>) getBaseMapper()).selectJoinMapsPage(page, wrapper);
}
}

View File

@ -1,14 +1,11 @@
package com.github.yulichang.base;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.mapper.MPJDeepMapper;
import com.github.yulichang.base.mapper.MPJJoinMapper;
/**
* @author yulichang
* @see BaseMapper
*/
public interface MPJBaseMapper<T> extends MPJJoinMapper<T>, MPJDeepMapper<T> {
public interface MPJBaseMapper<T> extends BaseMapper<T>, JoinMapper<T> {
}

View File

@ -1,15 +1,14 @@
package com.github.yulichang.base;
import com.github.yulichang.base.service.MPJDeepService;
import com.github.yulichang.base.service.MPJJoinService;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 基础service
* 目前包含两个模块 连表查询 关系映射
*
* @author yulichang
* @see MPJJoinService
* @see MPJDeepService
*/
public interface MPJBaseService<T> extends MPJJoinService<T>, MPJDeepService<T> {
@SuppressWarnings({"unused"})
public interface MPJBaseService<T> extends IService<T>, JoinService<T> {
}

View File

@ -9,8 +9,4 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@SuppressWarnings("unused")
public class MPJBaseServiceImpl<M extends MPJBaseMapper<T>, T> extends ServiceImpl<M, T> implements MPJBaseService<T> {
@Override
public Class<T> currentModelClass() {
return super.currentModelClass();
}
}

View File

@ -1,495 +0,0 @@
package com.github.yulichang.base.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.*;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.base.mapper.wrapper.MappingQuery;
import com.github.yulichang.mapper.MPJTableFieldInfo;
import com.github.yulichang.mapper.MPJTableInfo;
import com.github.yulichang.toolkit.LambdaUtils;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
/**
* 关联查询
*
* @author yulichang
* @see BaseMapper
*/
@SuppressWarnings({"unused", "unchecked"})
public interface MPJDeepMapper<T> extends BaseMapper<T> {
/**
* 根据 ID 查询 并关联全部映射
*
* @param id 主键ID
*/
default T selectByIdDeep(Serializable id) {
return mpjQueryMapping(selectById(id), null);
}
/**
* 根据 ID 查询 并关联指定映射
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param id 主键ID
* @param property 需要关联的字段
*/
default <R> T selectByIdDeep(Serializable id, SFunction<T, R>... property) {
return mpjQueryMapping(selectById(id), Arrays.asList(property));
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectByIdDeep(1, Arrays.asList(User::getId, ... ))
*
* @param id 主键ID
* @param property 需要关联的字段
*/
default <R> T selectByIdDeep(Serializable id, List<SFunction<T, R>> property) {
return mpjQueryMapping(selectById(id), property);
}
/**
* 查询根据ID 批量查询
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
default List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList) {
return mpjQueryMapping(selectBatchIds(idList), null);
}
/**
* 查询根据ID 批量查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
* @param property 需要关联的字段
*/
default <R> List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList, SFunction<T, R>... property) {
return mpjQueryMapping(selectBatchIds(idList), Arrays.asList(property));
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectBatchIdsDeep(idList, Arrays.asList(User::getId, ... ))
*
* @param idList 主键ID列表(不能为 null 以及 empty)
* @param property 需要关联的字段
*/
default <R> List<T> selectBatchIdsDeep(Collection<? extends Serializable> idList, List<SFunction<T, R>> property) {
return mpjQueryMapping(selectBatchIds(idList), property);
}
/**
* 查询根据 columnMap 条件
*
* @param columnMap 表字段 map 对象
*/
default List<T> selectByMapDeep(Map<String, Object> columnMap) {
return mpjQueryMapping(selectByMap(columnMap), null);
}
/**
* 查询根据 columnMap 条件
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param columnMap 表字段 map 对象
* @param property 需要关联的字段
*/
default <R> List<T> selectByMapDeep(Map<String, Object> columnMap, SFunction<T, R>... property) {
return mpjQueryMapping(selectByMap(columnMap), Arrays.asList(property));
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectByMapDeep(columnMap, Arrays.asList(User::getId, ... ))
*
* @param columnMap 表字段 map 对象
* @param property 需要关联的字段
*/
default <R> List<T> selectByMapDeep(Map<String, Object> columnMap, List<SFunction<T, R>> property) {
return mpjQueryMapping(selectByMap(columnMap), property);
}
/**
* 根据 entity 条件查询一条记录
*
* @param queryWrapper 实体对象封装操作类可以为 null
*/
default T selectOneDeep(Wrapper<T> queryWrapper) {
return mpjQueryMapping(selectOne(queryWrapper), null);
}
/**
* 根据 entity 条件查询一条记录
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R> T selectOneDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return mpjQueryMapping(selectOne(queryWrapper), Arrays.asList(property));
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectOneDeep(queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R> T selectOneDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return mpjQueryMapping(selectOne(queryWrapper), property);
}
/**
* 根据 entity 条件查询全部记录
*
* @param queryWrapper 实体对象封装操作类可以为 null
*/
default List<T> selectListDeep(Wrapper<T> queryWrapper) {
return mpjQueryMapping(selectList(queryWrapper), null);
}
/**
* 根据 entity 条件查询全部记录
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R> List<T> selectListDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return mpjQueryMapping(selectList(queryWrapper), Arrays.asList(property));
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectListDeep(queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R> List<T> selectListDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return mpjQueryMapping(selectList(queryWrapper), property);
}
/**
* 根据 Wrapper 条件查询全部记录
*
* @param queryWrapper 实体对象封装操作类可以为 null
*/
default List<Map<String, Object>> selectMapsDeep(Class<T> clazz, Wrapper<T> queryWrapper) {
return mpjQueryMapMapping(selectMaps(queryWrapper), clazz, null);
}
/**
* 根据 entity 条件查询全部记录并翻页
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param clazz 实体类class
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R> List<Map<String, Object>> selectMapsDeep(Class<T> clazz, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return mpjQueryMapMapping(selectMaps(queryWrapper), clazz, Arrays.asList(property));
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectMapsDeep(UserDO.class, queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R> List<Map<String, Object>> selectMapsDeep(Class<T> clazz, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return mpjQueryMapMapping(selectMaps(queryWrapper), clazz, property);
}
/**
* 根据 entity 条件查询全部记录并翻页
*
* @param page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null
*/
default <E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper) {
E e = selectPage(page, queryWrapper);
mpjQueryMapping(e.getRecords(), null);
return e;
}
/**
* 根据 entity 条件查询全部记录并翻页
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R, E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
E e = selectPage(page, queryWrapper);
mpjQueryMapping(e.getRecords(), Arrays.asList(property));
return e;
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectPageDeep(page, queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R, E extends IPage<T>> E selectPageDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
E e = selectPage(page, queryWrapper);
mpjQueryMapping(e.getRecords(), property);
return e;
}
/**
* 根据 entity 条件查询全部记录并翻页
*
* @param page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null
*/
default <R, E extends IPage<Map<String, Object>>> E selectMapsPageDeep(E page, Class<T> clazz, Wrapper<T> queryWrapper) {
E e = selectMapsPage(page, queryWrapper);
mpjQueryMapMapping(e.getRecords(), clazz, null);
return e;
}
/**
* 根据 entity 条件查询全部记录并翻页
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R, E extends IPage<Map<String, Object>>> E selectMapsPageDeep(E page, Class<T> clazz, Wrapper<T> queryWrapper,
SFunction<T, R>... property) {
E e = selectMapsPage(page, queryWrapper);
mpjQueryMapMapping(e.getRecords(), clazz, Arrays.asList(property));
return e;
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* selectMapsPage(page, UserDO.class, queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param page 分页查询条件可以为 RowBounds.DEFAULT
* @param queryWrapper 实体对象封装操作类可以为 null
* @param property 需要关联的字段
*/
default <R, E extends IPage<Map<String, Object>>> E selectMapsPageDeep(E page, Class<T> clazz, Wrapper<T> queryWrapper,
List<SFunction<T, R>> property) {
E e = selectMapsPage(page, queryWrapper);
mpjQueryMapMapping(e.getRecords(), clazz, property);
return e;
}
/**
* 查询映射关系<br/>
* 对结果进行二次查询<br/>
* 可以自行查询然后在通过此方法进行二次查询<br/>
* list为null或空会查询全部映射关系<br/>
*
* @param t 第一次查询结果
*/
default <R> T mpjQueryMapping(T t, List<SFunction<T, R>> property) {
if (t == null) {
return null;
}
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass());
if (tableInfo.isHasMappingOrField()) {
boolean hasProperty = CollectionUtils.isNotEmpty(property);
List<String> list = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
Collectors.toList()) : null;
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (!hasProperty || list.contains(fieldInfo.getProperty())) {
Object obj = fieldInfo.thisFieldGet(t);
if (obj != null) {
List<?> joinList = MappingQuery.mpjQueryList(fieldInfo.getJoinMapper(),
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo);
mpjBindData(t, fieldInfo, joinList);
fieldInfo.removeJoinField(joinList);
}
}
}
}
return t;
}
/**
* 查询映射关系<br/>
* 对结果进行二次查询<br/>
* 可以自行查询然后在通过此方法进行二次查询<br/>
* list为null或空会查询全部映射关系<br/>
*
* @param map 第一次查询结果
*/
default <R> Map<String, Object> mpjQueryMapMapping(Map<String, Object> map, Class<T> clazz, List<SFunction<T, R>> property) {
if (CollectionUtils.isEmpty(map)) {
return map;
}
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(clazz);
if (tableInfo.isHasMappingOrField()) {
boolean hasProperty = CollectionUtils.isNotEmpty(property);
List<String> list = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
Collectors.toList()) : null;
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (!hasProperty || list.contains(fieldInfo.getProperty())) {
Object obj = map.get(fieldInfo.getThisMapKey());
if (obj != null) {
List<?> joinList = MappingQuery.mpjQueryList(fieldInfo.getJoinMapper(),
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo);
mpjBindMap(map, fieldInfo, joinList);
fieldInfo.removeJoinField(joinList);
}
}
}
}
return map;
}
/**
* 查询映射关系<br/>
* 对结果进行二次查询<br/>
* 可以自行查询然后在通过此方法进行二次查询<br/>
* list为null或空会查询全部映射关系<br/>
*
* @param list 第一次查询结果
*/
default <R> List<T> mpjQueryMapping(List<T> list, List<SFunction<T, R>> property) {
if (CollectionUtils.isEmpty(list)) {
return list;
}
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(list.get(0).getClass());
if (tableInfo.isHasMappingOrField()) {
boolean hasProperty = CollectionUtils.isNotEmpty(property);
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
Collectors.toList()) : null;
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
List<Object> itemList = list.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(itemList)) {
List<?> joinList = MappingQuery.mpjQueryList(fieldInfo.getJoinMapper(),
fieldInfo.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN,
fieldInfo.getJoinColumn(), itemList, fieldInfo);
list.forEach(i -> mpjBindData(i, fieldInfo, joinList));
fieldInfo.removeJoinField(joinList);
} else {
list.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>()));
}
}
}
}
return list;
}
/**
* 查询映射关系<br/>
* 对结果进行二次查询<br/>
* 可以自行查询然后在通过此方法进行二次查询<br/>
* list为null或空会查询全部映射关系<br/>
*
* @param list 第一次查询结果
*/
default <R> List<Map<String, Object>> mpjQueryMapMapping(List<Map<String, Object>> list, Class<T> clazz, List<SFunction<T, R>> property) {
if (CollectionUtils.isEmpty(list)) {
return list;
}
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(clazz);
if (tableInfo.isHasMappingOrField()) {
boolean hasProperty = CollectionUtils.isNotEmpty(property);
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
Collectors.toList()) : null;
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
List<Object> itemList = list.stream().map(m -> m.get(fieldInfo.getThisMapKey()))
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(itemList)) {
List<?> joinList = MappingQuery.mpjQueryList(fieldInfo.getJoinMapper(),
fieldInfo.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN,
fieldInfo.getJoinColumn(), itemList, fieldInfo);
list.forEach(i -> mpjBindMap(i, fieldInfo, joinList));
fieldInfo.removeJoinField(joinList);
} else {
list.forEach(i -> i.put(fieldInfo.getField().getName(), new ArrayList<>()));
}
}
}
}
return list;
}
/**
* 绑定数据
*/
default void mpjBindData(T t, MPJTableFieldInfo fieldInfo, List<?> joinList) {
if (fieldInfo.isMappingEntity()) {
List<?> list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(fieldInfo.thisFieldGet(t)))
.collect(Collectors.toList());
MPJTableFieldInfo.bind(fieldInfo, t, list);
}
if (fieldInfo.isMappingField()) {
MPJTableFieldInfo.bind(fieldInfo, t, joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(
fieldInfo.thisFieldGet(t))).map(fieldInfo::bindFieldGet).collect(Collectors.toList()));
}
}
/**
* 绑定数据
*/
default void mpjBindMap(Map<String, Object> t, MPJTableFieldInfo fieldInfo, List<?> joinList) {
List<?> list = null;
if (fieldInfo.isMappingEntity()) {
if (fieldInfo.isFieldIsMap()) {
list = ((List<Map<String, Object>>) joinList).stream().filter(j ->
j.get(fieldInfo.getJoinMapKey()).equals(t.get(fieldInfo.getThisMapKey())))
.collect(Collectors.toList());
} else {
list = joinList.stream().filter(j ->
fieldInfo.joinFieldGet(j).equals(t.get(fieldInfo.getThisMapKey())))
.collect(Collectors.toList());
}
}
if (fieldInfo.isMappingField()) {
list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(
t.get(fieldInfo.getThisMapKey()))).map(fieldInfo::bindFieldGet).collect(Collectors.toList());
}
MPJTableFieldInfo.bindMap(fieldInfo, t, list);
}
}

View File

@ -1,76 +0,0 @@
package com.github.yulichang.base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.toolkit.Constant;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* @author yulichang
* @see BaseMapper
*/
public interface MPJJoinMapper<T> extends BaseMapper<T> {
/**
* 根据 Wrapper 条件查询总记录数
*
* @param wrapper joinWrapper
*/
Integer selectJoinCount(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回一条记录
*
* @param wrapper joinWrapper
* @param clazz resultType
*/
<DTO> DTO selectJoinOne(@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map
*
* @param wrapper joinWrapper
*/
Map<String, Object> selectJoinMap(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回记录集合
*
* @param wrapper joinWrapper
* @param clazz resultType
*/
<DTO> List<DTO> selectJoinList(@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map集合
*
* @param wrapper joinWrapper
*/
List<Map<String, Object>> selectJoinMaps(@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回记录集合并分页
*
* @param wrapper joinWrapper
* @param clazz resultType
* @param <DTO> 分页返回对象
*/
<DTO, P extends IPage<?>> IPage<DTO> selectJoinPage(P page,
@Param(Constant.CLAZZ) Class<DTO> clazz,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
/**
* 连表查询返回Map集合并分页
*
* @param wrapper joinWrapper
*/
<P extends IPage<?>> IPage<Map<String, Object>> selectJoinMapsPage(P page,
@Param(Constants.WRAPPER) MPJBaseJoin<T> wrapper);
}

View File

@ -1,556 +0,0 @@
package com.github.yulichang.base.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.annotation.EntityMapping;
import com.github.yulichang.annotation.FieldMapping;
import com.github.yulichang.base.MPJBaseMapper;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 深度查询
* <p>
* 对配置了映射注解的字段进行查询
* 目前查询深度只支持2级(只解析当前实体类的映射注解,不会对查询结果再次解析注解)
* 多级查询可能存在循环引用的问题也可能会导致全量查询
*
* @author yulichang
* @see EntityMapping
* @see FieldMapping
* @since 1.2.0
*/
@SuppressWarnings({"unused", "unchecked"})
public interface MPJDeepService<T> extends IService<T> {
Class<T> currentModelClass();
/**
* 根据 ID 深度查询
*
* @param id 主键ID列表
*/
default T getByIdDeep(Serializable id) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id);
}
/**
* 根据 ID 深度查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param id 主键ID列表
* @param property 需要关联的字段
*/
default <R> T getByIdDeep(Serializable id, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
}
/**
* 针对可变参数堆污染提供的重载
* list为null或空会查询全部映射关系
* <p>
* getByIdDeep(id, Arrays.asList(User::getId, ... ))
*
* @param id 主键ID列表
* @param property 需要关联的字段
*/
default <R> T getByIdDeep(Serializable id, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
}
/**
* 查询根据ID 批量查询
*
* @param idList 主键ID列表
*/
default List<T> listByIdsDeep(Collection<? extends Serializable> idList) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList);
}
/**
* 查询根据ID 批量查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param idList 主键ID列表
* @param property 需要关联的字段
*/
default <R> List<T> listByIdsDeep(Collection<? extends Serializable> idList, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, Arrays.asList(property));
}
/**
* 查询根据ID 批量查询
* list为null或空会查询全部映射关系
* <p>
* listByIdsDeep(idList, Arrays.asList(User::getId, ... ))
*
* @param idList 主键ID列表
* @param property 需要关联的字段
*/
default <R> List<T> listByIdsDeep(Collection<? extends Serializable> idList, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, property);
}
/**
* 查询根据 columnMap 条件
*
* @param columnMap 表字段 map 对象
*/
default List<T> listByMapDeep(Map<String, Object> columnMap) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap);
}
/**
* 查询根据 columnMap 条件
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param columnMap 表字段 map 对象
* @param property 需要关联的字段
*/
default <R> List<T> listByMapDeep(Map<String, Object> columnMap, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, Arrays.asList(property));
}
/**
* 查询根据 columnMap 条件
* list为null或空会查询全部映射关系
* <p>
* listByMapDeep(columnMap, Arrays.asList(User::getId, ... ))
*
* @param columnMap 表字段 map 对象
* @param property 需要关联的字段
*/
default <R> List<T> listByMapDeep(Map<String, Object> columnMap, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, property);
}
/**
* 根据 Wrapper查询一条记录 <br/>
* <p>结果集如果是多个会抛出异常随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default T getOneDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper);
}
/**
* 根据 Wrapper查询一条记录 <br/>
* <p>结果集如果是多个会抛出异常随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, Arrays.asList(property));
}
/**
* 根据 Wrapper查询一条记录 <br/>
* list为null或空会查询全部映射关系<br/>
* <p>结果集如果是多个会抛出异常随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
* <p>
* getOneDeep(queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, property);
}
/**
* 根据 Wrapper查询一条记录
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param throwEx 有多个 result 是否抛出异常
*/
default T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), null);
}
/**
* 根据 Wrapper查询一条记录
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param throwEx 有多个 result 是否抛出异常
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), Arrays.asList(property));
}
/**
* 根据 Wrapper查询一条记录
* list为null或空会查询全部映射关系
* <p>
* getOneDeep(queryWrapper, throwEx, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param throwEx 有多个 result 是否抛出异常
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), property);
}
/**
* 根据 Wrapper查询一条记录
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(),
null);
}
/**
* 根据 Wrapper查询一条记录
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(),
Arrays.asList(property));
}
/**
* 根据 Wrapper查询一条记录
* list为null或空会查询全部映射关系
* <p>
* getMapDeep(queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(), property);
}
/**
* 查询列表
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default List<T> listDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper);
}
/**
* 查询列表
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> List<T> listDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, Arrays.asList(property));
}
/**
* 查询列表
* list为null或空会查询全部映射关系
* <p>
* listDeep(queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> List<T> listDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, property);
}
/**
* 查询所有
*
* @see Wrappers#emptyWrapper()
*/
default List<T> listDeep() {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper());
}
/**
* 查询所有
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R> List<T> listDeep(SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), Arrays.asList(property));
}
/**
* 查询所有
* list为null或空会查询全部映射关系
* <p>
* listDeep(Arrays.asList(User::getId, ... ))
*
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R> List<T> listDeep(List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), property);
}
/**
* 翻页查询
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default <E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper) {
E e = page(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), null);
return e;
}
/**
* 翻页查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R, E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
E e = page(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), Arrays.asList(property));
return e;
}
/**
* 翻页查询
* list为null或空会查询全部映射关系
* <p>
* pageDeep(page, queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R, E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
E e = page(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), property);
return e;
}
/**
* 无条件翻页查询
*
* @param page 翻页对象
* @see Wrappers#emptyWrapper()
*/
default <E extends IPage<T>> E pageDeep(E page) {
E e = page(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), null);
return e;
}
/**
* 无条件翻页查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param page 翻页对象
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R, E extends IPage<T>> E pageDeep(E page, SFunction<T, R>... property) {
E e = page(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), Arrays.asList(property));
return e;
}
/**
* 无条件翻页查询
* list为null或空会查询全部映射关系
* <p>
* pageDeep(page, Arrays.asList(User::getId, ... ))
*
* @param page 翻页对象
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R, E extends IPage<T>> E pageDeep(E page, List<SFunction<T, R>> property) {
E e = page(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), property);
return e;
}
/**
* 查询列表
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(), null);
}
/**
* 查询列表
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(),
Arrays.asList(property));
}
/**
* 查询列表
* list为null或空会查询全部映射关系
* <p>
* listMapsDeep(queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(), property);
}
/**
* 查询所有列表
*
* @see Wrappers#emptyWrapper()
*/
default List<Map<String, Object>> listMapsDeep() {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), null);
}
/**
* 查询所有列表
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R> List<Map<String, Object>> listMapsDeep(SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), Arrays.asList(property));
}
/**
* 查询所有列表
* list为null或空会查询全部映射关系
* <p>
* listMapsDeep(Arrays.asList(User::getId, ... ))
*
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R> List<Map<String, Object>> listMapsDeep(List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), property);
}
/**
* 翻页查询
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper) {
E e = pageMaps(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), null);
return e;
}
/**
* 翻页查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
E e = pageMaps(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
return e;
}
/**
* 翻页查询
* list为null或空会查询全部映射关系
* <p>
* pageMapsDeep(page, queryWrapper, Arrays.asList(User::getId, ... ))
*
* @param page 翻页对象
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* @param property 需要关联的字段
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
E e = pageMaps(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), property);
return e;
}
/**
* 无条件翻页查询
*
* @param page 翻页对象
* @see Wrappers#emptyWrapper()
*/
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) {
E e = pageMaps(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), null);
return e;
}
/**
* 无条件翻页查询
* <p>
* JDK 默认不推荐泛型数组会引起 Java堆污染(Heap Pollution)
*
* @param page 翻页对象
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, SFunction<T, R>... property) {
E e = pageMaps(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
return e;
}
/**
* 无条件翻页查询
* list为null或空会查询全部映射关系
* <p>
* pageMapsDeep(page, Arrays.asList(User::getId, ... ))
*
* @param page 翻页对象
* @param property 需要关联的字段
* @see Wrappers#emptyWrapper()
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, List<SFunction<T, R>> property) {
E e = pageMaps(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), property);
return e;
}
}

View File

@ -1,67 +0,0 @@
package com.github.yulichang.base.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.interfaces.MPJBaseJoin;
import java.util.List;
import java.util.Map;
/**
* @author yulichang
* @see IService
*/
@SuppressWarnings("unused")
public interface MPJJoinService<T> extends IService<T> {
/**
* 根据 Wrapper 条件查询总记录数
*/
default Integer selectJoinCount(MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinCount(wrapper);
}
/**
* 连接查询返回一条记录
*/
default <DTO> DTO selectJoinOne(Class<DTO> clazz, MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinOne(clazz, wrapper);
}
/**
* 连接查询返回集合
*/
default <DTO> List<DTO> selectJoinList(Class<DTO> clazz, MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinList(clazz, wrapper);
}
/**
* 连接查询返回集合并分页
*/
default <DTO, P extends IPage<?>> IPage<DTO> selectJoinListPage(P page, Class<DTO> clazz, MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinPage(page, clazz, wrapper);
}
/**
* 连接查询返回Map
*/
default Map<String, Object> selectJoinMap(MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinMap(wrapper);
}
/**
* 连接查询返回Map集合
*/
default List<Map<String, Object>> selectJoinMaps(MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinMaps(wrapper);
}
/**
* 连接查询返回Map集合并分页
*/
default <P extends IPage<Map<String, Object>>> IPage<Map<String, Object>> selectJoinMapsPage(
P page, MPJBaseJoin<T> wrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectJoinMapsPage(page, wrapper);
}
}

View File

@ -1,12 +1,64 @@
package com.github.yulichang.config;
import com.github.yulichang.config.enums.IfExistsEnum;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.interfaces.MBiPredicate;
/**
* @author yulichang
* @since 1.3.7
*/
public class ConfigProperties {
/**
* 是否打印banner
*/
public static boolean banner = true;
/**
* 是否开启副表逻辑删除
*/
public static boolean subTableLogic = true;
/**
* 是否开启 ms 缓存
*/
public static boolean msCache = true;
/**
* 表别名
*/
public static String tableAlias = "t";
/**
* 字段名重复时前缀
*/
public static String joinPrefix = "join";
/**
* 逻辑删除类型 支持 where on
*/
public static LogicDelTypeEnum logicDelType = LogicDelTypeEnum.ON;
/**
* 映射查询最大深度
*/
public static int mappingMaxCount = 5;
/**
* 子查询别名
*/
public static String subQueryAlias = "st";
/**
* Wrapper IfExists 判断策略
* <p>
* NOT_NULL 非null
* <p>
* NOT_EMPTY 非空字符串 "" -> false, " " -> true ...
* <p>
* NOT_BLANK 非空白字符串 "" -> false, " " -> false, "\r" -> false, "abc" -> true ...
*/
public static MBiPredicate<Object, IfExistsSqlKeyWordEnum> ifExists = (val, key) -> IfExistsEnum.NOT_EMPTY.test(val);
/**
* 暂存 不可使用 用于规避starter包中需要序列化
*/
public static class Convert {
public static IfExistsEnum IfExists = IfExistsEnum.NOT_EMPTY;
}
}

View File

@ -3,6 +3,7 @@ package com.github.yulichang.config;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.interceptor.MPJInterceptor;
import com.github.yulichang.toolkit.InterceptorList;
import com.github.yulichang.toolkit.MybatisJoinPlusVersion;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.plugin.Interceptor;
@ -29,11 +30,11 @@ public class MPJInterceptorConfig {
//打印banner
System.out.println(" _ _ |_ _ _|_. ___ _ | _ . _ . _ \n" +
"| | |\\/|_)(_| | |_\\ |_)||_|_\\ | (_) | | | \n" +
" / | / 1.4.2.2");
" / | /\n" +
" " + MybatisJoinPlusVersion.getVersion());
}
}
@SuppressWarnings("unchecked")
private void replaceInterceptorChain(List<SqlSessionFactory> sqlSessionFactoryList) {
if (CollectionUtils.isEmpty(sqlSessionFactoryList)) {
return;
@ -45,6 +46,7 @@ public class MPJInterceptorConfig {
InterceptorChain chain = (InterceptorChain) interceptorChain.get(factory.getConfiguration());
Field interceptors = InterceptorChain.class.getDeclaredField("interceptors");
interceptors.setAccessible(true);
@SuppressWarnings("unchecked")
List<Interceptor> list = (List<Interceptor>) interceptors.get(chain);
if (CollectionUtils.isEmpty(list)) {
interceptors.set(chain, new InterceptorList<>());
@ -53,8 +55,7 @@ public class MPJInterceptorConfig {
}
chain.addInterceptor(new MPJInterceptor());
} catch (NoSuchFieldException | IllegalAccessException e) {
logger.error("初始化 MPJ 拦截器失败");
e.printStackTrace();
logger.error("初始化 MPJ 拦截器失败", e);
}
}
}

View File

@ -1,20 +0,0 @@
package com.github.yulichang.config;
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.github.yulichang.mapper.MPJTableMapperHelper;
/**
* 关系映射配置
*
* @author yulichang
* @since 1.2.0
*/
public class MappingConfig {
public MappingConfig() {
TableInfoHelper.getTableInfos().forEach(i ->
MPJTableInfoHelper.initTableInfo(i.getEntityType(), MPJTableMapperHelper.getMapper(i.getEntityType())));
}
}

View File

@ -0,0 +1,40 @@
package com.github.yulichang.config.enums;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.wrapper.interfaces.MPredicate;
import java.io.Serializable;
import java.util.Objects;
/**
* 条件判断策略
*
* @author yulichang
* @since 1.4.9
*/
public enum IfExistsEnum implements MPredicate<Object>, Serializable {
/**
* 非null
*/
NOT_NULL(Objects::nonNull),
/**
* 非空字符串 "" -> false, " " -> true ...
*/
NOT_EMPTY(val -> NOT_NULL.and(v -> !(v instanceof CharSequence) || StrUtils.isNotEmpty((CharSequence) v)).test(val)),
/**
* NOT_BLANK 非空白字符串 "" -> false, " " -> false, "\r" -> false, "abc" -> true ...
*/
NOT_BLANK(val -> NOT_NULL.and(v -> !(v instanceof CharSequence) || StrUtils.isNotBlank((CharSequence) v)).test(val));
private final MPredicate<Object> predicate;
IfExistsEnum(MPredicate<Object> predicate) {
this.predicate = predicate;
}
@Override
public boolean test(Object obj) {
return this.predicate.test(obj);
}
}

View File

@ -0,0 +1,13 @@
package com.github.yulichang.config.enums;
import java.io.Serializable;
/**
* 逻辑删除位置
*
* @author yulichang
* @since 1.4.4
*/
public enum LogicDelTypeEnum implements Serializable {
WHERE, ON
}

View File

@ -1,13 +0,0 @@
package com.github.yulichang.exception;
/**
* mpj 异常
*
* @author yulichang
*/
public class MPJException extends RuntimeException {
public MPJException(String msg) {
super(msg);
}
}

View File

@ -0,0 +1,451 @@
package com.github.yulichang.extension.apt;
import com.baomidou.mybatisplus.annotation.OrderBy;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import com.github.yulichang.extension.apt.interfaces.QueryJoin;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.segments.PageInfo;
import com.github.yulichang.wrapper.segments.SelectCache;
import lombok.Getter;
import lombok.Setter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY;
import static java.util.stream.Collectors.joining;
/**
* 参考 {@link com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper}
*
* @author yulichang
*/
@SuppressWarnings({"DuplicatedCode", "unused"})
public abstract class AptAbstractWrapper<T, Children extends AptAbstractWrapper<T, Children>>
extends JoinAbstractWrapper<T, Children> implements QueryJoin<Children, T> {
/**
* 主表别名
*/
@Getter
protected String alias = ConfigProperties.tableAlias;
/**
* 副表别名
*/
protected String subTableAlias = ConfigProperties.tableAlias;
/**
* 是否构建是否存在一对多
*/
@Getter
protected boolean resultMap = false;
@Getter
protected boolean resultMapCollection = false;
@Setter
protected PageInfo pageInfo;
@Getter
protected boolean pageByMain = false;
/**
* 表序号
*/
protected int tableIndex = 1;
protected boolean isMain = true;
/**
* 主表 表名处理方法
*/
protected boolean dynamicTableName = false;
/**
* 主表 表名处理方法
*/
protected SFunction<String, String> tableFunc;
/**
* 逻辑删除位置
*/
protected LogicDelTypeEnum logicDelType = ConfigProperties.logicDelType;
/**
* 查询表
*/
protected final SharedString from = new SharedString();
/**
* 是否有表别名
*/
@Getter
protected boolean hasAlias;
/**
* 连表关键字 on 条件 func 使用
*/
@Getter
protected String keyWord;
/**
* 副表逻辑删除开关
*/
protected boolean subLogicSql = ConfigProperties.subTableLogic;
/**
* 主表逻辑删除开关
*/
protected boolean logicSql = true;
@Getter
protected BaseColumn<T> baseColumn;
/**
* apt别名对应
*/
@Getter
protected TableMap aptIndex;
/**
* 构造方法
*/
protected AptAbstractWrapper(BaseColumn<T> baseColumn) {
this.alias = StrUtils.isNotBlank(baseColumn.getAlias()) ? baseColumn.getAlias() : this.alias;
setEntityClass(baseColumn.getColumnClass());
this.baseColumn = baseColumn;
initNeed();
}
/**
* 构造方法
*
* @param entity 主表实体类
*/
protected AptAbstractWrapper(BaseColumn<T> baseColumn, T entity) {
this.alias = StrUtils.isNotBlank(baseColumn.getAlias()) ? baseColumn.getAlias() : this.alias;
setEntity(entity);
this.baseColumn = baseColumn;
initNeed();
}
/**
* 根据主表分页
*/
public Children pageByMain() {
this.pageByMain = true;
return typedThis;
}
/**
* 根据主表分页
*/
public Children pageByMain(MFunction<PageInfo> function) {
this.pageByMain = true;
function.apply(getPageInfo());
return typedThis;
}
public PageInfo getPageInfo() {
if (pageInfo == null) {
pageInfo = new PageInfo();
}
return pageInfo;
}
/**
* 设置表别名
* 设置表别名注意sql注入问题
*
* @return 自定义表别名
*/
public Children setTableName(SFunction<String, String> tableFunc) {
if (isMain) {
if (tableFunc != null) {
this.dynamicTableName = true;
this.tableFunc = tableFunc;
}
} else {
this.tableName = tableFunc.apply(this.tableName);
}
return typedThis;
}
public String getTableName(String tableName) {
if (isMain) {
if (dynamicTableName) {
return tableFunc.apply(tableName);
}
return tableName;
}
return super.getTableName();
}
public String getTableNameEnc(String tableName) {
Class<T> entityClass = getEntityClass();
if (entityClass != null) {
TableInfo tableInfo = TableHelper.get(entityClass);
if (tableInfo != null) {
if (dynamicTableName) {
return tableFunc.apply(tableInfo.getTableName());
}
return tableInfo.getTableName();
}
}
String decode;
try {
decode = URLDecoder.decode(tableName, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (dynamicTableName) {
return tableFunc.apply(decode);
}
return decode;
}
@Override
protected String columnsToString(Column... columns) {
return Arrays.stream(columns).map(this::columnToString)
.collect(joining(StringPool.COMMA));
}
@Override
protected String columnToString(Column column) {
String pf = column.getAlias().get();
if (Objects.nonNull(pf)) {
return pf + StringPool.DOT + getCache(column).getColumn();
}
return this.aptIndex.get(column.getRoot()) + StringPool.DOT + getCache(column).getColumn();
}
protected SelectCache getCache(Column fn) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(fn.getClazz());
return cacheMap.get(fn.getProperty());
}
/**
* 关闭副表逻辑删除
* <p>
* 副表逻辑删除默认在where语句中
* 但有时候需要让它出现在on语句中, 这两种写法区别还是很大的
* 所以可以关闭副表逻辑删除, 通过on语句多条件, 自己实现on语句的逻辑删除
*/
public Children disableSubLogicDel() {
this.subLogicSql = false;
return typedThis;
}
public Children enableSubLogicDel() {
this.subLogicSql = true;
return typedThis;
}
/**
* 关闭主表逻辑删除
*/
public Children disableLogicDel() {
this.logicSql = false;
return typedThis;
}
public Children enableLogicDel() {
this.logicSql = true;
return typedThis;
}
/**
* 副表部分逻辑删除支持
*/
public String getSubLogicSql() {
if (subLogicSql && logicDelType == LogicDelTypeEnum.WHERE) {
if (aptIndex.isEmpty()) {
return StringPool.EMPTY;
}
return aptIndex.keyList().stream().map(key -> LogicInfoUtils.getLogicInfoApt(key.getColumnClass(), this.aptIndex.get(key)))
.collect(Collectors.joining(StringPool.SPACE));
}
return StringPool.EMPTY;
}
/**
* 主表部分逻辑删除支持
*/
public boolean getLogicSql() {
return this.logicSql;
}
/**
* 调整逻辑删除位置为ON语句
*/
public Children logicDelToOn() {
this.logicDelType = LogicDelTypeEnum.ON;
return typedThis;
}
/**
* 调整逻辑删除位置为WHERE语句
*/
public Children logicDelToWhere() {
this.logicDelType = LogicDelTypeEnum.WHERE;
return typedThis;
}
/**
* 获取连表部分语句
*/
public String getFrom() {
if (StrUtils.isBlank(from.getStringValue())) {
StringBuilder value = new StringBuilder();
for (Children wrapper : onWrappers) {
if (StrUtils.isBlank(wrapper.from.getStringValue())) {
if (this.subLogicSql && this.logicDelType == LogicDelTypeEnum.ON) {
TableInfo tableInfo = TableHelper.getAssert(wrapper.getJoinClass());
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo)) {
wrapper.appendSqlSegments(APPLY, () -> LogicInfoUtils.getLogicInfoNoAnd(
wrapper.getIndex(), wrapper.getJoinClass(), wrapper.isHasAlias(), wrapper.getAlias()
));
}
}
value.append(StringPool.SPACE)
.append(wrapper.getKeyWord())
.append(StringPool.SPACE)
.append(wrapper.getTableName())
.append(StringPool.SPACE)
.append(wrapper.hasAlias ? wrapper.alias : (wrapper.alias + wrapper.getIndex()))
.append(Constant.ON)
.append(wrapper.getExpression().getNormal().getSqlSegment());
} else {
value.append(StringPool.SPACE)
.append(wrapper.getKeyWord())
.append(StringPool.SPACE)
.append(wrapper.from.getStringValue())
.append(StringPool.SPACE);
}
}
from.setStringValue(value.toString());
}
return from.getStringValue();
}
/**
* 检验表是否已连接
*/
public boolean checkJoinTable(Class<?> clazz) {
return onWrappers.stream().anyMatch(wrapper -> {
if (Objects.equals(wrapper.getJoinClass(), clazz)) {
return true;
} else {
TableInfo info = TableHelper.getAssert(clazz);
String tableName = info.getTableName();
return Optional.ofNullable(wrapper.from.getStringValue())
.map(w -> w.contains(Constant.JOIN + StringPool.SPACE + tableName + StringPool.SPACE))
.orElse(false);
}
});
}
/**
* 内部调用, 不建议使用
*/
@Override
public <R> Children join(String keyWord, BaseColumn<R> baseColumn, MFunction<AptAbstractWrapper<T, ?>> function) {
Integer oldIndex = this.getIndex();
int newIndex = tableIndex;
TableInfo info = TableHelper.getAssert(baseColumn.getColumnClass());
Children instance = instance(newIndex, keyWord, baseColumn.getColumnClass(), info.getTableName());
instance.isMain = false;
onWrappers.add(instance);
if (StrUtils.isBlank(baseColumn.getAlias())) {
aptIndex.put(baseColumn, subTableAlias + newIndex);
instance.alias = subTableAlias;
instance.hasAlias = false;
} else {
aptIndex.put(baseColumn, baseColumn.getAlias());
instance.alias = baseColumn.getAlias();
instance.hasAlias = true;
}
tableIndex++;
function.apply(instance);
return typedThis;
}
/**
* 自定义关键词连接
*
* @param keyWord 连表关键词
* @param condition 条件
* @param joinSql sql
*/
@Override
public Children join(String keyWord, boolean condition, String joinSql, Object... objects) {
if (condition) {
Children wrapper = instanceEmpty();
wrapper.from.setStringValue(formatSqlMaybeWithParam(joinSql, objects));
wrapper.keyWord = keyWord;
onWrappers.add(wrapper);
}
return typedThis;
}
/**
* 是否使用默认注解 {@link OrderBy} 排序
*
* @return true 使用 false 不使用
*/
public boolean isUseAnnotationOrderBy() {
final String _sqlSegment = this.getSqlSegment();
if (StrUtils.isBlank(_sqlSegment)) {
return true;
}
final String _sqlSegmentToUpperCase = _sqlSegment.toUpperCase();
return !(_sqlSegmentToUpperCase.contains(Constants.ORDER_BY)
|| _sqlSegmentToUpperCase.contains(Constants.LIMIT));
}
/**
* 必要的初始化
*/
protected void initNeed() {
paramNameSeq = new AtomicInteger(0);
paramNameValuePairs = new HashMap<>(16);
expression = new MergeSegments();
lastSql = SharedString.emptyString();
sqlComment = SharedString.emptyString();
sqlFirst = SharedString.emptyString();
aptIndex = new TableMap(this.baseColumn, this.alias);
}
@Override
public void clear() {
super.clear();
this.alias = ConfigProperties.tableAlias;
this.resultMap = false;
this.resultMapCollection = false;
this.pageInfo = null;
this.pageByMain = false;
this.tableIndex = 1;
this.dynamicTableName = false;
this.tableFunc = null;
this.logicDelType = ConfigProperties.logicDelType;
this.from.toEmpty();
this.hasAlias = false;
this.keyWord = null;
this.logicSql = true;
this.isMain = true;
this.checkSqlInjection = false;
this.onWrappers.clear();
this.aptIndex.clear();
}
}

View File

@ -0,0 +1,361 @@
package com.github.yulichang.extension.apt;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.extension.apt.interfaces.Query;
import com.github.yulichang.extension.apt.interfaces.QueryLabel;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.extension.apt.toolkit.AptWrapperUtils;
import com.github.yulichang.extension.apt.toolkit.AptWrappers;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.TableMap;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.interfaces.Chain;
import com.github.yulichang.wrapper.interfaces.MBiPredicate;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.interfaces.SelectWrapper;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.segments.*;
import lombok.Getter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
* Lambda 语法使用 Wrapper
*
* @author yulichang
* @since 1.5.0
*/
@SuppressWarnings("unused")
public class AptQueryWrapper<T> extends AptAbstractWrapper<T, AptQueryWrapper<T>> implements
Query<AptQueryWrapper<T>>, QueryLabel<AptQueryWrapper<T>>, Chain<T>, SelectWrapper<T, AptQueryWrapper<T>> {
/**
* 查询字段 sql
*/
private SharedString sqlSelect = new SharedString();
/**
* 是否 select distinct
*/
private boolean selectDistinct = false;
/**
* 查询的字段
*/
@Getter
private final List<Select> selectColumns = new ArrayList<>();
/**
* 映射关系
*/
@Getter
private final List<Label<?>> resultMapMybatisLabel = new ArrayList<>();
/**
* union sql
*/
private SharedString unionSql;
/**
* 自定义wrapper索引
*/
private AtomicInteger wrapperIndex;
/**
* 自定义wrapper
*/
@Getter
private Map<String, Wrapper<?>> wrapperMap;
/**
* 推荐使用此构造方法
*/
public AptQueryWrapper(BaseColumn<T> baseColumn) {
super(baseColumn);
}
public AptQueryWrapper(BaseColumn<T> baseColumn, T entity) {
super(baseColumn, entity);
}
/**
* 不建议直接 new 该实例使用 JoinWrappers.lambda(UserDO.class)
*/
protected AptQueryWrapper(T entity, BaseColumn<T> baseColumn, SharedString sqlSelect, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
TableMap aptIndex, Integer index, String keyWord, Class<?> joinClass, String tableName,
MBiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
super(baseColumn);
super.setEntity(entity);
super.setEntityClass(baseColumn.getColumnClass());
this.baseColumn = baseColumn;
this.paramNameSeq = paramNameSeq;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
this.sqlSelect = sqlSelect;
this.paramAlias = paramAlias;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
if (aptIndex != null) {
this.aptIndex = aptIndex;
}
this.index = index;
this.keyWord = keyWord;
this.joinClass = joinClass;
this.tableName = tableName;
this.ifExists = IfExists;
}
/**
* sql去重
* select distinct
*/
public AptQueryWrapper<T> distinct() {
this.selectDistinct = true;
return typedThis;
}
@Override
public List<Select> getSelectColum() {
return this.selectColumns;
}
@Override
public void addLabel(Label<?> label, boolean isCollection) {
if (isCollection) {
this.resultMapCollection = true;
}
this.resultMap = true;
this.resultMapMybatisLabel.add(label);
}
@Override
public AptQueryWrapper<T> getChildren() {
return typedThis;
}
/**
* 设置查询字段
*
* @param columns 字段数组
* @return children
*/
public final AptQueryWrapper<T> select(Column... columns) {
if (ArrayUtils.isNotEmpty(columns)) {
for (Column s : columns) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(s.getClazz());
SelectCache cache = cacheMap.get(s.getProperty());
getSelectColum().add(new SelectApt(cache, s));
}
}
return typedThis;
}
/**
* 查询实体类全部字段
*/
@Override
public final <E> AptQueryWrapper<T> selectAll(BaseColumn<E> baseColumn, Column... exclude) {
return Query.super.selectAll(baseColumn, exclude);
}
/**
* 查询主表全部字段
* <p>
* 需要使用 使用 JoinWrappers.lambda(clazz) 或者 new MPJLambdaQueryWrapper&lt;&lt;(clazz) 构造
*
* @return children
*/
@Override
public AptQueryWrapper<T> selectAll() {
Assert.notNull(getEntityClass(), "使用 AptWrappers.query(clazz) 或者 new JoinAptQueryWrapper<>(BaseColum)");
return selectAll(getBaseColumn());
}
@Override
public AptQueryWrapper<T> selectFunc(String sql, MFunction<AptConsumer> column, String alias) {
AptConsumer apply = column.apply(new AptConsumer());
String formatSql;
if (ArrayUtils.isEmpty(apply.getValues())) {
formatSql = sql;
} else {
formatSql = formatSqlMaybeWithParam(sql, apply.getValues());
}
getSelectColum().add(new SelectApt(apply.getColumns(), () -> formatSql, alias));
return typedThis;
}
public <E, F> AptQueryWrapper<T> selectSub(BaseColumn<E> baseColumn, Consumer<AptQueryWrapper<E>> consumer, SFunction<F, ?> alias) {
return selectSub(baseColumn, consumer, LambdaUtils.getName(alias));
}
/**
* 子查询
*/
public <E, F> AptQueryWrapper<T> selectSub(BaseColumn<E> baseColumn, Consumer<AptQueryWrapper<E>> consumer, String alias) {
AptQueryWrapper<E> wrapper = new AptQueryWrapper<E>(null, baseColumn, SharedString.emptyString(),
paramNameSeq, paramNameValuePairs, new MergeSegments(), new SharedString(this.paramAlias
.getStringValue()), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
null, null, null, null, null, ifExists) {
};
wrapper.aptIndex.setParent(this.aptIndex);
if (null == baseColumn.getAlias()) {
wrapper.alias = ConfigProperties.subQueryAlias;
wrapper.aptIndex.setRootAlias(ConfigProperties.subQueryAlias);
}
wrapper.subTableAlias = ConfigProperties.subQueryAlias;
consumer.accept(wrapper);
addCustomWrapper(wrapper);
this.selectColumns.add(new SelectSub(() -> AptWrapperUtils.buildSubSqlByWrapper(baseColumn.getColumnClass(), wrapper, alias), hasAlias, this.alias, alias));
return typedThis;
}
/**
* union
* <p>
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param baseColumn union语句的主表类型
* @since 1.4.8
*/
public <U> AptQueryWrapper<T> union(BaseColumn<U> baseColumn, Consumer<AptQueryWrapper<U>> consumer) {
AptQueryWrapper<U> unionWrapper = AptWrappers.query(baseColumn);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION " + AptWrapperUtils.buildUnionSqlByWrapper(baseColumn.getColumnClass(), unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param baseColumn union语句的主表类型
* @since 1.4.8
*/
public <U> AptQueryWrapper<T> unionAll(BaseColumn<U> baseColumn, Consumer<AptQueryWrapper<U>> consumer) {
AptQueryWrapper<U> unionWrapper = AptWrappers.query(baseColumn);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION ALL " + AptWrapperUtils.buildUnionSqlByWrapper(baseColumn.getColumnClass(), unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
private void addCustomWrapper(AptQueryWrapper<?> wrapper) {
if (Objects.isNull(wrapperIndex)) {
wrapperIndex = new AtomicInteger(0);
}
int index = wrapperIndex.incrementAndGet();
if (Objects.isNull(wrapperMap)) {
wrapperMap = new HashMap<>();
}
String key = "ew" + index;
wrapper.setParamAlias(wrapper.getParamAlias() + ".wrapperMap." + key);
wrapperMap.put(key, wrapper);
}
/**
* 查询条件 SQL 片段
*/
@Override
public String getSqlSelect() {
if (StrUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {
if (i.isStr()) {
return i.getColumn();
}
if (i.isFunc()) {
return String.format(i.getFunc().getSql(), Arrays.stream(i.getColumns()).map(c ->
this.aptIndex.get(c.getRoot()) + StringPool.DOT + i.getColumn()).toArray()) + Constant.AS + i.getAlias();
} else {
String prefix;
if (null == i.getTableAlias() && null != i.getBaseColumn()) {
prefix = this.aptIndex.get(i.getBaseColumn());
} else {
prefix = i.getTableAlias();
}
String col = prefix + StringPool.DOT + i.getColumn();
return i.isHasAlias() ? col + Constants.AS + i.getAlias() : col;
}
}).collect(Collectors.joining(StringPool.COMMA));
sqlSelect.setStringValue(s);
}
return sqlSelect.getStringValue();
}
@Override
public String getUnionSql() {
return Optional.ofNullable(unionSql).map(SharedString::getStringValue).orElse(StringPool.EMPTY);
}
public boolean getSelectDistinct() {
return selectDistinct;
}
/**
* 用于生成嵌套 sql
* <p> sqlSelect 不向下传递</p>
*/
@Override
protected AptQueryWrapper<T> instance() {
return instance(index, null, null, null);
}
@Override
protected AptQueryWrapper<T> instanceEmpty() {
return new AptQueryWrapper<>(getBaseColumn());
}
@Override
protected AptQueryWrapper<T> instance(Integer index, String keyWord, Class<?> joinClass, String tableName) {
return new AptQueryWrapper<>(getEntity(), baseColumn, null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.aptIndex, index, keyWord, joinClass, tableName, ifExists);
}
@Override
public void clear() {
super.clear();
selectDistinct = false;
sqlSelect.toNull();
selectColumns.clear();
wrapperIndex = new AtomicInteger(0);
if (Objects.nonNull(wrapperMap)) wrapperMap.clear();
if (Objects.nonNull(unionSql)) unionSql.toEmpty();
resultMapMybatisLabel.clear();
ifExists = ConfigProperties.ifExists;
}
}

View File

@ -1,4 +1,4 @@
package com.github.yulichang.wrapper;
package com.github.yulichang.extension.apt;
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.SharedString;
@ -7,21 +7,35 @@ import com.baomidou.mybatisplus.core.conditions.interfaces.Nested;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.extension.apt.interfaces.CompareIfExists;
import com.github.yulichang.extension.apt.interfaces.Func;
import com.github.yulichang.extension.apt.interfaces.OnCompare;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.toolkit.MPJSqlInjectionUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.Ref;
import com.github.yulichang.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.wrapper.enums.PrefixEnum;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.interfaces.*;
import com.github.yulichang.wrapper.segments.AptConsumer;
import lombok.Getter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*;
import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY;
@ -33,10 +47,10 @@ import static java.util.stream.Collectors.joining;
*
* @author yulichang
*/
@SuppressWarnings("ALL")
public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<T, Children>> extends Wrapper<T>
implements Compare<Children>, Nested<Children, Children>, Join<Children>, Func<Children>, OnCompare<Children>,
CompareStr<Children, String>, FuncStr<Children, String> {
@SuppressWarnings({"unchecked", "unused", "DuplicatedCode"})
public abstract class JoinAbstractWrapper<T, Children extends JoinAbstractWrapper<T, Children>> extends Wrapper<T>
implements CompareIfExists<Children>, Nested<Children, Children>, Join<Children>, Func<Children>, OnCompare<Children>,
CompareStrIfExists<Children, String>, FuncStr<Children, String> {
/**
* 占位符
@ -50,13 +64,15 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
/**
* 必要度量
*/
@Getter
protected AtomicInteger paramNameSeq;
@Getter
protected Map<String, Object> paramNameValuePairs;
/**
* 其他
*/
/* mybatis plus 3.4.3新增 这个时wrapper的别名 不是MPJ的别名 */
protected SharedString paramAlias;
protected SharedString paramAlias = new SharedString(null);
protected SharedString lastSql;
/**
* SQL注释
@ -69,9 +85,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
/**
* ON sql wrapper集合
*/
protected final List<MPJLambdaWrapper<T>> onWrappers = new ArrayList<>();
protected final List<Children> onWrappers = new ArrayList<>();
/**
* ß
* 数据库表映射实体类
*/
private T entity;
@ -85,19 +100,23 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
*/
@Getter
protected Class<?> joinClass;
/**
* 主表wrapper
*/
protected boolean isMain = true;
/**
* 是否是OnWrapper
*/
protected boolean isNo = false;
/**
* 关联的表
* 连表表名
*/
protected TableList tableList;
@Getter
protected String tableName;
/**
* 检查 SQL 注入过滤
*/
protected boolean checkSqlInjection = false;
/**
* IfExists 策略
*/
@Getter
protected MBiPredicate<Object, IfExistsSqlKeyWordEnum> ifExists = ConfigProperties.ifExists;
@Override
public T getEntity() {
@ -121,105 +140,118 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
onWrappers.forEach(i -> i.setEntityClass(entityClass));
this.entityClass = entityClass;
}
if (tableList != null) {
tableList.setRootClass(entityClass);
}
return typedThis;
}
/**
* 转为子类方便自定义继承扩展
*/
public <C extends Children> C toChildren(Ref<C> children) {
return (C) this;
}
/**
* 转为子类方便自定义继承扩展
* 需要子类自定义字段
*/
public <C extends Children> C toChildren(Supplier<C> s) {
return (C) this;
}
/**
* 开启检查 SQL 注入
*/
public Children checkSqlInjection() {
this.checkSqlInjection = true;
return typedThis;
}
public Children setIfExists(MBiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
this.ifExists = IfExists;
return typedThis;
}
/**
* 设置 IfExists
* .IfExists(val -> val != null && StrUtils.isNotBlank(val))
*
* @param IfExists 判断
* @return Children
*/
public Children setIfExists(Predicate<Object> IfExists) {
this.ifExists = (obj, key) -> IfExists.test(obj);
return typedThis;
}
@Override
public <X, V> Children allEq(boolean condition, Map<SFunction<X, ?>, V> params, boolean null2IsNull) {
if (condition && CollectionUtils.isNotEmpty(params)) {
params.forEach((k, v) -> {
if (StringUtils.checkValNotNull(v)) {
eq(k, v);
} else {
if (null2IsNull) {
isNull(k);
}
}
});
}
return typedThis;
}
@Override
public <X, V> Children allEq(boolean condition, BiPredicate<SFunction<X, ?>, V> filter, Map<SFunction<X, ?>, V> params, boolean null2IsNull) {
if (condition && CollectionUtils.isNotEmpty(params)) {
params.forEach((k, v) -> {
if (filter.test(k, v)) {
if (StringUtils.checkValNotNull(v)) {
eq(k, v);
} else {
if (null2IsNull) {
isNull(k);
}
}
}
});
}
return typedThis;
}
@Override
public <X> Children eq(boolean condition, SFunction<X, ?> column, Object val) {
public Children eq(boolean condition, Column column, Object val) {
return addCondition(condition, column, EQ, val);
}
@Override
public <X> Children ne(boolean condition, SFunction<X, ?> column, Object val) {
public Children ne(boolean condition, Column column, Object val) {
return addCondition(condition, column, NE, val);
}
@Override
public <X> Children gt(boolean condition, SFunction<X, ?> column, Object val) {
public Children gt(boolean condition, Column column, Object val) {
return addCondition(condition, column, GT, val);
}
@Override
public <X> Children ge(boolean condition, SFunction<X, ?> column, Object val) {
public Children ge(boolean condition, Column column, Object val) {
return addCondition(condition, column, GE, val);
}
@Override
public <X> Children lt(boolean condition, SFunction<X, ?> column, Object val) {
public Children lt(boolean condition, Column column, Object val) {
return addCondition(condition, column, LT, val);
}
@Override
public <X> Children le(boolean condition, SFunction<X, ?> column, Object val) {
public Children le(boolean condition, Column column, Object val) {
return addCondition(condition, column, LE, val);
}
@Override
public <X> Children like(boolean condition, SFunction<X, ?> column, Object val) {
public Children like(boolean condition, Column column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.DEFAULT);
}
@Override
public <X> Children notLike(boolean condition, SFunction<X, ?> column, Object val) {
public Children notLike(boolean condition, Column column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.DEFAULT);
}
@Override
public <X> Children likeLeft(boolean condition, SFunction<X, ?> column, Object val) {
public Children likeLeft(boolean condition, Column column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.LEFT);
}
@Override
public <X> Children likeRight(boolean condition, SFunction<X, ?> column, Object val) {
public Children notLikeLeft(boolean condition, Column column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.LEFT);
}
@Override
public Children likeRight(boolean condition, Column column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.RIGHT);
}
@Override
public <X> Children between(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), BETWEEN,
public Children notLikeRight(boolean condition, Column column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.RIGHT);
}
@Override
public Children between(boolean condition, Column column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
}
@Override
public <X> Children notBetween(boolean condition, SFunction<X, ?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_BETWEEN,
public Children notBetween(boolean condition, Column column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_BETWEEN,
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
}
@ -251,13 +283,28 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public Children apply(boolean condition, String applySql, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(APPLY,
() -> formatSqlMaybeWithParam(applySql, null, values)));
() -> formatSqlMaybeWithParam(applySql, values)));
}
public Children applyFunc(String applySql, MFunction<AptConsumer> consumerFunction, Object... values) {
return applyFunc(true, applySql, consumerFunction, values);
}
public Children applyFunc(boolean condition, String applySql,
MFunction<AptConsumer> consumerFunction, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(APPLY,
() -> {
AptConsumer apply = consumerFunction.apply(new AptConsumer());
return formatSqlMaybeWithParam(String.format(applySql,
Arrays.stream(apply.getColumns()).map(this::columnToString).toArray()),
ArrayUtils.isNotEmpty(values) ? values : apply.getValues());
}));
}
@Override
public Children last(boolean condition, String lastSql) {
if (condition) {
this.lastSql.setStringValue(StringPool.SPACE + lastSql);
this.lastSql.setStringValue(this.lastSql.getStringValue() + StringPool.SPACE + lastSql);
}
return typedThis;
}
@ -273,15 +320,22 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public Children first(boolean condition, String firstSql) {
if (condition) {
this.sqlFirst.setStringValue(firstSql);
this.sqlFirst.setStringValue(firstSql + StringPool.SPACE + this.sqlFirst.getStringValue());
}
return typedThis;
}
@Override
public Children around(boolean condition, String firstSql, String lastSql) {
this.first(condition, firstSql);
this.last(condition, lastSql);
return typedThis;
}
@Override
public Children exists(boolean condition, String existsSql, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(EXISTS,
() -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, null, values))));
() -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, values))));
}
@Override
@ -290,89 +344,94 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
}
@Override
public <X> Children isNull(boolean condition, SFunction<X, ?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IS_NULL));
public Children isNull(boolean condition, Column column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IS_NULL));
}
@Override
public <X> Children isNotNull(boolean condition, SFunction<X, ?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IS_NOT_NULL));
public Children isNotNull(boolean condition, Column column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IS_NOT_NULL));
}
@Override
public <X> Children in(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN, inExpression(coll)));
public Children in(boolean condition, Column column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN, inExpression(coll)));
}
@Override
public <X> Children in(boolean condition, SFunction<X, ?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN, inExpression(values)));
public Children in(boolean condition, Column column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN, inExpression(values)));
}
@Override
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN, inExpression(coll)));
public Children notIn(boolean condition, Column column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN, inExpression(coll)));
}
@Override
public <X> Children notIn(boolean condition, SFunction<X, ?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN, inExpression(values)));
public Children notIn(boolean condition, Column column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN, inExpression(values)));
}
@Override
public <X> Children inSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN,
public Children inSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), IN,
() -> String.format("(%s)", inValue)));
}
@Override
public <X> Children notInSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN,
public Children notInSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN,
() -> String.format("(%s)", inValue)));
}
@Override
public <X> Children gtSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), GT,
public Children gtSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), GT,
() -> String.format("(%s)", inValue)));
}
@Override
public <X> Children geSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), GE,
public Children geSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), GE,
() -> String.format("(%s)", inValue)));
}
@Override
public <X> Children ltSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), LT,
public Children ltSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), LT,
() -> String.format("(%s)", inValue)));
}
@Override
public <X> Children leSql(boolean condition, SFunction<X, ?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), LE,
public Children leSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), LE,
() -> String.format("(%s)", inValue)));
}
@Override
public <R> Children groupBy(boolean condition, List<SFunction<R, ?>> columns) {
public Children eqSql(boolean condition, Column column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), EQ,
() -> String.format("(%s)", inValue)));
}
@Override
public Children groupBy(boolean condition, List<Column> columns) {
return maybeDo(condition, () -> {
if (CollectionUtils.isNotEmpty(columns)) {
String one = (StringPool.COMMA + columnsToString(index, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, columns));
final String finalOne = one;
final String finalOne = columnsToString(columns, false);
appendSqlSegments(GROUP_BY, () -> finalOne);
}
});
}
@Override
public <X> Children groupBy(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns) {
public Children groupBy(boolean condition, Column column, Column... columns) {
return maybeDo(condition, () -> {
String one = columnToString(index, column, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST);
String one = columnToString(column);
if (ArrayUtils.isNotEmpty(columns)) {
one += (StringPool.COMMA + columnsToString(index, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, columns));
one += (StringPool.COMMA + columnsToString(columns));
}
final String finalOne = one;
appendSqlSegments(GROUP_BY, () -> finalOne);
@ -380,58 +439,62 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
}
@Override
public <R> Children orderByAsc(boolean condition, List<SFunction<R, ?>> columns) {
public Children orderByAsc(boolean condition, List<Column> columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = ASC;
if (CollectionUtils.isNotEmpty(columns)) {
columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
columnToSqlSegment(columnSqlInjectFilter(c)), ASC));
}
});
}
@Override
public <R> Children orderByDesc(boolean condition, List<SFunction<R, ?>> columns) {
public Children orderByDesc(boolean condition, List<Column> columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = DESC;
if (CollectionUtils.isNotEmpty(columns)) {
columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
columnToSqlSegment(columnSqlInjectFilter(c)), DESC));
}
});
}
@Override
public <X> Children orderBy(boolean condition, boolean isAsc, SFunction<X, ?> column, SFunction<X, ?>... columns) {
public Children orderBy(boolean condition, boolean isAsc, Column column, Column... columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = isAsc ? ASC : DESC;
appendSqlSegments(ORDER_BY, columnToSqlSegment(index, column, false), mode);
appendSqlSegments(ORDER_BY, columnToSqlSegment(column), mode);
if (ArrayUtils.isNotEmpty(columns)) {
Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
columnToSqlSegment(columnSqlInjectFilter(c)), mode));
}
});
}
/**
* 字段 SQL 注入过滤处理子类重写实现过滤逻辑
*
* @param column 字段内容
* @return
*/
protected <X> SFunction<X, ?> columnSqlInjectFilter(SFunction<X, ?> column) {
protected Column columnSqlInjectFilter(Column column) {
return column;
}
@Override
public Children having(boolean condition, String sqlHaving, Object... params) {
return maybeDo(condition, () -> appendSqlSegments(HAVING,
() -> formatSqlMaybeWithParam(sqlHaving, null, params)));
() -> formatSqlMaybeWithParam(sqlHaving, params)));
}
@Override
public Children func(boolean condition, Consumer<Children> consumer) {
return maybeDo(condition, () -> consumer.accept(typedThis));
public Children func(boolean condition, Consumer<Children> consumer, Consumer<Children> consumerElse) {
if (condition) {
consumer.accept(typedThis);
}
if (!condition && Objects.nonNull(consumerElse)) {
consumerElse.accept(typedThis);
}
return typedThis;
}
/**
@ -454,8 +517,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* 内部自用
* <p>拼接 LIKE 以及 </p>
*/
protected <X> Children likeValue(boolean condition, SqlKeyword keyword, SFunction<X, ?> column, Object val, SqlLike sqlLike) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), keyword,
protected <X> Children likeValue(boolean condition, SqlKeyword keyword, Column column, Object val, SqlLike sqlLike) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), keyword,
() -> formatParam(null, SqlUtils.concatLike(val, sqlLike))));
}
@ -472,24 +535,17 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* @param sqlKeyword SQL 关键词
* @param val 条件值
*/
protected <X> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, Object val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), sqlKeyword,
protected <X> Children addCondition(boolean condition, Column column, SqlKeyword sqlKeyword, Object val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword,
() -> formatParam(null, val)));
}
protected <X, S> Children addCondition(boolean condition, SFunction<X, ?> column, SqlKeyword sqlKeyword, SFunction<S, ?> val) {
Class<X> c = LambdaUtils.getEntityClass(column);
Class<S> v = LambdaUtils.getEntityClass(val);
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), sqlKeyword,
isNo ?
columnToSqlSegmentS(index, val, v == c && v == joinClass) :
columnToSqlSegmentS(index, val, v == c)
));
protected <X, S> Children addCondition(boolean condition, Column column, SqlKeyword sqlKeyword, Column val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, columnToSqlSegment(val)));
}
protected Children addCondition(boolean condition, String column, SqlKeyword sqlKeyword, Object val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword,
() -> formatParam(null, val)));
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, () -> formatParam(null, val)));
}
/**
@ -510,25 +566,36 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
*/
protected abstract Children instance();
protected abstract Children instanceEmpty();
protected abstract Children instance(Integer index, String keyWord, Class<?> joinClass, String tableName);
/**
* 格式化 sql
* <p>
* 支持 "{0}" 这种,或者 "sql {0} sql" 这种
*
* @param sqlStr 可能是sql片段
* @param mapping 例如: "javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler" 这种
* @param params 参数
* @param sqlStr 可能是sql片段
* @param params 参数
* @return sql片段
*/
protected final String formatSqlMaybeWithParam(String sqlStr, String mapping, Object... params) {
if (StringUtils.isBlank(sqlStr)) {
// todo 何时会这样?
protected final String formatSqlMaybeWithParam(String sqlStr, Object... params) {
if (StrUtils.isBlank(sqlStr)) {
return null;
}
if (ArrayUtils.isNotEmpty(params)) {
for (int i = 0; i < params.length; ++i) {
final String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE;
sqlStr = sqlStr.replace(target, formatParam(mapping, params[i]));
String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE;
if (sqlStr.contains(target)) {
sqlStr = sqlStr.replace(target, formatParam(null, params[i]));
} else {
Matcher matcher = Pattern.compile("[{]" + i + ",[a-zA-Z0-9.,=]+}").matcher(sqlStr);
if (!matcher.find()) {
throw ExceptionUtils.mpe("Please check the syntax correctness! sql not contains: \"%s\"", target);
}
String group = matcher.group();
sqlStr = sqlStr.replace(group, formatParam(group.substring(target.length(), group.length() - 1), params[i]));
}
}
}
return sqlStr;
@ -591,12 +658,17 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public void clear() {
entity = null;
paramAlias.toNull();
paramNameSeq.set(0);
paramNameValuePairs.clear();
expression.clear();
lastSql.toEmpty();
sqlComment.toEmpty();
sqlFirst.toEmpty();
if (Objects.nonNull(lastSql)) lastSql.toEmpty();
if (Objects.nonNull(sqlComment)) sqlComment.toEmpty();
if (Objects.nonNull(sqlFirst)) sqlFirst.toEmpty();
entityClass = null;
onWrappers.clear();
index = null;
ifExists = ConfigProperties.ifExists;
}
/**
@ -615,7 +687,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public String getSqlComment() {
if (StringUtils.isNotBlank(sqlComment.getStringValue())) {
if (StrUtils.isNotBlank(sqlComment.getStringValue())) {
return "/*" + StringEscape.escapeRawString(sqlComment.getStringValue()) + "*/";
}
return null;
@ -623,7 +695,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public String getSqlFirst() {
if (StringUtils.isNotBlank(sqlFirst.getStringValue())) {
if (StrUtils.isNotBlank(sqlFirst.getStringValue())) {
return StringEscape.escapeRawString(sqlFirst.getStringValue());
}
return null;
@ -634,12 +706,8 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
return expression;
}
public Map<String, Object> getParamNameValuePairs() {
return paramNameValuePairs;
}
public String getParamAlias() {
return paramAlias == null ? Constants.WRAPPER : paramAlias.getStringValue();
return paramAlias.getStringValue() == null ? Constants.WRAPPER : paramAlias.getStringValue();
}
/**
@ -648,49 +716,33 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
* @param paramAlias 参数别名
* @return Children
*/
@SuppressWarnings("UnusedReturnValue")
public Children setParamAlias(String paramAlias) {
Assert.notEmpty(paramAlias, "paramAlias can not be empty!");
Assert.isTrue(CollectionUtils.isEmpty(paramNameValuePairs), "Please call this method before working!");
Assert.isNull(this.paramAlias, "Please do not call the method repeatedly!");
this.paramAlias = new SharedString(paramAlias);
this.paramAlias.setStringValue(paramAlias);
return typedThis;
}
/**
* 获取 columnName
*/
protected final <X> ISqlSegment columnToSqlSegment(Integer index, SFunction<X, ?> column, boolean isJoin) {
PrefixEnum prefixEnum;
if (isMain) {
prefixEnum = isNo ? PrefixEnum.ON_FIRST /* 理论上不可能有这种情况 */ : PrefixEnum.CD_FIRST;
} else {
prefixEnum = isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_ON_FIRST;
}
return () -> columnToString(index, column, isJoin, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST);
protected final ISqlSegment columnToSqlSegment(Column column) {
return () -> columnToString(column);
}
protected final <X> ISqlSegment columnToSqlSegmentS(Integer index, SFunction<X, ?> column, boolean isJoin) {
PrefixEnum prefixEnum;
if (isMain) {
prefixEnum = isNo ? PrefixEnum.ON_SECOND /* 理论上不可能有这种情况 */ : PrefixEnum.CD_SECOND;
} else {
prefixEnum = isNo ? PrefixEnum.ON_SECOND : PrefixEnum.CD_ON_SECOND;
}
return () -> columnToString(index, column, isJoin, prefixEnum);
}
protected final <X> ISqlSegment columnToSqlSegment(String column) {
return () -> (String) column;
protected final ISqlSegment columnToSqlSegment(String column) {
return () -> columnsToString(column);
}
/**
* 获取 columnName
*/
protected <X> String columnToString(Integer index, X column, boolean isJoin, PrefixEnum prefixEnum) {
return (String) column;
}
abstract protected String columnToString(Column column);
protected String columnToString(String column) {
if (checkSqlInjection && MPJSqlInjectionUtils.check(column)) {
throw new MybatisPlusException("Discovering SQL injection column: " + column);
}
return column;
}
@ -708,65 +760,119 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
*
* @param columns 多字段
*/
protected <X> String columnsToString(Integer index, boolean isJoin, PrefixEnum prefixEnum, X... columns) {
return Arrays.stream(columns).map(i -> this.columnToString(index, i, isJoin, prefixEnum)).collect(joining(StringPool.COMMA));
abstract <X> String columnsToString(Column... columns);
public String columnsToString(List<Column> columns, boolean flag) {
return columns.stream().map(this::columnToString).collect(joining(StringPool.COMMA));
}
@Override
@SuppressWarnings("all")
@SuppressWarnings("MethodDoesntCallSuperMethod")
public Children clone() {
return SerializationUtils.clone(typedThis);
}
/**
* 做事函数
*/
@FunctionalInterface
public interface DoSomething {
void doIt();
}
/* ************************* on语句重载 *************************** */
@Override
public <R, S> Children eq(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
public Children eq(boolean condition, Column column, Column val) {
return addCondition(condition, column, EQ, val);
}
@Override
public <R, S> Children ne(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
public Children ne(boolean condition, Column column, Column val) {
return addCondition(condition, column, NE, val);
}
@Override
public <R, S> Children gt(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
public Children gt(boolean condition, Column column, Column val) {
return addCondition(condition, column, GT, val);
}
@Override
public <R, S> Children ge(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
public Children ge(boolean condition, Column column, Column val) {
return addCondition(condition, column, GE, val);
}
@Override
public <R, S> Children lt(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
public Children lt(boolean condition, Column column, Column val) {
return addCondition(condition, column, LT, val);
}
@Override
public <R, S> Children le(boolean condition, SFunction<R, ?> column, SFunction<S, ?> val) {
public Children le(boolean condition, Column column, Column val) {
return addCondition(condition, column, LE, val);
}
/* ****************************************** **/
/* ******* lambda group by order by ********* */
@Override
public <X> Children groupByLambda(boolean condition, List<SFunction<X, ?>> columns) {
return groupBy(condition, columns.stream().map(LambdaUtils::getName).collect(joining(StringPool.COMMA)));
}
@Override
@SafeVarargs
public final <X> Children groupBy(SFunction<X, ?> column, SFunction<X, ?>... columns) {
return groupBy(true, column, columns);
}
@Override
@SafeVarargs
public final <X> Children groupBy(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns) {
return groupBy(condition, LambdaUtils.getName(column), Arrays.stream(columns).map(LambdaUtils::getName).toArray(String[]::new));
}
@Override
public <X> Children orderByAscLambda(boolean condition, List<SFunction<X, ?>> columns) {
return orderByAscStr(condition, columns.stream().map(LambdaUtils::getName).collect(Collectors.toList()));
}
@Override
@SafeVarargs
public final <X> Children orderByAsc(SFunction<X, ?> column, SFunction<X, ?>... columns) {
return orderByAsc(true, column, columns);
}
@Override
@SafeVarargs
public final <X> Children orderByAsc(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns) {
return orderByAsc(condition, LambdaUtils.getName(column), Arrays.stream(columns).map(LambdaUtils::getName).toArray(String[]::new));
}
@Override
public <X> Children orderByDescLambda(boolean condition, List<SFunction<X, ?>> columns) {
return orderByDescStr(condition, columns.stream().map(LambdaUtils::getName).collect(Collectors.toList()));
}
@Override
@SafeVarargs
public final <X> Children orderByDesc(SFunction<X, ?> column, SFunction<X, ?>... columns) {
return orderByDesc(true, column, columns);
}
@Override
@SafeVarargs
public final <X> Children orderByDesc(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns) {
return orderByDesc(condition, LambdaUtils.getName(column), Arrays.stream(columns).map(LambdaUtils::getName).toArray(String[]::new));
}
@Override
@SafeVarargs
public final <X> Children orderBy(boolean condition, boolean isAsc, SFunction<X, ?> column, SFunction<X, ?>... columns) {
return orderBy(condition, isAsc, LambdaUtils.getName(column), Arrays.stream(columns).map(LambdaUtils::getName).toArray(String[]::new));
}
/* ******************************************** */
@Override
public <V> Children allEqStr(boolean condition, Map<String, V> params, boolean null2IsNull) {
if (condition && CollectionUtils.isNotEmpty(params)) {
params.forEach((k, v) -> {
if (StringUtils.checkValNotNull(v)) {
if (StrUtils.checkValNotNull(v)) {
eq(k, v);
} else {
if (null2IsNull) {
@ -783,7 +889,7 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
if (condition && CollectionUtils.isNotEmpty(params)) {
params.forEach((k, v) -> {
if (filter.test(k, v)) {
if (StringUtils.checkValNotNull(v)) {
if (StrUtils.checkValNotNull(v)) {
eq(k, v);
} else {
if (null2IsNull) {
@ -841,11 +947,21 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
return likeValue(condition, LIKE, column, val, SqlLike.LEFT);
}
@Override
public Children notLikeLeft(boolean condition, String column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.LEFT);
}
@Override
public Children likeRight(boolean condition, String column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.RIGHT);
}
@Override
public Children notLikeRight(boolean condition, String column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.RIGHT);
}
@Override
public Children between(boolean condition, String column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
@ -922,6 +1038,12 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
() -> String.format("(%s)", inValue)));
}
@Override
public Children eqSql(boolean condition, String column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), EQ,
() -> String.format("(%s)", inValue)));
}
@Override
public Children notInSql(boolean condition, String column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN,
@ -944,18 +1066,14 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
public final Children orderBy(boolean condition, boolean isAsc, String column, String... columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = isAsc ? ASC : DESC;
appendSqlSegments(ORDER_BY, columnToSqlSegment(columnSqlInjectFilter(column)), mode);
appendSqlSegments(ORDER_BY, columnToSqlSegment(column), mode);
if (ArrayUtils.isNotEmpty(columns)) {
Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(columnSqlInjectFilter(c)), mode));
columnToSqlSegment(c), mode));
}
});
}
protected String columnSqlInjectFilter(String column) {
return StringUtils.sqlInjectionReplaceBlank(column);
}
@Override
public Children groupBy(boolean condition, String column) {
return maybeDo(condition, () -> appendSqlSegments(GROUP_BY, () -> columnToString(column)));
@ -968,15 +1086,13 @@ public abstract class MPJAbstractWrapper<T, Children extends MPJAbstractWrapper<
@Override
public Children orderBy(boolean condition, boolean isAsc, String column) {
return maybeDo(condition, () -> appendSqlSegments(ORDER_BY, columnToSqlSegment(columnSqlInjectFilter(column)),
return maybeDo(condition, () -> appendSqlSegments(ORDER_BY, columnToSqlSegment(column),
isAsc ? ASC : DESC));
}
@Override
public Children orderByStr(boolean condition, boolean isAsc, List<String> columns) {
return maybeDo(condition, () -> columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(columnSqlInjectFilter(c)), isAsc ? ASC : DESC)));
columnToSqlSegment(c), isAsc ? ASC : DESC)));
}
}

View File

@ -0,0 +1,98 @@
package com.github.yulichang.extension.apt.interfaces;
import com.github.yulichang.extension.apt.matedata.Column;
import java.io.Serializable;
/**
* 将原来的泛型R改成Column
* <p>
* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare}
*/
@SuppressWarnings("unused")
public interface Compare<Children> extends Serializable {
default Children eq(Column column, Object val) {
return eq(true, column, val);
}
Children eq(boolean condition, Column column, Object val);
default Children ne(Column column, Object val) {
return ne(true, column, val);
}
Children ne(boolean condition, Column column, Object val);
default Children gt(Column column, Object val) {
return gt(true, column, val);
}
Children gt(boolean condition, Column column, Object val);
default Children ge(Column column, Object val) {
return ge(true, column, val);
}
Children ge(boolean condition, Column column, Object val);
default Children lt(Column column, Object val) {
return lt(true, column, val);
}
Children lt(boolean condition, Column column, Object val);
default Children le(Column column, Object val) {
return le(true, column, val);
}
Children le(boolean condition, Column column, Object val);
default Children between(Column column, Object val1, Object val2) {
return between(true, column, val1, val2);
}
Children between(boolean condition, Column column, Object val1, Object val2);
default Children notBetween(Column column, Object val1, Object val2) {
return notBetween(true, column, val1, val2);
}
Children notBetween(boolean condition, Column column, Object val1, Object val2);
default Children like(Column column, Object val) {
return like(true, column, val);
}
Children like(boolean condition, Column column, Object val);
default Children notLike(Column column, Object val) {
return notLike(true, column, val);
}
Children notLike(boolean condition, Column column, Object val);
default Children likeLeft(Column column, Object val) {
return likeLeft(true, column, val);
}
Children likeLeft(boolean condition, Column column, Object val);
default Children notLikeLeft(Column column, Object val) {
return notLikeLeft(true, column, val);
}
Children notLikeLeft(boolean condition, Column column, Object val);
default Children likeRight(Column column, Object val) {
return likeRight(true, column, val);
}
Children likeRight(boolean condition, Column column, Object val);
default Children notLikeRight(Column column, Object val) {
return notLikeRight(true, column, val);
}
Children notLikeRight(boolean condition, Column column, Object val);
}

View File

@ -0,0 +1,66 @@
package com.github.yulichang.extension.apt.interfaces;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import java.util.function.BiPredicate;
/**
* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare}
*
* @author yulichang
* @since 1.4.9
*/
@SuppressWarnings("unused")
public interface CompareIfExists<Children> extends Compare<Children> {
BiPredicate<Object, IfExistsSqlKeyWordEnum> getIfExists();
default Children eqIfExists(Column column, Object val) {
return eq(getIfExists().test(val, IfExistsSqlKeyWordEnum.EQ), column, val);
}
default Children neIfExists(Column column, Object val) {
return ne(getIfExists().test(val, IfExistsSqlKeyWordEnum.NE), column, val);
}
default Children gtIfExists(Column column, Object val) {
return gt(getIfExists().test(val, IfExistsSqlKeyWordEnum.GT), column, val);
}
default Children geIfExists(Column column, Object val) {
return ge(getIfExists().test(val, IfExistsSqlKeyWordEnum.GE), column, val);
}
default Children ltIfExists(Column column, Object val) {
return lt(getIfExists().test(val, IfExistsSqlKeyWordEnum.LT), column, val);
}
default Children leIfExists(Column column, Object val) {
return le(getIfExists().test(val, IfExistsSqlKeyWordEnum.LE), column, val);
}
default Children likeIfExists(Column column, Object val) {
return like(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE), column, val);
}
default Children notLikeIfExists(Column column, Object val) {
return notLike(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE), column, val);
}
default Children likeLeftIfExists(Column column, Object val) {
return likeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_LEFT), column, val);
}
default Children notLikeLeftIfExists(Column column, Object val) {
return notLikeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_LEFT), column, val);
}
default Children likeRightIfExists(Column column, Object val) {
return likeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_RIGHT), column, val);
}
default Children notLikeRightIfExists(Column column, Object val) {
return notLikeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_RIGHT), column, val);
}
}

View File

@ -0,0 +1,191 @@
package com.github.yulichang.extension.apt.interfaces;
import com.github.yulichang.extension.apt.matedata.Column;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
/**
* 将原来的泛型R改成Column
* <p>
* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Func}
*/
@SuppressWarnings("unused")
public interface Func<Children> extends FuncLambda<Children> {
default Children isNull(Column column) {
return isNull(true, column);
}
Children isNull(boolean condition, Column column);
default Children isNotNull(Column column) {
return isNotNull(true, column);
}
Children isNotNull(boolean condition, Column column);
default Children in(Column column, Collection<?> coll) {
return in(true, column, coll);
}
Children in(boolean condition, Column column, Collection<?> coll);
default Children in(Column column, Object... values) {
return in(true, column, values);
}
Children in(boolean condition, Column column, Object... values);
default Children notIn(Column column, Collection<?> coll) {
return notIn(true, column, coll);
}
Children notIn(boolean condition, Column column, Collection<?> coll);
default Children notIn(Column column, Object... values) {
return notIn(true, column, values);
}
Children notIn(boolean condition, Column column, Object... values);
default Children inSql(Column column, String inValue) {
return inSql(true, column, inValue);
}
Children inSql(boolean condition, Column column, String inValue);
default Children notInSql(Column column, String inValue) {
return notInSql(true, column, inValue);
}
Children notInSql(boolean condition, Column column, String inValue);
default Children gtSql(Column column, String inValue) {
return gtSql(true, column, inValue);
}
Children gtSql(boolean condition, Column column, String inValue);
default Children geSql(Column column, String inValue) {
return geSql(true, column, inValue);
}
Children geSql(boolean condition, Column column, String inValue);
default Children ltSql(Column column, String inValue) {
return ltSql(true, column, inValue);
}
Children ltSql(boolean condition, Column column, String inValue);
default Children leSql(Column column, String inValue) {
return leSql(true, column, inValue);
}
Children leSql(boolean condition, Column column, String inValue);
default Children eqSql(Column column, String inValue) {
return eqSql(true, column, inValue);
}
Children eqSql(boolean condition, Column column, String inValue);
default Children groupBy(Column column) {
return groupBy(true, column);
}
default Children groupBy(List<Column> column) {
return groupBy(true, column);
}
Children groupBy(boolean condition, List<Column> columns);
default Children groupBy(Column column, Column... columns) {
return groupBy(true, column, columns);
}
Children groupBy(boolean condition, Column column, Column... columns);
default Children orderByAsc(Column column) {
return orderByAsc(true, column);
}
default Children orderByAsc(List<Column> columns) {
return orderByAsc(true, columns);
}
Children orderByAsc(boolean condition, List<Column> columns);
default Children orderByAsc(Column column, Column... columns) {
return orderByAsc(true, column, columns);
}
default Children orderByAsc(boolean condition, Column column, Column... columns) {
return orderBy(condition, true, column, columns);
}
default Children orderByDesc(Column column) {
return orderByDesc(true, column);
}
default Children orderByDesc(List<Column> columns) {
return orderByDesc(true, columns);
}
Children orderByDesc(boolean condition, List<Column> columns);
default Children orderByDesc(Column column, Column... columns) {
return orderByDesc(true, column, columns);
}
default Children orderByDesc(boolean condition, Column column, Column... columns) {
return orderBy(condition, false, column, columns);
}
Children orderBy(boolean condition, boolean isAsc, Column column, Column... columns);
default Children having(String sqlHaving, Object... params) {
return having(true, sqlHaving, params);
}
/**
* HAVING ( sql语句 )
* <p>例1: having("sum(age) &gt; 10")</p>
* <p>例2: having("sum(age) &gt; {0}", 10)</p>
*
* @param condition 执行条件
* @param sqlHaving sql 语句
* @param params 参数数组
* @return children
*/
Children having(boolean condition, String sqlHaving, Object... params);
default Children func(Consumer<Children> consumer) {
return func(true, consumer);
}
/**
* 消费函数
*
* @param consumer 消费函数
* @return children
* @since 3.3.1
*/
default Children func(boolean condition, Consumer<Children> consumer) {
return func(condition, consumer, null);
}
Children func(boolean condition, Consumer<Children> consumer, Consumer<Children> consumerElse);
}

View File

@ -0,0 +1,61 @@
package com.github.yulichang.extension.apt.interfaces;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import java.io.Serializable;
import java.util.List;
/**
* 将原来的泛型R改成SFunction<X,?>
* <p>
* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Func}
*/
@SuppressWarnings({"unused", "unchecked"})
public interface FuncLambda<Children> extends Serializable {
default <X> Children groupBy(SFunction<X, ?> column) {
return groupBy(true, column);
}
default <X> Children groupByLambda(List<SFunction<X, ?>> column) {
return groupByLambda(true, column);
}
<X> Children groupByLambda(boolean condition, List<SFunction<X, ?>> columns);
<X> Children groupBy(SFunction<X, ?> column, SFunction<X, ?>... columns);
<X> Children groupBy(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns);
default <X> Children orderByAsc(SFunction<X, ?> column) {
return orderByAsc(true, column);
}
default <X> Children orderByAscLambda(List<SFunction<X, ?>> columns) {
return orderByAscLambda(true, columns);
}
<X> Children orderByAscLambda(boolean condition, List<SFunction<X, ?>> columns);
<X> Children orderByAsc(SFunction<X, ?> column, SFunction<X, ?>... columns);
<X> Children orderByAsc(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns);
default <X> Children orderByDesc(SFunction<X, ?> column) {
return orderByDesc(true, column);
}
default <X> Children orderByDescLambda(List<SFunction<X, ?>> columns) {
return orderByDescLambda(true, columns);
}
<X> Children orderByDescLambda(boolean condition, List<SFunction<X, ?>> columns);
<X> Children orderByDesc(SFunction<X, ?> column, SFunction<X, ?>... columns);
<X> Children orderByDesc(boolean condition, SFunction<X, ?> column, SFunction<X, ?>... columns);
<X> Children orderBy(boolean condition, boolean isAsc, SFunction<X, ?> column, SFunction<X, ?>... columns);
}

View File

@ -0,0 +1,101 @@
package com.github.yulichang.extension.apt.interfaces;
import com.github.yulichang.extension.apt.matedata.Column;
import java.io.Serializable;
/**
* 将原来的泛型R改成Column, Object改为Column
* 以及移除不会在ON语句中出现的条件 比如like相关 保留原来的like 只是不太可能会出现 on a.id like b.id 所以不会支持这种写法
* <p>
* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare}
*
* @since 1.1.8
*/
@SuppressWarnings("unused")
public interface OnCompare<Children> extends Serializable {
default Children eq(Column column, Column val) {
return eq(true, column, val);
}
/**
* 等于 =
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children eq(boolean condition, Column column, Column val);
default Children ne(Column column, Column val) {
return ne(true, column, val);
}
/**
* 不等于 &lt;&gt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children ne(boolean condition, Column column, Column val);
default Children gt(Column column, Column val) {
return gt(true, column, val);
}
/**
* 大于 &gt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children gt(boolean condition, Column column, Column val);
default Children ge(Column column, Column val) {
return ge(true, column, val);
}
/**
* 大于等于 &gt;=
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children ge(boolean condition, Column column, Column val);
default Children lt(Column column, Column val) {
return lt(true, column, val);
}
/**
* 小于 &lt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children lt(boolean condition, Column column, Column val);
default Children le(Column column, Column val) {
return le(true, column, val);
}
/**
* 小于等于 &lt;=
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children le(boolean condition, Column column, Column val);
}

View File

@ -0,0 +1,280 @@
package com.github.yulichang.extension.apt.interfaces;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import com.github.yulichang.wrapper.enums.DefaultFuncEnum;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.segments.*;
import java.io.Serializable;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* 参考 {@link com.baomidou.mybatisplus.core.conditions.query.Query}
*
* @author yulichang
*/
@SuppressWarnings({"unused"})
public interface Query<Children> extends Serializable {
List<Select> getSelectColum();
Children getChildren();
/**
* 过滤查询的字段信息
* <p>例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))</p>
* <p>例2: 只要 java 字段属性是 CharSequence 类型的 -> select(TableFieldInfo::isCharSequence)</p>
* <p>例3: 只要 java 字段没有填充策略的 -> select(i -> i.getFieldFill() == FieldFill.DEFAULT)</p>
* <p>例4: 要全部字段 -> select(i -> true)</p>
* <p>例5: 只要主键字段 -> select(i -> false)</p>
*
* @param predicate 过滤方式
* @return children
*/
default <E> Children selectFilter(BaseColumn<E> baseColumn, Predicate<SelectCache> predicate) {
TableInfo info = TableHelper.getAssert(baseColumn.getColumnClass());
List<SelectCache> cacheList = ColumnCache.getListField(baseColumn.getColumnClass());
cacheList.stream().filter(SelectCache::isSelect).filter(predicate).collect(Collectors.toList()).forEach(
i -> getSelectColum().add(new SelectApt(i, baseColumn)));
return getChildren();
}
<E> Children select(Column... columns);
/**
* String 查询
*
* @param columns
*/
default Children select(String... columns) {
getSelectColum().add(new SelectString(String.join(StringPool.COMMA, columns), null));
return getChildren();
}
/**
* String 查询
*
* @param column
*/
default <E> Children selectAs(String column, SFunction<E, ?> alias) {
String name = LambdaUtils.getName(alias);
getSelectColum().add(new SelectString(column + Constant.AS + name, name));
return getChildren();
}
/**
* String 查询
*
* @param column
*/
default <X> Children selectAs(String index, Column column, SFunction<X, ?> alias) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(column.getClazz());
SelectCache cache = cacheMap.get(column.getProperty());
String name = LambdaUtils.getName(alias);
getSelectColum().add(new SelectApt(cache, column, name));
return getChildren();
}
default <E> Children selectAsClass(BaseColumn<E> baseColumn, Class<?> tag) {
Map<String, SelectCache> normalMap = ColumnCache.getMapField(baseColumn.getColumnClass());
List<FieldCache> fieldList = MPJReflectionKit.getFieldList(tag);
for (FieldCache cache : fieldList) {
if (normalMap.containsKey(cache.getField().getName())) {
SelectCache selectCache = normalMap.get(cache.getField().getName());
if (selectCache.isSelect()) {
getSelectColum().add(new SelectApt(selectCache, baseColumn));
}
}
}
return getChildren();
}
/**
* ignore
*/
default <X> Children selectAs(Column column, SFunction<X, ?> alias) {
return selectAs(column, LambdaUtils.getName(alias));
}
/**
* 别名查询
*/
default Children selectAs(Column column, String alias) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(column.getClazz());
SelectCache cache = cacheMap.get(column.getProperty());
getSelectColum().add(new SelectApt(cache, column, alias));
return getChildren();
}
/**
* 查询实体类全部字段
*/
default <E> Children selectAll(BaseColumn<E> baseColumn) {
getSelectColum().addAll(ColumnCache.getListField(baseColumn.getColumnClass()).stream().filter(SelectCache::isSelect).map(i ->
new SelectApt(i, baseColumn)).collect(Collectors.toList()));
return getChildren();
}
/**
* 查询实体类全部字段
*
* @param baseColumn 查询的实体类
* @param exclude 排除字段
*/
default <E> Children selectAll(BaseColumn<E> baseColumn, Column... exclude) {
Set<String> excludeSet = Arrays.stream(exclude).map(i ->
i.getProperty().toUpperCase(Locale.ENGLISH)).collect(Collectors.toSet());
getSelectColum().addAll(ColumnCache.getListField(baseColumn.getColumnClass()).stream().filter(e -> e.isSelect() &&
!excludeSet.contains(e.getColumProperty().toUpperCase(Locale.ENGLISH))).map(i ->
new SelectApt(i, baseColumn)).collect(Collectors.toList()));
return getChildren();
}
/**
* select sql 片段
*/
String getSqlSelect();
/**
* 聚合函数查询
* <p>
* wrapper.selectFunc(() -> "COUNT(%s)", "t.id", "total");
* <p>
* lambda
* wrapper.selectFunc(() -> "COUNT(%s)", UserDO::getId, UserDTO::getTotal);
*
* @param funcEnum 函数枚举 {@link DefaultFuncEnum}
* @param column 函数作用的字段
* @param alias 别名
*/
default Children selectFunc(BaseFuncEnum funcEnum, Column column, String alias) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(column.getClazz());
getSelectColum().add(new SelectApt(cacheMap.get(column.getProperty()), column, funcEnum, alias));
return getChildren();
}
default <X> Children selectFunc(BaseFuncEnum funcEnum, Column column, SFunction<X, ?> alias) {
return selectFunc(funcEnum, column, LambdaUtils.getName(alias));
}
default Children selectFunc(BaseFuncEnum funcEnum, Column column) {
return selectFunc(funcEnum, column, column.getProperty());
}
Children selectFunc(String sql, MFunction<AptConsumer> column, String alias);
default <S> Children selectFunc(String sql, MFunction<AptConsumer> column, SFunction<S, ?> alias) {
return selectFunc(sql, column, LambdaUtils.getName(alias));
}
/* 默认聚合函数扩展 */
/**
* SUM()
*/
default Children selectSum(Column column) {
return selectFunc(DefaultFuncEnum.SUM, column);
}
default <X> Children selectSum(Column column, SFunction<X, ?> alias) {
return selectFunc(DefaultFuncEnum.SUM, column, alias);
}
default Children selectSum(Column column, String alias) {
return selectFunc(DefaultFuncEnum.SUM, column, alias);
}
/**
* COUNT()
*/
default Children selectCount(Column column) {
return selectFunc(DefaultFuncEnum.COUNT, column);
}
default <X> Children selectCount(Column column, SFunction<X, ?> alias) {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
default Children selectCount(Column column, String alias) {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
/**
* MAX()
*/
default Children selectMax(Column column) {
return selectFunc(DefaultFuncEnum.MAX, column);
}
default <X> Children selectMax(Column column, SFunction<X, ?> alias) {
return selectFunc(DefaultFuncEnum.MAX, column, alias);
}
default Children selectMax(Column column, String alias) {
return selectFunc(DefaultFuncEnum.MAX, column, alias);
}
/**
* MIN()
*/
default Children selectMin(Column column) {
return selectFunc(DefaultFuncEnum.MIN, column);
}
default <X> Children selectMin(Column column, SFunction<X, ?> alias) {
return selectFunc(DefaultFuncEnum.MIN, column, alias);
}
default Children selectMin(Column column, String alias) {
return selectFunc(DefaultFuncEnum.MIN, column, alias);
}
/**
* MIN()
*/
default Children selectAvg(Column column) {
return selectFunc(DefaultFuncEnum.AVG, column);
}
default <X> Children selectAvg(Column column, SFunction<X, ?> alias) {
return selectFunc(DefaultFuncEnum.AVG, column, alias);
}
default Children selectAvg(Column column, String alias) {
return selectFunc(DefaultFuncEnum.AVG, column, alias);
}
/**
* LEN()
*/
default Children selectLen(Column column) {
return selectFunc(DefaultFuncEnum.LEN, column);
}
default <X> Children selectLen(Column column, SFunction<X, ?> alias) {
return selectFunc(DefaultFuncEnum.LEN, column, alias);
}
default Children selectLen(Column column, String alias) {
return selectFunc(DefaultFuncEnum.LEN, column, alias);
}
}

View File

@ -0,0 +1,91 @@
package com.github.yulichang.extension.apt.interfaces;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.query.interfaces.StringJoin;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.extension.apt.AptAbstractWrapper;
import com.github.yulichang.wrapper.interfaces.MFunction;
/**
* @author yulichang
*/
@SuppressWarnings("unused")
public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, StringJoin<Children, Entity> {
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default <T> Children leftJoin(BaseColumn<T> clazz, Column left, Column right) {
return join(Constant.LEFT_JOIN, clazz, left, right);
}
/**
* left join 多条件
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param function 条件`
*/
default <T> Children leftJoin(BaseColumn<T> clazz, MFunction<AptAbstractWrapper<Entity, ?>> function) {
return join(Constant.LEFT_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(BaseColumn<T> clazz, Column left, Column right) {
return join(Constant.RIGHT_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default <T> Children rightJoin(BaseColumn<T> clazz, MFunction<AptAbstractWrapper<Entity, ?>> function) {
return join(Constant.RIGHT_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(BaseColumn<T> clazz, Column left, Column right) {
return join(Constant.INNER_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default <T> Children innerJoin(BaseColumn<T> clazz, MFunction<AptAbstractWrapper<Entity, ?>> function) {
return join(Constant.INNER_JOIN, clazz, function);
}
/**
* 自定义连表关键词
* 调用此方法 keyword 前后需要带空格 比如 " LEFT JOIN " " RIGHT JOIN "
* <p>
* 查询基类 可以直接调用此方法实现以上所有功能
*
* @param keyWord 连表关键字
* @param clazz 连表实体类
* @param left 关联条件
* @param right 扩展 用于关联表的 select where
*/
default <T> Children join(String keyWord, BaseColumn<T> clazz, Column left, Column right) {
return join(keyWord, clazz, on -> on.eq(left, right));
}
/**
* 内部使用, 不建议直接调用
*/
<T> Children join(String keyWord, BaseColumn<T> clazz, MFunction<AptAbstractWrapper<Entity, ?>> function);
}

View File

@ -0,0 +1,172 @@
package com.github.yulichang.extension.apt.interfaces;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.extension.apt.resultmap.MybatisLabel;
import com.github.yulichang.extension.apt.resultmap.MybatisLabelFree;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.resultmap.Label;
import java.util.Collection;
import java.util.Map;
/**
* 对一或对多查询
*
* @author yulichang
* @since 1.3.0
*/
@SuppressWarnings({"unchecked", "unused", "DuplicatedCode"})
public interface QueryLabel<Children> {
void addLabel(Label<?> label, boolean isCollection);
Children getChildren();
/**
* 一对多查询 调用此方法必需要调用对应的 left join / right join ... 连表方法否则会报错
* <p>
* 举例 UserDO AddressDO 为一对多关系 UserDTO 为结果类
* <pre>
* MPJLambdaWrapper&lt;UserDO&gt; wrapper = new MPJLambdaWrapper&lt;UserDO&gt;();
* wrapper.selectAll(UserDO.class)
* .selectCollection(AddressDO.class, UserDTO::getAddressListDTO)
* .leftJoin(AddressDO.class, ...... )
* .eq(...)
* ...
* <pre/>
* 会自动将 AddressDO类中相同属性的字段 以mybatis&lt;collection&gt;的方式映射到UserDTO.addressListDTO属性中
*
* @since 1.3.0
*
* @param child 连表数据库实体类
* @param dtoField 包装类对应的属性
* @param <S> 包装类
* @param <C> 对多数据库实体类
* @param <Z> 包装类集合泛型
* @param <F> 包装类集合字段泛型
*/
default <S, C, Z, F extends Collection<?>> Children selectCollection(BaseColumn<C> child, SFunction<S, F> dtoField) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
FieldCache field = fieldMap.get(dtoFieldName);
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabel.Builder<C, Z> builder;
if (genericType == null || genericType.isAssignableFrom(child.getColumnClass())) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType());
} else {
Class<Z> ofType = (Class<Z>) genericType;
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), ofType, true);
}
addLabel(builder.build(), true);
return getChildren();
}
/**
* 一对多查询 调用此方法必需要调用对应的 left join / right join ... 连表方法否则会报错
* <p>
* 举例 UserDO AddressDO 为一对多关系 UserDTO 为结果类
* <pre>
* MPJLambdaWrapper&lt;UserDO&gt; wrapper = new MPJLambdaWrapper&lt;UserDO&gt;()
* .selectAll(UserDO.class)
* .selectCollection(AddressDO.class, UserDTO::getAddressListDTO, map -> map
* .id(AddressDO::getId, AddressDTO::getId) //如果属性名一致 可以传一个
* .result(AddressDO::getUserId) //如果属性名一致 可以传一个
* .result(AddressDO::getAddress, AddressDTO::getAddress)) //如果属性名一致 可以传一个
* .leftJoin(AddressDO.class, ...... )
* .eq(...)
* ...
* <pre/>
*
* 会自动将 AddressDO类中指定的字段 以mybatis&lt;collection&gt;的方式映射到UserDTO.addressListDTO属性中
*
* @since 1.3.0
*
* @param child 连表数据库实体类
* @param dtoField 包装类对应的属性
* @param collection collection标签内容
* @param <S> 包装类
* @param <C> 对多数据库实体类
* @param <Z> 包装类集合泛型
* @param <F> 包装类集合字段泛型
*/
default <S, C, Z, F extends Collection<Z>> Children selectCollection(BaseColumn<C> child,
SFunction<S, F> dtoField,
MFunction<MybatisLabel.Builder<C, Z>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<Z> ofType = (Class<Z>) genericType;
MybatisLabel.Builder<C, Z> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), ofType, false);
MybatisLabel.Builder<C, Z> czBuilder = collection.apply(builder);
addLabel(czBuilder.build(), true);
return getChildren();
}
default <S, Z, F extends Collection<Z>> Children selectCollection(SFunction<S, F> dtoField,
MFunction<MybatisLabelFree.Builder<Z>> collection) {
//自由映射必须存在泛型Z
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<Z> ofType = (Class<Z>) genericType;
MybatisLabelFree.Builder<Z> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), ofType);
MybatisLabelFree.Builder<Z> czBuilder = collection.apply(builder);
addLabel(czBuilder.build(), true);
return getChildren();
}
/**
* 对一查询 用法参考 selectCollection
*
* @since 1.3.0
*/
default <S, C, F> Children selectAssociation(BaseColumn<C> child, SFunction<S, F> dtoField) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
FieldCache field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<C, F> builder;
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<F>) field.getType(), true);
addLabel(builder.build(), false);
return getChildren();
}
default <S, C, F> Children selectAssociation(SFunction<S, F> dtoField,
MFunction<MybatisLabelFree.Builder<F>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabelFree.Builder<F> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), (Class<F>) field.getType());
MybatisLabelFree.Builder<F> cfBuilder = collection.apply(builder);
addLabel(cfBuilder.build(), false);
return getChildren();
}
default <S, C, F> Children selectAssociation(BaseColumn<C> child, SFunction<S, F> dtoField,
MFunction<MybatisLabel.Builder<C, F>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<C, F> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<F>) field.getType(), false);
MybatisLabel.Builder<C, F> cfBuilder = collection.apply(builder);
addLabel(cfBuilder.build(), false);
return getChildren();
}
}

View File

@ -0,0 +1,20 @@
package com.github.yulichang.extension.apt.matedata;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author yulichang
* @since 1.5.0
*/
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class BaseColumn<T> implements Serializable {
protected String alias;
abstract public Class<T> getColumnClass();
}

View File

@ -0,0 +1,31 @@
package com.github.yulichang.extension.apt.matedata;
import lombok.Getter;
import java.io.Serializable;
import java.util.function.Supplier;
/**
* @author yulichang
* @since 1.5.0
*/
@Getter
public class Column implements Serializable {
private final BaseColumn<?> root;
private final String property;
public Column(BaseColumn<?> root, String property) {
this.root = root;
this.property = property;
}
public Class<?> getClazz() {
return root.getColumnClass();
}
public Supplier<String> getAlias() {
return root::getAlias;
}
}

View File

@ -0,0 +1,275 @@
package com.github.yulichang.extension.apt.resultmap;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.segments.SelectCache;
import lombok.Getter;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* collection 标签 目前先支持这几个属性 后续在扩展
*
* @author yulichang
* @since 1.3.0
*/
@Getter
public class MybatisLabel<E, T> implements Label<T> {
private String property;
private BaseColumn<E> baseColumn;
private Class<?> javaType;
private Class<T> ofType;
private List<IResult> resultList;
/**
* wrapper里面的引用
*/
private List<Label<?>> mybatisLabels;
private MybatisLabel() {
}
@SuppressWarnings({"unused", "unchecked", "DuplicatedCode"})
public static class Builder<E, T> {
private final MybatisLabel<E, T> mybatisLabel;
/**
* 自动构建
*/
public Builder(String property, BaseColumn<E> baseColumn, Class<?> javaType) {
this.mybatisLabel = new MybatisLabel<>();
mybatisLabel.property = property;
mybatisLabel.baseColumn = baseColumn;
mybatisLabel.javaType = javaType;
mybatisLabel.ofType = (Class<T>) baseColumn.getColumnClass();
mybatisLabel.resultList = new ArrayList<>();
mybatisLabel.mybatisLabels = new ArrayList<>();
autoBuild(true, baseColumn.getColumnClass(), (Class<T>) baseColumn.getColumnClass());
}
/**
* 手动构建
*
* @param property property
* @param baseColumn 数据库实体类
* @param javaType javaType
* @param ofType 映射类
* @param auto 自动映射数据库实体对应的字段
*/
public Builder(String property, BaseColumn<E> baseColumn, Class<?> javaType, Class<T> ofType, boolean auto) {
this.mybatisLabel = new MybatisLabel<>();
mybatisLabel.property = property;
mybatisLabel.baseColumn = baseColumn;
mybatisLabel.javaType = javaType;
mybatisLabel.ofType = ofType;
mybatisLabel.resultList = new ArrayList<>();
mybatisLabel.mybatisLabels = new ArrayList<>();
autoBuild(auto, baseColumn.getColumnClass(), ofType);
}
/**
* 映射实体全部字段
*/
public Builder<E, T> all() {
autoBuild(true, mybatisLabel.baseColumn.getColumnClass(), mybatisLabel.ofType);
return this;
}
/**
* 映射实体字段过滤(含主键)
*/
public Builder<E, T> filter(Predicate<SelectCache> predicate) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
ColumnCache.getListField(mybatisLabel.baseColumn.getColumnClass()).stream().filter(predicate)
.filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
mybatisLabel.resultList.add(new Result.Builder<T>(c.isPk(), mybatisLabel.baseColumn, c).build()));
return this;
}
public Builder<E, T> id(Column column, SFunction<T, ?> tag) {
Result.Builder<T> builder = new Result.Builder<>(true, column);
builder.column(column).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<E, T> id(Column column) {
Result.Builder<T> builder = new Result.Builder<>(true, column);
builder.column(column);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<E, T> result(Column column, SFunction<T, ?> tag) {
Result.Builder<T> builder = new Result.Builder<>(false, column);
builder.column(column).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<E, T> result(Column column) {
Result.Builder<T> builder = new Result.Builder<>(false, column);
builder.column(column);
mybatisLabel.resultList.add(builder.build());
return this;
}
/**
* 嵌套
*/
public <A, R, B extends Collection<R>> Builder<E, T> collection(BaseColumn<A> entityClass, SFunction<T, B> func) {
String dtoFieldName = LambdaUtils.getName(func);
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
FieldCache field = fieldMap.get(dtoFieldName);
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Builder<A, R> builder;
if (genericType == null || genericType.isAssignableFrom(entityClass.getColumnClass())) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new Builder<>(dtoFieldName, entityClass, field.getType());
} else {
Class<R> ofType = (Class<R>) genericType;
builder = new Builder<>(dtoFieldName, entityClass, field.getType(), ofType, true);
}
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
/**
* 嵌套
*/
public <A, R, B extends Collection<R>> Builder<E, T> collection(SFunction<T, B> func,
MFunction<MybatisLabelFree.Builder<R>> mFunc) {
String dtoFieldName = LambdaUtils.getName(func);
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<R> ofType = (Class<R>) genericType;
MybatisLabelFree.Builder<R> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), ofType);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, R, B extends Collection<R>> Builder<E, T> collection(BaseColumn<A> entityClass,
SFunction<T, B> func,
MFunction<Builder<A, R>> mFunc) {
String dtoFieldName = LambdaUtils.getName(func);
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<R> ofType = (Class<R>) genericType;
Builder<A, R> builder = new Builder<>(dtoFieldName, entityClass, field.getType(), ofType, false);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, B> Builder<E, T> association(BaseColumn<A> child, SFunction<T, B> dtoField) {
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
String dtoFieldName = LambdaUtils.getName(dtoField);
FieldCache field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
Builder<A, B> builder;
builder = new Builder<>(dtoFieldName, child, field.getType(), (Class<B>) field.getType(), true);
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
/**
* 嵌套
*/
public <A, B> Builder<E, T> association(SFunction<T, B> dtoField,
MFunction<MybatisLabelFree.Builder<B>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabelFree.Builder<B> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), (Class<B>) field.getType());
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, B> Builder<E, T> association(BaseColumn<A> child, SFunction<T, B> dtoField,
MFunction<Builder<A, B>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
Builder<A, B> builder = new Builder<>(dtoFieldName, child, field.getType(), (Class<B>) field.getType(), false);
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
return this;
}
public MybatisLabel<E, T> build() {
if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {
autoBuild(true, mybatisLabel.baseColumn.getColumnClass(), mybatisLabel.ofType);
}
return mybatisLabel;
}
private void autoBuild(boolean auto, Class<E> entityClass, Class<T> tagClass) {
TableInfo tableInfo = TableHelper.getAssert(entityClass);
Map<String, FieldCache> tagMap = MPJReflectionKit.getFieldMap(tagClass);
if (auto && !tagMap.isEmpty()) {
List<SelectCache> listField = ColumnCache.getListField(entityClass);
if (entityClass.isAssignableFrom(tagClass)) {
mybatisLabel.resultList.addAll(listField.stream().map(i -> {
Result result = new Result();
result.setId(i.isPk());
result.setBaseColumn(mybatisLabel.baseColumn);
result.setProperty(i.getColumProperty());
result.setJavaType(i.getColumnType());
result.setJdbcType(i.getJdbcType());
result.setSelectNormal(i);
return result;
}).collect(Collectors.toList()));
} else {
for (SelectCache s : listField) {
FieldCache field = tagMap.get(s.getColumProperty());
if (Objects.nonNull(field)) {
Result result = new Result();
result.setId(s.isPk());
result.setBaseColumn(mybatisLabel.baseColumn);
result.setProperty(s.getColumProperty());
result.setJavaType(field.getType());
result.setSelectNormal(s);
mybatisLabel.resultList.add(result);
}
}
}
}
}
}
}

View File

@ -0,0 +1,220 @@
package com.github.yulichang.extension.apt.resultmap;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.resultmap.ResultList;
import com.github.yulichang.wrapper.segments.SelectCache;
import lombok.Getter;
import java.util.*;
import java.util.function.Predicate;
/**
* 无泛型约束 实现自由映射
*
* @author yulichang
* @since 1.4.4
*/
@Getter
public class MybatisLabelFree<T> implements Label<T> {
private String property;
private Class<?> javaType;
private Class<T> ofType;
private List<IResult> resultList;
/**
* wrapper里面的引用
*/
private List<Label<?>> mybatisLabels;
private MybatisLabelFree() {
}
@SuppressWarnings({"unused", "unchecked", "DuplicatedCode"})
public static class Builder<T> {
private final MybatisLabelFree<T> mybatisLabel;
/**
* 手动构建
*
* @param property property
* @param javaType javaType
* @param ofType 映射类
*/
public Builder(String property, Class<?> javaType, Class<T> ofType) {
this.mybatisLabel = new MybatisLabelFree<>();
mybatisLabel.property = property;
mybatisLabel.javaType = javaType;
mybatisLabel.ofType = ofType;
mybatisLabel.resultList = new ResultList();
mybatisLabel.mybatisLabels = new ArrayList<>();
}
public <E> Builder<T> all(BaseColumn<E> entityClass) {
allBuild(entityClass);
return this;
}
/**
* 映射实体字段过滤(含主键)
*/
public <E> Builder<T> filter(BaseColumn<E> baseColumn, Predicate<SelectCache> predicate) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
ColumnCache.getListField(baseColumn.getColumnClass()).stream().filter(predicate)
.filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
mybatisLabel.resultList.add(new Result.Builder<T>(false, baseColumn, c).build()));
return this;
}
public Builder<T> id(Column column, SFunction<T, ?> tag) {
Result.Builder<T> builder = new Result.Builder<>(true, column);
builder.column(column).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> id(Column column) {
Result.Builder<T> builder = new Result.Builder<>(true, column);
builder.column(column);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> result(Column column, SFunction<T, ?> tag) {
Result.Builder<T> builder = new Result.Builder<>(false, column);
builder.column(column).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> result(Column column) {
Result.Builder<T> builder = new Result.Builder<>(false, column);
builder.column(column);
mybatisLabel.resultList.add(builder.build());
return this;
}
/**
* 嵌套
*/
public <A, R, B extends Collection<R>> Builder<T> collection(BaseColumn<A> baseColumn, SFunction<T, B> func) {
String dtoFieldName = LambdaUtils.getName(func);
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
FieldCache field = fieldMap.get(dtoFieldName);
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabel.Builder<A, R> builder;
if (genericType == null || genericType.isAssignableFrom(baseColumn.getColumnClass())) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new MybatisLabel.Builder<>(dtoFieldName, baseColumn, field.getType());
} else {
Class<R> ofType = (Class<R>) genericType;
builder = new MybatisLabel.Builder<>(dtoFieldName, baseColumn, field.getType(), ofType, true);
}
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
public <A, R, B extends Collection<R>> Builder<T> collection(SFunction<T, B> func,
MFunction<Builder<R>> mFunc) {
String dtoFieldName = LambdaUtils.getName(func);
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<R> ofType = (Class<R>) genericType;
Builder<R> builder = new Builder<>(dtoFieldName, field.getType(), ofType);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, R, B extends Collection<R>> Builder<T> collection(BaseColumn<A> entityClass,
SFunction<T, B> func,
MFunction<MybatisLabel.Builder<A, R>> mFunc) {
String dtoFieldName = LambdaUtils.getName(func);
Class<T> dtoClass = LambdaUtils.getEntityClass(func);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<R> ofType = (Class<R>) genericType;
MybatisLabel.Builder<A, R> builder = new MybatisLabel.Builder<>(dtoFieldName, entityClass, field.getType(), ofType, false);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, B> Builder<T> association(BaseColumn<A> child, SFunction<T, B> dtoField) {
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
String dtoFieldName = LambdaUtils.getName(dtoField);
FieldCache field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<A, B> builder;
builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<B>) field.getType(), true);
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
/**
* 嵌套
*/
public <A, B> Builder<T> association(BaseColumn<A> child, SFunction<T, B> dtoField,
MFunction<MybatisLabel.Builder<A, B>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<T> dtoClass = LambdaUtils.getEntityClass(dtoField);
FieldCache field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<A, B> builder = new MybatisLabel.Builder<>(dtoFieldName, child, field.getType(), (Class<B>) field.getType(), false);
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
return this;
}
public MybatisLabelFree<T> build() {
if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {
throw ExceptionUtils.mpe("无法自动映射, 找不到 <%s> 对应的表, 请使用 .all(xxx.class), id()或者result() 手动映射",
mybatisLabel.ofType.getSimpleName());
}
return mybatisLabel;
}
private void allBuild(BaseColumn<?> entityClass) {
Map<String, FieldCache> tagMap = MPJReflectionKit.getFieldMap(mybatisLabel.getOfType());
List<SelectCache> listField = ColumnCache.getListField(entityClass.getColumnClass());
for (SelectCache s : listField) {
FieldCache field = tagMap.get(s.getColumProperty());
if (Objects.nonNull(field)) {
Result result = new Result();
result.setBaseColumn(entityClass);
result.setId(s.isPk());
result.setJavaType(field.getType());
result.setProperty(s.getColumProperty());
result.setSelectNormal(s);
mybatisLabel.resultList.add(result);
}
}
}
}
}

View File

@ -0,0 +1,123 @@
package com.github.yulichang.extension.apt.resultmap;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.matedata.Column;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.segments.SelectCache;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.type.JdbcType;
import java.util.Map;
import java.util.Objects;
/**
* result 标签
*
* @author yulichang
* @since 1.3.0
*/
@Getter
@Setter(AccessLevel.PACKAGE)
public class Result implements IResult {
private boolean isId;
private BaseColumn<?> baseColumn;
private Column column;
private SelectCache selectNormal;
private String property;
private Class<?> javaType;
private JdbcType jdbcType;
public Result() {
}
@Override
public String getIndex() {
return null;
}
@SuppressWarnings({"UnusedReturnValue", "unused"})
public static class Builder<T> {
private final Result result;
public Builder(boolean isId, Column column) {
this.result = new Result();
result.isId = isId;
result.column = column;
result.baseColumn = column.getRoot();
}
public Builder(boolean isId, Column column, SelectCache selectCache) {
this.result = new Result();
result.isId = isId;
result.column = column;
result.baseColumn = column.getRoot();
result.selectNormal = selectCache;
result.property = selectCache.getColumProperty();
result.javaType = selectCache.getColumnType();
result.jdbcType = selectCache.getJdbcType();
}
public Builder(boolean isId, BaseColumn<?> baseColumn, SelectCache selectCache) {
this.result = new Result();
result.isId = isId;
result.column = null;
result.baseColumn = baseColumn;
result.selectNormal = selectCache;
result.property = selectCache.getColumProperty();
result.javaType = selectCache.getColumnType();
result.jdbcType = selectCache.getJdbcType();
}
public Builder<T> property(SFunction<T, ?> property) {
result.property = LambdaUtils.getName(property);
return this;
}
public Builder<T> column(Column column) {
Map<String, SelectCache> normalMap = ColumnCache.getMapField(column.getClazz());
SelectCache normal = normalMap.get(column.getProperty());
result.selectNormal = normal;
result.column = column;
if (StrUtils.isBlank(result.property)) {
result.property = normal.getColumProperty();
}
if (Objects.isNull(result.javaType)) {
result.javaType = normal.getColumnType();
}
if (Objects.isNull(result.jdbcType)) {
result.jdbcType = normal.getJdbcType();
}
return this;
}
public Builder<T> javaType(Class<?> javaType) {
result.javaType = javaType;
return this;
}
public Builder<T> jdbcType(JdbcType jdbcType) {
result.jdbcType = jdbcType;
return this;
}
public Result build() {
return result;
}
}
}

View File

@ -0,0 +1,151 @@
package com.github.yulichang.extension.apt.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.extension.apt.AptQueryWrapper;
import com.github.yulichang.toolkit.LogicInfoUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.sql.SqlScriptUtils;
import java.util.Objects;
import java.util.Optional;
/**
* @author yulichang
* @since 1.4.5
*/
@SuppressWarnings("DuplicatedCode")
public class AptWrapperUtils {
public static <T> String buildSubSqlByWrapper(Class<T> clazz, AptQueryWrapper<T> wrapper, String alias) {
TableInfo tableInfo = TableHelper.getAssert(clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
if (StrUtils.isNotBlank(entityWhere)) {
hasWhere = true;
}
String mainLogic = mainLogic(hasWhere, clazz, wrapper);
if (StrUtils.isNotBlank(mainLogic)) {
hasWhere = true;
}
String subLogic = subLogic(hasWhere, wrapper);
if (StrUtils.isNotBlank(subLogic)) {
hasWhere = true;
}
String sqlSegment = (wrapper.getSqlSegment() != null && StrUtils.isNotBlank(wrapper.getSqlSegment())) ?
((wrapper.isEmptyOfNormal() ? StringPool.EMPTY : (hasWhere ? " AND " : " WHERE ")) + wrapper.getSqlSegment()) : StringPool.EMPTY;
String sqlComment = Optional.ofNullable(wrapper.getSqlComment()).orElse(StringPool.EMPTY);
return String.format(" (%s SELECT %s FROM %s %s %s %s %s %s %s) AS %s ",
first,
wrapper.getSqlSelect(),
wrapper.getTableName(tableInfo.getTableName()),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
subLogic,
sqlSegment,
sqlComment,
alias);
}
public static String buildUnionSqlByWrapper(Class<?> clazz, AptQueryWrapper<?> wrapper) {
TableInfo tableInfo = TableHelper.getAssert(clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
if (StrUtils.isNotBlank(entityWhere)) {
hasWhere = true;
}
String mainLogic = mainLogic(hasWhere, clazz, wrapper);
if (StrUtils.isNotBlank(mainLogic)) {
hasWhere = true;
}
String subLogic = subLogic(hasWhere, wrapper);
if (StrUtils.isNotBlank(subLogic)) {
hasWhere = true;
}
String sqlSegment = (wrapper.getSqlSegment() != null && StrUtils.isNotBlank(wrapper.getSqlSegment())) ?
((wrapper.isEmptyOfNormal() ? StringPool.EMPTY : (hasWhere ? " AND " : " WHERE ")) + wrapper.getSqlSegment()) : StringPool.EMPTY;
String sqlComment = Optional.ofNullable(wrapper.getSqlComment()).orElse(StringPool.EMPTY);
return String.format(" %s SELECT %s FROM %s %s %s %s %s %s %s ",
first,
wrapper.getSqlSelect(),
wrapper.getTableName(tableInfo.getTableName()),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
subLogic,
sqlSegment,
sqlComment);
}
private static <T> String formatParam(AptQueryWrapper<T> wrapper, Object param) {
final String genParamName = Constants.WRAPPER_PARAM + wrapper.getParamNameSeq().incrementAndGet();
final String paramStr = wrapper.getParamAlias() + ".paramNameValuePairs." + genParamName;
wrapper.getParamNameValuePairs().put(genParamName, param);
return SqlScriptUtils.safeParam(paramStr, null);
}
private static String getEntitySql(TableInfo tableInfo, AptQueryWrapper<?> wrapper) {
Object obj = wrapper.getEntity();
if (Objects.isNull(obj)) {
return StringPool.EMPTY;
}
StringBuilder sb = new StringBuilder(StringPool.EMPTY);
for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
continue;
}
Object val;
try {
val = fieldInfo.getField().get(obj);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
if (Objects.isNull(val)) {
continue;
}
String s = wrapper.getAptIndex().get(wrapper.getBaseColumn());
sb.append(" AND ").append(s == null ? wrapper.getAlias() : s).append(Constants.DOT)
.append(fieldInfo.getColumn()).append(Constants.EQUALS).append(formatParam(wrapper, val));
}
//条件不为空 加上 where
if (sb.length() > 0) {
sb.delete(0, 4);
sb.insert(0, " WHERE ");
}
return sb.toString();
}
private static String mainLogic(boolean hasWhere, Class<?> clazz, AptQueryWrapper<?> wrapper) {
if (!wrapper.getLogicSql()) {
return StringPool.EMPTY;
}
String info = LogicInfoUtils.getLogicInfo(null, clazz, true, wrapper.getAlias());
if (StrUtils.isNotBlank(info)) {
if (hasWhere) {
return " AND " + info;
}
return " WHERE " + info.substring(4);
}
return StringPool.EMPTY;
}
private static String subLogic(boolean hasWhere, AptQueryWrapper<?> wrapper) {
String sql = wrapper.getSubLogicSql();
if (StrUtils.isNotBlank(sql)) {
if (hasWhere) {
return sql;
}
return " WHERE " + sql.substring(4);
}
return StringPool.EMPTY;
}
}

View File

@ -0,0 +1,26 @@
package com.github.yulichang.extension.apt.toolkit;
import com.github.yulichang.extension.apt.matedata.BaseColumn;
import com.github.yulichang.extension.apt.AptQueryWrapper;
/**
* @author yulichang
* @since 1.5.0
*/
@SuppressWarnings("unused")
public class AptWrappers {
/**
* AptWrappers.query(User.class)
*/
public static <T> AptQueryWrapper<T> query(BaseColumn<T> baseColumn) {
return new AptQueryWrapper<>(baseColumn);
}
/**
* AptWrappers.query("t", User.class)
*/
public static <T> AptQueryWrapper<T> query(BaseColumn<T> baseColumn, T entity) {
return new AptQueryWrapper<>(baseColumn, entity);
}
}

View File

@ -0,0 +1,495 @@
package com.github.yulichang.extension.kt;
import com.baomidou.mybatisplus.annotation.OrderBy;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import com.github.yulichang.extension.kt.interfaces.QueryJoin;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.enums.PrefixEnum;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.segments.PageInfo;
import com.github.yulichang.wrapper.segments.SelectCache;
import kotlin.reflect.KProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY;
import static java.util.stream.Collectors.joining;
/**
* 参考 {@link com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper}
*
* @author yulichang
*/
@SuppressWarnings({"DuplicatedCode", "unused"})
public abstract class KtAbstractLambdaWrapper<T, Children extends KtAbstractLambdaWrapper<T, Children>>
extends KtAbstractWrapper<T, Children> implements QueryJoin<Children, T> {
/**
* 主表别名
*/
@Getter
protected String alias = ConfigProperties.tableAlias;
/**
* 副表别名
*/
protected String subTableAlias = ConfigProperties.tableAlias;
/**
* 是否构建是否存在一对多
*/
@Getter
protected boolean resultMap = false;
@Getter
protected boolean resultMapCollection = false;
@Setter
protected PageInfo pageInfo;
@Getter
protected boolean pageByMain = false;
/**
* 表序号
*/
protected int tableIndex = 1;
/**
* 主表 表名处理方法
*/
protected boolean dynamicTableName = false;
/**
* 主表 表名处理方法
*/
protected Function<String, String> tableFunc;
/**
* 逻辑删除位置
*/
protected LogicDelTypeEnum logicDelType = ConfigProperties.logicDelType;
/**
* 查询表
*/
protected final SharedString from = new SharedString();
/**
* 是否有表别名
*/
@Getter
protected boolean hasAlias;
/**
* 连表关键字 on 条件 func 使用
*/
@Getter
protected String keyWord;
/**
* 副表逻辑删除开关
*/
protected boolean subLogicSql = ConfigProperties.subTableLogic;
/**
* 主表逻辑删除开关
*/
protected boolean logicSql = true;
/**
* 推荐使用 class 的构造方法
*/
public KtAbstractLambdaWrapper() {
initNeed();
}
/**
* 推荐使用此构造方法
*/
public KtAbstractLambdaWrapper(Class<T> clazz) {
initNeed();
setEntityClass(clazz);
tableList.setRootClass(clazz);
}
/**
* 构造方法
*
* @param entity 主表实体
*/
public KtAbstractLambdaWrapper(T entity) {
initNeed();
setEntity(entity);
if (entity != null) {
tableList.setRootClass(entity.getClass());
}
}
/**
* 自定义主表别名
*/
public KtAbstractLambdaWrapper(String alias) {
this.alias = alias;
initNeed();
tableList.setAlias(alias);
}
/**
* 构造方法
*
* @param clazz 主表class类
* @param alias 主表别名
*/
public KtAbstractLambdaWrapper(Class<T> clazz, String alias) {
this.alias = alias;
setEntityClass(clazz);
initNeed();
tableList.setAlias(alias);
tableList.setRootClass(clazz);
}
/**
* 构造方法
*
* @param entity 主表实体类
* @param alias 主表别名
*/
public KtAbstractLambdaWrapper(T entity, String alias) {
this.alias = alias;
setEntity(entity);
initNeed();
tableList.setAlias(alias);
if (entity != null) {
tableList.setRootClass(entity.getClass());
}
}
/**
* 根据主表分页
*/
public Children pageByMain() {
this.pageByMain = true;
return typedThis;
}
/**
* 根据主表分页
*/
public Children pageByMain(MFunction<PageInfo> function) {
this.pageByMain = true;
function.apply(getPageInfo());
return typedThis;
}
public PageInfo getPageInfo() {
if (pageInfo == null) {
pageInfo = new PageInfo();
}
return pageInfo;
}
/**
* 设置表别名
* 设置表别名注意sql注入问题
*
* @return 自定义表别名
*/
public Children setTableName(Function<String, String> tableFunc) {
if (isMain) {
if (tableFunc != null) {
this.dynamicTableName = true;
this.tableFunc = tableFunc;
}
} else {
this.tableName = tableFunc.apply(this.tableName);
}
return typedThis;
}
public String getTableName(String tableName) {
if (isMain) {
if (dynamicTableName) {
return tableFunc.apply(tableName);
}
return tableName;
}
return super.getTableName();
}
public String getTableNameEnc(String tableName) {
Class<T> entityClass = getEntityClass();
if (entityClass != null) {
TableInfo tableInfo = TableHelper.get(entityClass);
if (tableInfo != null) {
if (dynamicTableName) {
return tableFunc.apply(tableInfo.getTableName());
}
return tableInfo.getTableName();
}
}
String decode;
try {
decode = URLDecoder.decode(tableName, StandardCharsets.UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
if (dynamicTableName) {
return tableFunc.apply(decode);
}
return decode;
}
@Override
protected final String columnsToString(Integer index, PrefixEnum prefixEnum, String alias, KProperty<?>... columns) {
return Arrays.stream(columns).map(i -> columnToString(index, alias, i, false, prefixEnum)).collect(joining(StringPool.COMMA));
}
protected String columnToString(Integer index, String alias, KProperty<?> column, boolean isJoin, PrefixEnum prefixEnum) {
Class<?> entityClass = KtUtils.ref(column);
return (alias == null ? getDefault(index, entityClass, isJoin, prefixEnum) : alias) + StringPool.DOT + getCache(column).getColumn();
}
protected SelectCache getCache(KProperty<?> fn) {
Class<?> aClass = KtUtils.ref(fn);
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(aClass);
return cacheMap.get(fn.getName());
}
/**
* 返回前缀
*/
protected String getDefault(Integer index, Class<?> clazz, boolean isJoin, PrefixEnum prefixEnum) {
if (prefixEnum == PrefixEnum.ON_FIRST) {
return tableList.getPrefix(index, clazz, false);
} else if (prefixEnum == PrefixEnum.ON_SECOND) {
return isJoin ? tableList.getPrefixOther(index, clazz) : tableList.getPrefix(index, clazz, false);
} else if (prefixEnum == PrefixEnum.CD_FIRST) {
return tableList.getPrefix(index, clazz, false);
} else if (prefixEnum == PrefixEnum.CD_SECOND) {
return isJoin ? tableList.getPrefixOther(index, clazz) :
tableList.getPrefix(index, clazz, false);
} else if (prefixEnum == PrefixEnum.CD_ON_FIRST) {
return tableList.getPrefix(index, clazz, false);
} else if (prefixEnum == PrefixEnum.CD_ON_SECOND) {
return isJoin ? tableList.getPrefixOther(index, clazz) :
tableList.getPrefix(index, clazz, false);
} else {
return tableList.getAlias();
}
}
/**
* 关闭副表逻辑删除
* <p>
* 副表逻辑删除默认在where语句中
* 但有时候需要让它出现在on语句中, 这两种写法区别还是很大的
* 所以可以关闭副表逻辑删除, 通过on语句多条件, 自己实现on语句的逻辑删除
*/
public Children disableSubLogicDel() {
this.subLogicSql = false;
return typedThis;
}
public Children enableSubLogicDel() {
this.subLogicSql = true;
return typedThis;
}
/**
* 关闭主表逻辑删除
*/
public Children disableLogicDel() {
this.logicSql = false;
return typedThis;
}
public Children enableLogicDel() {
this.logicSql = true;
return typedThis;
}
/**
* 副表部分逻辑删除支持
*/
public String getSubLogicSql() {
if (subLogicSql && logicDelType == LogicDelTypeEnum.WHERE) {
if (tableList.getAll().isEmpty()) {
return StringPool.EMPTY;
}
return tableList.getAll().stream().map(t -> LogicInfoUtils.getLogicInfo(t.getIndex(),
t.getClazz(), t.isHasAlias(), t.getAlias())).collect(Collectors.joining(StringPool.SPACE));
}
return StringPool.EMPTY;
}
/**
* 主表部分逻辑删除支持
*/
public boolean getLogicSql() {
return this.logicSql;
}
/**
* 调整逻辑删除位置为ON语句
*/
public Children logicDelToOn() {
this.logicDelType = LogicDelTypeEnum.ON;
return typedThis;
}
/**
* 调整逻辑删除位置为WHERE语句
*/
public Children logicDelToWhere() {
this.logicDelType = LogicDelTypeEnum.WHERE;
return typedThis;
}
/**
* 获取连表部分语句
*/
public String getFrom() {
if (StrUtils.isBlank(from.getStringValue())) {
StringBuilder value = new StringBuilder();
for (Children wrapper : onWrappers) {
if (StrUtils.isBlank(wrapper.from.getStringValue())) {
if (this.subLogicSql && this.logicDelType == LogicDelTypeEnum.ON) {
TableInfo tableInfo = TableHelper.getAssert(wrapper.getJoinClass());
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo)) {
wrapper.appendSqlSegments(APPLY, () -> LogicInfoUtils.getLogicInfoNoAnd(
wrapper.getIndex(), wrapper.getJoinClass(), wrapper.isHasAlias(), wrapper.getAlias()
));
}
}
value.append(StringPool.SPACE)
.append(wrapper.getKeyWord())
.append(StringPool.SPACE)
.append(wrapper.getTableName())
.append(StringPool.SPACE)
.append(wrapper.hasAlias ? wrapper.alias : (wrapper.alias + wrapper.getIndex()))
.append(Constant.ON)
.append(wrapper.getExpression().getNormal().getSqlSegment());
} else {
value.append(StringPool.SPACE)
.append(wrapper.getKeyWord())
.append(StringPool.SPACE)
.append(wrapper.from.getStringValue())
.append(StringPool.SPACE);
}
}
from.setStringValue(value.toString());
}
return from.getStringValue();
}
/**
* 内部调用, 不建议使用
*/
@Override
public Children join(String keyWord, Class<?> clazz, String tableAlias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
Integer oldIndex = this.getIndex();
int newIndex = tableIndex;
TableInfo info = TableHelper.getAssert(clazz);
Children instance = instance(newIndex, keyWord, clazz, info.getTableName());
instance.isNo = true;
instance.isMain = false;
onWrappers.add(instance);
if (StrUtils.isBlank(tableAlias)) {
tableList.put(oldIndex, clazz, false, subTableAlias, newIndex);
instance.alias = subTableAlias;
instance.hasAlias = false;
} else {
tableList.put(oldIndex, clazz, true, tableAlias, newIndex);
instance.alias = tableAlias;
instance.hasAlias = true;
}
tableIndex++;
this.index = newIndex;
boolean isM = this.isMain;
this.isMain = false;
consumer.accept(instance, typedThis);
this.isMain = isM;
this.index = oldIndex;
return typedThis;
}
/**
* 自定义关键词连接
*
* @param keyWord 连表关键词
* @param condition 条件
* @param joinSql sql
*/
@Override
public Children join(String keyWord, boolean condition, String joinSql,Object... args) {
if (condition) {
Children wrapper = instanceEmpty();
wrapper.from.setStringValue(formatSqlMaybeWithParam(joinSql,args));
wrapper.keyWord = keyWord;
onWrappers.add(wrapper);
}
return typedThis;
}
/**
* 是否使用默认注解 {@link OrderBy} 排序
*
* @return true 使用 false 不使用
*/
public boolean isUseAnnotationOrderBy() {
final String _sqlSegment = this.getSqlSegment();
if (StrUtils.isBlank(_sqlSegment)) {
return true;
}
final String _sqlSegmentToUpperCase = _sqlSegment.toUpperCase();
return !(_sqlSegmentToUpperCase.contains(Constants.ORDER_BY)
|| _sqlSegmentToUpperCase.contains(Constants.LIMIT));
}
/**
* 必要的初始化
*/
protected void initNeed() {
paramNameSeq = new AtomicInteger(0);
paramNameValuePairs = new HashMap<>(16);
expression = new MergeSegments();
lastSql = SharedString.emptyString();
sqlComment = SharedString.emptyString();
sqlFirst = SharedString.emptyString();
tableList = new TableList();
tableList.setAlias(alias);
}
@Override
public void clear() {
super.clear();
this.alias = ConfigProperties.tableAlias;
this.resultMap = false;
this.resultMapCollection = false;
this.pageInfo = null;
this.pageByMain = false;
this.tableIndex = 1;
this.dynamicTableName = false;
this.tableFunc = null;
this.logicDelType = ConfigProperties.logicDelType;
this.from.toNull();
this.hasAlias = false;
this.keyWord = null;
this.logicSql = true;
this.onWrappers.clear();
}
}

View File

@ -0,0 +1,253 @@
package com.github.yulichang.extension.kt;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.toolkit.LogicInfoUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.wrapper.interfaces.DeleteChain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.5
*/
@SuppressWarnings({"unused", "DuplicatedCode"})
public class KtDeleteJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtDeleteJoinWrapper<T>> implements DeleteChain<T> {
/**
* 删除表
*/
private final SharedString deleteSql = new SharedString();
/**
* 删除的表
*/
private List<Class<?>> deleteTableList;
/**
* 删除的表
*/
private List<String> deleteTableName;
/**
* 是否删除主表以及所有副表
*/
private boolean deleteAll = false;
private KtDeleteJoinWrapper() {
super();
}
/**
* 推荐使用此构造方法
*/
public KtDeleteJoinWrapper(Class<T> clazz) {
super(clazz);
}
/**
* 构造方法
*
* @param clazz 主表class类
* @param alias 主表别名
*/
public KtDeleteJoinWrapper(Class<T> clazz, String alias) {
super(clazz, alias);
}
/**
* 获取删除的表
*/
@Override
public String getDeleteSql() {
if (StrUtils.isNotBlank(this.deleteSql.getStringValue())) {
return this.deleteSql.getStringValue();
}
String delete = null;
if (deleteAll) {
check();
List<String> tables = tableList.getAll().stream().map(i -> i.isHasAlias() ? i.getAlias() :
(i.getAlias() + i.getIndex())).collect(Collectors.toList());
tables.add(0, this.alias);
delete = String.join(StringPool.COMMA, tables);
} else {
if (CollectionUtils.isNotEmpty(deleteTableList)) {
delete = deleteTableList.stream().map(c -> tableList.getPrefixByClassAssert(c)).collect(Collectors.joining(StringPool.COMMA));
}
}
if (CollectionUtils.isNotEmpty(deleteTableName)) {
delete = delete + StringPool.COMMA + String.join(StringPool.COMMA, deleteTableName);
}
if (StrUtils.isBlank(delete)) {
delete = this.alias;
}
deleteSql.setStringValue(delete);
return delete;
}
/**
* 获取删除的表
*/
@Override
public String getDeleteLogicSql() {
if (StrUtils.isNotBlank(this.deleteSql.getStringValue())) {
return this.deleteSql.getStringValue();
}
String delete = null;
if (deleteAll) {
check();
delete = tableList.getAll().stream().map(i -> LogicInfoUtils.getLogicInfoInvert(i.getIndex(), i.getClazz(),
i.isHasAlias(), i.getAlias())).collect(Collectors.joining(StringPool.COMMA));
} else {
if (CollectionUtils.isNotEmpty(deleteTableList)) {
delete = deleteTableList.stream().map(c -> tableList.getByClassFirst(c)).map(i ->
LogicInfoUtils.getLogicInfoInvert(i.getIndex(), i.getClazz(), i.isHasAlias(), i.getAlias()))
.collect(Collectors.joining(StringPool.COMMA));
}
}
if (CollectionUtils.isNotEmpty(deleteTableName)) {
delete = delete + StringPool.COMMA + String.join(StringPool.COMMA, deleteTableName);
}
if (StrUtils.isNotBlank(delete)) {
delete = StringPool.COMMA + delete;
} else {
delete = StringPool.EMPTY;
}
deleteSql.setStringValue(delete);
return delete;
}
/**
* 删除表
*/
public KtDeleteJoinWrapper<T> deleteAll() {
this.deleteAll = true;
return typedThis;
}
/**
* 删除表
* 注意!!!
* 字符串不支持逻辑删除校验
* 也就算说此方法不管副表有没有逻辑删除 都按照主表的方式执行delete或update
*/
public KtDeleteJoinWrapper<T> delete(String... tables) {
if (CollectionUtils.isEmpty(deleteTableName)) {
deleteTableName = new ArrayList<>();
deleteTableName.addAll(Arrays.asList(tables));
}
return typedThis;
}
/**
* 删除表
*/
public KtDeleteJoinWrapper<T> delete(Class<?>... deleteClass) {
Class<T> entityClass = getEntityClass();
Assert.notNull(entityClass, "缺少主表类型, 请使用 new MPJLambdaWrapper<>(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
if (CollectionUtils.isEmpty(deleteTableList)) {
deleteTableList = new ArrayList<>();
}
check(Arrays.asList(deleteClass));
deleteTableList.addAll(Arrays.asList(deleteClass));
return typedThis;
}
private void check(List<Class<?>> classList) {
Class<T> entityClass = getEntityClass();
TableInfo tableInfo = TableHelper.getAssert(entityClass);
//检查
boolean mainLogic = AdapterHelper.getAdapter().mpjHasLogic(tableInfo);
boolean check = classList.stream().allMatch(t -> {
TableInfo ti = TableHelper.getAssert(t);
return mainLogic == AdapterHelper.getAdapter().mpjHasLogic(ti);
});
if (!check) {
throw ExceptionUtils.mpe("连表删除只适用于全部表(主表和副表)都是物理删除或全部都是逻辑删除, " +
"不支持同时存在物理删除和逻辑删除 [物理删除->(%s)] [逻辑删除->(%s)]",
classList.stream().filter(t -> !AdapterHelper.getAdapter().mpjHasLogic(TableHelper.getAssert(t)))
.map(Class::getSimpleName).collect(Collectors.joining(StringPool.COMMA)),
classList.stream().filter(t -> AdapterHelper.getAdapter().mpjHasLogic(TableHelper.getAssert(t)))
.map(Class::getSimpleName).collect(Collectors.joining(StringPool.COMMA)));
}
}
private void check() {
if (CollectionUtils.isNotEmpty(tableList.getAll())) {
Class<T> entityClass = getEntityClass();
Assert.notNull(entityClass, "缺少主表类型, 请使用 new MPJLambdaWrapper<>(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
ArrayList<Class<?>> list = tableList.getAll().stream().map(TableList.Node::getClazz)
.collect(Collectors.toCollection(ArrayList::new));
list.add(entityClass);
check(list);
}
}
/**
* 用于生成嵌套 sql
* <p> sqlSelect 不向下传递</p>
*/
@Override
protected KtDeleteJoinWrapper<T> instance() {
return instance(index, null, null, null);
}
@Override
protected KtDeleteJoinWrapper<T> instanceEmpty() {
return new KtDeleteJoinWrapper<>();
}
@Override
protected KtDeleteJoinWrapper<T> instance(Integer index, String keyWord, Class<?> joinClass, String tableName) {
return new KtDeleteJoinWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.tableList, index, keyWord, joinClass, tableName);
}
/**
* 不建议直接 new 该实例使用 JoinWrappers.delete(User.class)
*/
public KtDeleteJoinWrapper(T entity, Class<T> entityClass, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
TableList tableList, Integer index, String keyWord, Class<?> joinClass, String tableName) {
super.setEntity(entity);
super.setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
this.tableList = tableList;
this.index = index;
this.keyWord = keyWord;
this.joinClass = joinClass;
this.tableName = tableName;
}
@Override
public void clear() {
super.clear();
if (CollectionUtils.isNotEmpty(deleteTableList)) {
deleteTableList.clear();
}
if (CollectionUtils.isNotEmpty(deleteTableName)) {
deleteTableName.clear();
}
this.deleteSql.toNull();
this.deleteAll = false;
}
}

View File

@ -0,0 +1,449 @@
package com.github.yulichang.extension.kt;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.extension.kt.interfaces.Query;
import com.github.yulichang.extension.kt.interfaces.QueryLabel;
import com.github.yulichang.extension.kt.segments.FuncArgs;
import com.github.yulichang.extension.kt.toolkit.KtWrapperUtils;
import com.github.yulichang.extension.kt.toolkit.KtWrappers;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.interfaces.Chain;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.interfaces.SelectWrapper;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.segments.*;
import kotlin.reflect.KProperty;
import lombok.Getter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
* 参考 {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper}
* Lambda 语法使用 Wrapper
*
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings({"unused", "unchecked", "rawtypes", "DuplicatedCode"})
public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapper<T>> implements
Query<KtLambdaWrapper<T>>, QueryLabel<KtLambdaWrapper<T>>, Chain<T>, SelectWrapper<T, KtLambdaWrapper<T>> {
/**
* 查询字段 sql
*/
private SharedString sqlSelect = new SharedString();
/**
* 是否 select distinct
*/
private boolean selectDistinct = false;
/**
* 查询的字段
*/
@Getter
private final List<Select> selectColumns = new ArrayList<>();
/**
* 映射关系
*/
@Getter
private final List<Label<?>> resultMapMybatisLabel = new ArrayList<>();
/**
* union sql
*/
private SharedString unionSql;
/**
* 自定义wrapper索引
*/
private AtomicInteger wrapperIndex;
/**
* 自定义wrapper
*/
@Getter
private Map<String, Wrapper<?>> wrapperMap;
/**
* 推荐使用 class 的构造方法
*/
public KtLambdaWrapper() {
super();
}
/**
* 推荐使用此构造方法
*/
public KtLambdaWrapper(Class<T> clazz) {
super(clazz);
}
/**
* 构造方法
*
* @param entity 主表实体
*/
public KtLambdaWrapper(T entity) {
super(entity);
}
/**
* 自定义主表别名
*/
public KtLambdaWrapper(String alias) {
super(alias);
}
/**
* 构造方法
*
* @param clazz 主表class类
* @param alias 主表别名
*/
public KtLambdaWrapper(Class<T> clazz, String alias) {
super(clazz, alias);
}
/**
* 构造方法
*
* @param entity 主表实体类
* @param alias 主表别名
*/
public KtLambdaWrapper(T entity, String alias) {
super(entity, alias);
}
/**
* 不建议直接 new 该实例使用 JoinWrappers.lambda(UserDO.class)
*/
KtLambdaWrapper(T entity, Class<T> entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
TableList tableList, Integer index, String keyWord, Class<?> joinClass, String tableName) {
super.setEntity(entity);
super.setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
this.sqlSelect = sqlSelect;
this.paramAlias = paramAlias;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
this.tableList = tableList;
this.index = index;
this.keyWord = keyWord;
this.joinClass = joinClass;
this.tableName = tableName;
}
/**
* sql去重
* select distinct
*/
public KtLambdaWrapper<T> distinct() {
this.selectDistinct = true;
return typedThis;
}
@Override
public List<Select> getSelectColum() {
return this.selectColumns;
}
@Override
public void addLabel(Label<?> label, boolean isCollection) {
if (isCollection) {
this.resultMapCollection = true;
}
this.resultMap = true;
this.resultMapMybatisLabel.add(label);
}
@Override
public KtLambdaWrapper<T> getChildren() {
return typedThis;
}
/**
* 设置查询字段
*
* @param columns 字段数组
* @return children
*/
public final KtLambdaWrapper<T> select(KProperty<?>... columns) {
if (ArrayUtils.isNotEmpty(columns)) {
for (KProperty<?> s : columns) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(KtUtils.ref(s));
SelectCache cache = cacheMap.get(s.getName());
getSelectColum().add(new SelectNormal(cache, index, hasAlias, alias));
}
}
return typedThis;
}
@Override
public KtLambdaWrapper<T> selectAll() {
return Query.super.selectAll(getEntityClass());
}
/**
* 子查询
*/
public KtLambdaWrapper<T> selectSub(Class<?> clazz, Consumer<KtLambdaWrapper<?>> consumer, KProperty<?> alias) {
return selectSub(clazz, ConfigProperties.subQueryAlias, consumer, alias);
}
public <E, F> KtLambdaWrapper<T> selectSub(Class<E> clazz, String st, Consumer<KtLambdaWrapper<?>> consumer, KProperty<?> alias) {
return selectSub(clazz, st, consumer, alias.getName());
}
/**
* 子查询
*/
public KtLambdaWrapper<T> selectSub(Class<?> clazz, String st,
Consumer<KtLambdaWrapper<?>> consumer, String alias) {
KtLambdaWrapper<?> wrapper = new KtLambdaWrapper(null, clazz, SharedString.emptyString(), paramNameSeq,
paramNameValuePairs, new MergeSegments(), new SharedString(this.paramAlias.getStringValue()),
SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), new TableList(),
null, null, null, null) {
};
wrapper.tableList.setAlias(st);
wrapper.tableList.setRootClass(clazz);
wrapper.tableList.setParent(this.tableList);
wrapper.alias = st;
wrapper.subTableAlias = st;
consumer.accept(wrapper);
addCustomWrapper(wrapper);
this.selectColumns.add(new SelectSub(() -> KtWrapperUtils.buildSubSqlByWrapper(
clazz, wrapper, alias), hasAlias, this.alias, alias));
return typedThis;
}
@Override
public KtLambdaWrapper<T> selectFunc(String sql, MFunction<FuncArgs> column, String alias) {
FuncArgs apply = column.apply(new FuncArgs());
String formatSql;
if (ArrayUtils.isEmpty(apply.getValues())) {
formatSql = sql;
} else {
formatSql = formatSqlMaybeWithParam(sql, apply.getValues());
}
getSelectColum().add(new SelectFunc(alias, getIndex(), () -> formatSql, apply.getFuncArg(),
isHasAlias(), getAlias()));
return typedThis;
}
/**
* union
* <p>
* 推荐使用 union(Class&lt;U&gt; clazz, Consumer&lt;MPJLambdaWrapper&lt;U&gt;&gt; consumer)
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #union(Class, Consumer)
* @deprecated union 不支持子查询
*/
@Deprecated
@SuppressWarnings("ALL")
public final KtLambdaWrapper<T> union(KtLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (KtLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ").append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.8
*/
public <U> KtLambdaWrapper<T> union(Class<U> clazz, Consumer<KtLambdaWrapper<U>> consumer) {
KtLambdaWrapper<U> unionWrapper = KtWrappers.query(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION " + KtWrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* 推荐使用 unionAll(Class&lt;U&gt; clazz, Consumer&lt;MPJLambdaWrapper&lt;U&gt;&gt; consumer)
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #unionAll(Class, Consumer)
* @deprecated union 不支持子查询
*/
@Deprecated
@SuppressWarnings("ALL")
public final KtLambdaWrapper<T> unionAll(KtLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (KtLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ALL ").append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.8
*/
public <U> KtLambdaWrapper<T> unionAll(Class<U> clazz, Consumer<KtLambdaWrapper<U>> consumer) {
KtLambdaWrapper<U> unionWrapper = KtWrappers.query(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION ALL " + KtWrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
private void addCustomWrapper(KtLambdaWrapper<?> wrapper) {
if (Objects.isNull(wrapperIndex)) {
wrapperIndex = new AtomicInteger(0);
}
int index = wrapperIndex.incrementAndGet();
if (Objects.isNull(wrapperMap)) {
wrapperMap = new HashMap<>();
}
String key = "ew" + index;
wrapper.setParamAlias(wrapper.getParamAlias() + ".wrapperMap." + key);
wrapperMap.put(key, wrapper);
}
/**
* 查询条件 SQL 片段
*/
@Override
public String getSqlSelect() {
if (StrUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {
if (i.isStr()) {
return i.getColumn();
}
String prefix;
if (i.isHasTableAlias()) {
prefix = i.getTableAlias();
} else {
if (i.isLabel()) {
if (i.isHasTableAlias()) {
prefix = i.getTableAlias();
} else {
prefix = tableList.getPrefix(i.getIndex(), i.getClazz(), true);
}
} else {
prefix = tableList.getPrefix(i.getIndex(), i.getClazz(), false);
}
}
String str = prefix + StringPool.DOT + i.getColumn();
if (i.isFunc()) {
SelectFunc.Arg[] args = i.getArgs();
if (Objects.isNull(args) || args.length == 0) {
return String.format(i.getFunc().getSql(), str) + Constant.AS + i.getAlias();
} else {
return String.format(i.getFunc().getSql(), Arrays.stream(args).map(arg -> {
String prefixByClass = tableList.getPrefixByClass(arg.getClazz());
Map<String, SelectCache> mapField = ColumnCache.getMapField(arg.getClazz());
SelectCache cache = mapField.get(arg.getProp());
return prefixByClass + StringPool.DOT + cache.getColumn();
}).toArray()) + Constant.AS + i.getAlias();
}
} else {
return i.isHasAlias() ? (str + Constant.AS + i.getAlias()) : str;
}
}).collect(Collectors.joining(StringPool.COMMA));
sqlSelect.setStringValue(s);
}
return sqlSelect.getStringValue();
}
@Override
public String getUnionSql() {
return Optional.ofNullable(unionSql).map(SharedString::getStringValue).orElse(StringPool.EMPTY);
}
public boolean getSelectDistinct() {
return selectDistinct;
}
/**
* 用于生成嵌套 sql
* <p> sqlSelect 不向下传递</p>
*/
@Override
protected KtLambdaWrapper<T> instance() {
return instance(index, null, null, null);
}
@Override
protected KtLambdaWrapper<T> instanceEmpty() {
return new KtLambdaWrapper<>();
}
@Override
protected KtLambdaWrapper<T> instance(Integer index, String keyWord, Class<?> joinClass, String tableName) {
return new KtLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.tableList, index, keyWord, joinClass, tableName);
}
@Override
public void clear() {
super.clear();
selectDistinct = false;
sqlSelect.toEmpty();
if (Objects.nonNull(unionSql)) unionSql.toEmpty();
selectColumns.clear();
wrapperIndex = new AtomicInteger(0);
wrapperMap.clear();
resultMapMybatisLabel.clear();
}
}

View File

@ -0,0 +1,287 @@
package com.github.yulichang.extension.kt;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.extension.kt.interfaces.Update;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.ReflectionKit;
import com.github.yulichang.wrapper.interfaces.UpdateChain;
import kotlin.reflect.KProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings({"unused", "DuplicatedCode"})
public class KtUpdateJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtUpdateJoinWrapper<T>>
implements Update<KtUpdateJoinWrapper<T>>, UpdateChain<T> {
/**
* SQL 更新字段内容例如name='1', age=2
*/
private final SharedString sqlSetStr = new SharedString();
/**
* SQL 更新字段内容例如name='1', age=2
*/
private List<String> sqlSet;
/**
* SQL 更新字段内容例如name='1', age=2
*/
private List<UpdateSet> updateSet;
/**
* SQL 更新实体(更新非空字段)
*/
private List<Object> updateEntity;
/**
* SQL 更新实体(空字段也会更新)
*/
private List<Object> updateEntityNull;
private KtUpdateJoinWrapper() {
super();
}
/**
* 推荐使用此构造方法
*/
public KtUpdateJoinWrapper(Class<T> clazz) {
super(clazz);
}
public KtUpdateJoinWrapper(T entity) {
super(entity);
}
public KtUpdateJoinWrapper(Class<T> clazz, String alias) {
super(clazz, alias);
}
public KtUpdateJoinWrapper(T entity, String alias) {
super(entity, alias);
}
/**
* 设置更新的实体set语句部分, 更新非空字段
* <p>
* 注意!!!
* 这里这是的实体类是set部分, 不作为条件, where条件是wrapper.setEntity()
*/
public KtUpdateJoinWrapper<T> setUpdateEntity(Object... entity) {
if (Objects.isNull(updateEntity)) {
updateEntity = new ArrayList<>();
}
for (Object obj : entity) {
Assert.notNull(obj, "更新实体不能为空");
updateEntity.add(obj);
}
return typedThis;
}
/**
* 设置更新的实体set语句部分, 更新非空字段
* <p>
* 注意!!!
* 这里这是的实体类是set部分, 不作为条件, where条件是wrapper.setEntity()
*/
public KtUpdateJoinWrapper<T> setUpdateEntityAndNull(Object... entity) {
if (Objects.isNull(updateEntityNull)) {
updateEntityNull = new ArrayList<>();
}
for (Object obj : entity) {
Assert.notNull(obj, "更新实体不能为空");
updateEntityNull.add(obj);
}
return typedThis;
}
@Override
public KtUpdateJoinWrapper<T> set(boolean condition, KProperty<?> column, Object val, String mapping) {
return maybeDo(condition, () -> {
if (Objects.isNull(updateSet)) {
updateSet = new ArrayList<>();
}
updateSet.add(new UpdateSet(column, val, mapping, false, null));
});
}
@Override
public KtUpdateJoinWrapper<T> setIncrBy(boolean condition, KProperty<?> column, Number val) {
return maybeDo(condition, () -> {
if (Objects.isNull(updateSet)) {
updateSet = new ArrayList<>();
}
updateSet.add(new UpdateSet(column, val, null, true, Constant.PLUS));
});
}
@Override
public KtUpdateJoinWrapper<T> setDecrBy(boolean condition, KProperty<?> column, Number val) {
return maybeDo(condition, () -> {
if (Objects.isNull(updateSet)) {
updateSet = new ArrayList<>();
}
updateSet.add(new UpdateSet(column, val, null, true, Constant.DASH));
});
}
@Override
public KtUpdateJoinWrapper<T> setSql(boolean condition, String sql) {
if (condition && StrUtils.isNotBlank(sql)) {
if (Objects.isNull(sqlSet)) {
sqlSet = new ArrayList<>();
}
sqlSet.add(sql);
}
return typedThis;
}
@Override
public String getSqlSet() {
if (StrUtils.isNotBlank(sqlSetStr.getStringValue())) {
return sqlSetStr.getStringValue();
}
StringBuilder set = new StringBuilder(StringPool.EMPTY);
if (CollectionUtils.isNotEmpty(updateSet)) {
set = new StringBuilder(updateSet.stream().map(i -> {
String col = tableList.getPrefixByClass(KtUtils.ref(i.getColumn())) +
Constants.DOT + getCache(i.getColumn()).getColumn();
if (i.incOrDnc) {
return col + Constants.EQUALS + col + i.cal + i.value;
} else {
return col + Constants.EQUALS + formatParam(i.mapping, i.value);
}
})
.collect(Collectors.joining(StringPool.COMMA)) + StringPool.COMMA);
}
if (CollectionUtils.isNotEmpty(sqlSet)) {
set.append(String.join(StringPool.COMMA, sqlSet)).append(StringPool.COMMA);
}
if (CollectionUtils.isNotEmpty(updateEntity)) {
getSqlByEntity(set, true, updateEntity);
}
if (CollectionUtils.isNotEmpty(updateEntityNull)) {
getSqlByEntity(set, false, updateEntityNull);
}
sqlSetStr.setStringValue(set.toString());
return set.toString();
}
/**
* 用于生成嵌套 sql
* <p> sqlSelect 不向下传递</p>
*/
@Override
protected KtUpdateJoinWrapper<T> instance() {
return instance(index, null, null, null);
}
@Override
protected KtUpdateJoinWrapper<T> instanceEmpty() {
return new KtUpdateJoinWrapper<>();
}
@Override
protected KtUpdateJoinWrapper<T> instance(Integer index, String keyWord, Class<?> joinClass, String tableName) {
return new KtUpdateJoinWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.tableList, index, keyWord, joinClass, tableName);
}
/**
* 不建议直接 new 该实例使用 JoinWrappers.update(User.class)
*/
public KtUpdateJoinWrapper(T entity, Class<T> entityClass, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
TableList tableList, Integer index, String keyWord, Class<?> joinClass, String tableName) {
super.setEntity(entity);
super.setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
this.tableList = tableList;
this.index = index;
this.keyWord = keyWord;
this.joinClass = joinClass;
this.tableName = tableName;
}
private void getSqlByEntity(StringBuilder sb, boolean filterNull, List<Object> entityList) {
for (Object obj : entityList) {
Assert.isTrue(tableList.contain(obj.getClass()), "更新的实体不是主表或关联表 <%>", obj.getClass().getSimpleName());
TableInfo tableInfo = TableHelper.getAssert(obj.getClass());
for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
continue;
}
Object val;
try {
Field field = AdapterHelper.getAdapter().mpjGetField(fieldInfo, () -> {
Field field1 = ReflectionKit.getFieldMap(obj.getClass()).get(fieldInfo.getProperty());
field1.setAccessible(true);
return field1;
});
val = field.get(obj);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
if (filterNull && Objects.isNull(val)) {
continue;
}
sb.append(tableList.getPrefixByClass(obj.getClass())).append(Constants.DOT)
.append(fieldInfo.getColumn()).append(Constants.EQUALS).append(formatParam(null, val))
.append(StringPool.COMMA);
}
}
}
@Override
public void clear() {
super.clear();
sqlSetStr.toNull();
if (CollectionUtils.isNotEmpty(sqlSet)) {
sqlSet.clear();
}
if (CollectionUtils.isNotEmpty(updateSet)) {
updateSet.clear();
}
if (CollectionUtils.isNotEmpty(updateEntity)) {
updateEntity.clear();
}
if (CollectionUtils.isNotEmpty(updateEntityNull)) {
updateEntityNull.clear();
}
}
@Data
@AllArgsConstructor
public static class UpdateSet {
private KProperty<?> column;
private Object value;
private String mapping;
private boolean incOrDnc;
private String cal;
}
}

View File

@ -0,0 +1,360 @@
package com.github.yulichang.extension.kt.interfaces;
import kotlin.reflect.KProperty;
import java.io.Serializable;
import java.util.Map;
/**
* 将原来的泛型R改成KProperty<?>
* <p>
* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare}
*/
@SuppressWarnings("unused")
public interface Compare<Children> extends Serializable {
default Children allEq(Map<KProperty<?>, ?> params) {
return allEq(params, true);
}
default Children allEq(Map<KProperty<?>, ?> params, boolean null2IsNull) {
return allEq(true, params, null2IsNull);
}
/**
* map 所有非空属性等于 =
*
* @param condition 执行条件
* @param params map 类型的参数, key 是字段名, value 是字段值
* @param null2IsNull 是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段\
* @return children
*/
Children allEq(boolean condition, Map<KProperty<?>, ?> params, boolean null2IsNull);
default Children eq(KProperty<?> column, Object val) {
return eq(true, null, column, val);
}
default Children eq(String alias, KProperty<?> column, Object val) {
return eq(true, alias, column, val);
}
default Children eq(boolean condition, KProperty<?> column, Object val) {
return eq(condition, null, column, val);
}
/**
* 等于 =
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children eq(boolean condition, String alias, KProperty<?> column, Object val);
default Children ne(KProperty<?> column, Object val) {
return ne(true, null, column, val);
}
default Children ne(String alias, KProperty<?> column, Object val) {
return ne(true, alias, column, val);
}
default Children ne(boolean condition, KProperty<?> column, Object val) {
return ne(condition, null, column, val);
}
/**
* 不等于 &lt;&gt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children ne(boolean condition, String alias, KProperty<?> column, Object val);
default Children gt(KProperty<?> column, Object val) {
return gt(true, null, column, val);
}
default Children gt(String alias, KProperty<?> column, Object val) {
return gt(true, alias, column, val);
}
default Children gt(boolean condition, KProperty<?> column, Object val) {
return gt(condition, null, column, val);
}
/**
* 大于 &gt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children gt(boolean condition, String alias, KProperty<?> column, Object val);
default Children ge(KProperty<?> column, Object val) {
return ge(true, null, column, val);
}
default Children ge(String alias, KProperty<?> column, Object val) {
return ge(true, alias, column, val);
}
default Children ge(boolean condition, KProperty<?> column, Object val) {
return ge(condition, null, column, val);
}
/**
* 大于等于 &gt;=
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children ge(boolean condition, String alias, KProperty<?> column, Object val);
default Children lt(KProperty<?> column, Object val) {
return lt(true, null, column, val);
}
default Children lt(String alias, KProperty<?> column, Object val) {
return lt(true, alias, column, val);
}
default Children lt(boolean condition, KProperty<?> column, Object val) {
return lt(condition, null, column, val);
}
/**
* 小于 &lt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children lt(boolean condition, String alias, KProperty<?> column, Object val);
default Children le(KProperty<?> column, Object val) {
return le(true, null, column, val);
}
default Children le(String alias, KProperty<?> column, Object val) {
return le(true, alias, column, val);
}
default Children le(boolean condition, KProperty<?> column, Object val) {
return le(condition, null, column, val);
}
/**
* 小于等于 &lt;=
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children le(boolean condition, String alias, KProperty<?> column, Object val);
default Children between(KProperty<?> column, Object val1, Object val2) {
return between(true, null, column, val1, val2);
}
default Children between(String alias, KProperty<?> column, Object val1, Object val2) {
return between(true, alias, column, val1, val2);
}
default Children between(boolean condition, KProperty<?> column, Object val1, Object val2) {
return between(condition, null, column, val1, val2);
}
/**
* BETWEEN 值1 AND 值2
*
* @param condition 执行条件
* @param column 字段
* @param val1 值1
* @param val2 值2
* @return children
*/
Children between(boolean condition, String alias, KProperty<?> column, Object val1, Object val2);
default Children notBetween(KProperty<?> column, Object val1, Object val2) {
return notBetween(true, null, column, val1, val2);
}
default Children notBetween(String alias, KProperty<?> column, Object val1, Object val2) {
return notBetween(true, alias, column, val1, val2);
}
default Children notBetween(boolean condition, KProperty<?> column, Object val1, Object val2) {
return notBetween(condition, null, column, val1, val2);
}
/**
* NOT BETWEEN 值1 AND 值2
*
* @param condition 执行条件
* @param column 字段
* @param val1 值1
* @param val2 值2
* @return children
*/
Children notBetween(boolean condition, String alias, KProperty<?> column, Object val1, Object val2);
default Children like(KProperty<?> column, Object val) {
return like(true, null, column, val);
}
default Children like(String alisa, KProperty<?> column, Object val) {
return like(true, alisa, column, val);
}
default Children like(boolean condition, KProperty<?> column, Object val) {
return like(condition, null, column, val);
}
/**
* LIKE '%%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children like(boolean condition, String alias, KProperty<?> column, Object val);
default Children notLike(KProperty<?> column, Object val) {
return notLike(true, null, column, val);
}
default Children notLike(String alias, KProperty<?> column, Object val) {
return notLike(true, alias, column, val);
}
default Children notLike(boolean condition, KProperty<?> column, Object val) {
return notLike(condition, null, column, val);
}
/**
* NOT LIKE '%%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children notLike(boolean condition, String alias, KProperty<?> column, Object val);
default Children likeLeft(KProperty<?> column, Object val) {
return likeLeft(true, null, column, val);
}
default Children likeLeft(String alias, KProperty<?> column, Object val) {
return likeLeft(true, alias, column, val);
}
default Children likeLeft(boolean condition, KProperty<?> column, Object val) {
return likeLeft(condition, null, column, val);
}
/**
* LIKE '%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children likeLeft(boolean condition, String alias, KProperty<?> column, Object val);
default Children notLikeLeft(KProperty<?> column, Object val) {
return notLikeLeft(true, null, column, val);
}
default Children notLikeLeft(String alias, KProperty<?> column, Object val) {
return notLikeLeft(true, alias, column, val);
}
default Children notLikeLeft(boolean condition, KProperty<?> column, Object val) {
return notLikeLeft(condition, null, column, val);
}
/**
* LIKE '%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children notLikeLeft(boolean condition, String alias, KProperty<?> column, Object val);
default Children likeRight(KProperty<?> column, Object val) {
return likeRight(true, null, column, val);
}
default Children likeRight(String alias, KProperty<?> column, Object val) {
return likeRight(true, alias, column, val);
}
default Children likeRight(boolean condition, KProperty<?> column, Object val) {
return likeRight(condition, null, column, val);
}
/**
* LIKE '%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children likeRight(boolean condition, String alias, KProperty<?> column, Object val);
default Children notLikeRight(KProperty<?> column, Object val) {
return notLikeRight(true, null, column, val);
}
default Children notLikeRight(String alias, KProperty<?> column, Object val) {
return notLikeRight(true, alias, column, val);
}
default Children notLikeRight(boolean condition, KProperty<?> column, Object val) {
return notLikeRight(condition, null, column, val);
}
/**
* LIKE '%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children notLikeRight(boolean condition, String alias, KProperty<?> column, Object val);
}

View File

@ -0,0 +1,115 @@
package com.github.yulichang.extension.kt.interfaces;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import kotlin.reflect.KProperty;
import java.util.function.BiPredicate;
/**
* IfExists
*
* @author yulichang
* @since 1.4.9
*/
@SuppressWarnings("unused")
public interface CompareIfExists<Children> extends Compare<Children> {
BiPredicate<Object, IfExistsSqlKeyWordEnum> getIfExists();
default Children eqIfExists(KProperty<?> column, Object val) {
return eq(getIfExists().test(val, IfExistsSqlKeyWordEnum.EQ), null, column, val);
}
default Children eqIfExists(String alias, KProperty<?> column, Object val) {
return eq(getIfExists().test(val, IfExistsSqlKeyWordEnum.EQ), alias, column, val);
}
default Children neIfExists(KProperty<?> column, Object val) {
return ne(getIfExists().test(val, IfExistsSqlKeyWordEnum.NE), null, column, val);
}
default Children neIfExists(String alias, KProperty<?> column, Object val) {
return ne(getIfExists().test(val, IfExistsSqlKeyWordEnum.NE), alias, column, val);
}
default Children gtIfExists(KProperty<?> column, Object val) {
return gt(getIfExists().test(val, IfExistsSqlKeyWordEnum.GT), null, column, val);
}
default Children gtIfExists(String alias, KProperty<?> column, Object val) {
return gt(getIfExists().test(val, IfExistsSqlKeyWordEnum.GT), alias, column, val);
}
default Children geIfExists(KProperty<?> column, Object val) {
return ge(getIfExists().test(val, IfExistsSqlKeyWordEnum.GE), null, column, val);
}
default Children geIfExists(String alias, KProperty<?> column, Object val) {
return ge(getIfExists().test(val, IfExistsSqlKeyWordEnum.GE), alias, column, val);
}
default Children ltIfExists(KProperty<?> column, Object val) {
return lt(getIfExists().test(val, IfExistsSqlKeyWordEnum.LT), null, column, val);
}
default Children ltIfExists(String alias, KProperty<?> column, Object val) {
return lt(getIfExists().test(val, IfExistsSqlKeyWordEnum.LT), alias, column, val);
}
default Children leIfExists(KProperty<?> column, Object val) {
return le(getIfExists().test(val, IfExistsSqlKeyWordEnum.LE), null, column, val);
}
default Children leIfExists(String alias, KProperty<?> column, Object val) {
return le(getIfExists().test(val, IfExistsSqlKeyWordEnum.LE), alias, column, val);
}
default Children likeIfExists(KProperty<?> column, Object val) {
return like(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE), null, column, val);
}
default Children likeIfExists(String alisa, KProperty<?> column, Object val) {
return like(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE), alisa, column, val);
}
default Children notLikeIfExists(KProperty<?> column, Object val) {
return notLike(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE), null, column, val);
}
default Children notLikeIfExists(String alias, KProperty<?> column, Object val) {
return notLike(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE), alias, column, val);
}
default Children likeLeftIfExists(KProperty<?> column, Object val) {
return likeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_LEFT), null, column, val);
}
default Children likeLeftIfExists(String alias, KProperty<?> column, Object val) {
return likeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_LEFT), alias, column, val);
}
default Children notLikeLeftIfExists(KProperty<?> column, Object val) {
return notLikeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_LEFT), null, column, val);
}
default Children notLikeLeftIfExists(String alias, KProperty<?> column, Object val) {
return notLikeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_LEFT), alias, column, val);
}
default Children likeRightIfExists(KProperty<?> column, Object val) {
return likeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_RIGHT), null, column, val);
}
default Children likeRightIfExists(String alias, KProperty<?> column, Object val) {
return likeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_RIGHT), alias, column, val);
}
default Children notLikeRightIfExists(KProperty<?> column, Object val) {
return notLikeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_RIGHT), null, column, val);
}
default Children notLikeRightIfExists(String alias, KProperty<?> column, Object val) {
return notLikeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_RIGHT), alias, column, val);
}
}

View File

@ -0,0 +1,491 @@
package com.github.yulichang.extension.kt.interfaces;
import kotlin.reflect.KProperty;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
/**
* 将原来的泛型R改成KProperty<?>
* <p>
* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Func}
*/
@SuppressWarnings("unused")
public interface Func<Children> extends Serializable {
default Children isNull(KProperty<?> column) {
return isNull(true, null, column);
}
default Children isNull(String alias, KProperty<?> column) {
return isNull(true, alias, column);
}
default Children isNull(boolean condition, KProperty<?> column) {
return isNull(condition, null, column);
}
/**
* 字段 IS NULL
* <p>: isNull("name")</p>
*
* @param condition 执行条件
* @param column 字段
* @return children
*/
Children isNull(boolean condition, String alias, KProperty<?> column);
default Children isNotNull(KProperty<?> column) {
return isNotNull(true, null, column);
}
default Children isNotNull(String alias, KProperty<?> column) {
return isNotNull(true, alias, column);
}
default Children isNotNull(boolean condition, KProperty<?> column) {
return isNotNull(condition, null, column);
}
/**
* 字段 IS NOT NULL
* <p>: isNotNull("name")</p>
*
* @param condition 执行条件
* @param column 字段
* @return children
*/
Children isNotNull(boolean condition, String alias, KProperty<?> column);
default Children in(KProperty<?> column, Collection<?> coll) {
return in(true, null, column, coll);
}
default Children in(String alias, KProperty<?> column, Collection<?> coll) {
return in(true, alias, column, coll);
}
default Children in(boolean condition, KProperty<?> column, Collection<?> coll) {
return in(condition, null, column, coll);
}
/**
* 字段 IN (value.get(0), value.get(1), ...)
* <p>: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
*
* <li> 注意集合为空若存在逻辑错误请在 condition 条件中判断 </li>
* <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
*
* @param condition 执行条件
* @param column 字段
* @param coll 数据集合
* @return children
*/
Children in(boolean condition, String alias, KProperty<?> column, Collection<?> coll);
default Children in(KProperty<?> column, Object... values) {
return in(true, null, column, values);
}
default Children in(String alias, KProperty<?> column, Object... values) {
return in(true, alias, column, values);
}
default Children in(boolean condition, KProperty<?> column, Object... values) {
return in(condition, null, column, values);
}
/**
* 字段 IN (v0, v1, ...)
* <p>: in("id", 1, 2, 3, 4, 5)</p>
*
* <li> 注意数组为空若存在逻辑错误请在 condition 条件中判断 </li>
* <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
*
* @param condition 执行条件
* @param column 字段
* @param values 数据数组
* @return children
*/
Children in(boolean condition, String alias, KProperty<?> column, Object... values);
default Children notIn(KProperty<?> column, Collection<?> coll) {
return notIn(true, null, column, coll);
}
default Children notIn(String alias, KProperty<?> column, Collection<?> coll) {
return notIn(true, alias, column, coll);
}
default Children notIn(boolean condition, KProperty<?> column, Collection<?> coll) {
return notIn(condition, null, column, coll);
}
/**
* 字段 NOT IN (value.get(0), value.get(1), ...)
* <p>: notIn("id", Arrays.asList(1, 2, 3, 4, 5))</p>
*
* @param condition 执行条件
* @param column 字段
* @param coll 数据集合
* @return children
*/
Children notIn(boolean condition, String alias, KProperty<?> column, Collection<?> coll);
default Children notIn(KProperty<?> column, Object... value) {
return notIn(true, null, column, value);
}
default Children notIn(String alias, KProperty<?> column, Object... value) {
return notIn(true, alias, column, value);
}
default Children notIn(boolean condition, KProperty<?> column, Object... values) {
return notIn(condition, null, column, values);
}
/**
* 字段 NOT IN (v0, v1, ...)
* <p>: notIn("id", 1, 2, 3, 4, 5)</p>
*
* @param condition 执行条件
* @param column 字段
* @param values 数据数组
* @return children
*/
Children notIn(boolean condition, String alias, KProperty<?> column, Object... values);
default Children inSql(KProperty<?> column, String inValue) {
return inSql(true, null, column, inValue);
}
default Children inSql(String alias, KProperty<?> column, String inValue) {
return inSql(true, alias, column, inValue);
}
default Children inSql(boolean condition, KProperty<?> column, String inValue) {
return inSql(condition, null, column, inValue);
}
/**
* 字段 IN ( sql语句 )
* <p>!! sql 注入方式的 in 方法 !!</p>
* <p>例1: inSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例2: inSql("id", "select id from table where id &lt; 3")</p>
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children inSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children notInSql(KProperty<?> column, String inValue) {
return notInSql(true, null, column, inValue);
}
default Children notInSql(String alias, KProperty<?> column, String inValue) {
return notInSql(true, alias, column, inValue);
}
default Children notInSql(boolean condition, KProperty<?> column, String inValue) {
return notInSql(condition, null, column, inValue);
}
/**
* 字段 NOT IN ( sql语句 )
* <p>!! sql 注入方式的 not in 方法 !!</p>
* <p>例1: notInSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例2: notInSql("id", "select id from table where id &lt; 3")</p>
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句 ---&gt; 1,2,3,4,5,6 或者 select id from table where id &lt; 3
* @return children
*/
Children notInSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children gtSql(KProperty<?> column, String inValue) {
return gtSql(true, null, column, inValue);
}
default Children gtSql(String alias, KProperty<?> column, String inValue) {
return gtSql(true, alias, column, inValue);
}
default Children gtSql(boolean condition, KProperty<?> column, String inValue) {
return gtSql(condition, null, column, inValue);
}
/**
* 字段 &gt; ( sql语句 )
* <p>例1: gtSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: gtSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children gtSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children geSql(KProperty<?> column, String inValue) {
return geSql(true, null, column, inValue);
}
default Children geSql(String alias, KProperty<?> column, String inValue) {
return geSql(true, alias, column, inValue);
}
default Children geSql(boolean condition, KProperty<?> column, String inValue) {
return geSql(condition, null, column, inValue);
}
/**
* 字段 >= ( sql语句 )
* <p>例1: geSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: geSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children geSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children ltSql(KProperty<?> column, String inValue) {
return ltSql(true, null, column, inValue);
}
default Children ltSql(String alias, KProperty<?> column, String inValue) {
return ltSql(true, alias, column, inValue);
}
default Children ltSql(boolean condition, KProperty<?> column, String inValue) {
return ltSql(condition, null, column, inValue);
}
/**
* 字段 &lt; ( sql语句 )
* <p>例1: ltSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: ltSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children ltSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children leSql(KProperty<?> column, String inValue) {
return leSql(true, null, column, inValue);
}
default Children leSql(String alias, KProperty<?> column, String inValue) {
return leSql(true, alias, column, inValue);
}
default Children leSql(boolean condition, KProperty<?> column, String inValue) {
return leSql(condition, null, column, inValue);
}
/**
* 字段 <= ( sql语句 )
* <p>例1: leSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: leSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children leSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children groupBy(List<KProperty<?>> column) {
return groupBy(true, null, column);
}
default Children groupBy(String alias, List<KProperty<?>> column) {
return groupBy(true, alias, column);
}
default Children groupBy(boolean condition, List<KProperty<?>> columns) {
return groupBy(condition, null, columns);
}
Children groupBy(boolean condition, String alias, List<KProperty<?>> columns);
default Children groupBy(KProperty<?>... columns) {
return groupBy(true, null, columns);
}
default Children groupBy(String alias, KProperty<?>... columns) {
return groupBy(true, alias, columns);
}
default Children groupBy(boolean condition, KProperty<?>... columns) {
return groupBy(condition, null, columns);
}
/**
* 分组GROUP BY 字段, ...
* <p>: groupBy("id", "name")</p>
*
* @param condition 执行条件
* @param columns 字段数组
* @return children
*/
Children groupBy(boolean condition, String alias, KProperty<?>... columns);
default Children orderByAsc(KProperty<?> column) {
return orderByAsc(true, (String) null, column);
}
default Children orderByAsc(String alias, KProperty<?> column) {
return orderByAsc(true, alias, column);
}
default Children orderByAsc(List<KProperty<?>> columns) {
return orderByAsc(true, null, columns);
}
default Children orderByAsc(String alias, List<KProperty<?>> columns) {
return orderByAsc(true, alias, columns);
}
default Children orderByAsc(boolean condition, List<KProperty<?>> columns) {
return orderByAsc(condition, null, columns);
}
Children orderByAsc(boolean condition, String alias, List<KProperty<?>> columns);
default Children orderByAsc(KProperty<?>... columns) {
return orderByAsc(true, null, columns);
}
default Children orderByAsc(String alias, KProperty<?>... columns) {
return orderByAsc(true, alias, columns);
}
/**
* 排序ORDER BY 字段, ... ASC
* <p>: orderByAsc("id", "name")</p>
*
* @param condition 执行条件
* @param columns 字段数组
* @return children
*/
default Children orderByAsc(boolean condition, KProperty<?>... columns) {
return orderBy(condition, true, null, columns);
}
default Children orderByAsc(boolean condition, String alias, KProperty<?>... columns) {
return orderBy(condition, true, alias, columns);
}
default Children orderByDesc(List<KProperty<?>> columns) {
return orderByDesc(true, null, columns);
}
default Children orderByDesc(String alias, List<KProperty<?>> columns) {
return orderByDesc(true, alias, columns);
}
default Children orderByDesc(boolean condition, List<KProperty<?>> columns) {
return orderByDesc(condition, null, columns);
}
Children orderByDesc(boolean condition, String alias, List<KProperty<?>> columns);
default Children orderByDesc(KProperty<?>... columns) {
return orderByDesc(true, null, columns);
}
default Children orderByDesc(String alias, KProperty<?>... columns) {
return orderByDesc(true, alias, columns);
}
/**
* 排序ORDER BY 字段, ... DESC
* <p>: orderByDesc("id", "name")</p>
*
* @param condition 执行条件
* @param columns 字段数组
* @return children
*/
default Children orderByDesc(boolean condition, KProperty<?>... columns) {
return orderBy(condition, false, null, columns);
}
default Children orderByDesc(boolean condition, String alias, KProperty<?>... columns) {
return orderBy(condition, false, alias, columns);
}
default Children orderBy(boolean condition, boolean isAsc, KProperty<?>... columns) {
return orderBy(condition, isAsc, null, columns);
}
/**
* 排序ORDER BY 字段, ...
* <p>: orderBy(true, "id", "name")</p>
*
* @param condition 执行条件
* @param isAsc 是否是 ASC 排序
* @param columns 字段数组
* @return children
*/
Children orderBy(boolean condition, boolean isAsc, String alias, KProperty<?>... columns);
default Children having(String sqlHaving, Object... params) {
return having(true, sqlHaving, params);
}
/**
* HAVING ( sql语句 )
* <p>例1: having("sum(age) &gt; 10")</p>
* <p>例2: having("sum(age) &gt; {0}", 10)</p>
*
* @param condition 执行条件
* @param sqlHaving sql 语句
* @param params 参数数组
* @return children
*/
Children having(boolean condition, String sqlHaving, Object... params);
default Children func(Consumer<Children> consumer) {
return func(true, consumer);
}
/**
* 消费函数
*
* @param consumer 消费函数
* @return children
* @since 3.3.1
*/
default Children func(boolean condition, Consumer<Children> consumer) {
return func(condition, consumer, null);
}
Children func(boolean condition, Consumer<Children> consumer, Consumer<Children> consumerElse);
}

View File

@ -0,0 +1,250 @@
package com.github.yulichang.extension.kt.interfaces;
import kotlin.reflect.KProperty;
import java.io.Serializable;
/**
* 将原来的泛型R改成KProperty<?>, Object改为KProperty<?>
* 以及移除不会在ON语句中出现的条件 比如like相关 保留原来的like 只是不太可能会出现 on a.id like b.id 所以不会支持这种写法
* <p>
* {@link com.baomidou.mybatisplus.core.conditions.interfaces.Compare}
*
* @since 1.4.6
*/
@SuppressWarnings("unused")
public interface OnCompare<Children> extends Serializable {
default Children eq(KProperty<?> column, KProperty<?> val) {
return eq(true, null, column, null, val);
}
default Children eq(String alias, KProperty<?> column, KProperty<?> val) {
return eq(true, alias, column, null, val);
}
default Children eq(KProperty<?> column, String rightAlias, KProperty<?> val) {
return eq(true, null, column, rightAlias, val);
}
default Children eq(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return eq(true, alias, column, rightAlias, val);
}
default Children eq(boolean condition, KProperty<?> column, KProperty<?> val) {
return eq(condition, null, column, null, val);
}
default Children eq(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return eq(condition, alias, column, null, val);
}
default Children eq(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return eq(condition, null, column, rightAlias, val);
}
/**
* 等于 =
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children eq(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
default Children ne(KProperty<?> column, KProperty<?> val) {
return ne(true, null, column, null, val);
}
default Children ne(String alias, KProperty<?> column, KProperty<?> val) {
return ne(true, alias, column, null, val);
}
default Children ne(KProperty<?> column, String rightAlias, KProperty<?> val) {
return ne(true, null, column, rightAlias, val);
}
default Children ne(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ne(true, alias, column, rightAlias, val);
}
default Children ne(boolean condition, KProperty<?> column, KProperty<?> val) {
return ne(condition, null, column, null, val);
}
default Children ne(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return ne(condition, alias, column, null, val);
}
default Children ne(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ne(condition, null, column, rightAlias, val);
}
/**
* 不等于 &lt;&gt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children ne(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
default Children gt(KProperty<?> column, KProperty<?> val) {
return gt(true, null, column, null, val);
}
default Children gt(String alias, KProperty<?> column, KProperty<?> val) {
return gt(true, alias, column, null, val);
}
default Children gt(KProperty<?> column, String rightAlias, KProperty<?> val) {
return gt(true, null, column, rightAlias, val);
}
default Children gt(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return gt(true, alias, column, rightAlias, val);
}
default Children gt(boolean condition, KProperty<?> column, KProperty<?> val) {
return gt(condition, null, column, null, val);
}
default Children gt(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return gt(condition, alias, column, null, val);
}
default Children gt(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return gt(condition, null, column, rightAlias, val);
}
/**
* 大于 &gt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children gt(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
default Children ge(KProperty<?> column, KProperty<?> val) {
return ge(true, null, column, null, val);
}
default Children ge(String alias, KProperty<?> column, KProperty<?> val) {
return ge(true, alias, column, null, val);
}
default Children ge(KProperty<?> column, String rightAlias, KProperty<?> val) {
return ge(true, null, column, rightAlias, val);
}
default Children ge(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ge(true, alias, column, rightAlias, val);
}
default Children ge(boolean condition, KProperty<?> column, KProperty<?> val) {
return ge(condition, null, column, null, val);
}
default Children ge(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return ge(condition, alias, column, null, val);
}
default Children ge(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ge(condition, null, column, rightAlias, val);
}
/**
* 大于等于 &gt;=
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children ge(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
default Children lt(KProperty<?> column, KProperty<?> val) {
return lt(true, null, column, null, val);
}
default Children lt(String alias, KProperty<?> column, KProperty<?> val) {
return lt(true, alias, column, null, val);
}
default Children lt(KProperty<?> column, String rightAlias, KProperty<?> val) {
return lt(true, null, column, rightAlias, val);
}
default Children lt(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return lt(true, alias, column, rightAlias, val);
}
default Children lt(boolean condition, KProperty<?> column, KProperty<?> val) {
return lt(condition, null, column, null, val);
}
default Children lt(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return lt(condition, alias, column, null, val);
}
default Children lt(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return lt(condition, null, column, rightAlias, val);
}
/**
* 小于 &lt;
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children lt(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
default Children le(KProperty<?> column, KProperty<?> val) {
return le(true, null, column, null, val);
}
default Children le(String alias, KProperty<?> column, KProperty<?> val) {
return le(true, alias, column, null, val);
}
default Children le(KProperty<?> column, String rightAlias, KProperty<?> val) {
return le(true, null, column, rightAlias, val);
}
default Children le(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return le(true, alias, column, rightAlias, val);
}
default Children le(boolean condition, KProperty<?> column, KProperty<?> val) {
return le(condition, null, column, null, val);
}
default Children le(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return le(condition, alias, column, null, val);
}
default Children le(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return le(condition, null, column, rightAlias, val);
}
/**
* 小于等于 &lt;=
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children le(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
}

View File

@ -0,0 +1,324 @@
package com.github.yulichang.extension.kt.interfaces;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.github.yulichang.extension.kt.segments.FuncArgs;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
import com.github.yulichang.wrapper.enums.DefaultFuncEnum;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.segments.*;
import kotlin.reflect.KProperty;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* 参考 {@link com.baomidou.mybatisplus.core.conditions.query.Query}
*
* @author yulichang
*/
@SuppressWarnings({"unused", "DuplicatedCode"})
public interface Query<Children> extends Serializable {
List<Select> getSelectColum();
Children getChildren();
Integer getIndex();
boolean isHasAlias();
String getAlias();
/**
* 过滤查询的字段信息(主键除外!)
* 推荐使用 selectFilter(Class, Predicate) 含主键
*
* @param predicate 过滤方式
* @return children
* @see Query#selectFilter(Class, Predicate)
*/
@Deprecated
default Children select(Class<?> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableHelper.getAssert(entityClass);
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(entityClass);
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
i -> getSelectColum().add(new SelectNormal(cacheMap.get(i.getProperty()), getIndex(), isHasAlias(), getAlias())));
return getChildren();
}
/**
* 过滤查询的字段信息
* <p>例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))</p>
* <p>例2: 只要 java 字段属性是 CharSequence 类型的 -> select(TableFieldInfo::isCharSequence)</p>
* <p>例3: 只要 java 字段没有填充策略的 -> select(i -> i.getFieldFill() == FieldFill.DEFAULT)</p>
* <p>例4: 要全部字段 -> select(i -> true)</p>
* <p>例5: 只要主键字段 -> select(i -> false)</p>
*
* @param predicate 过滤方式
* @return children
*/
default Children selectFilter(Class<?> entityClass, Predicate<SelectCache> predicate) {
TableInfo info = TableHelper.getAssert(entityClass);
List<SelectCache> cacheList = ColumnCache.getListField(entityClass);
cacheList.stream().filter(predicate).collect(Collectors.toList()).forEach(
i -> getSelectColum().add(new SelectNormal(i, getIndex(), isHasAlias(), getAlias())));
return getChildren();
}
Children select(KProperty<?>... columns);
/**
* String 查询
*
* @param columns
*/
default Children select(String... columns) {
getSelectColum().addAll(Arrays.stream(columns).map(i ->
new SelectString(i, null)).collect(Collectors.toList()));
return getChildren();
}
/**
* String 查询
*
* @param column
*/
default Children selectAs(String column, KProperty<?> alias) {
getSelectColum().add(new SelectString(column + Constant.AS + alias.getName(), alias.getName()));
return getChildren();
}
/**
* String 查询
*
* @param column
*/
default Children selectAs(String index, KProperty<?> column, KProperty<?> alias) {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(KtUtils.ref(column));
SelectCache cache = cacheMap.get(column.getName());
getSelectColum().add(new SelectString(
index + Constants.DOT + cache.getColumn() + Constant.AS + alias.getName(), alias.getName()));
return getChildren();
}
/**
* 说明
* 比如我们需要查询用户表有10个字段然而我们只需要3个就够了用mybatis-plus提供的select<p />
* 需要一个属性一个属性填入很不优雅现在我们可以用selectAsClass(UserDO.class, UserVo.class)<p />
* 即可按所需的UserVo返回前提是UserVo.class中的属性必须是UserDO.class中存在的
*
* @param source 数据源实体类
* @param tag 目标类
* @return children
*/
default Children selectAsClass(Class<?> source, Class<?> tag) {
Map<String, SelectCache> normalMap = ColumnCache.getMapField(source);
List<FieldCache> fieldList = MPJReflectionKit.getFieldList(tag);
for (FieldCache cache : fieldList) {
if (normalMap.containsKey(cache.getField().getName())) {
SelectCache selectCache = normalMap.get(cache.getField().getName());
getSelectColum().add(new SelectNormal(selectCache, getIndex(), isHasAlias(), getAlias()));
}
}
return getChildren();
}
/**
* ignore
*/
default Children selectAs(KProperty<?> column, KProperty<?> alias) {
return selectAs(column, alias.getName());
}
/**
* 别名查询
*/
default Children selectAs(KProperty<?> column, String alias) {
Class<?> aClass = KtUtils.ref(column);
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(aClass);
getSelectColum().add(new SelectAlias(cacheMap.get(column.getName()), getIndex(), alias, isHasAlias(), getAlias()));
return getChildren();
}
/**
* 查询实体类全部字段
*/
default Children selectAll(Class<?> clazz) {
getSelectColum().addAll(ColumnCache.getListField(clazz).stream().map(i ->
new SelectNormal(i, getIndex(), isHasAlias(), getAlias())).collect(Collectors.toList()));
return getChildren();
}
/**
* 查询实体类全部字段
*/
default Children selectAll(Class<?> clazz, String prefix) {
getSelectColum().addAll(ColumnCache.getListField(clazz).stream().map(i ->
new SelectNormal(i, getIndex(), true, prefix)).collect(Collectors.toList()));
return getChildren();
}
/**
* select sql 片段
*/
String getSqlSelect();
/**
* 聚合函数查询
* <p>
* wrapper.selectFunc(() -> "COUNT(%s)", "t.id", "total");
* <p>
* lambda
* wrapper.selectFunc(() -> "COUNT(%s)", UserDO::getId, UserDTO::getTotal);
*
* @param funcEnum 函数枚举 {@link DefaultFuncEnum}
* @param column 函数作用的字段
* @param alias 别名
*/
default Children selectFunc(BaseFuncEnum funcEnum, Object column, String alias) {
getSelectColum().add(new SelectFunc(alias, getIndex(), funcEnum, column.toString(), isHasAlias(), getAlias()));
return getChildren();
}
default Children selectFunc(BaseFuncEnum funcEnum, KProperty<?> column, String alias) {
Class<?> aClass = KtUtils.ref(column);
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(aClass);
getSelectColum().add(new SelectFunc(cacheMap.get(column.getName()), getIndex(), alias, funcEnum, isHasAlias(), getAlias()));
return getChildren();
}
default Children selectFunc(BaseFuncEnum funcEnum, KProperty<?> column, KProperty<?> alias) {
return selectFunc(funcEnum, column, alias.getName());
}
default Children selectFunc(BaseFuncEnum funcEnum, KProperty<?> column) {
return selectFunc(funcEnum, column, column);
}
default Children selectFunc(BaseFuncEnum funcEnum, Object column, KProperty<?> alias) {
return selectFunc(funcEnum, column, alias.getName());
}
Children selectFunc(String sql, MFunction<FuncArgs> column, String alias);
default Children selectFunc(String sql, MFunction<FuncArgs> column, KProperty<?> alias) {
return selectFunc(sql, column, alias.getName());
}
/* 默认聚合函数扩展 */
/**
* SUM()
*/
default Children selectSum(KProperty<?> column) {
return selectFunc(DefaultFuncEnum.SUM, column);
}
default Children selectSum(KProperty<?> column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.SUM, column, alias);
}
default Children selectSum(KProperty<?> column, String alias) {
return selectFunc(DefaultFuncEnum.SUM, column, alias);
}
/**
* COUNT()
*/
default Children selectCount(KProperty<?> column) {
return selectFunc(DefaultFuncEnum.COUNT, column);
}
default Children selectCount(Object column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
default Children selectCount(Object column, String alias) {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
default Children selectCount(KProperty<?> column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
default Children selectCount(KProperty<?> column, String alias) {
return selectFunc(DefaultFuncEnum.COUNT, column, alias);
}
/**
* MAX()
*/
default Children selectMax(KProperty<?> column) {
return selectFunc(DefaultFuncEnum.MAX, column);
}
default Children selectMax(KProperty<?> column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.MAX, column, alias);
}
default Children selectMax(KProperty<?> column, String alias) {
return selectFunc(DefaultFuncEnum.MAX, column, alias);
}
/**
* MIN()
*/
default Children selectMin(KProperty<?> column) {
return selectFunc(DefaultFuncEnum.MIN, column);
}
default Children selectMin(KProperty<?> column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.MIN, column, alias);
}
default Children selectMin(KProperty<?> column, String alias) {
return selectFunc(DefaultFuncEnum.MIN, column, alias);
}
/**
* MIN()
*/
default Children selectAvg(KProperty<?> column) {
return selectFunc(DefaultFuncEnum.AVG, column);
}
default Children selectAvg(KProperty<?> column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.AVG, column, alias);
}
default Children selectAvg(KProperty<?> column, String alias) {
return selectFunc(DefaultFuncEnum.AVG, column, alias);
}
/**
* LEN()
*/
default Children selectLen(KProperty<?> column) {
return selectFunc(DefaultFuncEnum.LEN, column);
}
default Children selectLen(KProperty<?> column, KProperty<?> alias) {
return selectFunc(DefaultFuncEnum.LEN, column, alias);
}
default Children selectLen(KProperty<?> column, String alias) {
return selectFunc(DefaultFuncEnum.LEN, column, alias);
}
}

View File

@ -0,0 +1,452 @@
package com.github.yulichang.extension.kt.interfaces;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.extension.kt.KtAbstractLambdaWrapper;
import com.github.yulichang.query.interfaces.StringJoin;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.wrapper.interfaces.MFunction;
import kotlin.reflect.KProperty;
import java.util.function.BiConsumer;
/**
* @author yulichang
*/
@SuppressWarnings("unused")
public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, StringJoin<Children, Entity> {
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right) {
return join(Constant.LEFT_JOIN, clazz, left, right);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.LEFT_JOIN, clazz, left, rightAlias, right);
}
/**
* left join 多条件
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param function 条件`
*/
default Children leftJoin(Class<?> clazz, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.LEFT_JOIN, clazz, function);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.LEFT_JOIN, clazz, left, right, ext);
}
/**
* left join 多条件
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param consumer 条件
*/
default Children leftJoin(Class<?> clazz, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.LEFT_JOIN, clazz, consumer);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right) {
return join(Constant.LEFT_JOIN, clazz, alias, left, right);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.LEFT_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* left join 多条件
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param function 条件
*/
default Children leftJoin(Class<?> clazz, String alias, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.LEFT_JOIN, clazz, alias, function);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.LEFT_JOIN, clazz, alias, left, right, ext);
}
/**
* left join 多条件
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param consumer 条件
*/
default Children leftJoin(Class<?> clazz, String alias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.LEFT_JOIN, clazz, alias, consumer);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right) {
return join(Constant.RIGHT_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.RIGHT_JOIN, clazz, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.RIGHT_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.RIGHT_JOIN, clazz, left, right, ext);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.RIGHT_JOIN, clazz, consumer);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right) {
return join(Constant.RIGHT_JOIN, clazz, alias, left, right);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.RIGHT_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, String alias, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.RIGHT_JOIN, clazz, alias, function);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.RIGHT_JOIN, clazz, alias, left, right, ext);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, String alias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.RIGHT_JOIN, clazz, alias, consumer);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right) {
return join(Constant.INNER_JOIN, clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.INNER_JOIN, clazz, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.INNER_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.INNER_JOIN, clazz, left, right, ext);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.INNER_JOIN, clazz, consumer);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right) {
return join(Constant.INNER_JOIN, clazz, alias, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.INNER_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, String alias, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.INNER_JOIN, clazz, alias, function);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.INNER_JOIN, clazz, alias, left, right, ext);
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, String alias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.INNER_JOIN, clazz, alias, consumer);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right) {
return join(Constant.FULL_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.FULL_JOIN, clazz, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.FULL_JOIN, clazz, function);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.FULL_JOIN, clazz, left, right, ext);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.FULL_JOIN, clazz, consumer);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right) {
return join(Constant.FULL_JOIN, clazz, alias, left, right);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.FULL_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, String alias, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(Constant.FULL_JOIN, clazz, alias, function);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(Constant.FULL_JOIN, clazz, alias, left, right, ext);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, String alias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(Constant.FULL_JOIN, clazz, alias, consumer);
}
/**
* 自定义连表关键词
* 调用此方法 keyword 前后需要带空格 比如 " LEFT JOIN " " RIGHT JOIN "
* <p>
* 查询基类 可以直接调用此方法实现以上所有功能
*
* @param keyWord 连表关键字
* @param clazz 连表实体类
* @param left 关联条件
* @param right 扩展 用于关联表的 select where
*/
default Children join(String keyWord, Class<?> clazz, KProperty<?> left, KProperty<?> right) {
return join(keyWord, clazz, on -> on.eq(left, right));
}
/**
* ignore
*/
default Children join(String keyWord, Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(keyWord, clazz, on -> on.eq(left, rightAlias, right));
}
/**
* 自定义连表关键词
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param function 条件
*/
default Children join(String keyWord, Class<?> clazz, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(keyWord, clazz, (on, e) -> function.apply(on));
}
/**
* 自定义连表关键词
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children join(String keyWord, Class<?> clazz, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(keyWord, clazz, (on, e) -> {
on.eq(left, right);
ext.apply(e);
});
}
/**
* 自定义连表关键词
* 调用此方法 keyword 前后需要带空格 比如 " LEFT JOIN " " RIGHT JOIN "
* <p>
* 查询基类 可以直接调用此方法实现以上所有功能
*
* @param keyWord 连表关键字
* @param clazz 连表实体类
* @param left 关联条件
* @param right 扩展 用于关联表的 select where
*/
default <T, X> Children join(String keyWord, Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right) {
return join(keyWord, clazz, alias, on -> on.eq(left, right));
}
/**
* ignore
*/
default <T, X> Children join(String keyWord, Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(keyWord, clazz, alias, on -> on.eq(left, rightAlias, right));
}
/**
* 自定义连表关键词
* <p>
* leftJoin(UserDO.class, on -> on.eq(UserDO::getId,UserAddressDO::getUserId).le().gt()...)
*
* @param clazz 关联实体类
* @param function 条件
*/
default Children join(String keyWord, Class<?> clazz, String alias, MFunction<KtAbstractLambdaWrapper<?, ?>> function) {
return join(keyWord, clazz, alias, (on, e) -> function.apply(on));
}
/**
* 自定义连表关键词
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children join(String keyWord, Class<?> clazz, String alias, KProperty<?> left, KProperty<?> right, MFunction<Children> ext) {
return join(keyWord, clazz, alias, (on, e) -> {
on.eq(left, right);
ext.apply(e);
});
}
/**
* 内部使用, 不建议直接调用
*/
default Children join(String keyWord, Class<?> clazz, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
return join(keyWord, clazz, null, consumer);
}
/**
* 内部使用, 不建议直接调用
*/
Children join(String keyWord, Class<?> clazz, String alias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer);
}

View File

@ -0,0 +1,178 @@
package com.github.yulichang.extension.kt.interfaces;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.github.yulichang.extension.kt.resultmap.MybatisLabel;
import com.github.yulichang.extension.kt.resultmap.MybatisLabelFree;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.resultmap.Label;
import kotlin.reflect.KProperty;
import java.util.Collection;
import java.util.Map;
/**
* 对一或对多查询
*
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings({"unused", "DuplicatedCode"})
public interface QueryLabel<Children> {
void addLabel(Label<?> label, boolean isCollection);
Children getChildren();
/**
* 一对多查询 调用此方法发必需要调用对应的 left join / right join ... 连表方法否则会报错
* <p>
* 举例 UserDO AddressDO 为一对多关系 UserDTO 为结果类
* <pre>
* MPJLambdaWrapper&lt;UserDO&gt; wrapper = new MPJLambdaWrapper&lt;UserDO&gt;();
* wrapper.selectAll(UserDO.class)
* .selectCollection(AddressDO.class, UserDTO::getAddressListDTO)
* .leftJoin(AddressDO.class, ...... )
* .eq(...)
* ...
* <pre/>
* 会自动将 AddressDO类中相同属性的字段 以mybatis<collection>的方式映射到UserDTO.addressListDTO属性中
*
* @since 1.3.0
*
* @param child 连表数据库实体类
* @param dtoField 包装类对应的属性
*/
default Children selectCollection(Class<?> child, KProperty<?> dtoField) {
return selectCollection(null, child, dtoField);
}
default Children selectCollection(String prefix, Class<?> child, KProperty<?> dtoField) {
String dtoFieldName = dtoField.getName();
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField));
FieldCache field = fieldMap.get(dtoFieldName);
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabel.Builder<?, ?> builder;
if (genericType == null || genericType.isAssignableFrom(child)) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, child, field.getType());
} else {
builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, child, field.getType(), genericType, true);
}
addLabel(builder.build(), true);
return getChildren();
}
/**
* 一对多查询 调用此方法发必需要调用对应的 left join / right join ... 连表方法否则会报错
* <p>
* 举例 UserDO AddressDO 为一对多关系 UserDTO 为结果类
* <pre>
* MPJLambdaWrapper&lt;UserDO&gt; wrapper = new MPJLambdaWrapper();
* wrapper.selectAll(UserDO.class)
* .selectCollection(AddressDO.class, UserDTO::getAddressListDTO, map -> map
* .id(AddressDO::getId, AddressDTO::getId) //如果属性名一致 可以传一个
* .result(AddressDO::getUserId) //如果属性名一致 可以传一个
* .result(AddressDO::getAddress, AddressDTO::getAddress))) //如果属性名一致 可以传一个
* .leftJoin(AddressDO.class, ...... )
* .eq(...)
* ...
* <pre/>
*
* 会自动将 AddressDO类中指定的字段 以mybatis<collection>的方式映射到UserDTO.addressListDTO属性中
*
* @since 1.3.0
*
* @param child 连表数据库实体类
* @param dtoField 包装类对应的属性
* @param collection collection标签内容
*/
default Children selectCollection(Class<?> child,
KProperty<?> dtoField,
MFunction<MybatisLabel.Builder<?, ?>> collection) {
return selectCollection(null, child, dtoField, collection);
}
default Children selectCollection(KProperty<?> dtoField, MFunction<MybatisLabelFree.Builder<?>> collection) {
//自由映射必须存在泛型Z
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabelFree.Builder<?> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), genericType);
MybatisLabelFree.Builder<?> czBuilder = collection.apply(builder);
addLabel(czBuilder.build(), true);
return getChildren();
}
default Children selectCollection(String prefix,
Class<?> child,
KProperty<?> dtoField,
MFunction<MybatisLabel.Builder<?, ?>> collection) {
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabel.Builder<?, ?> builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, child, field.getType(), genericType, false);
MybatisLabel.Builder<?, ?> czBuilder = collection.apply(builder);
addLabel(czBuilder.build(), true);
return getChildren();
}
/**
* 对一查询 用法参考 selectCollection
*
* @since 1.3.0
*/
default Children selectAssociation(Class<?> child, KProperty<?> dtoField) {
return selectAssociation(null, child, dtoField);
}
default Children selectAssociation(String prefix, Class<?> child, KProperty<?> dtoField) {
String dtoFieldName = dtoField.getName();
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField));
FieldCache field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<?, ?> builder;
builder = new MybatisLabel.Builder<>(StrUtils.isBlank(prefix) ? null : prefix,
dtoFieldName, child, field.getType(), (Class<?>) field.getType(), true);
addLabel(builder.build(), false);
return getChildren();
}
/**
* 对一查询 用法参考 selectCollection
*
* @since 1.3.0
*/
default Children selectAssociation(Class<?> child, KProperty<?> dtoField,
MFunction<MybatisLabel.Builder<?, ?>> collection) {
return selectAssociation(null, child, dtoField, collection);
}
default Children selectAssociation(KProperty<?> dtoField,
MFunction<MybatisLabelFree.Builder<?>> collection) {
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabelFree.Builder<?> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), (Class<?>) field.getType());
MybatisLabelFree.Builder<?> cfBuilder = collection.apply(builder);
addLabel(cfBuilder.build(), false);
return getChildren();
}
default Children selectAssociation(String prefix, Class<?> child, KProperty<?> dtoField,
MFunction<MybatisLabel.Builder<?, ?>> collection) {
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<?, ?> builder = new MybatisLabel.Builder<>(StrUtils.isBlank(prefix) ? null : prefix,
dtoFieldName, child, field.getType(), (Class<?>) field.getType(), false);
MybatisLabel.Builder<?, ?> cfBuilder = collection.apply(builder);
addLabel(cfBuilder.build(), false);
return getChildren();
}
}

View File

@ -0,0 +1,84 @@
package com.github.yulichang.extension.kt.interfaces;
import kotlin.reflect.KProperty;
import java.io.Serializable;
/**
* copy {@link com.baomidou.mybatisplus.core.conditions.update.Update}
*
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings("unused")
public interface Update<Children> extends Serializable {
/**
* ignore
*/
default Children set(KProperty<?> column, Object val) {
return set(true, column, val);
}
/**
* 设置 更新 SQL SET 片段
*
* @param condition 是否加入 set
* @param column 字段
* @param val
* @return children
*/
default Children set(boolean condition, KProperty<?> column, Object val) {
return set(condition, column, val, null);
}
/**
* ignore
*/
default Children set(KProperty<?> column, Object val, String mapping) {
return set(true, column, val, mapping);
}
/**
* 设置 更新 SQL SET 片段
*
* @param condition 是否加入 set
* @param column 字段
* @param val
* @param mapping : javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler
* @return children
*/
Children set(boolean condition, KProperty<?> column, Object val, String mapping);
default Children setIncrBy(KProperty<?> column, Number val) {
return setIncrBy(true, column, val);
}
Children setIncrBy(boolean condition, KProperty<?> column, Number val);
default Children setDecrBy(KProperty<?> column, Number val) {
return setDecrBy(true, column, val);
}
Children setDecrBy(boolean condition, KProperty<?> column, Number val);
/**
* ignore
*/
default Children setSql(String sql) {
return setSql(true, sql);
}
/**
* 设置 更新 SQL SET 片段
*
* @param sql set sql
* @return children
*/
Children setSql(boolean condition, String sql);
/**
* 获取 更新 SQL SET 片段
*/
String getSqlSet();
}

View File

@ -0,0 +1,288 @@
package com.github.yulichang.extension.kt.resultmap;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.segments.SelectCache;
import kotlin.reflect.KProperty;
import lombok.Getter;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* collection 标签 目前先支持这几个属性 后续在扩展
*
* @author yulichang
* @since 1.4.6
*/
@Getter
public class MybatisLabel<E, T> implements Label<T> {
private String index;
private String property;
private Class<E> entityClass;
private Class<?> javaType;
private Class<T> ofType;
private List<IResult> resultList;
/**
* wrapper里面的引用
*/
private List<Label<?>> mybatisLabels;
private MybatisLabel() {
}
@SuppressWarnings({"unused", "unchecked", "DuplicatedCode"})
public static class Builder<E, T> {
private final MybatisLabel<E, T> mybatisLabel;
/**
* 自动构建
*/
@SuppressWarnings("unchecked")
public Builder(String index, String property, Class<E> entityClass, Class<?> javaType) {
this.mybatisLabel = new MybatisLabel<>();
mybatisLabel.property = property;
mybatisLabel.index = index;
mybatisLabel.entityClass = entityClass;
mybatisLabel.javaType = javaType;
mybatisLabel.ofType = (Class<T>) entityClass;
mybatisLabel.resultList = new ArrayList<>();
mybatisLabel.mybatisLabels = new ArrayList<>();
autoBuild(true, entityClass, (Class<T>) entityClass);
}
/**
* 手动构建
*
* @param property property
* @param entityClass 数据库实体类
* @param javaType javaType
* @param ofType 映射类
* @param auto 自动映射数据库实体对应的字段
*/
public Builder(String index, String property, Class<E> entityClass, Class<?> javaType, Class<T> ofType, boolean auto) {
this.mybatisLabel = new MybatisLabel<>();
mybatisLabel.property = property;
mybatisLabel.index = index;
mybatisLabel.entityClass = entityClass;
mybatisLabel.javaType = javaType;
mybatisLabel.ofType = ofType;
mybatisLabel.resultList = new ArrayList<>();
mybatisLabel.mybatisLabels = new ArrayList<>();
autoBuild(auto, entityClass, ofType);
}
/**
* 映射实体全部字段
*/
public Builder<E, T> all() {
autoBuild(true, mybatisLabel.entityClass, mybatisLabel.ofType);
return this;
}
/**
* 映射实体字段过滤(含主键)
*/
public Builder<E, T> filter(Predicate<SelectCache> predicate) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
ColumnCache.getListField(mybatisLabel.entityClass).stream().filter(predicate)
.filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
mybatisLabel.resultList.add(new Result.Builder<T>(c.isPk(), mybatisLabel.index, c).build()));
return this;
}
public Builder<E, T> id(KProperty<?> entity, KProperty<?> tag) {
Result.Builder<T> builder = new Result.Builder<>(true, mybatisLabel.index);
builder.column(entity).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<E, T> id(KProperty<?> entity) {
Result.Builder<T> builder = new Result.Builder<>(true, mybatisLabel.index);
builder.column(entity);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<E, T> result(KProperty<?> entity, KProperty<?> tag) {
Result.Builder<T> builder = new Result.Builder<>(false, mybatisLabel.index);
builder.column(entity).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<E, T> result(KProperty<?> entity) {
Result.Builder<T> builder = new Result.Builder<>(false, mybatisLabel.index);
builder.column(entity);
mybatisLabel.resultList.add(builder.build());
return this;
}
public <A, R, B extends Collection<R>> Builder<E, T> collection(Class<A> entityClass, KProperty<?> func) {
return collection(null, entityClass, func);
}
/**
* 嵌套
*/
public Builder<E, T> collection(String prefix, Class<?> entityClass, KProperty<?> func) {
String dtoFieldName = func.getName();
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(func));
FieldCache field = fieldMap.get(dtoFieldName);
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Builder<?, ?> builder;
if (genericType == null || genericType.isAssignableFrom(entityClass)) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new Builder<>(prefix, dtoFieldName, entityClass, field.getType());
} else {
builder = new Builder<>(prefix, dtoFieldName, entityClass, field.getType(), genericType, true);
}
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
public <A, R> Builder<E, T> collection(Class<A> entityClass, KProperty<?> func, MFunction<Builder<A, R>> mFunc) {
return collection(null, entityClass, func, mFunc);
}
/**
* 嵌套
*/
public <A, R> Builder<E, T> collection(KProperty<?> func,
MFunction<MybatisLabelFree.Builder<R>> mFunc) {
String dtoFieldName = func.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(func)).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<R> ofType = (Class<R>) genericType;
MybatisLabelFree.Builder<R> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), ofType);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, R> Builder<E, T> collection(String prefix,
Class<A> entityClass,
KProperty<?> func,
MFunction<Builder<A, R>> mFunc) {
String dtoFieldName = func.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(func)).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Class<R> ofType = (Class<R>) genericType;
Builder<A, R> builder = new Builder<>(prefix, dtoFieldName, entityClass, field.getType(), ofType, false);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
public <A> Builder<E, T> association(Class<A> child, KProperty<?> dtoField) {
return association(null, child, dtoField);
}
/**
* 嵌套
*/
public <A, B> Builder<E, T> association(String index, Class<A> child, KProperty<?> dtoField) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField));
String dtoFieldName = dtoField.getName();
FieldCache field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
Builder<A, B> builder;
builder = new Builder<>(index, dtoFieldName, child, field.getType(), (Class<B>) field.getType(), true);
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
public <A, B> Builder<E, T> association(Class<A> child, KProperty<?> dtoField,
MFunction<Builder<A, B>> collection) {
return association(null, child, dtoField, collection);
}
/**
* 嵌套
*/
public <A, B> Builder<E, T> association(KProperty<?> dtoField,
MFunction<MybatisLabelFree.Builder<B>> collection) {
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabelFree.Builder<B> builder = new MybatisLabelFree.Builder<>(dtoFieldName, field.getType(), (Class<B>) field.getType());
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public <A, B> Builder<E, T> association(String index, Class<A> child, KProperty<?> dtoField,
MFunction<Builder<A, B>> collection) {
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
Builder<A, B> builder = new Builder<>(index, dtoFieldName, child, field.getType(), (Class<B>) field.getType(), false);
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
return this;
}
public MybatisLabel<E, T> build() {
if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {
autoBuild(true, mybatisLabel.entityClass, mybatisLabel.ofType);
}
return mybatisLabel;
}
private void autoBuild(boolean auto, Class<E> entityClass, Class<T> tagClass) {
TableInfo tableInfo = TableHelper.getAssert(entityClass);
Map<String, FieldCache> tagMap = MPJReflectionKit.getFieldMap(tagClass);
if (auto && !tagMap.isEmpty()) {
List<SelectCache> listField = ColumnCache.getListField(entityClass);
if (entityClass.isAssignableFrom(tagClass)) {
mybatisLabel.resultList.addAll(listField.stream().map(i -> {
Result result = new Result();
result.setId(i.isPk());
result.setIndex(mybatisLabel.index);
result.setProperty(i.getColumProperty());
result.setJavaType(i.getColumnType());
result.setJdbcType(i.getJdbcType());
result.setSelectNormal(i);
return result;
}).collect(Collectors.toList()));
} else {
for (SelectCache s : listField) {
FieldCache field = tagMap.get(s.getColumProperty());
if (Objects.nonNull(field)) {
Result result = new Result();
result.setId(s.isPk());
result.setIndex(mybatisLabel.index);
result.setProperty(s.getColumProperty());
result.setJavaType(field.getType());
result.setSelectNormal(s);
mybatisLabel.resultList.add(result);
}
}
}
}
}
}
}

View File

@ -0,0 +1,273 @@
package com.github.yulichang.extension.kt.resultmap;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.interfaces.MFunction;
import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.resultmap.ResultList;
import com.github.yulichang.wrapper.segments.SelectCache;
import kotlin.reflect.KProperty;
import lombok.Getter;
import java.util.*;
import java.util.function.Predicate;
/**
* 无泛型约束 实现自由映射
*
* @author yulichang
* @since 1.4.6
*/
@Getter
public class MybatisLabelFree<T> implements Label<T> {
private String property;
private Class<?> javaType;
private Class<T> ofType;
private List<IResult> resultList;
/**
* wrapper里面的引用
*/
private List<Label<?>> mybatisLabels;
private MybatisLabelFree() {
}
@SuppressWarnings({"unused", "DuplicatedCode"})
public static class Builder<T> {
private final MybatisLabelFree<T> mybatisLabel;
/**
* 手动构建
*
* @param property property
* @param javaType javaType
* @param ofType 映射类
*/
public Builder(String property, Class<?> javaType, Class<T> ofType) {
this.mybatisLabel = new MybatisLabelFree<>();
mybatisLabel.property = property;
mybatisLabel.javaType = javaType;
mybatisLabel.ofType = ofType;
mybatisLabel.resultList = new ResultList();
mybatisLabel.mybatisLabels = new ArrayList<>();
}
public Builder<T> all(Class<?> entityClass) {
allBuild(null, entityClass);
return this;
}
public Builder<T> all(String prefix, Class<?> entityClass) {
allBuild(prefix, entityClass);
return this;
}
/**
* 映射实体字段过滤(含主键)
*/
public Builder<T> filter(Class<?> entityClass, Predicate<SelectCache> predicate) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
ColumnCache.getListField(entityClass).stream().filter(predicate)
.filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
mybatisLabel.resultList.add(new Result.Builder<T>(false, null, c).build()));
return this;
}
/**
* 映射实体字段过滤(含主键)
*/
public Builder<T> filter(String prefix, Class<?> entityClass, Predicate<SelectCache> predicate) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(mybatisLabel.ofType);
ColumnCache.getListField(entityClass).stream().filter(predicate)
.filter(p -> fieldMap.containsKey(p.getColumProperty())).forEach(c ->
mybatisLabel.resultList.add(new Result.Builder<T>(false, prefix, c).build()));
return this;
}
public Builder<T> id(KProperty<?> entity, KProperty<?> tag) {
Result.Builder<T> builder = new Result.Builder<>(true, null);
builder.column(entity).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> id(KProperty<?> entity) {
Result.Builder<T> builder = new Result.Builder<>(true, null);
builder.column(entity);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> id(String index, KProperty<?> entity, KProperty<?> tag) {
Result.Builder<T> builder = new Result.Builder<>(true, index);
builder.column(entity).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> id(String index, KProperty<?> entity) {
Result.Builder<T> builder = new Result.Builder<>(true, index);
builder.column(entity);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> result(KProperty<?> entity, KProperty<?> tag) {
Result.Builder<T> builder = new Result.Builder<>(false, null);
builder.column(entity).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> result(KProperty<?> entity) {
Result.Builder<T> builder = new Result.Builder<>(false, null);
builder.column(entity);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> result(String index, KProperty<?> entity, KProperty<?> tag) {
Result.Builder<T> builder = new Result.Builder<>(false, index);
builder.column(entity).property(tag);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> result(String index, KProperty<?> entity) {
Result.Builder<T> builder = new Result.Builder<>(false, index);
builder.column(entity);
mybatisLabel.resultList.add(builder.build());
return this;
}
public Builder<T> collection(Class<?> entityClass, KProperty<?> func) {
return collection(null, entityClass, func);
}
/**
* 嵌套
*/
public Builder<T> collection(String prefix, Class<?> entityClass, KProperty<?> func) {
String dtoFieldName = func.getName();
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(func));
FieldCache field = fieldMap.get(dtoFieldName);
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabel.Builder<?, ?> builder;
if (genericType == null || genericType.isAssignableFrom(entityClass)) {
//找不到集合泛型 List List<?> List<Object> 直接查询数据库实体
builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, entityClass, field.getType());
} else {
builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, entityClass, field.getType(), genericType, true);
}
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
public Builder<T> collection(Class<?> entityClass, KProperty<?> func, MFunction<MybatisLabel.Builder<?, ?>> mFunc) {
return collection(null, entityClass, func, mFunc);
}
public Builder<T> collection(KProperty<?> func, MFunction<Builder<?>> mFunc) {
String dtoFieldName = func.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(func)).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
Builder<?> builder = new Builder<>(dtoFieldName, field.getType(), genericType);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
/**
* 嵌套
*/
public Builder<T> collection(String prefix,
Class<?> entityClass,
KProperty<?> func,
MFunction<MybatisLabel.Builder<?, ?>> mFunc) {
String dtoFieldName = func.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(func)).get(dtoFieldName);
//获取集合泛型
Class<?> genericType = MPJReflectionKit.getGenericType(field.getField());
MybatisLabel.Builder<?, ?> builder = new MybatisLabel.Builder<>(prefix, dtoFieldName, entityClass, field.getType(), genericType, false);
mybatisLabel.mybatisLabels.add(mFunc.apply(builder).build());
return this;
}
public Builder<T> association(Class<?> child, KProperty<?> dtoField) {
return association(null, child, dtoField);
}
/**
* 嵌套
*/
public Builder<T> association(String index, Class<?> child, KProperty<?> dtoField) {
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField));
String dtoFieldName = dtoField.getName();
FieldCache field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<?, ?> builder;
builder = new MybatisLabel.Builder<>(index, dtoFieldName, child, field.getType(), (Class<?>) field.getType(), true);
mybatisLabel.mybatisLabels.add(builder.build());
return this;
}
public Builder<T> association(Class<?> child, KProperty<?> dtoField,
MFunction<MybatisLabel.Builder<?, ?>> collection) {
return association(null, child, dtoField, collection);
}
/**
* 嵌套
*/
public Builder<T> association(String index, Class<?> child, KProperty<?> dtoField,
MFunction<MybatisLabel.Builder<?, ?>> collection) {
String dtoFieldName = dtoField.getName();
FieldCache field = MPJReflectionKit.getFieldMap(KtUtils.ref(dtoField)).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<?, ?> builder = new MybatisLabel.Builder<>(index, dtoFieldName, child, field.getType(), (Class<?>) field.getType(), false);
mybatisLabel.mybatisLabels.add(collection.apply(builder).build());
return this;
}
public MybatisLabelFree<T> build() {
if (CollectionUtils.isEmpty(mybatisLabel.resultList)) {
TableInfo tableInfo = TableHelper.get(mybatisLabel.ofType);
Assert.notNull(tableInfo,
"无法自动映射, 找不到 <%s> 对应的表, 请使用 .all(xxx.class), id()或者result() 手动映射",
mybatisLabel.ofType.getSimpleName());
all(mybatisLabel.ofType);
}
return mybatisLabel;
}
private void allBuild(String prefix, Class<?> entityClass) {
Map<String, FieldCache> tagMap = MPJReflectionKit.getFieldMap(mybatisLabel.getOfType());
List<SelectCache> listField = ColumnCache.getListField(entityClass);
for (SelectCache s : listField) {
FieldCache field = tagMap.get(s.getColumProperty());
if (Objects.nonNull(field)) {
Result result = new Result();
result.setIndex(prefix);
result.setId(s.isPk());
result.setJavaType(field.getType());
result.setProperty(s.getColumProperty());
result.setSelectNormal(s);
mybatisLabel.resultList.add(result);
}
}
}
}
}

View File

@ -0,0 +1,101 @@
package com.github.yulichang.extension.kt.resultmap;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.StrUtils;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.segments.SelectCache;
import kotlin.reflect.KProperty;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.apache.ibatis.type.JdbcType;
import java.util.Map;
import java.util.Objects;
/**
* result 标签
*
* @author yulichang
* @since 1.4.6
*/
@Getter
@Setter(AccessLevel.PACKAGE)
public class Result implements IResult {
private boolean isId;
private String index;
private SelectCache selectNormal;
private String property;
private Class<?> javaType;
private JdbcType jdbcType;
public Result() {
}
@SuppressWarnings({"UnusedReturnValue", "unused"})
public static class Builder<T> {
private final Result result;
public Builder(boolean isId, String index) {
this.result = new Result();
result.isId = isId;
result.index = index;
}
public Builder(boolean isId, String index, SelectCache selectCache) {
this.result = new Result();
result.isId = isId;
result.index = index;
result.selectNormal = selectCache;
result.property = selectCache.getColumProperty();
result.javaType = selectCache.getColumnType();
result.jdbcType = selectCache.getJdbcType();
}
public Builder<T> property(KProperty<?> property) {
result.property = property.getName();
return this;
}
public <E> Builder<T> column(KProperty<?> column) {
Map<String, SelectCache> normalMap = ColumnCache.getMapField(KtUtils.ref(column));
String name = column.getName();
SelectCache normal = normalMap.get(name);
result.selectNormal = normal;
if (StrUtils.isBlank(result.property)) {
result.property = normal.getColumProperty();
}
if (Objects.isNull(result.javaType)) {
result.javaType = normal.getColumnType();
}
if (Objects.isNull(result.jdbcType)) {
result.jdbcType = normal.getJdbcType();
}
return this;
}
public Builder<T> javaType(Class<?> javaType) {
result.javaType = javaType;
return this;
}
public Builder<T> jdbcType(JdbcType jdbcType) {
result.jdbcType = jdbcType;
return this;
}
public Result build() {
return result;
}
}
}

View File

@ -0,0 +1,40 @@
package com.github.yulichang.extension.kt.segments;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.wrapper.segments.SelectFunc;
import kotlin.reflect.KProperty;
import lombok.Data;
import java.util.Arrays;
/**
* 自定义函数列
*
* @author yulichang
* @since 1.4.6
*/
@Data
@SuppressWarnings("unused")
public class FuncArgs {
private KProperty<?>[] args;
private Object[] values;
public FuncArgs accept(KProperty<?>... kProperty) {
this.args = kProperty;
return this;
}
public FuncArgs values(Object... values) {
this.values = values;
return this;
}
public SelectFunc.Arg[] getFuncArg() {
return Arrays.stream(args).map(i ->
new SelectFunc.Arg(KtUtils.ref(i), i.getName(), false, null, i,false,null))
.toArray(SelectFunc.Arg[]::new);
}
}

Some files were not shown because too many files have changed in this diff Show More