From 233b5f5052ae28532cc1b7c06ec68136df1fe8bc Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Thu, 10 Aug 2023 16:19:52 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20saveOrUpdateBa?= =?UTF-8?q?tch=20=E6=96=B9=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatisflex/core/service/IService.java | 83 ++++++++++++++----- 1 file changed, 62 insertions(+), 21 deletions(-) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java index 3504283e..389c46a3 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java @@ -46,8 +46,6 @@ public interface IService { int DEFAULT_BATCH_SIZE = 1000; - // ===== 保存(增)操作 ===== - /** *

获取对应实体类(Entity)的基础映射类(BaseMapper)。 * @@ -55,27 +53,18 @@ public interface IService { */ BaseMapper getMapper(); + // ===== 保存(增)操作 ===== + /** *

保存实体类对象数据。 * * @param entity 实体类对象 * @return {@code true} 保存成功,{@code false} 保存失败。 - * @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略 - * {@code null} 字段的数据,使数据库配置的默认值生效。 + * @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略实体类 + * {@code null} 属性的数据,使数据库配置的默认值生效。 */ default boolean save(T entity) { - return SqlUtil.toBool(getMapper().insertSelective(entity)); - } - - /** - *

保存或者更新实体类对象数据。 - * - * @param entity 实体类对象 - * @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。 - * @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据。 - */ - default boolean saveOrUpdate(T entity) { - return SqlUtil.toBool(getMapper().insertOrUpdate(entity, true)); + return SqlUtil.toBool(getMapper().insert(entity, true)); } /** @@ -83,6 +72,8 @@ public interface IService { * * @param entities 实体类对象 * @return {@code true} 保存成功,{@code false} 保存失败。 + * @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略实体类 + * {@code null} 属性的数据,使数据库配置的默认值生效。 */ default boolean saveBatch(Collection entities) { return saveBatch(entities, DEFAULT_BATCH_SIZE); @@ -94,10 +85,12 @@ public interface IService { * @param entities 实体类对象 * @param batchSize 每次保存切分的数量 * @return {@code true} 保存成功,{@code false} 保存失败。 + * @apiNote 默认调用的是 {@link BaseMapper#insertSelective(Object)} 方法,忽略实体类 + * {@code null} 属性的数据,使数据库配置的默认值生效。 */ default boolean saveBatch(Collection entities, int batchSize) { Class> usefulClass = (Class>) ClassUtil.getUsefulClass(getMapper().getClass()); - return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insert)); + return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insertSelective)); } /** @@ -105,7 +98,10 @@ public interface IService { * * @param entities 实体类对象 * @return {@code true} 保存成功,{@code false} 保存失败。 + * @deprecated 为保持 Service 层 API 一致性,默认方法都是忽略实体类 {@code null} 属性的数据。 + * 另外,该方法将在 1.6.0 版本被移除。 */ + @Deprecated default boolean saveBatchSelective(Collection entities) { return saveBatchSelective(entities, DEFAULT_BATCH_SIZE); } @@ -116,12 +112,53 @@ public interface IService { * @param entities 实体类对象 * @param batchSize 每次保存切分的数量 * @return {@code true} 保存成功,{@code false} 保存失败。 + * @deprecated 为保持 Service 层 API 一致性,默认方法都是忽略实体类 {@code null} 属性的数据。 + * 另外,该方法将在 1.6.0 版本被移除。 */ + @Deprecated default boolean saveBatchSelective(Collection entities, int batchSize) { Class> usefulClass = (Class>) ClassUtil.getUsefulClass(getMapper().getClass()); return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insertSelective)); } + /** + *

保存或者更新实体类对象数据。 + * + * @param entity 实体类对象 + * @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。 + * @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据,无论新增还是更新都会忽略实体类 + * {@code null} 属性的数据。 + */ + default boolean saveOrUpdate(T entity) { + return SqlUtil.toBool(getMapper().insertOrUpdate(entity, true)); + } + + /** + *

保存或者更新实体类对象数据。 + * + * @param entities 实体类对象 + * @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。 + * @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据,无论新增还是更新都会忽略实体类 + * {@code null} 属性的数据。 + */ + default boolean saveOrUpdateBatch(Collection entities) { + return saveOrUpdateBatch(entities, DEFAULT_BATCH_SIZE); + } + + /** + *

保存或者更新实体类对象数据。 + * + * @param entities 实体类对象 + * @param batchSize 每次操作切分的数量 + * @return {@code true} 保存或更新成功,{@code false} 保存或更新失败。 + * @apiNote 如果实体类对象主键有值,则更新数据,若没有值,则保存数据,无论新增还是更新都会忽略实体类 + * {@code null} 属性的数据。 + */ + default boolean saveOrUpdateBatch(Collection entities, int batchSize) { + Class> usefulClass = (Class>) ClassUtil.getUsefulClass(getMapper().getClass()); + return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::insertOrUpdateSelective)); + } + // ===== 删除(删)操作 ===== /** @@ -167,8 +204,6 @@ public interface IService { return SqlUtil.toBool(getMapper().deleteBatchByIds(ids)); } - // ===== 更新(改)操作 ===== - /** *

根据 {@link Map} 构建查询条件删除数据。 * @@ -183,6 +218,8 @@ public interface IService { return remove(query().where(query)); } + // ===== 更新(改)操作 ===== + /** *

根据数据主键更新数据。 * @@ -211,6 +248,7 @@ public interface IService { * @param entity 实体类对象 * @param query 查询条件 * @return {@code true} 更新成功,{@code false} 更新失败。 + * @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。 */ default boolean update(T entity, Map query) { return update(entity, query().where(query)); @@ -222,6 +260,7 @@ public interface IService { * @param entity 实体类对象 * @param query 查询条件 * @return {@code true} 更新成功,{@code false} 更新失败。 + * @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。 */ default boolean update(T entity, QueryWrapper query) { return SqlUtil.toBool(getMapper().updateByQuery(entity, query)); @@ -233,6 +272,7 @@ public interface IService { * @param entity 实体类对象 * @param condition 查询条件 * @return {@code true} 更新成功,{@code false} 更新失败。 + * @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。 */ default boolean update(T entity, QueryCondition condition) { return update(entity, query().where(condition)); @@ -243,6 +283,7 @@ public interface IService { * * @param entities 实体类对象集合 * @return boolean {@code true} 更新成功,{@code false} 更新失败。 + * @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。 */ default boolean updateBatch(Collection entities) { return updateBatch(entities, DEFAULT_BATCH_SIZE); @@ -254,13 +295,13 @@ public interface IService { * @param entities 实体类对象集合 * @param batchSize 每批次更新数量 * @return {@code true} 更新成功,{@code false} 更新失败。 + * @apiNote 若实体类属性数据为 {@code null},该属性不会新到数据库。 */ default boolean updateBatch(Collection entities, int batchSize) { Class> usefulClass = (Class>) ClassUtil.getUsefulClass(getMapper().getClass()); return SqlUtil.toBool(Db.executeBatch(entities, batchSize, usefulClass, BaseMapper::update)); } - // ===== 查询(查)操作 ===== /** @@ -428,7 +469,7 @@ public interface IService { * @return {@code true} 数据存在,{@code false} 数据不存在。 */ default boolean exists(QueryCondition condition) { - return CollectionUtil.isNotEmpty(getMapper().selectListByCondition(condition,1L)); + return CollectionUtil.isNotEmpty(getMapper().selectListByCondition(condition, 1L)); } /** From d7535294ef6d190ec7e6b859280a6b4867db353e Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Thu, 10 Aug 2023 16:20:13 +0800 Subject: [PATCH 2/5] =?UTF-8?q?test:=20=E6=B5=8B=E8=AF=95=20saveOrUpdateBa?= =?UTF-8?q?tch=20=E6=96=B9=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/mybatisflex/test/ArticleTester.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/ArticleTester.java b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/ArticleTester.java index f195dd04..aeae9ef0 100644 --- a/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/ArticleTester.java +++ b/mybatis-flex-test/mybatis-flex-native-test/src/main/java/com/mybatisflex/test/ArticleTester.java @@ -77,10 +77,7 @@ public class ArticleTester { articles.add(article); } - Db.executeBatch(articles, ArticleMapper.class, (mapper, article) -> { - System.out.println("article: " + article); - mapper.insertSelective(article); - }); + Db.executeBatch(articles, ArticleMapper.class, ArticleMapper::insertOrUpdateSelective); articleMapper.selectAll().forEach(System.out::println); } From c2ea3f52c15029b446eb7374a570ae4d3274d2f6 Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Thu, 10 Aug 2023 16:20:26 +0800 Subject: [PATCH 3/5] =?UTF-8?q?test:=20=E5=87=BD=E6=95=B0=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=B5=8B=E8=AF=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatisflex/coretest/FunctionSqlTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/FunctionSqlTest.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/FunctionSqlTest.java index 790fed6c..c6186c46 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/FunctionSqlTest.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/FunctionSqlTest.java @@ -52,4 +52,27 @@ public class FunctionSqlTest { System.out.println(sql); } + @Test + public void test03() { + String sql = QueryWrapper.create() + .select() + .from(ACCOUNT) + .where(upper(ACCOUNT.USER_NAME).likeRaw(raw("UPPER('ws')"))) + .toSQL(); + + System.out.println(sql); + } + + @Test + public void test04() { + String sql = QueryWrapper.create() + .select() + .from(ACCOUNT) +// .where("FIND_IN_SET(?, `id`)", 100) + .where(findInSet(number(100), ACCOUNT.ID).eq(true)) + .toSQL(); + + System.out.println(sql); + } + } From 3c95f07e6c2ae4949a4f57b17a93362931ad52fe Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Thu, 10 Aug 2023 16:45:21 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=20Object=20=E7=9B=B8=E5=85=B3=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mybatisflex/core/service/IService.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java index 389c46a3..64db3362 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/service/IService.java @@ -390,6 +390,70 @@ public interface IService { return Optional.ofNullable(getOne(condition)); } + /** + *

查询结果集中第一列,且第一条数据。 + * + * @param query 查询条件 + * @return 数据值 + */ + default Object getObj(QueryWrapper query) { + return getMapper().selectObjectByQuery(query); + } + + /** + *

查询结果集中第一列,且第一条数据,并封装为 {@link Optional} 返回。 + * + * @param query 查询条件 + * @return 数据值 + */ + default Optional getObjOpt(QueryWrapper query) { + return Optional.ofNullable(getObj(query)); + } + + /** + *

查询结果集中第一列,且第一条数据,并转换为指定类型,比如 {@code Long}, {@code String} 等。 + * + * @param query 查询条件 + * @param asType 接收的数据类型 + * @return 数据值 + */ + default R getObjAs(QueryWrapper query, Class asType) { + return getMapper().selectObjectByQueryAs(query, asType); + } + + /** + *

查询结果集中第一列,且第一条数据,并转换为指定类型,比如 {@code Long}, {@code String} + * 等,封装为 {@link Optional} 返回。 + * + * @param query 查询条件 + * @param asType 接收的数据类型 + * @return 数据值 + */ + default Optional getObjAsOpt(QueryWrapper query, Class asType) { + return Optional.ofNullable(getObjAs(query, asType)); + } + + /** + *

查询结果集中第一列所有数据。 + * + * @param query 查询条件 + * @return 数据列表 + */ + default List objList(QueryWrapper query) { + return getMapper().selectObjectListByQuery(query); + } + + /** + *

查询结果集中第一列所有数据,并转换为指定类型,比如 {@code Long}, {@code String} 等。 + * + * @param query 查询条件 + * @param asType 接收的数据类型 + * @return 数据列表 + */ + default List objListAs(QueryWrapper query, Class asType) { + return getMapper().selectObjectListByQueryAs(query, asType); + } + /** *

查询所有数据。 * From e5f2c41d04405d5abf2e2cb29491246d22438d70 Mon Sep 17 00:00:00 2001 From: Suomm <1474983351@qq.com> Date: Thu, 10 Aug 2023 16:45:38 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=20Object=20=E7=9B=B8=E5=85=B3=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E7=BC=93=E5=AD=98=E7=A4=BA=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/templates/enjoy/serviceImpl.tpl | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/mybatis-flex-codegen/src/main/resources/templates/enjoy/serviceImpl.tpl b/mybatis-flex-codegen/src/main/resources/templates/enjoy/serviceImpl.tpl index edcb3693..c1669d7e 100644 --- a/mybatis-flex-codegen/src/main/resources/templates/enjoy/serviceImpl.tpl +++ b/mybatis-flex-codegen/src/main/resources/templates/enjoy/serviceImpl.tpl @@ -87,6 +87,30 @@ public class #(table.buildServiceImplClassName()) extends #(serviceImplConfig.bu return super.getOneAs(query, asType); } + @Override + @Cacheable(key = "#root.methodName + ':' + #query.toSQL()") + public Object getObj(QueryWrapper query) { + return super.getObj(query); + } + + @Override + @Cacheable(key = "#root.methodName + ':' + #query.toSQL()") + public R getObjAs(QueryWrapper query, Class asType) { + return super.getObjAs(query, asType); + } + + @Override + @Cacheable(key = "#root.methodName + ':' + #query.toSQL()") + public List objList(QueryWrapper query) { + return super.objList(query); + } + + @Override + @Cacheable(key = "#root.methodName + ':' + #query.toSQL()") + public List objListAs(QueryWrapper query, Class asType) { + return super.objListAs(query, asType); + } + @Override @Cacheable(key = "#root.methodName + ':' + #query.toSQL()") public List<#(entityClassName)> list(QueryWrapper query) {