diff --git a/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/mapper/BaseMapper.java b/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/mapper/BaseMapper.java index 2d19d62c6b3cfd39dcd4e005b8e8abea48f5b288..9339b57eca16f1bc05a47c598e292026bee5fb91 100644 --- a/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/mapper/BaseMapper.java +++ b/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/mapper/BaseMapper.java @@ -23,6 +23,7 @@ import net.hasor.dbvisitor.page.PageResult; import java.io.Serializable; import java.sql.SQLException; import java.util.List; +import java.util.Map; /** * Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得 CRUD 功能 @@ -110,12 +111,30 @@ public interface BaseMapper extends Mapper { */ int updateById(T entity) throws RuntimeSQLException; + /** + * 修改,忽略为null的字段 + * @param entity 实体对象 + */ + int updateByIdIgnoreNull(T entity) throws RuntimeSQLException; + + /** + * 局部修改 + * @param map 局部更新对象 + */ + int updateByMap(Map map) throws RuntimeSQLException; + /** * 保存或修改 * @param entity 实体对象 */ int upsertById(T entity) throws RuntimeSQLException; + /** + * 保存或修改,忽略为null的字段 + * @param entity 实体对象 + */ + int upsertByIdIgnoreNull(T entity) throws RuntimeSQLException; + /** * 删除 * @param entity 实体对象 diff --git a/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/session/BaseMapperHandler.java b/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/session/BaseMapperHandler.java index 0739811cdb21c2e4779dc216d5757607684ec176..b2f7a7ed67e5b927a4b0955ca04499d2fe1a1022 100644 --- a/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/session/BaseMapperHandler.java +++ b/dbvisitor/src/main/java/net/hasor/dbvisitor/dal/session/BaseMapperHandler.java @@ -14,6 +14,7 @@ * limitations under the License. */ package net.hasor.dbvisitor.dal.session; +import net.hasor.cobble.StringUtils; import net.hasor.dbvisitor.dal.mapper.BaseMapper; import net.hasor.dbvisitor.lambda.EntityDeleteOperation; import net.hasor.dbvisitor.lambda.EntityQueryOperation; @@ -27,9 +28,8 @@ import net.hasor.dbvisitor.page.PageResult; import java.io.Serializable; import java.sql.SQLException; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; /** @@ -76,8 +76,7 @@ class BaseMapperHandler implements BaseMapper { return tableMapping.getProperties().stream().filter(ColumnMapping::isPrimaryKey).collect(Collectors.toList()); } - @Override - public int updateById(Object entity) throws RuntimeSQLException { + private int updateById(Object entity, boolean ignoreNull) { if (entity == null) { throw new NullPointerException("entity is null."); } @@ -89,16 +88,27 @@ class BaseMapperHandler implements BaseMapper { EntityUpdateOperation update = update(); + update.allowReplaceRow(); + + boolean isPrimaryKeyEmpty = true; for (ColumnMapping pk : pks) { Object o = pk.getHandler().get(entity); - if (o == null) { - update.and().isNull(pk.getColumn()); - } else { - update.and().eq(pk.getColumn(), o); - } + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + update.and().eq(pk.getProperty(), o); + isPrimaryKeyEmpty = false; + } + + if (isPrimaryKeyEmpty) { + throw new NullPointerException("primary key is empty."); } try { + if (ignoreNull) { + return update.updateBySample(entity).doUpdate(); + } return update.updateTo(entity).doUpdate(); } catch (SQLException e) { throw new RuntimeSQLException(e); @@ -106,7 +116,70 @@ class BaseMapperHandler implements BaseMapper { } @Override - public int upsertById(Object entity) throws RuntimeSQLException { + public int updateById(Object entity) throws RuntimeSQLException { + return updateById(entity, false); + } + + @Override + public int updateByIdIgnoreNull(Object entity) throws RuntimeSQLException { + return updateById(entity, true); + } + + @Override + public int updateByMap(Map map) throws RuntimeSQLException { + if (map == null) { + throw new NullPointerException("map is null."); + } + + // column 转 property + Map tempMap = new HashMap<>(); + map.forEach((key, value) -> { + if (key.contains("_")) { + tempMap.put(StringUtils.lineToHump(key), value); + } else { + tempMap.put(key, value); + } + }); + map.clear(); + map.putAll(tempMap); + + List pks = foundPrimaryKey(); + if (pks.isEmpty()) { + throw new RuntimeSQLException(entityType() + " no primary key is identified"); + } + + EntityUpdateOperation update = update(); + + boolean isPrimaryKeyEmpty = true; + for (ColumnMapping pk : pks) { + String key = pk.getProperty(); + Object o = map.get(key); + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + update.and().eq(pk.getProperty(), o); + map.remove(key); + + isPrimaryKeyEmpty = false; + } + + if (isPrimaryKeyEmpty) { + throw new NullPointerException("primary key is empty."); + } + + if (map.size() <= 0) { + throw new NullPointerException("map is empty."); + } + + try { + return update.updateByMap(map).doUpdate(); + } catch (SQLException e) { + throw new RuntimeSQLException(e); + } + } + + private int upsertById(Object entity, boolean ignoreNull) throws RuntimeSQLException { if (entity == null) { throw new NullPointerException("entity is null."); } @@ -119,21 +192,32 @@ class BaseMapperHandler implements BaseMapper { EntityQueryOperation query = query(); EntityUpdateOperation update = update(); + update.allowReplaceRow(); + + boolean isPrimaryKeyEmpty = true; for (ColumnMapping pk : pks) { Object o = pk.getHandler().get(entity); - if (o == null) { - query.and().isNull(pk.getColumn()); - update.and().isNull(pk.getColumn()); - } else { - query.and().eq(pk.getColumn(), o); - update.and().eq(pk.getColumn(), o); - } + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + query.and().eq(pk.getProperty(), o); + update.and().eq(pk.getProperty(), o); + + isPrimaryKeyEmpty = false; + } + + if (isPrimaryKeyEmpty) { + throw new NullPointerException("primary key is empty."); } try { if (query.queryForCount() == 0) { return insert().applyEntity(entity).executeSumResult(); } else { + if (ignoreNull) { + return update.updateBySample(entity).doUpdate(); + } return update.updateTo(entity).doUpdate(); } } catch (SQLException e) { @@ -141,6 +225,16 @@ class BaseMapperHandler implements BaseMapper { } } + @Override + public int upsertById(Object entity) throws RuntimeSQLException { + return upsertById(entity, false); + } + + @Override + public int upsertByIdIgnoreNull(Object entity) throws RuntimeSQLException { + return upsertById(entity, true); + } + @Override public int delete(Object entity) throws RuntimeSQLException { if (entity == null) { @@ -154,13 +248,20 @@ class BaseMapperHandler implements BaseMapper { EntityDeleteOperation delete = delete(); + boolean isPrimaryKeyEmpty = true; for (ColumnMapping pk : pks) { Object o = pk.getHandler().get(entity); - if (o == null) { - delete.and().isNull(pk.getColumn()); - } else { - delete.and().eq(pk.getColumn(), o); - } + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + delete.and().eq(pk.getProperty(), o); + + isPrimaryKeyEmpty = false; + } + + if (isPrimaryKeyEmpty) { + throw new NullPointerException("primary key is empty."); } try { @@ -182,17 +283,21 @@ class BaseMapperHandler implements BaseMapper { } EntityDeleteOperation delete = delete(); - if (pks.size() == 1) { - delete.and().eq(pks.get(0).getColumn(), id); - } else { - for (ColumnMapping pk : pks) { - Object o = pk.getHandler().get(id); - if (o == null) { - delete.and().isNull(pk.getColumn()); - } else { - delete.and().eq(pk.getColumn(), o); - } - } + + boolean isPrimaryKeyEmpty = true; + for (ColumnMapping pk : pks) { + Object o = pks.size() == 1 ? id : pk.getHandler().get(id); + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + delete.and().eq(pk.getProperty(), o); + + isPrimaryKeyEmpty = false; + } + + if (isPrimaryKeyEmpty) { + throw new NullPointerException("primary key is empty."); } try { @@ -213,27 +318,35 @@ class BaseMapperHandler implements BaseMapper { throw new RuntimeSQLException(entityType() + " no primary key is identified"); } + EntityDeleteOperation delete = delete(); + if (pks.size() == 1) { try { - return delete().and().in(pks.get(0).getColumn(), idList).doDelete(); + return delete.and().in(pks.get(0).getProperty(), idList).doDelete(); } catch (SQLException e) { throw new RuntimeSQLException(e); } } else { - EntityDeleteOperation delete = delete(); + AtomicBoolean isPrimaryKeyEmpty = new AtomicBoolean(true); for (Object obj : idList) { delete.or(queryCompare -> { - for (ColumnMapping pkColumn : pks) { - Object keyValue = pkColumn.getHandler().get(obj); - if (keyValue == null) { - queryCompare.and().isNull(pkColumn.getColumn()); - } else { - queryCompare.and().eq(pkColumn.getColumn(), keyValue); - } + for (ColumnMapping pk : pks) { + Object o = pk.getHandler().get(obj); + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + queryCompare.and().eq(pk.getProperty(), o); + + isPrimaryKeyEmpty.set(false); } }); } + if (isPrimaryKeyEmpty.get()) { + throw new NullPointerException("primary key is empty."); + } + try { return delete.doDelete(); } catch (SQLException e) { @@ -254,17 +367,14 @@ class BaseMapperHandler implements BaseMapper { } EntityQueryOperation query = query(); - if (pks.size() == 1) { - query.and().eq(pks.get(0).getColumn(), id); - } else { - for (ColumnMapping pk : pks) { - Object o = pk.getHandler().get(id); - if (o == null) { - query.and().isNull(pk.getColumn()); - } else { - query.and().eq(pk.getColumn(), o); - } - } + + for (ColumnMapping pk : pks) { + Object o = pks.size() == 1 ? id : pk.getHandler().get(id); + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + query.and().eq(pk.getProperty(), o); } try { @@ -285,23 +395,24 @@ class BaseMapperHandler implements BaseMapper { throw new RuntimeSQLException(entityType() + " no primary key is identified"); } + EntityQueryOperation query = query(); + if (pks.size() == 1) { try { - return query().and().in(pks.get(0).getColumn(), idList).queryForList(); + return query.and().in(pks.get(0).getProperty(), idList).queryForList(); } catch (SQLException e) { throw new RuntimeSQLException(e); } } else { - EntityQueryOperation query = query(); for (Object obj : idList) { query.or(queryCompare -> { - for (ColumnMapping pkColumn : pks) { - Object keyValue = pkColumn.getHandler().get(obj); - if (keyValue == null) { - queryCompare.and().isNull(pkColumn.getColumn()); - } else { - queryCompare.and().eq(pkColumn.getColumn(), keyValue); - } + for (ColumnMapping pk : pks) { + Object o = pk.getHandler().get(obj); + + if (o == null) continue; + if (o instanceof String && StringUtils.isBlank((String)o)) continue; + + queryCompare.and().eq(pk.getProperty(), o); } }); } @@ -321,7 +432,7 @@ class BaseMapperHandler implements BaseMapper { for (ColumnMapping mapping : getMapping().getProperties()) { Object value = mapping.getHandler().get(sample); if (value != null) { - query.and().eq(mapping.getColumn(), value); + query.and().eq(mapping.getProperty(), value); } } }