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

Signed-off-by: 卡莫sama <837080904@qq.com>
This commit is contained in:
卡莫sama 2023-08-09 13:03:25 +00:00 committed by Gitee
commit 668d4de0fd
53 changed files with 547 additions and 495 deletions

View File

@ -46,6 +46,7 @@ export default defineConfig({
{text: 'MyBatis-Flex 是什么', link: '/zh/intro/what-is-mybatisflex'},
{text: '快速开始', link: '/zh/intro/getting-started'},
{text: 'Maven 依赖', link: '/zh/intro/maven'},
{text: 'Gradle 依赖', link: '/zh/intro/gradle'},
{text: '和同类框架「功能」对比', link: '/zh/intro/comparison'},
{text: '和同类框架「性能」对比', link: '/zh/intro/benchmark'},
{text: '使用 Mybatis 原生功能', link: '/zh/intro/use-mybatis-native'},
@ -100,6 +101,7 @@ export default defineConfig({
items: [
{text: '代码生成器', link: '/zh/others/codegen'},
{text: 'APT 设置', link: '/zh/others/apt'},
{text: 'KAPT 设置', link: '/zh/others/kapt'},
]
}
],

View File

@ -115,7 +115,7 @@ const {Layout} = DefaultTheme
<a href="https://gitee.com/sdyunze/iotlink" target="_blank"><img src="/assets/images/ad/iotlink_20240802.png"></a>
</div>
<div class="banner">
虚以待位
<a href="https://eiam.topiam.cn" target="_blank"><img src="/assets/images/ad/topiam_20230909.png" style="width: 105px;height: 50px"></a>
</div>
</div>
<div class="banner-bottom">

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -1017,7 +1017,7 @@ QueryWrapper query2 = QueryWrapper.create()
在以上的 `query1` 中,由于 `userName``id` 都为 nullMyBatis-Flex 会自动忽略 null 值的条件,因此,它们构建出来的 SQL 条件是和 `query2` 完全一致的 。
## QueryColumnBehavior <Badge type="tip" text="^ v1.5.6" />
## QueryColumnBehavior <Badge type="tip" text="^ v1.5.7" />
在以上的内容中,我们知道 MyBatis-Flex 会自动忽略 `null` 值的条件,但是在实际开发中,有的开发者希望除了自动忽略 `null`
值以外,还可以自动忽略其他值,比如 `空字符串` 等。

View File

@ -1,5 +1,7 @@
# 常见问题
[[toc]]
## MyBatis-Flex 没有启动或者启动出错怎么办?
正常情况下MyBatis-Flex 在启动时,会在控制台打印如下 Banner 信息,包含版本与官方网址,如果在项目启动中没有发现 MyBatis-Flex 的 Banner 打印,那就说明 MyBatis-Flex 没有被正常加载。
@ -21,7 +23,7 @@
就可以了,不需要再添加其他 MyBatis 依赖。
- 3、是否与 `mybatis-plus-boot-starter` 共用,使 MyBatis 被优先初始化,而导致 MyBatis-Flex 没有被加载。
- 4、是否添加了 `pagehelper-spring-boot-starter` 依赖,导致传递了 `mybatis-spring-boot-starter` 依赖。如还想继续使用 pagehelper 插件,点击 [这里](#与-pagehelper-集成出现错误) 查看解决方案。
- 5、是否 Spring Boot 版本过低,请使用 Spring Boot 2.2 及其以上版本,点击 [这里](#springboot-项目启动报错-javalangclassnotfoundexception-orgspringframeworktransactiontransactionmanager) 获取详细信息。
- 5、是否 Spring Boot 版本过低,请使用 Spring Boot 2.2 及其以上版本,点击 [这里](#springboot-项目-启动报错-java-lang-classnotfoundexception-org-springframework-transaction-transactionmanager) 获取详细信息。
## 示例中的 AccountMapper 和 "ACCOUNT" 在哪里,报错了。
@ -94,6 +96,18 @@ SpringBoot v3.x 添加 hikariCP 的内容如下:
> 如果使用的是 druid 数据库连接池,则需要添加数据源类型的配置 `spring.datasource.type=com.alibaba.druid.pool.DruidDataSource`
## SpringBoot 项目中出现 class "com.xxx" cannot be cast class "com.xxx" 的错误
这个问题是由于 Spring 的 devtools 热加载引起的,可以在项目的 `resources/META-INF`
目录下创建一个名为 `spring-devtools.properties` 的配置文件,配置内容如下:
```properties
restart.include.mapper=/mapper-[\\w-\\.].jar
restart.include.pagehelper=/pagehelper-[\\w-\\.].jar
restart.include.mybatis-flex=/mybatis-flex-[\\w-\\.]+jar
```
相关文档参考 Spring 的官方网站https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using.devtools.restart.customizing-the-classload
## java.sql.SQLException: No value specified for parameter x
出现这个问题,原因是 MyBatis-Flex 未能正常启动SQL 执行没有经过 MyBatis-Flex 导致的。其直接是因为和其他第三方增强框架整合使用了,
比如和 MyBatis-Plus、或者 PageHelper 等整合造成的。
@ -167,13 +181,29 @@ spring:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>版本号</version>
<version>5.3.3</version>
</dependency>
```
解决方案https://gitee.com/mybatis-flex/mybatis-flex/issues/I71AUE
## 代码生成器获取不到注释
如果是 MySQL 数据库的话可能是因为数据库版本太低解决办法MySQL 5.* 需要在 jdbcUrl 设置参数 `useInformationSchema=true` 才能获取到注释。
例如:`jdbc:mysql://127.0.0.1:3306/mybatis-flex?characterEncoding=UTF-8&useInformationSchema=true`
## 与 Nacos 集成时出错,无法正常启动 MyBatis-Flex
一般请看下是缺少 Nacos 的相关 Maven注意添加如下的 Nacos 依赖:
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2022.0.0.0</version>
</dependency>
```
## 如何自定义 MyBatis 的 Configuration?

View File

@ -1,14 +1,14 @@
# Gradle 依赖
> 以下的 xml gradle 依赖示例中,可能并非最新的 MyBatis-Flex 版本,请自行查看最新版本,并修改版本号。
>
> 建议配置 annotationProcessor那么可以省略mybatis-flex-processor的依赖
>
> 以下的 gradle 依赖示例中,可能并非最新的 MyBatis-Flex 版本,请自行查看最新版本,并修改版本号。
> 建议配置 annotationProcessor那么可以省略 mybatis-flex-processor 的依赖
1、只用到了 MyBatis没用到 Spring 的场景:
**【Kotlin】**
```kotlin
dependencies {
implementation("com.mybatis-flex:mybatis-flex-core:1.5.6")
@ -17,6 +17,7 @@ dependencies {
```
**【Groovy】**
```groovy
dependencies {
implementation 'com.mybatis-flex:mybatis-flex-core:1.5.6'
@ -41,9 +42,11 @@ dependencies {
compileOnly 'com.mybatis-flex:mybatis-flex-processor:1.5.6'
}
```
3、用到了 Spring Boot 的场景
**【Kotlin】**
```kotlin
dependencies {
implementation("com.mybatis-flex:mybatis-flex-spring-boot-starter:1.5.6")
@ -52,6 +55,7 @@ dependencies {
```
**【Groovy】**
```groovy
dependencies {
implementation 'com.mybatis-flex:mybatis-flex-spring-boot-starter:1.5.6'
@ -59,15 +63,16 @@ dependencies {
}
```
4. 配置 annotationProcessor
4配置 annotationProcessor
`mybatis-flex-processor`提供APT服务可以配置到annotationProcessorPaths配置后无需在依赖中声明`mybatis-flex-processor`依赖。
`mybatis-flex-processor` 提供 APT 服务,可以配置到 annotationProcessorPaths,配置后,无需在依赖中声明 `mybatis-flex-processor` 依赖。
参考:[APT 设置-和 Lombok、Mapstruct 整合](../others/apt.md)
参考:[APT 设置-和 Lombok、Mapstruct 整合](../others/apt.md)
> 在Kotlin中使用时请参考[在Kotlin中使用注解处理器](../kotlin/kapt.md)
> 在 Kotlin 中使用时,请参考[在 Kotlin 中使用注解处理器](../others/kapt.md)
**【Kotlin】**
```kotlin
dependencies {
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor:1.5.6")
@ -75,6 +80,7 @@ dependencies {
```
**【Groovy】**
```groovy
dependencies {
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:1.5.6'

View File

@ -60,7 +60,7 @@
参考:[APT 设置-和 Lombok、Mapstruct 整合](../others/apt.md)
> 在Kotlin中使用时请参考[在Kotlin中使用注解处理器](../kotlin/kapt.md)
> 在Kotlin中使用时请参考[在Kotlin中使用注解处理器](../others/kapt.md)
```xml
<plugin>

View File

@ -1,11 +1,10 @@
# 在Kotlin中使用注解处理器
# 在 Kotlin 中使用注解处理器
> 在Kotlin中想要使`@Table`等注解生效十分简单。只需要使用kapt即可。
>
> 在 Kotlin 中想要使 `@Table` 等注解生效十分简单。只需要使用 KAPT 即可。
## 在Gradle中使用
## 在 Gradle 中使用
1. 应用Gradle插件kotlin-kapt
1、应用 Gradle 插件:`kotlin-kapt`
**【Kotlin】**
@ -23,7 +22,9 @@ plugins {
}
```
2. 在 dependencies 块中使用 kapt 配置添加相应的依赖项
2、在 dependencies 块中使用 KAPT 配置添加相应的依赖项
**【Kotlin】**
```kotlin
@ -39,7 +40,8 @@ dependencies {
}
```
## 在Maven中使用
## 在 Maven 中使用
在 compile 之前在 kotlin-maven-plugin 中添加 kapt 目标的执行:
```xml
@ -60,4 +62,4 @@ dependencies {
</execution>
```
> 关于Kapt更详细的说明请看[Kotlin官网说明](https://book.kotlincn.net/text/kapt.html),或[Kotlin语言中文站](https://www.kotlincn.net/docs/reference/kapt.html)。
> 关于 KAPT 更详细的说明,请看 [Kotlin 官网说明](https://book.kotlincn.net/text/kapt.html),或 [Kotlin 语言中文站](https://www.kotlincn.net/docs/reference/kapt.html)。

View File

@ -17,6 +17,9 @@ package com.mybatisflex.core;
/**
* Mybatis-Flex 可能用到的静态常量
*
* @author michael
* @author 王帅
*/
public class FlexConsts {
@ -26,7 +29,6 @@ public class FlexConsts {
public static final String NAME = "MyBatis-Flex";
public static final String VERSION = "1.5.6";
public static final String DEFAULT_PRIMARY_FIELD = "id";
public static final String SQL = "$$sql";
public static final String SQL_ARGS = "$$sql_args";

View File

@ -44,11 +44,20 @@ public abstract class QueryModel<T extends QueryModel<T>> {
protected QueryWrapper queryWrapper() {
if (queryWrapper == null) {
queryWrapper = QueryWrapper.create();
TableInfo tableInfo = TableInfoFactory.ofEntityClass(getClass());
QueryTable queryTable = new QueryTable();
queryTable.setSchema(tableInfo.getSchema());
queryTable.setName(tableInfo.getTableName());
queryWrapper = QueryWrapper.create().from(queryTable);
}
return queryWrapper;
}
public T as(String alias) {
queryWrapper().as(alias);
return (T) this;
}
public T select() {
return (T) this;
}

View File

@ -103,12 +103,13 @@ public class DialectFactory {
case GBASE:
case OSCAR:
case XUGU:
case CLICK_HOUSE:
case OCEAN_BASE:
case CUBRID:
case GOLDILOCKS:
case CSIIDB:
return new CommonsDialectImpl(KeywordWrap.BACK_QUOTE, LimitOffsetProcessor.MYSQL);
case CLICK_HOUSE:
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.MYSQL);
case DM:
return new DmDialect();
case ORACLE:
@ -134,13 +135,13 @@ public class DialectFactory {
return new OracleDialect(LimitOffsetProcessor.DERBY);
case FIREBIRD:
case DB2:
return new CommonsDialectImpl(KeywordWrap.DOUBLE_QUOTATION, LimitOffsetProcessor.DERBY);
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.DERBY);
case SQLSERVER:
return new CommonsDialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER);
case SQLSERVER_2005:
return new CommonsDialectImpl(KeywordWrap.SQUARE_BRACKETS, LimitOffsetProcessor.SQLSERVER_2005);
case INFORMIX:
return new CommonsDialectImpl(KeywordWrap.DOUBLE_QUOTATION, LimitOffsetProcessor.INFORMIX);
return new CommonsDialectImpl(KeywordWrap.NONE, LimitOffsetProcessor.INFORMIX);
case SINODB:
return new CommonsDialectImpl(KeywordWrap.DOUBLE_QUOTATION, LimitOffsetProcessor.SINODB);
case SYBASE:

View File

@ -242,7 +242,7 @@ public class CommonsDialectImpl implements IDialect {
@Override
public String forUpdateByQuery(QueryWrapper queryWrapper, Row row) {
StringBuilder sql = new StringBuilder();
StringBuilder sqlBuilder = new StringBuilder();
Set<String> modifyAttrs = RowCPI.getModifyAttrs(row);
Map<String, RawValue> rawValueMap = RowCPI.getRawValueMap(row);
@ -254,30 +254,39 @@ public class CommonsDialectImpl implements IDialect {
//fix: support schema
QueryTable queryTable = queryTables.get(0);
sql.append(UPDATE).append(queryTable.toSql(this)).append(SET);
sqlBuilder.append(UPDATE).append(queryTable.toSql(this)).append(SET);
int index = 0;
for (String modifyAttr : modifyAttrs) {
if (index > 0) {
sql.append(DELIMITER);
sqlBuilder.append(DELIMITER);
}
sql.append(wrap(modifyAttr));
sqlBuilder.append(wrap(modifyAttr));
if (rawValueMap.containsKey(modifyAttr)) {
sql.append(EQUALS).append(rawValueMap.get(modifyAttr).toSql(this));
sqlBuilder.append(EQUALS).append(rawValueMap.get(modifyAttr).toSql(this));
} else {
sql.append(EQUALS_PLACEHOLDER);
sqlBuilder.append(EQUALS_PLACEHOLDER);
}
index++;
}
String whereConditionSql = buildWhereConditionSql(queryWrapper);
if (StringUtil.isNotBlank(whereConditionSql)) {
sql.append(WHERE).append(whereConditionSql);
buildJoinSql(sqlBuilder, queryWrapper, queryTables);
buildWhereSql(sqlBuilder, queryWrapper, queryTables, false);
buildGroupBySql(sqlBuilder, queryWrapper, queryTables);
buildHavingSql(sqlBuilder, queryWrapper, queryTables);
//ignore orderBy and limit
buildOrderBySql(sqlBuilder, queryWrapper, queryTables);
Long limitRows = CPI.getLimitRows(queryWrapper);
Long limitOffset = CPI.getLimitOffset(queryWrapper);
if (limitRows != null || limitOffset != null) {
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
}
return sql.toString();
return sqlBuilder.toString();
}
@Override
@ -473,8 +482,13 @@ public class CommonsDialectImpl implements IDialect {
buildHavingSql(sqlBuilder, queryWrapper, allTables);
//ignore orderBy and limit
//buildOrderBySql(sqlBuilder, queryWrapper)
//buildLimitSql(sqlBuilder, queryWrapper)
buildOrderBySql(sqlBuilder, queryWrapper, allTables);
Long limitRows = CPI.getLimitRows(queryWrapper);
Long limitOffset = CPI.getLimitOffset(queryWrapper);
if (limitRows != null || limitOffset != null) {
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
}
List<String> endFragments = CPI.getEndFragments(queryWrapper);
if (CollectionUtil.isNotEmpty(endFragments)) {
@ -777,13 +791,19 @@ public class CommonsDialectImpl implements IDialect {
@Override
public String forUpdateEntityByQuery(TableInfo tableInfo, Object entity, boolean ignoreNulls, QueryWrapper queryWrapper) {
StringBuilder sql = new StringBuilder();
StringBuilder sqlBuilder = new StringBuilder();
Set<String> updateColumns = tableInfo.obtainUpdateColumns(entity, ignoreNulls, true);
Map<String, RawValue> rawValueMap = tableInfo.obtainUpdateRawValueMap(entity);
sql.append(UPDATE).append(forHint(CPI.getHint(queryWrapper)));
sql.append(tableInfo.getWrapSchemaAndTableName(this)).append(SET);
sqlBuilder.append(UPDATE).append(forHint(CPI.getHint(queryWrapper)));
sqlBuilder.append(tableInfo.getWrapSchemaAndTableName(this));
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
buildJoinSql(sqlBuilder, queryWrapper, queryTables);
sqlBuilder.append(SET);
StringJoiner stringJoiner = new StringJoiner(DELIMITER);
@ -807,26 +827,40 @@ public class CommonsDialectImpl implements IDialect {
stringJoiner.add(wrap(versionColumn) + EQUALS + wrap(versionColumn) + " + 1 ");
}
sql.append(stringJoiner);
sqlBuilder.append(stringJoiner);
String whereConditionSql = buildWhereConditionSql(queryWrapper);
buildWhereSql(sqlBuilder, queryWrapper, queryTables, false);
buildGroupBySql(sqlBuilder, queryWrapper, queryTables);
buildHavingSql(sqlBuilder, queryWrapper, queryTables);
//不允许全量更新
if (StringUtil.isBlank(whereConditionSql)) {
throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW);
//ignore orderBy and limit
buildOrderBySql(sqlBuilder, queryWrapper, queryTables);
Long limitRows = CPI.getLimitRows(queryWrapper);
Long limitOffset = CPI.getLimitOffset(queryWrapper);
if (limitRows != null || limitOffset != null) {
sqlBuilder = buildLimitOffsetSql(sqlBuilder, queryWrapper, limitRows, limitOffset);
}
sql.append(WHERE).append(whereConditionSql);
// String whereConditionSql = buildWhereConditionSql(queryWrapper);
//
// //不允许全量更新
// if (StringUtil.isBlank(whereConditionSql)) {
// throw FlexExceptions.wrap(LocalizedFormats.UPDATE_OR_DELETE_NOT_ALLOW);
// }
//
// sql.append(WHERE).append(whereConditionSql);
List<String> endFragments = CPI.getEndFragments(queryWrapper);
if (CollectionUtil.isNotEmpty(endFragments)) {
for (String endFragment : endFragments) {
sql.append(BLANK).append(endFragment);
sqlBuilder.append(BLANK).append(endFragment);
}
}
return sql.toString();
return sqlBuilder.toString();
}
@ -973,16 +1007,19 @@ public class CommonsDialectImpl implements IDialect {
}
protected void buildJoinSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, List<QueryTable> queryTables) {
protected boolean buildJoinSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, List<QueryTable> queryTables) {
List<Join> joins = CPI.getJoins(queryWrapper);
boolean joinSuccess = false;
if (joins != null && !joins.isEmpty()) {
for (Join join : joins) {
if (!join.checkEffective()) {
continue;
}
sqlBuilder.append(join.toSql(queryTables, this));
joinSuccess = true;
}
}
return joinSuccess;
}

View File

@ -261,7 +261,9 @@ public class EntitySqlProvider {
FlexAssert.notNull(entity, "entity can not be null");
boolean ignoreNulls = ProviderUtil.isIgnoreNulls(params);
QueryWrapper queryWrapper = ProviderUtil.getQueryWrapper(params);
appendTableConditions(context,queryWrapper,false);
TableInfo tableInfo = ProviderUtil.getTableInfo(context);
@ -274,9 +276,13 @@ public class EntitySqlProvider {
//优先构建 sql再构建参数
String sql = DialectFactory.getDialect().forUpdateEntityByQuery(tableInfo, entity, ignoreNulls, queryWrapper);
Object[] joinValueArray = CPI.getJoinValueArray(queryWrapper);
Object[] values = tableInfo.buildUpdateSqlArgs(entity, ignoreNulls, true);
Object[] queryParams = CPI.getValueArray(queryWrapper);
ProviderUtil.setSqlArgs(params, ArrayUtil.concat(values, queryParams));
Object[] queryParams = CPI.getConditionValueArray(queryWrapper);
Object[] paramValues = ArrayUtil.concat(joinValueArray,ArrayUtil.concat(values,queryParams));
ProviderUtil.setSqlArgs(params, paramValues);
return sql;
}

View File

@ -34,7 +34,15 @@ public class CPI {
}
public static Object[] getValueArray(QueryWrapper queryWrapper) {
return queryWrapper.getValueArray();
return queryWrapper.getAllValueArray();
}
public static Object[] getJoinValueArray(QueryWrapper queryWrapper) {
return queryWrapper.getJoinValueArray();
}
public static Object[] getConditionValueArray(QueryWrapper queryWrapper) {
return queryWrapper.getConditionValueArray();
}
public static List<QueryWrapper> getChildSelect(QueryWrapper queryWrapper) {

View File

@ -71,7 +71,7 @@ public class OperatorSelectCondition extends QueryCondition {
@Override
public Object getValue() {
return queryWrapper.getValueArray();
return queryWrapper.getAllValueArray();
}
@Override

View File

@ -692,7 +692,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
* 获取 queryWrapper 的参数
* 在构建 sql 的时候需要保证 where having 的前面
*/
Object[] getValueArray() {
Object[] getAllValueArray() {
List<Object> withValues = null;
if (with != null) {
@ -770,7 +770,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
if (CollectionUtil.isNotEmpty(unions)) {
for (UnionWrapper union : unions) {
QueryWrapper queryWrapper = union.getQueryWrapper();
paramValues = ArrayUtil.concat(paramValues, queryWrapper.getValueArray());
paramValues = ArrayUtil.concat(paramValues, queryWrapper.getAllValueArray());
}
}
@ -783,6 +783,67 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
return returnValues;
}
/**
* 获取 queryWrapper 的参数
* 在构建 sql 的时候需要保证 where having 的前面
*/
Object[] getJoinValueArray() {
//join 子查询的参数left join (select ...)
List<Object> joinValues = null;
List<Join> joins = getJoins();
if (CollectionUtil.isNotEmpty(joins)) {
for (Join join : joins) {
QueryTable joinTable = join.getQueryTable();
Object[] valueArray = joinTable.getValueArray();
if (valueArray.length > 0) {
if (joinValues == null) {
joinValues = new ArrayList<>(valueArray.length);
}
joinValues.addAll(Arrays.asList(valueArray));
}
QueryCondition onCondition = join.getOnCondition();
Object[] values = WrapperUtil.getValues(onCondition);
if (values.length > 0) {
if (joinValues == null) {
joinValues = new ArrayList<>(values.length);
}
joinValues.addAll(Arrays.asList(values));
}
}
}
return joinValues == null ? FlexConsts.EMPTY_ARRAY : joinValues.toArray();
}
/**
* 获取 queryWrapper 的参数
* 在构建 sql 的时候需要保证 where having 的前面
*/
Object[] getConditionValueArray() {
//where 参数
Object[] whereValues = WrapperUtil.getValues(whereQueryCondition);
//having 参数
Object[] havingValues = WrapperUtil.getValues(havingQueryCondition);
Object[] paramValues = ArrayUtil.concat(whereValues, havingValues);
//unions 参数
if (CollectionUtil.isNotEmpty(unions)) {
for (UnionWrapper union : unions) {
QueryWrapper queryWrapper = union.getQueryWrapper();
paramValues = ArrayUtil.concat(paramValues, queryWrapper.getAllValueArray());
}
}
return paramValues;
}
List<QueryWrapper> getChildSelect() {
List<QueryWrapper> tableChildQuery = null;
@ -815,7 +876,7 @@ public class QueryWrapper extends BaseQueryWrapper<QueryWrapper> {
public String toSQL() {
String sql = DialectFactory.getDialect().forSelectByQuery(this);
return SqlUtil.replaceSqlParams(sql, getValueArray());
return SqlUtil.replaceSqlParams(sql, getAllValueArray());
}
@Override

View File

@ -58,7 +58,7 @@ public class SelectQueryColumn extends QueryColumn implements HasParamsColumn {
@Override
public Object[] getParamValues() {
return queryWrapper.getValueArray();
return queryWrapper.getAllValueArray();
}
}

View File

@ -42,7 +42,7 @@ public class SelectQueryTable extends QueryTable {
@Override
Object[] getValueArray() {
return queryWrapper.getValueArray();
return queryWrapper.getAllValueArray();
}
@Override

View File

@ -44,7 +44,7 @@ public class WithSelectDetail implements WithDetail {
@Override
public Object[] getParamValues() {
return queryWrapper.getValueArray();
return queryWrapper.getAllValueArray();
}
@Override

View File

@ -57,7 +57,7 @@ public class WithValuesDetail implements WithDetail {
@Override
public Object[] getParamValues() {
return queryWrapper.getValueArray();
return queryWrapper.getAllValueArray();
}
@Override

View File

@ -115,7 +115,7 @@ class WrapperUtil {
addParam(paras, Array.get(value, i));
}
} else if (value instanceof QueryWrapper) {
Object[] valueArray = ((QueryWrapper) value).getValueArray();
Object[] valueArray = ((QueryWrapper) value).getAllValueArray();
paras.addAll(Arrays.asList(valueArray));
} else if (value.getClass().isEnum()) {
EnumWrapper enumWrapper = EnumWrapper.of(value.getClass());

View File

@ -45,21 +45,6 @@ public class IdInfo extends ColumnInfo {
private Boolean before;
public IdInfo(ColumnInfo columnInfo) {
this.setColumn(columnInfo.getColumn());
this.setAlias(columnInfo.getAlias());
this.setProperty(columnInfo.getProperty());
this.setPropertyType(columnInfo.getPropertyType());
// id 的类型为数值时默认设置为自增的方式
if (Number.class.isAssignableFrom(columnInfo.getPropertyType())) {
keyType = KeyType.Auto;
} else {
initDefaultKeyType();
}
}
public IdInfo(Id id) {
this.keyType = id.keyType();
this.value = id.value();

View File

@ -17,7 +17,6 @@ package com.mybatisflex.core.table;
import com.mybatisflex.annotation.*;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.exception.FlexExceptions;
import com.mybatisflex.core.util.ClassUtil;
@ -179,7 +178,7 @@ public class TableInfoFactory {
List<ColumnInfo> columnInfoList = new ArrayList<>();
List<IdInfo> idInfos = new ArrayList<>();
Field idField = null;
// Field idField = null;
String logicDeleteColumn = null;
String versionColumn = null;
@ -330,27 +329,9 @@ public class TableInfoFactory {
columnInfo.setJdbcType(column.jdbcType());
}
if (FlexConsts.DEFAULT_PRIMARY_FIELD.equals(field.getName())) {
idField = field;
}
}
if (idInfos.isEmpty() && idField != null) {
int index = -1;
for (int i = 0; i < columnInfoList.size(); i++) {
ColumnInfo columnInfo = columnInfoList.get(i);
if (FlexConsts.DEFAULT_PRIMARY_FIELD.equals(columnInfo.getProperty())) {
index = i;
break;
}
}
if (index >= 0) {
ColumnInfo removedColumnInfo = columnInfoList.remove(index);
idInfos.add(new IdInfo(removedColumnInfo));
}
}
tableInfo.setLogicDeleteColumn(logicDeleteColumn);
tableInfo.setVersionColumn(versionColumn);
tableInfo.setTenantIdColumn(tenantIdColumn);

View File

@ -92,12 +92,12 @@ public class UpdateChain<T> extends QueryWrapperAdapter<UpdateChain<T>> {
return this;
}
public UpdateChain<T> set(LambdaGetter<T> getter, Object value, boolean condition) {
public <L> UpdateChain<T> set(LambdaGetter<L> getter, Object value, boolean condition) {
entityWrapper.set(getter, value, condition);
return this;
}
public UpdateChain<T> set(LambdaGetter<T> getter, Object value) {
public <L> UpdateChain<T> set(LambdaGetter<L> getter, Object value) {
entityWrapper.set(getter, value);
return this;
}
@ -123,12 +123,12 @@ public class UpdateChain<T> extends QueryWrapperAdapter<UpdateChain<T>> {
return this;
}
public UpdateChain<T> setRaw(LambdaGetter<T> getter, Object value, boolean condition) {
public <L> UpdateChain<T> setRaw(LambdaGetter<L> getter, Object value, boolean condition) {
entityWrapper.setRaw(getter, value, condition);
return this;
}
public UpdateChain<T> setRaw(LambdaGetter<T> getter, Object value) {
public <L> UpdateChain<T> setRaw(LambdaGetter<L> getter, Object value) {
entityWrapper.setRaw(getter, value);
return this;
}

View File

@ -44,7 +44,7 @@ public class LambdaUtil {
public static <T> Class<?> getImplClass(LambdaGetter<T> getter) {
SerializedLambda lambda = getSerializedLambda(getter);
return getImplClass(lambda);
return getImplClass(lambda, getter.getClass().getClassLoader());
}
@ -56,9 +56,10 @@ public class LambdaUtil {
public static <T> QueryColumn getQueryColumn(LambdaGetter<T> getter) {
ClassLoader classLoader = getter.getClass().getClassLoader();
SerializedLambda lambda = getSerializedLambda(getter);
String methodName = lambda.getImplMethodName();
Class<?> entityClass = getImplClass(lambda);
Class<?> entityClass = getImplClass(lambda, classLoader);
TableInfo tableInfo = TableInfoFactory.ofEntityClass(entityClass);
return tableInfo.getQueryColumnByProperty(PropertyNamer.methodToProperty(methodName));
}
@ -77,11 +78,11 @@ public class LambdaUtil {
}
private static Class<?> getImplClass(SerializedLambda lambda) {
private static Class<?> getImplClass(SerializedLambda lambda, ClassLoader classLoader) {
String implClass = getImplClassName(lambda);
return MapUtil.computeIfAbsent(classMap, implClass, s -> {
try {
return Class.forName(s.replace("/", "."));
return Class.forName(s.replace("/", "."), true, classLoader);
} catch (ClassNotFoundException e) {
throw FlexExceptions.wrap(e);
}

View File

@ -359,6 +359,21 @@ public class AccountSqlTester {
System.out.println(sql);
}
@Test
public void testJoin4Sql() {
QueryWrapper query = QueryWrapper.create()
.select(ACCOUNT.ALL_COLUMNS,
column("bui.user_code"),
column("bui.user_name"),
column("burmc.user_name as created_by_name"))
.from(ACCOUNT).as("burm")
.leftJoin("base_admin_user_info").as("bui").on("bui.user_id = burm.user_id")
.leftJoin("base_admin_user_info").as("burmc").on("burmc.user_id = burm.created_by")
.where("bui.is_valid = ?", 3);
System.out.println(query.toSQL());
}
@Test
public void testJoinSelf() {
QueryWrapper queryWrapper = QueryWrapper.create()

View File

@ -95,6 +95,7 @@
<groupId>io.seata</groupId>
<artifactId>seata-rm-datasource</artifactId>
<version>1.7.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -19,7 +19,6 @@ import com.mybatisflex.core.datasource.DataSourceBuilder;
import com.mybatisflex.core.datasource.DataSourceDecipher;
import com.mybatisflex.core.datasource.DataSourceManager;
import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.spring.SeataMode;
import com.mybatisflex.spring.boot.MybatisFlexProperties.SeataConfig;
import com.mybatisflex.spring.datasource.DataSourceAdvice;
import io.seata.rm.datasource.DataSourceProxy;
@ -87,7 +86,7 @@ public class MultiDataSourceAutoConfiguration {
DataSourceManager.decryptDataSource(dataSource);
if (seataConfig != null && seataConfig.isEnable()) {
if (seataConfig.getSeataMode() == SeataMode.XA) {
if (seataConfig.getSeataMode() == MybatisFlexProperties.SeataMode.XA) {
dataSource = new DataSourceProxyXA(dataSource);
} else {
dataSource = new DataSourceProxy(dataSource);

View File

@ -17,7 +17,6 @@ package com.mybatisflex.spring.boot;
import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.spring.SeataMode;
import org.apache.ibatis.io.VFS;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.mapping.ResultSetType;
@ -42,6 +41,7 @@ import java.util.stream.Stream;
/**
* Mybatis-Flex 的配置属性
* 参考https://github.com/mybatis/spring-boot-starter/blob/master/mybatis-spring-boot-autoconfigure/src/main/java/org/mybatis/spring/boot/autoconfigure/MybatisProperties.java
*
* @author Eddú Meléndez
* @author Kazuki Shimizu
* @author micahel
@ -909,7 +909,7 @@ public class MybatisFlexProperties {
*
* @author life
*/
public static class SeataConfig{
public static class SeataConfig {
/**
* 是否开启
@ -936,6 +936,18 @@ public class MybatisFlexProperties {
public void setSeataMode(SeataMode seataMode) {
this.seataMode = seataMode;
}
}
/**
* @author life
*/
public enum SeataMode {
XA,
AT
}
}

View File

@ -39,14 +39,6 @@
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
</project>

View File

@ -19,8 +19,6 @@ import com.mybatisflex.core.FlexConsts;
import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.rm.datasource.xa.DataSourceProxyXA;
import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.cache.Cache;
@ -37,7 +35,6 @@ import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;

View File

@ -1,3 +1,19 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test;
import com.mybatisflex.core.MybatisFlexBootstrap;
@ -15,6 +31,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import javax.sql.DataSource;
import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT;
import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE;
public class UpdateChainTest {
@ -69,4 +86,17 @@ public class UpdateChainTest {
.list()
.forEach(System.out::println);
}
@Test
public void testUpdateChainToSql() {
String sql = UpdateChain.of(Account.class)
.set(ACCOUNT.AGE, 18)
.set(Article::getAccountId, 4, 1 == 1)
.leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
.where(ACCOUNT.ID.eq(4))
.toSQL();
System.out.println(sql);
}
}

View File

@ -0,0 +1 @@
processor.mapper.generateEnable=true

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mybatis-flex-test</artifactId>
<groupId>com.mybatis-flex</groupId>
<version>1.5.6</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mybatis-flex-seata-test</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
<version>${mybatis-flex.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.mybatisflex.test.mapper")
public class MybatisFlexSpringBootSeataApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisFlexSpringBootSeataApplication.class, args);
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.controller;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import com.mybatisflex.test.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@Autowired
TestService testService;
@RequestMapping("buy")
public String buy() {
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
MessageCollector collector = new ConsoleMessageCollector();
AuditManager.setMessageCollector(collector);
return String.valueOf(testService.buy());
}
}

View File

@ -1,13 +1,26 @@
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 实体类

View File

@ -1,13 +1,26 @@
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 实体类

View File

@ -1,13 +1,26 @@
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 实体类

View File

@ -1,23 +1,37 @@
package com.mybatisfle.test.mybatisflexspringbootseata.service;
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.service;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.AccountTbl;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.OrderTbl;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.StockTbl;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.table.AccountTblTableDef;
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.AccountTblMapper;
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.OrderTblMapper;
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.StockTblMapper;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.test.entity.AccountTbl;
import com.mybatisflex.test.entity.OrderTbl;
import com.mybatisflex.test.entity.StockTbl;
import com.mybatisflex.test.entity.table.AccountTblTableDef;
import com.mybatisflex.test.mapper.AccountTblMapper;
import com.mybatisflex.test.mapper.OrderTblMapper;
import com.mybatisflex.test.mapper.StockTblMapper;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TestService {
@ -33,12 +47,12 @@ public class TestService {
@Autowired
StockTblMapper stockTblMapper;
// @Transactional
// @Transactional
@GlobalTransactional
public boolean buy() {
// DataSourceKey.use("accountdb");
LOGGER.warn(() -> "xid:"+RootContext.getXID());
QueryWrapper account =new QueryWrapper();
LOGGER.warn(() -> "xid:" + RootContext.getXID());
QueryWrapper account = new QueryWrapper();
account.where(AccountTblTableDef.ACCOUNT_TBL.USER_ID.eq("1001"));
AccountTbl accountTbl = accountTblMapper.selectOneByQuery(account);
accountTbl.setMoney(accountTbl.getMoney() - 5);
@ -59,4 +73,5 @@ public class TestService {
orderTblMapper.insert(orderTbl);
return true;
}
}

View File

@ -13,14 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.spring;
/**
* @author life
*/
public enum SeataMode {
package com.mybatisflex.test;
XA,
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class MybatisFlexSpringBootSeataApplicationTests {
@Test
void contextLoads() {
}
AT
}

View File

@ -1,149 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>mybatis-flex-test</artifactId>
<groupId>com.mybatis-flex</groupId>
<version>1.5.6</version>
</parent>
<groupId>com.mybatisfle.test</groupId>
<artifactId>mybatis-flex-spring-boot-seata</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-flex-spring-boot-seata</name>
<description>mybatis-flex-spring-boot-seata</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
<version>${mybatis-flex.version}</version>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-codegen</artifactId>
<version>${mybatis-flex.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
<!-- <version>2.7.9</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework</groupId>-->
<!-- <artifactId>spring-jdbc</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.h2database</groupId>-->
<!-- <artifactId>h2</artifactId>-->
<!-- <version>2.1.214</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.yaml</groupId>-->
<!-- <artifactId>snakeyaml</artifactId>-->
<!-- <version>1.33</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>

View File

@ -1,15 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.mybatisfle.test.mybatisflexspringbootseata")
@SpringBootApplication
public class MybatisFlexSpringBootSeataApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisFlexSpringBootSeataApplication.class, args);
}
}

View File

@ -1,28 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata.controller;
import com.mybatisfle.test.mybatisflexspringbootseata.service.TestService;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@Autowired
TestService testService;
@RequestMapping("buy")
public String buy(){
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
MessageCollector collector = new ConsoleMessageCollector();
AuditManager.setMessageCollector(collector);
String flag =String.valueOf(testService.buy());
return flag;
}
}

View File

@ -1,15 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.AccountTbl;
import com.mybatisflex.core.BaseMapper;
/**
* 映射层
*
* @author life
* @since 2023-08-03
*/
public interface AccountTblMapper extends BaseMapper<AccountTbl> {
}

View File

@ -1,15 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.OrderTbl;
import com.mybatisflex.core.BaseMapper;
/**
* 映射层
*
* @author life
* @since 2023-08-03
*/
public interface OrderTblMapper extends BaseMapper<OrderTbl> {
}

View File

@ -1,15 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.StockTbl;
import com.mybatisflex.core.BaseMapper;
/**
* 映射层
*
* @author life
* @since 2023-08-03
*/
public interface StockTblMapper extends BaseMapper<StockTbl> {
}

View File

@ -1,88 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata.utils;
import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.ColumnConfig;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.zaxxer.hikari.HikariDataSource;
public class Codegen {
public static void main(String[] args) {
//配置数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/db_stock?characterEncoding=utf-8");
dataSource.setUsername("root");
dataSource.setPassword("131496");
//创建配置内容两种风格都可以
GlobalConfig globalConfig = createGlobalConfigUseStyle1();
//GlobalConfig globalConfig = createGlobalConfigUseStyle2();
//通过 datasource globalConfig 创建代码生成器
Generator generator = new Generator(dataSource, globalConfig);
//生成代码
generator.generate();
}
public static GlobalConfig createGlobalConfigUseStyle1() {
//创建配置内容
GlobalConfig globalConfig = new GlobalConfig();
//设置根包
globalConfig.setBasePackage("com.mybatisfle.test.mybatisflexspringbootseata");
//设置表前缀和只生成哪些表
globalConfig.setGenerateSchema("db_stock");
// globalConfig.setTablePrefix("tb_");
globalConfig.setGenerateTable("stock_tbl");
//设置生成 entity 并启用 Lombok
globalConfig.setEntityGenerateEnable(true);
globalConfig.setEntityWithLombok(true);
//设置生成 mapper
globalConfig.setMapperGenerateEnable(true);
//可以单独配置某个列
// ColumnConfig columnConfig = new ColumnConfig();
// columnConfig.setColumnName("tenant_id");
// columnConfig.setLarge(true);
// columnConfig.setVersion(true);
// globalConfig.setColumnConfig("account", columnConfig);
return globalConfig;
}
public static GlobalConfig createGlobalConfigUseStyle2() {
//创建配置内容
GlobalConfig globalConfig = new GlobalConfig();
//设置根包
globalConfig.getPackageConfig()
.setBasePackage("com.test");
//设置表前缀和只生成哪些表setGenerateTable 未配置时生成所有表
globalConfig.getStrategyConfig()
.setGenerateSchema("schema")
.setTablePrefix("tb_")
.setGenerateTable("account", "account_session");
//设置生成 entity 并启用 Lombok
globalConfig.enableEntity()
.setWithLombok(true);
//设置生成 mapper
globalConfig.enableMapper();
//可以单独配置某个列
ColumnConfig columnConfig = new ColumnConfig();
columnConfig.setColumnName("tenant_id");
columnConfig.setLarge(true);
columnConfig.setVersion(true);
globalConfig.getStrategyConfig()
.setColumnConfig("account", columnConfig);
return globalConfig;
}
}

View File

@ -1,13 +0,0 @@
package com.mybatisfle.test.mybatisflexspringbootseata;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class MybatisFlexSpringBootSeataApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -156,4 +156,18 @@ class ActiveRecordTest {
.forEach(System.out::println);
}
@Test
void testToSql() {
String sql = User.create()
.as("u")
.select(USER.ALL_COLUMNS, ROLE.ALL_COLUMNS)
.leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID))
.leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID))
.where(USER.USER_ID.eq(2))
.toQueryWrapper()
.toSQL();
System.out.println(sql);
}
}

View File

@ -15,10 +15,10 @@
<modules>
<module>mybatis-flex-native-test</module>
<module>mybatis-flex-seata-test</module>
<module>mybatis-flex-spring-test</module>
<module>mybatis-flex-spring-boot-test</module>
<module>mybatis-flex-spring-cloud-test</module>
<module>mybatis-flex-spring-boot-seata</module>
<module>mybatis-flex-spring-kotlin-test</module>
</modules>