From b4a134e924ec3dc468f1c24ee12990c8c1f53050 Mon Sep 17 00:00:00 2001 From: Faputa <2238932729@qq.com> Date: Thu, 23 Nov 2023 14:21:41 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=9B=B4=E5=A5=BD=E7=9A=84getEntityClass?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使mapper可以支持多继承、继承泛型接口等场景 --- .../core/table/TableInfoFactory.java | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java index 152d983b..dc7fe35e 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java @@ -115,20 +115,62 @@ public class TableInfoFactory { private static Class getEntityClass(Class mapperClass) { - if (mapperClass == null || mapperClass == Object.class) { - return null; - } + return getEntityClass(mapperClass, null); + } + + private static Class getEntityClass(Class mapperClass, Type[] actualTypeArguments) { + // 检查基接口 Type[] genericInterfaces = mapperClass.getGenericInterfaces(); - if (genericInterfaces.length == 1) { - Type type = genericInterfaces[0]; + for (Type type : genericInterfaces) { if (type instanceof ParameterizedType) { - Type actualTypeArgument = ((ParameterizedType) type).getActualTypeArguments()[0]; - return actualTypeArgument instanceof Class ? (Class) actualTypeArgument : null; + // 泛型基接口 + ParameterizedType parameterizedType = (ParameterizedType) type; + Type rawType = parameterizedType.getRawType(); + Type[] typeArguments = parameterizedType.getActualTypeArguments(); + adjustTypeArguments(mapperClass, actualTypeArguments, typeArguments); + if (rawType == BaseMapper.class) { + // 找到了 + if (typeArguments[0] instanceof Class) { + return (Class) typeArguments[0]; + } + } else if (rawType instanceof Class) { + // 其他泛型基接口 + Class entityClass = getEntityClass((Class) rawType, typeArguments); + if (entityClass != null) { + return entityClass; + } + } } else if (type instanceof Class) { - return getEntityClass((Class) type); + // 其他基接口 + Class entityClass = getEntityClass((Class) type); + if (entityClass != null) { + return entityClass; + } + } + } + // 检查基类 + Class superclass = mapperClass.getSuperclass(); + if (superclass == null || superclass == Object.class) { + return null; + } + Type[] typeArguments = superclass.getTypeParameters(); + adjustTypeArguments(mapperClass, actualTypeArguments, typeArguments); + return getEntityClass(superclass, typeArguments); + } + + private static void adjustTypeArguments(Class subclass, Type[] subclassTypeArguments, Type[] typeArguments) { + for (int i = 0; i < typeArguments.length; i++) { + if (typeArguments[i] instanceof TypeVariable) { + TypeVariable typeVariable = (TypeVariable) typeArguments[i]; + TypeVariable[] typeParameters = subclass.getTypeParameters(); + for (int j = 0; j < typeParameters.length; j++) { + if (Objects.equals(typeVariable.getName(), typeParameters[j].getName())) { + typeArguments[i] = subclassTypeArguments[j]; + break; + } + } } } - return getEntityClass(mapperClass.getSuperclass()); } From d5d3de74e7f8a5a4b34be1a599561334117eb85d Mon Sep 17 00:00:00 2001 From: Faputa <2238932729@qq.com> Date: Thu, 23 Nov 2023 14:28:08 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BF=9D=E7=95=99=E5=8E=9F=E6=9D=A5?= =?UTF-8?q?=E7=9A=84=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/mybatisflex/core/table/TableInfoFactory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java index dc7fe35e..61712630 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfoFactory.java @@ -115,6 +115,9 @@ public class TableInfoFactory { private static Class getEntityClass(Class mapperClass) { + if (mapperClass == null || mapperClass == Object.class) { + return null; + } return getEntityClass(mapperClass, null); } From 7f3be5f8db4ae381ab09c064838018340bfc01c7 Mon Sep 17 00:00:00 2001 From: xiawang <1358208301@qq.com> Date: Wed, 29 Nov 2023 16:00:30 +0800 Subject: [PATCH 3/6] build(deps): bump mybatis-spring version to 2.1.2 1. update mybatis-spring version to 2.1.2 2. update mybatis version to 3.5.14 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e268bb4b..f1fdbfb8 100644 --- a/pom.xml +++ b/pom.xml @@ -57,8 +57,8 @@ 1.7.5 - 3.5.13 - 2.1.0 + 3.5.14 + 2.1.2 1.2.4 2.1.2 1.0.4 From 64f96dbc76f782988c5e5732cfabe42be15aa410 Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Wed, 29 Nov 2023 21:49:06 +0800 Subject: [PATCH 4/6] =?UTF-8?q?typo:=20=E5=88=AB=E5=90=8D=E6=8B=BC?= =?UTF-8?q?=E5=86=99=E9=94=99=E8=AF=AF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mybatisflex/core/query/QueryCondition.java | 2 +- .../com/mybatisflex/core/query/RawQueryCondition.java | 6 +++--- .../main/java/com/mybatisflex/core/util/StringUtil.java | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java index 702f5d46..adbb994f 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/QueryCondition.java @@ -295,7 +295,7 @@ public class QueryCondition implements CloneSupport { return nextContainsTable(tables); } for (String table : tables) { - String tableName = StringUtil.getTableNameWithAlisa(table)[0]; + String tableName = StringUtil.getTableNameWithAlias(table)[0]; if (column.table != null && tableName.equals(column.table.name)) { return true; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/RawQueryCondition.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/RawQueryCondition.java index bd524266..06890cfa 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/RawQueryCondition.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/query/RawQueryCondition.java @@ -43,9 +43,9 @@ public class RawQueryCondition extends QueryCondition { @Override boolean containsTable(String... tables) { for (String table : tables) { - String[] tableNameWithAlisa = StringUtil.getTableNameWithAlisa(table); - if (content.contains(tableNameWithAlisa[0]) - || (tableNameWithAlisa[1] != null && content.contains(tableNameWithAlisa[1]))) { + String[] tableNameWithAlias = StringUtil.getTableNameWithAlias(table); + if (content.contains(tableNameWithAlias[0]) + || (tableNameWithAlias[1] != null && content.contains(tableNameWithAlias[1]))) { return true; } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/StringUtil.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/StringUtil.java index edbd7ab3..3f0f45e3 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/StringUtil.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/util/StringUtil.java @@ -303,10 +303,10 @@ public class StringUtil { : new String[]{tableNameWithSchema.substring(0, index).trim(), tableNameWithSchema.substring(index + 1).trim()}; } - public static String[] getTableNameWithAlisa(String tableNameWithAlisa) { - int index = tableNameWithAlisa.indexOf("."); - return index <= 0 ? new String[]{tableNameWithAlisa, null} - : new String[]{tableNameWithAlisa.substring(0, index), tableNameWithAlisa.substring(index + 1)}; + public static String[] getTableNameWithAlias(String tableNameWithAlias) { + int index = tableNameWithAlias.indexOf("."); + return index <= 0 ? new String[]{tableNameWithAlias, null} + : new String[]{tableNameWithAlias.substring(0, index), tableNameWithAlias.substring(index + 1)}; } public static String tryTrim(String string) { From 74c29444796fe711dabfc2e51f9f1ff5f40d0361 Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Wed, 29 Nov 2023 21:58:42 +0800 Subject: [PATCH 5/6] =?UTF-8?q?doc:=20=E6=B7=BB=E5=8A=A0=20SpringBoot=203.?= =?UTF-8?q?2=20=E7=89=88=E6=9C=AC=E5=90=AF=E5=8A=A8=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=8A=9E=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh/faq.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/zh/faq.md b/docs/zh/faq.md index 01a98bb1..73074f11 100644 --- a/docs/zh/faq.md +++ b/docs/zh/faq.md @@ -65,6 +65,31 @@ in alimaven (http://maven.aliyun.com/nexus/content/groups/public/) ``` +## SpringBoot 3.2 项目,启动报错 Invalid value type for attribute 'factoryBeanObjectType': java.lang.String + +这个是 `mybatis-spring` 依赖版本过低造成的,需要将内置的低版本 `mybatis-spring` 换为最新版。 + +```xml {6-9,17} + + com.mybatis-flex + mybatis-flex-spring-boot-starter + ${mybatis-flex.version} + + + org.mybatis + mybatis-spring + + + + + + + org.mybatis + mybatis-spring + 3.0.3 + +``` + ## SpringBoot 项目,启动报错 java.lang.ClassNotFoundException: org.springframework.transaction.TransactionManager 这个应该是 Spring Boot 版本的问题,`org.springframework.transaction.TransactionManager` 这个类是 Spring Framework 5.2 From 6105923d94e5eaaab4cde448cd92ba82df08b192 Mon Sep 17 00:00:00 2001 From: mofan Date: Thu, 30 Nov 2023 10:48:34 +0800 Subject: [PATCH 6/6] docs: polish docs --- readme.md | 65 +++++++++++++++++---------------- readme_zh.md | 101 +++++++++++++++++++++++++-------------------------- 2 files changed, 82 insertions(+), 84 deletions(-) diff --git a/readme.md b/readme.md index 46ba88b3..4672f141 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,8 @@ -![](./docs/assets/images/logo_en.png) +

English | 简体中文

+ +

+ +

# MyBatis-Flex is an elegant Mybatis Enhancement Framework. @@ -33,20 +37,19 @@ ## Features -- 1、MyBatis-Flex is very lightweight, and it only depends on Mybatis and no other third-party dependencies -- 2、Basic CRUD operator and paging query of Entity class -- 3、Row mapping support, you can add, delete, modify and query the database without entity classes -- 4、Support multiple databases, and expand through dialects flexibly. -- 5、Support combined primary keys and different primary key content generation strategies -- 6、Extremely friendly SQL query, IDE automatically prompts and no worries about mistakes -- 7、More little surprises +1. MyBatis-Flex is very lightweight, and it only depends on Mybatis and no other third-party dependencies +2. Basic CRUD operator and paging query of Entity class +3. Row mapping support, you can add, delete, modify and query the database without entity classes +4. Support multiple databases, and expand through dialects flexibly +5. Support combined primary keys and different primary key content generation strategies +6. Extremely friendly SQL query, IDE automatically prompts and no worries about mistakes +7. More little surprises -## hello world(Without Spring) +## hello world(Without Spring) **step 1: write entity class** ```java - @Table("tb_account") public class Account { @@ -56,7 +59,7 @@ public class Account { private Date birthday; private int sex; - //getter setter + // getter setter } ``` @@ -64,13 +67,13 @@ public class Account { ```java public interface AccountMapper extends BaseMapper { - //only Mapper interface define. + // only Mapper interface define } ``` **step 3: start query data** -e.g. 1: query by primary key +e.g. 1: query by primary key ```java class HelloWorld { @@ -90,7 +93,7 @@ class HelloWorld { .getMapper(AccountMapper.class); - //id=100 + // id = 100 Account account = mapper.selectOneById(100); } } @@ -99,7 +102,7 @@ class HelloWorld { e.g.2: query list ```java -//use QueryWrapper to build query conditions +// use QueryWrapper to build query conditions QueryWrapper query = QueryWrapper.create() .select() .from(ACCOUNT) @@ -116,7 +119,7 @@ List accounts = mapper.selectListByQuery(query); e.g.3: paging query ```java -//use QueryWrapper to build query conditions +// use QueryWrapper to build query conditions QueryWrapper query = QueryWrapper.create() .select() .from(ACCOUNT) @@ -138,7 +141,7 @@ Page accountPage = mapper.paginate(5, 10, query); ### select * ```java -QueryWrapper query=new QueryWrapper(); +QueryWrapper query = new QueryWrapper(); query.select().from(ACCOUNT) // SQL: @@ -148,7 +151,7 @@ query.select().from(ACCOUNT) ### select columns ```java -QueryWrapper query=new QueryWrapper(); +QueryWrapper query = new QueryWrapper(); query.select(ACCOUNT.ID,ACCOUNT.USER_NAME).from(ACCOUNT) // SQL: @@ -175,7 +178,7 @@ QueryWrapper query = new QueryWrapper() ### select functions ```java - QueryWrapper query=new QueryWrapper() + QueryWrapper query = new QueryWrapper() .select( ACCOUNT.ID, ACCOUNT.USER_NAME, @@ -193,7 +196,7 @@ QueryWrapper query = new QueryWrapper() ### where ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .where(ACCOUNT.ID.ge(100)) @@ -208,7 +211,7 @@ QueryWrapper queryWrapper=QueryWrapper.create() ### exists, not exists ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .where(ACCOUNT.ID.ge(100)) @@ -229,7 +232,7 @@ QueryWrapper queryWrapper=QueryWrapper.create() ### and (...) or (...) ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .where(ACCOUNT.ID.ge(100)) @@ -246,7 +249,7 @@ QueryWrapper queryWrapper=QueryWrapper.create() ### group by ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .groupBy(ACCOUNT.USER_NAME); @@ -259,7 +262,7 @@ QueryWrapper queryWrapper=QueryWrapper.create() ### having ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .groupBy(ACCOUNT.USER_NAME) @@ -275,7 +278,7 @@ QueryWrapper queryWrapper=QueryWrapper.create() ### orderBy ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .orderBy(ACCOUNT.AGE.asc(), ACCOUNT.USER_NAME.desc().nullsLast()); @@ -342,19 +345,17 @@ QueryWrapper queryWrapper = QueryWrapper.create() ### Questions? -**1、how to generate "ACCOUNT" class for QueryWrapper by Account.java ?** +**1. How to generate "ACCOUNT" class for QueryWrapper by Account.java ?** -build the project by IDE, or execute maven build command: `mvn clean package` +Build the project by IDE, or execute maven build command: `mvn clean package` ![](./docs/assets/images/build_idea.png) - - ## More Samples -- 1、[Mybatis-Flex Only (Native)](./mybatis-flex-test/mybatis-flex-native-test) -- 2、[Mybatis-Flex with Spring](./mybatis-flex-test/mybatis-flex-spring-test) -- 3、[Mybatis-Flex with Spring boot](./mybatis-flex-test/mybatis-flex-spring-boot-test) +1. [Mybatis-Flex Only (Native)](./mybatis-flex-test/mybatis-flex-native-test) +2. [Mybatis-Flex with Spring](./mybatis-flex-test/mybatis-flex-spring-test) +3. [Mybatis-Flex with Spring boot](./mybatis-flex-test/mybatis-flex-spring-boot-test) diff --git a/readme_zh.md b/readme_zh.md index eb923b72..764647f6 100644 --- a/readme_zh.md +++ b/readme_zh.md @@ -1,4 +1,8 @@ -![](./docs/assets/images/logo_en.png) +

English | 简体中文

+ +

+ +

# MyBatis-Flex: 一个优雅的 MyBatis 增强框架 @@ -34,18 +38,17 @@ ## 特征 -#### 1、很轻量 +#### 1. 很轻量 > MyBatis-Flex 整个框架只依赖 MyBatis,再无其他任何第三方依赖。 -#### 2、只增强 +#### 2. 只增强 > MyBatis-Flex 支持 CRUD、分页查询、多表查询、批量操作,但不丢失 MyBatis 原有的任何功能。 -#### 3、高性能 -> MyBatis-Flex 采用独特的技术架构、相比许多同类框架,MyBatis-Flex 的在增删改查等方面的性能均超越其 5~10 倍或以上。 +#### 3. 高性能 +> MyBatis-Flex 采用独特的技术架构、相比许多同类框架,MyBatis-Flex 的在增删改查等方面的性能均超越其 5-10 倍或以上。 -#### 4、更灵动 -> MyBatis-Flex 支持多主键、多表查询、逻辑删除、乐观锁、数据脱敏、数据加密、多数据源、分库分表、字段权限、 -> 字段加密、多租户、事务管理、SQL 审计... 等等等等。 这一切,免费且灵动。 +#### 4. 更灵动 +> MyBatis-Flex 支持多主键、多表查询、逻辑删除、乐观锁、数据脱敏、数据加密、多数据源、分库分表、字段权限、字段加密、多租户、事务管理、SQL 审计等特性。 这一切,免费且灵动。 ## QQ 群 @@ -62,14 +65,11 @@ - 示例 3:[Mybatis-Flex with Spring boot](./mybatis-flex-test/mybatis-flex-spring-boot-test) - 示例 4:[Db + Row](./mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/DbTestStarter.java) - - ## hello world(原生) **第 1 步:编写 Entity 实体类** ```java - @Table("tb_account") public class Account { @@ -79,11 +79,10 @@ public class Account { private Date birthday; private int sex; - //getter setter + // getter setter } ``` - **第 2 步:开始查询数据** 示例 1:查询 1 条数据 @@ -106,21 +105,21 @@ class HelloWorld { .getMapper(AccountMapper.class); - //示例1:查询 id=100 条数据 + // 示例1:查询 id = 100 条数据 Account account = mapper.selectOneById(100); } } ``` -> 以上的 `AccountMapper.class` 为 Mybatis-Flex 自动通过 APT 生成,无需手动编码。也可以关闭自动生成功能,手动编写 AccountMapper,更多查看 APT 文档。 +> 以上的 `AccountMapper.class` 为 MyBatis-Flex 自动通过 APT 生成,无需手动编码。也可以关闭自动生成功能,手动编写 AccountMapper,更多查看 APT 文档。 -示例2:查询列表 +示例 2:查询列表 ```java -//示例2:通过 QueryWrapper 构建条件查询数据列表 +// 示例 2:通过 QueryWrapper 构建条件查询数据列表 QueryWrapper query = QueryWrapper.create() .select() - .from(ACCOUNT) // 单表查询时表名可省略,自动使用Mapper泛型对应的表 + .from(ACCOUNT) // 单表查询时表名可省略,自动使用 Mapper 泛型对应的表 .where(ACCOUNT.ID.ge(100)) .and(ACCOUNT.USER_NAME.like("张").or(ACCOUNT.USER_NAME.like("李"))); @@ -131,10 +130,10 @@ QueryWrapper query = QueryWrapper.create() List accounts = accountMapper.selectListByQuery(query); ``` -示例3:分页查询 +示例 3:分页查询 ```java -// 示例3:分页查询 +// 示例 3:分页查询 // 查询第 5 页,每页 10 条数据,通过 QueryWrapper 构建条件查询 QueryWrapper query=QueryWrapper.create() .select() @@ -299,7 +298,7 @@ QueryWrapper queryWrapper = QueryWrapper.create() ### exists, not exists ```java -QueryWrapper queryWrapper=QueryWrapper.create() +QueryWrapper queryWrapper = QueryWrapper.create() .select() .from(ACCOUNT) .where(ACCOUNT.ID.ge(100)) @@ -431,8 +430,7 @@ QueryWrapper queryWrapper = QueryWrapper.create() // SELECT * FROM "tb_account" ORDER BY "id" DESC ROWS 20 TO 30 ``` -> 在以上的 "limit... offset" 示例中,Mybatis-Flex 能够自动识别当前数据库,并生成不同的 SQL,用户也可以很轻易的通过 -> `DialectFactory` 注册(新增或改写)自己的实现方言。 +> 在以上的 "limit... offset" 示例中,MyBatis-Flex 能够自动识别当前数据库,并生成不同的 SQL,用户也可以很轻易的通过 `DialectFactory` 注册(新增或改写)自己的实现方言。 ### 存在疑问? @@ -443,43 +441,42 @@ QueryWrapper queryWrapper = QueryWrapper.create() **疑问 2:如何通过实体类 Account.java 生成 QueryWrapper 所需要的 "ACCOUNT" 类 ?** -答:Mybatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编译的时候,会自动根据 Entity 类定义的字段帮你生成 "ACCOUNT" 类以及 Entity 对应的 Mapper 类, -通过开发工具构建项目(如下图),或者执行 maven 编译命令: `mvn clean package` 都可以自动生成。这个原理和 lombok 一致。 +答:MyBatis-Flex 使用了 APT(Annotation Processing Tool)技术,在项目编译的时候,会自动根据 Entity 类定义的字段帮你生成 "ACCOUNT" 类以及 Entity 对应的 Mapper 类, +通过开发工具构建项目(如下图),或者执行 maven 编译命令: `mvn clean package` 都可以自动生成。这个原理和 Lombok 一致。 ![](./docs/assets/images/build_idea.png) -> 更多关于 Mybatis-Flex APT 的配置,请点击 [这里](./docs/zh/others/apt.md)。 +> 更多关于 MyBatis-Flex APT 的配置,请点击 [这里](./docs/zh/others/apt.md)。 ## Db + Row 工具类 -Db + Row 工具类,提供了在 Entity 实体类之外的数据库操作能力。使用 Db + Row 时,无需对数据库表进行映射, Row 是一个 HashMap 的子类,相当于一个通用的 Entity。以下为 Db + Row -的一些示例: +Db + Row 工具类,提供了在 Entity 实体类之外的数据库操作能力。使用 Db + Row 时,无需对数据库表进行映射, Row 是一个 HashMap 的子类,相当于一个通用的 Entity。以下为 Db + Row 的一些示例: ```java -//使用原生 SQL 插入数据 +// 使用原生 SQL 插入数据 String sql="insert into tb_account(id,name) value (?, ?)"; Db.insertBySql(sql, 1, "michael"); -//使用 Row 插入数据 +// 使用 Row 插入数据 Row account = new Row(); account.set("id", 100); account.set("name", "Michael"); Db.insert("tb_account", account); -//根据主键查询数据 +// 根据主键查询数据 Row row = Db.selectOneById("tb_account", "id", 1); -//Row 可以直接转换为 Entity 实体类,且性能极高 +// Row 可以直接转换为 Entity 实体类,且性能极高 Account account = row.toEntity(Account.class); -//查询所有大于 18 岁的用户 +// 查询所有大于 18 岁的用户 String listsql = "select * from tb_account where age > ?" List rows = Db.selectListBySql(sql, 18); -//分页查询:每页 10 条数据,查询第 3 页的年龄大于 18 的用户 +// 分页查询:每页 10 条数据,查询第 3 页的年龄大于 18 的用户 QueryWrapper query = QueryWrapper.create() .where(ACCOUNT.AGE.ge(18)); Page rowPage = Db.paginate("tb_account", 3, 10, query); @@ -487,19 +484,19 @@ Page rowPage = Db.paginate("tb_account", 3, 10, query); > Db 工具类还提供了更多 增、删、改、查和分页查询等方法。 > -> 具体参考: [Db.java](./mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java) 。 +> 具体参考:[Db.java](./mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Db.java) 。 > -> 更多关于 Row 插入时的**主键生成机制**、以及Db 的**事务管理**等,请点击 [这里](./docs/zh/core/db-row.md) 。 +> 更多关于 Row 插入时的 **主键生成机制**、以及Db 的 **事务管理** 等,请点击 [这里](./docs/zh/core/db-row.md) 。 ## Entity 部分字段更新 -相比市面上的其他框架,这部分的功能应该也算是 MyBatis-Flex 的亮点之一。在 BaseMapper 中,Mybatis-Flex 提供了如下的方法: +相比市面上的其他框架,这部分的功能应该也算是 MyBatis-Flex 的亮点之一。在 BaseMapper 中,MyBatis-Flex 提供了如下的方法: ```java update(T entity) ``` -有些场景下,我们可能希望只更新 几个 字段,而其中个别字段需要更新为 null。此时需要用到 `UpdateEntity` 工具类,以下是示例代码: +有些场景下,我们可能希望只更新 几个 字段,而其中个别字段需要更新为 `null`,此时需要用到 `UpdateEntity` 工具类: ```java Account account = UpdateEntity.of(Account.class); @@ -510,21 +507,20 @@ account.setSex(1); accountMapper.update(account); ``` -以上的示例中,会把 id 为 100 这条数据中的 user_name 字段更新为 null,sex 字段更新为 1,其他字段不会被更新。也就是说,通过 `UpdateEntity` -创建的对象,只会更新调用了 setter 方法的字段,若不调用 setter 方法,不管这个对象里的属性的值是什么,都不会更新到数据库。 +在以上的示例中,会把 id 为 100 这条数据中的 user_name 字段更新为 `null`,sex 字段更新为 1,其他字段不会被更新。也就是说,通过 `UpdateEntity` 创建的对象,只会更新调用了 setter 方法的字段,若不调用 setter 方法,不管这个对象里的属性的值是什么,都不会更新到数据库。 -其生成的 sql 内容如下: +其生成的 SQL 内容如下: ```sql update tb_account set user_name = ?, sex = ? where id = ? -#params: null,1,100 +# params: null,1,100 ``` ## 自定义 TypeHandler -使用 @Column 注解: +使用 `@Column` 注解: ```java @Table("tb_account") @@ -538,7 +534,7 @@ public class Account { @Column(typeHandler = Fastjson2TypeHandler.class) private Map options; - //getter setter + // getter setter public void addOption(String key, Object value) { if (options == null) { @@ -558,7 +554,7 @@ account.addOption("c1", 11); account.addOption("c2", "zhang"); account.addOption("c3", new Date()); ``` -mybatis 日志: +MyBatis 日志: ``` ==> Preparing: INSERT INTO tb_account (user_name, options) VALUES (?, ?) ==> Parameters: test(String), {"c3":"2023-03-17 09:10:16.546","c1":11,"c2":"zhang"}(String) @@ -566,7 +562,7 @@ mybatis 日志: ## 多主键 -Mybatis-Flex 多主键就是在 Entity 类里有多个 `@Id` 注解标识而已,比如: +MyBatis-Flex 多主键就是在 Entity 类里有多个 `@Id` 注解标识而已,比如: ```java @@ -583,11 +579,11 @@ public class Account { } ``` -当我们保存数据的时候,Account 的 id 主键为自增,而 otherId 主键则通过 uuid 生成。 +保存数据时,Account 的 id 主键为自增,而 otherId 主键则通过 uuid 生成。 ### 自定义主键生成器 -第 1 步:编写一个类,实现 `IKeyGenerator` 接口,例如: +第 1 步:编写一个类,实现 `IKeyGenerator` 接口: ```java public class UUIDKeyGenerator implements IKeyGenerator { @@ -599,7 +595,7 @@ public class UUIDKeyGenerator implements IKeyGenerator { } ``` -第 2 步:注册 UUIDKeyGenerator +第 2 步:注册 `UUIDKeyGenerator`: ```java KeyGeneratorFactory.register("myUUID", new UUIDKeyGenerator()); @@ -622,7 +618,6 @@ public class Account { ### 使用数据库 Sequence 生成 ```java - @Table("tb_account") public class Account { @@ -636,11 +631,13 @@ public class Account { ## 更多文档 -- [https://mybatis-flex.com](https://mybatis-flex.com) +- [mybatis-flex](https://mybatis-flex.com) ## 还有问题? 加入 QQ 交流群: 532992631 -![](./docs/assets/images/qq_group.png) +

+ +