From 157dd0eafeb8652b9cd4369e6b164091ef3cb9ff Mon Sep 17 00:00:00 2001 From: lhpqaq <657407891@qq.com> Date: Thu, 19 Sep 2024 14:35:34 +0800 Subject: [PATCH] add partial flag --- .../manager/dao/repository/BaseDao.java | 12 +- .../manager/dao/sql/BaseSqlProvider.java | 19 +- .../bigtop/manager/dao/sql/SQLBuilder.java | 184 +++++++++++------- 3 files changed, 134 insertions(+), 81 deletions(-) diff --git a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/BaseDao.java b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/BaseDao.java index 2b5dbb64..a98d1155 100644 --- a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/BaseDao.java +++ b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/repository/BaseDao.java @@ -65,12 +65,12 @@ public interface BaseDao { */ @UpdateProvider(type = BaseSqlProvider.class, method = "partialUpdateByIds") int partialUpdateByIds(List entities); - // - // /** - // * Fully update the entity by primary key. - // */ - // @UpdateProvider(type = BaseSqlProvider.class, method = "updateByIds") - // int updateByIds(List entities); + + /** + * Fully update the entity by primary key. + */ + @UpdateProvider(type = BaseSqlProvider.class, method = "updateByIds") + int updateByIds(List entities); /** * Query the entity by primary key. diff --git a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/BaseSqlProvider.java b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/BaseSqlProvider.java index 5f074af7..d2f92968 100644 --- a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/BaseSqlProvider.java +++ b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/BaseSqlProvider.java @@ -68,7 +68,7 @@ public String partialUpdateById(Entity entity, ProviderContext context) Class entityClass = entity.getClass(); TableMetaData tableMetaData = TableMetaData.forClass(entityClass); - return SQLBuilder.partialUpdate(tableMetaData, entity, databaseId); + return SQLBuilder.update(tableMetaData, entity, databaseId, true); } public String partialUpdateByIds(List entities, ProviderContext context) { @@ -81,7 +81,7 @@ public String partialUpdateByIds(List entities, ProviderContext TableMetaData tableMetaData = TableMetaData.forClass(entityClass); - return SQLBuilder.partialUpdateList(tableMetaData, entities, databaseId); + return SQLBuilder.updateList(tableMetaData, entities, databaseId, true); } public String updateById(Entity entity, ProviderContext context) { @@ -92,7 +92,20 @@ public String updateById(Entity entity, ProviderContext context) { Class entityClass = entity.getClass(); TableMetaData tableMetaData = TableMetaData.forClass(entityClass); - return SQLBuilder.update(tableMetaData, entity, databaseId); + return SQLBuilder.update(tableMetaData, entity, databaseId, false); + } + + public String updateByIds(List entities, ProviderContext context) { + Assert.notNull(entities, "entities must not be null"); + Assert.notEmpty(entities, "entities list must not be empty"); + + String databaseId = context.getDatabaseId(); + + Class entityClass = entities.get(0).getClass(); + + TableMetaData tableMetaData = TableMetaData.forClass(entityClass); + + return SQLBuilder.updateList(tableMetaData, entities, databaseId, false); } public String selectById(Serializable id, ProviderContext context) { diff --git a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java index 7f29b19b..a0e29d41 100644 --- a/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java +++ b/bigtop-manager-dao/src/main/java/org/apache/bigtop/manager/dao/sql/SQLBuilder.java @@ -193,7 +193,8 @@ public static String insertList(TableMetaData tableMetaData, List String partialUpdate(TableMetaData tableMetaData, Entity entity, String databaseId) { + public static String update( + TableMetaData tableMetaData, Entity entity, String databaseId, boolean partial) { Class entityClass = entity.getClass(); Map fieldColumnMap = tableMetaData.getFieldColumnMap(); @@ -211,59 +212,9 @@ public static String partialUpdate(TableMetaData tableMetaData, Entity continue; } Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity); - if (!ObjectUtils.isEmpty(value)) { - sql.SET(getEquals(entry.getValue(), entry.getKey())); - } - } - - sql.WHERE(getEquals(tableMetaData.getPkColumn(), tableMetaData.getPkProperty())); - break; - } - case POSTGRESQL: { - sql.UPDATE("\"" + tableMetaData.getTableName() + "\""); - for (Map.Entry entry : fieldColumnMap.entrySet()) { - // Ignore primary key - if (Objects.equals(entry.getKey(), tableMetaData.getPkProperty())) { - continue; - } - PropertyDescriptor ps = BeanUtils.getPropertyDescriptor(entityClass, entry.getKey()); - if (ps == null || ps.getReadMethod() == null) { - continue; - } - Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity); - if (!ObjectUtils.isEmpty(value)) { - sql.SET("\"" + getEquals(entry.getValue() + "\"", entry.getKey())); - } - } - sql.WHERE(getEquals(tableMetaData.getPkColumn(), tableMetaData.getPkProperty())); - break; - } - default: { - log.error("Unsupported data source"); - } - } - - return sql.toString(); - } - - public static String update(TableMetaData tableMetaData, Entity entity, String databaseId) { - Class entityClass = entity.getClass(); - Map fieldColumnMap = tableMetaData.getFieldColumnMap(); - - SQL sql = new SQL(); - switch (DBType.toType(databaseId)) { - case MYSQL: { - sql.UPDATE(tableMetaData.getTableName()); - for (Map.Entry entry : fieldColumnMap.entrySet()) { - // Ignore primary key - if (Objects.equals(entry.getKey(), tableMetaData.getPkProperty())) { - continue; - } - PropertyDescriptor ps = BeanUtils.getPropertyDescriptor(entityClass, entry.getKey()); - if (ps == null || ps.getReadMethod() == null) { + if (ObjectUtils.isEmpty(value) && partial) { continue; } - Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity); Field field = ReflectionUtils.findField(entityClass, entry.getKey()); if (field != null) { Column column = field.getAnnotation(Column.class); @@ -289,6 +240,9 @@ public static String update(TableMetaData tableMetaData, Entity entity, continue; } Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity); + if (ObjectUtils.isEmpty(value) && partial) { + continue; + } Field field = ReflectionUtils.findField(entityClass, entry.getKey()); if (field != null) { Column column = field.getAnnotation(Column.class); @@ -309,15 +263,8 @@ public static String update(TableMetaData tableMetaData, Entity entity, return sql.toString(); } - public static String escapeSingleQuote(String input) { - if (input != null) { - return input.replace("'", "''"); - } - return null; - } - - public static String partialUpdateList( - TableMetaData tableMetaData, List entities, String databaseId) { + public static String updateList( + TableMetaData tableMetaData, List entities, String databaseId, boolean partial) { if (entities == null || entities.isEmpty()) { throw new IllegalArgumentException("Entities list must not be null or empty"); } @@ -325,10 +272,9 @@ public static String partialUpdateList( Class entityClass = entities.get(0).getClass(); Map fieldColumnMap = tableMetaData.getFieldColumnMap(); - SQL sql = new SQL(); + StringBuilder sqlBuilder = new StringBuilder(); switch (DBType.toType(databaseId)) { case MYSQL: { - StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder .append("UPDATE ") .append(tableMetaData.getTableName()) @@ -336,8 +282,6 @@ public static String partialUpdateList( Map setClauses = new LinkedHashMap<>(); String primaryKey = "id"; for (Map.Entry entry : fieldColumnMap.entrySet()) { - log.info("entry: {}", entry); - log.info("primaryKey: {}", tableMetaData.getPkProperty()); // Ignore primary key if (Objects.equals(entry.getKey(), tableMetaData.getPkProperty())) { primaryKey = entry.getValue(); @@ -346,7 +290,6 @@ public static String partialUpdateList( StringBuilder caseClause = new StringBuilder(); caseClause.append(entry.getValue()).append(" = CASE "); - log.info(caseClause.toString()); for (Entity entity : entities) { PropertyDescriptor ps = BeanUtils.getPropertyDescriptor(entityClass, entry.getKey()); if (ps == null || ps.getReadMethod() == null) { @@ -354,22 +297,115 @@ public static String partialUpdateList( } Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity); + PropertyDescriptor pkPs = + BeanUtils.getPropertyDescriptor(entityClass, tableMetaData.getPkProperty()); + if (pkPs == null || pkPs.getReadMethod() == null) { + continue; + } + Object pkValue = ReflectionUtils.invokeMethod(pkPs.getReadMethod(), entity); + if (!ObjectUtils.isEmpty(value)) { + caseClause + .append("WHEN ") + .append(primaryKey) + .append(" = '") + .append(pkValue) + .append("' THEN '") + .append(escapeSingleQuote(value.toString())) + .append("' "); + } else if (!partial) { + Field field = ReflectionUtils.findField(entityClass, entry.getKey()); + if (field != null) { + Column column = field.getAnnotation(Column.class); + if (column != null && !column.nullable() && value == null) { + continue; + } + } + caseClause + .append("WHEN ") + .append(primaryKey) + .append(" = '") + .append(pkValue) + .append("' THEN NULL "); + } + } + caseClause.append("ELSE ").append(entry.getValue()).append(" "); + caseClause.append("END"); + setClauses.put(entry.getValue(), caseClause); + } + sqlBuilder.append(String.join(", ", setClauses.values())); + + sqlBuilder.append(" WHERE ").append(primaryKey).append(" IN ("); + String pkValues = entities.stream() + .map(entity -> { PropertyDescriptor pkPs = BeanUtils.getPropertyDescriptor(entityClass, tableMetaData.getPkProperty()); Object pkValue = ReflectionUtils.invokeMethod(pkPs.getReadMethod(), entity); + return "'" + pkValue.toString() + "'"; + }) + .collect(Collectors.joining(", ")); + + sqlBuilder.append(pkValues).append(")"); + break; + } + case POSTGRESQL: { + sqlBuilder + .append("UPDATE ") + .append("\"") + .append(tableMetaData.getTableName()) + .append("\"") + .append(" SET "); + Map setClauses = new LinkedHashMap<>(); + String primaryKey = "\"id\""; + for (Map.Entry entry : fieldColumnMap.entrySet()) { + // Ignore primary key + if (Objects.equals(entry.getKey(), tableMetaData.getPkProperty())) { + primaryKey = "\"" + entry.getValue() + "\""; + continue; + } + + StringBuilder caseClause = new StringBuilder(); + caseClause.append(entry.getValue()).append(" = CASE "); + + for (Entity entity : entities) { + PropertyDescriptor ps = BeanUtils.getPropertyDescriptor(entityClass, entry.getKey()); + if (ps == null || ps.getReadMethod() == null) { + continue; + } + Object value = ReflectionUtils.invokeMethod(ps.getReadMethod(), entity); + PropertyDescriptor pkPs = + BeanUtils.getPropertyDescriptor(entityClass, tableMetaData.getPkProperty()); + if (pkPs == null || pkPs.getReadMethod() == null) { + continue; + } + Object pkValue = ReflectionUtils.invokeMethod(pkPs.getReadMethod(), entity); + if (!ObjectUtils.isEmpty(value)) { caseClause .append("WHEN ") .append(primaryKey) .append(" = '") - .append(pkValue.toString()) + .append(pkValue) .append("' THEN '") .append(escapeSingleQuote(value.toString())) .append("' "); + } else if (!partial) { + Field field = ReflectionUtils.findField(entityClass, entry.getKey()); + if (field != null) { + Column column = field.getAnnotation(Column.class); + if (column != null && !column.nullable() && value == null) { + continue; + } + } + caseClause + .append("WHEN ") + .append(primaryKey) + .append(" = '") + .append(pkValue) + .append("' THEN NULL "); } } - + caseClause.append("ELSE \"").append(entry.getValue()).append("\" "); caseClause.append("END"); setClauses.put(entry.getValue(), caseClause); } @@ -386,9 +422,6 @@ public static String partialUpdateList( .collect(Collectors.joining(", ")); sqlBuilder.append(pkValues).append(")"); - return sqlBuilder.toString(); - } - case POSTGRESQL: { break; } default: { @@ -396,7 +429,7 @@ public static String partialUpdateList( } } - return sql.toString(); + return sqlBuilder.toString(); } public static String selectById(TableMetaData tableMetaData, String databaseId, Serializable id) { @@ -575,6 +608,13 @@ private static String getTokenParam(String property) { return "#{" + property + "}"; } + private static String escapeSingleQuote(String input) { + if (input != null) { + return input.replace("'", "''"); + } + return null; + } + private static SQL mysqlCondition(Condition condition, TableMetaData tableMetaData) throws IllegalAccessException {