重构 DAO 基础代码。

pull/1/head
ZhouXY108 2023-02-11 20:34:16 +08:00
parent 960a4d4ef3
commit cbc2711540
11 changed files with 292 additions and 182 deletions

View File

@ -4,7 +4,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
/** /**
* *
* *
* <p> * <p>
* *
@ -14,18 +14,18 @@ import org.springframework.web.bind.annotation.ResponseStatus;
* @see xyz.zhouxy.plusone.util.AssertResult * @see xyz.zhouxy.plusone.util.AssertResult
*/ */
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class DataOperationNumberException extends PlusoneException { public class DataOperationResultException extends PlusoneException {
@java.io.Serial @java.io.Serial
private static final long serialVersionUID = -9220765735990318186L; private static final long serialVersionUID = -9220765735990318186L;
public static final int ERROR_CODE = 4110200; public static final int ERROR_CODE = 4110200;
public DataOperationNumberException() { public DataOperationResultException() {
super(ERROR_CODE, "数据操作的行数不符合预期"); super(ERROR_CODE, "数据操作结果不符合预期");
} }
public DataOperationNumberException(String message) { public DataOperationResultException(String message) {
super(ERROR_CODE, message); super(ERROR_CODE, message);
} }
} }

View File

@ -1,10 +1,10 @@
package xyz.zhouxy.plusone.util; package xyz.zhouxy.plusone.util;
import xyz.zhouxy.plusone.exception.DataNotExistException; import xyz.zhouxy.plusone.exception.DataNotExistException;
import xyz.zhouxy.plusone.exception.DataOperationNumberException; import xyz.zhouxy.plusone.exception.DataOperationResultException;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier;
/** /**
* *
@ -17,59 +17,34 @@ public final class AssertResult {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }
public static void update(boolean expression) { public static <E extends Throwable> void isTrue(boolean condition, Supplier<E> e) throws E {
if (!expression) { if (!condition) {
throw new DataOperationNumberException(); throw e.get();
} }
} }
public static void update(boolean expression, String message) { public static <T> void equals(T result, T expectedValue) {
if (!expression) { isTrue(Objects.equals(result, expectedValue), DataOperationResultException::new);
throw new DataOperationNumberException(message);
}
} }
public static void update(Object i, int expectedValue) { public static <T> void equals(T result, T expectedValue, String msgTemplate, Object... args) {
if (!Objects.equals(i, expectedValue)) { isTrue(!Objects.equals(result, expectedValue),
throw new DataOperationNumberException(); () -> new DataOperationResultException(String.format(msgTemplate, args)));
}
}
public static void update(Object i, int expectedValue, String format) {
if (!Objects.equals(i, expectedValue)) {
throw new DataOperationNumberException(String.format(format, i));
}
} }
public static void updateOneRow(int i) { public static void updateOneRow(int i) {
update(i, 1); equals(i, 1);
} }
public static void updateOneRow(Object i, String format) { public static void updateOneRow(int i, String format, Object... args) {
update(i, 1, format); equals(i, 1, format, args);
}
public static void exist(boolean expression) {
if (!expression) {
throw new DataNotExistException();
}
}
public static void exist(boolean expression, String message) {
if (!expression) {
throw new DataNotExistException(message);
}
} }
public static void nonNull(Object obj) { public static void nonNull(Object obj) {
if (Objects.isNull(obj)) { isTrue(Objects.nonNull(obj), DataNotExistException::new);
throw new DataNotExistException();
}
} }
public static void nonNull(Object obj, String message) { public static void nonNull(Object obj, String message) {
if (Objects.isNull(obj)) { isTrue(Objects.nonNull(obj), () -> new DataNotExistException(message));
throw new DataNotExistException(message);
}
} }
} }

View File

@ -16,70 +16,48 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import xyz.zhouxy.plusone.domain.Entity; import xyz.zhouxy.plusone.domain.Entity;
public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Serializable> { public abstract class JdbcEntityDaoSupport<T extends Entity<ID>, ID extends Serializable>
protected final NamedParameterJdbcTemplate jdbc; extends PlusoneJdbcDaoSupport {
protected RowMapper<T> rowMapper; protected RowMapper<T> rowMapper;
protected ResultSetExtractor<T> resultSetExtractor; protected ResultSetExtractor<T> resultSetExtractor;
protected JdbcEntityDaoSupport(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) { protected JdbcEntityDaoSupport(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.jdbc = namedParameterJdbcTemplate; super(namedParameterJdbcTemplate);
this.rowMapper = (ResultSet rs, int rowNum) -> mapRow(rs); this.rowMapper = (ResultSet rs, int rowNum) -> mapRow(rs);
this.resultSetExtractor = (ResultSet rs) -> rs.next() ? mapRow(rs) : null; this.resultSetExtractor = (ResultSet rs) -> rs.next() ? mapRow(rs) : null;
} }
protected final T queryForObject(String sql) { protected final T queryForObject(String sql) {
return this.jdbc.query(sql, this.resultSetExtractor); return queryForObject(sql, this.resultSetExtractor);
} }
protected final T queryForObject(String sql, SqlParameterSource paramSource) { protected final T queryForObject(String sql, SqlParameterSource paramSource) {
return this.jdbc.query(sql, paramSource, this.resultSetExtractor); return queryForObject(sql, paramSource, this.resultSetExtractor);
} }
protected final T queryForObject(String sql, String paramName, Object value) { protected final T queryForObject(String sql, String paramName, Object value) {
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), this.resultSetExtractor); return queryForObject(sql, new MapSqlParameterSource(paramName, value), this.resultSetExtractor);
} }
protected final List<T> queryForList(String sql) { protected final List<T> queryForList(String sql) {
return this.jdbc.query(sql, this.rowMapper); return queryForList(sql, this.rowMapper);
} }
protected final List<T> queryForList(String sql, SqlParameterSource parameterSource) { protected final List<T> queryForList(String sql, SqlParameterSource parameterSource) {
return this.jdbc.query(sql, parameterSource, this.rowMapper); return queryForList(sql, parameterSource, this.rowMapper);
} }
protected final List<T> queryForList(String sql, String paramName, Object value) { protected final List<T> queryForList(String sql, String paramName, Object value) {
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), this.rowMapper); return queryForList(sql, new MapSqlParameterSource(paramName, value), this.rowMapper);
} }
protected final Stream<T> queryForStream(String sql, SqlParameterSource parameterSource) { protected final Stream<T> queryForStream(String sql, SqlParameterSource parameterSource) {
return this.jdbc.queryForStream(sql, parameterSource, this.rowMapper); return queryForStream(sql, parameterSource, this.rowMapper);
} }
protected final Stream<T> queryForStream(String sql, String paramName, Object value) { protected final Stream<T> queryForStream(String sql, String paramName, Object value) {
return this.jdbc.queryForStream(sql, new MapSqlParameterSource(paramName, value), this.rowMapper); return queryForStream(sql, new MapSqlParameterSource(paramName, value), this.rowMapper);
}
protected final <E> Stream<E> queryForStream(String sql, SqlParameterSource parameterSource, Class<E> elementType) {
return this.jdbc.queryForList(sql, parameterSource, elementType).stream();
}
protected final <E> Stream<E> queryForStream(String sql, String paramName, Object value, Class<E> elementType) {
return this.jdbc.queryForList(sql, new MapSqlParameterSource(paramName, value), elementType).stream();
}
protected final boolean queryExists(String sql, SqlParameterSource parameterSource) {
Boolean isExists = this.jdbc.query(sql, parameterSource, ResultSet::next);
return Boolean.TRUE.equals(isExists);
}
protected final boolean queryExists(String sql, String paramName, Object value) {
Boolean isExists = this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), ResultSet::next);
return Boolean.TRUE.equals(isExists);
}
protected final int update(String sql, SqlParameterSource parameterSource) {
return this.jdbc.update(sql, parameterSource);
} }
protected abstract T mapRow(ResultSet rs) throws SQLException; protected abstract T mapRow(ResultSet rs) throws SQLException;

View File

@ -1,5 +1,6 @@
package xyz.zhouxy.plusone.jdbc; package xyz.zhouxy.plusone.jdbc;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
@ -16,15 +17,17 @@ import xyz.zhouxy.plusone.spring.SpringContextHolder;
*/ */
public final class JdbcFactory { public final class JdbcFactory {
private static final ApplicationContext CONTEXT = SpringContextHolder.getContext();
private JdbcFactory() { private JdbcFactory() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }
public static JdbcTemplate getJdbcTemplate() { public static JdbcTemplate getJdbcTemplate() {
return SpringContextHolder.getContext().getBean(JdbcTemplate.class); return CONTEXT.getBean(JdbcTemplate.class);
} }
public static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { public static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
return SpringContextHolder.getContext().getBean(NamedParameterJdbcTemplate.class); return CONTEXT.getBean(NamedParameterJdbcTemplate.class);
} }
} }

View File

@ -0,0 +1,174 @@
package xyz.zhouxy.plusone.jdbc;
import java.sql.ResultSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import xyz.zhouxy.plusone.exception.DataOperationResultException;
import xyz.zhouxy.plusone.util.NumberUtil;
public abstract class PlusoneJdbcDaoSupport {
protected final NamedParameterJdbcTemplate jdbc;
protected PlusoneJdbcDaoSupport(@Nonnull NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.jdbc = namedParameterJdbcTemplate;
}
protected final <T> T queryForObject(String sql, ResultSetExtractor<T> resultSetExtractor) {
return this.jdbc.query(sql, resultSetExtractor);
}
protected final <T> T queryForObject(String sql, SqlParameterSource paramSource,
ResultSetExtractor<T> resultSetExtractor) {
return this.jdbc.query(sql, paramSource, resultSetExtractor);
}
protected final <T> T queryForObject(String sql, String paramName, Object value,
ResultSetExtractor<T> resultSetExtractor) {
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), resultSetExtractor);
}
protected final <T> List<T> queryForList(String sql, RowMapper<T> rowMapper) {
return this.jdbc.query(sql, rowMapper);
}
protected final <T> List<T> queryForList(String sql, SqlParameterSource parameterSource, RowMapper<T> rowMapper) {
return this.jdbc.query(sql, parameterSource, rowMapper);
}
protected final <T> List<T> queryForList(String sql, String paramName, Object value, RowMapper<T> rowMapper) {
return this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), rowMapper);
}
protected final <T> Stream<T> queryForStream(String sql, SqlParameterSource parameterSource,
RowMapper<T> rowMapper) {
return this.jdbc.queryForStream(sql, parameterSource, rowMapper);
}
protected final <T> Stream<T> queryForStream(String sql, String paramName, Object value, RowMapper<T> rowMapper) {
return this.jdbc.queryForStream(sql, new MapSqlParameterSource(paramName, value), rowMapper);
}
protected final <T> Stream<T> queryForStream(String sql, SqlParameterSource parameterSource, Class<T> elementType) {
return this.jdbc.queryForList(sql, parameterSource, elementType).stream();
}
protected final <T> Stream<T> queryForStream(String sql, String paramName, Object value, Class<T> elementType) {
return this.jdbc.queryForList(sql, new MapSqlParameterSource(paramName, value), elementType).stream();
}
protected final boolean queryExists(String sql, SqlParameterSource parameterSource) {
Boolean isExists = this.jdbc.query(sql, parameterSource, ResultSet::next);
return Boolean.TRUE.equals(isExists);
}
protected final boolean queryExists(String sql, String paramName, Object value) {
Boolean isExists = this.jdbc.query(sql, new MapSqlParameterSource(paramName, value), ResultSet::next);
return Boolean.TRUE.equals(isExists);
}
protected final int update(String sql, SqlParameterSource parameterSource) {
return this.jdbc.update(sql, parameterSource);
}
protected final int update(String sql, String paramName, Object value) {
return this.jdbc.update(sql, new MapSqlParameterSource(paramName, value));
}
protected final int batchUpdate(String sql, SqlParameterSource[] batchArgs) {
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
return NumberUtil.sum(i);
}
protected final <T> int batchUpdate(String sql, Stream<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
int[] i = this.jdbc.batchUpdate(sql, buildSqlParameterSourceArray(c, paramSourceBuilder));
return NumberUtil.sum(i);
}
protected final <T> int batchUpdate(String sql, Collection<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
int[] i = this.jdbc.batchUpdate(sql, buildSqlParameterSourceArray(c, paramSourceBuilder));
return NumberUtil.sum(i);
}
protected static final <T> void assertResultEquals(T result, T expectedValue) {
if (!Objects.equals(result, expectedValue)) {
throw new DataOperationResultException();
}
}
protected static final <T> void assertResultEquals(T result, T expectedValue, Function<T, String> errMsg) {
if (!Objects.equals(result, expectedValue)) {
throw new DataOperationResultException(errMsg.apply(result));
}
}
protected static final <T> void assertResultEquals(T result, T expectedValue, String msgTemplate, Object... args) {
if (!Objects.equals(result, expectedValue)) {
throw new DataOperationResultException(String.format(msgTemplate, args));
}
}
protected static final <T, E extends Throwable> void assertResultEqualsOrThrow(T result, T expectedValue,
Function<T, E> e) throws E {
if (!Objects.equals(result, expectedValue)) {
throw e.apply(result);
}
}
protected static final void assertUpdateOneRow(int result) {
assertResultEquals(result, 1);
}
protected static final void assertUpdateOneRow(int result, Function<Integer, String> errMsg) {
assertResultEquals(result, 1, errMsg);
}
protected static final void assertUpdateOneRow(int result, String msgTemplate, Object... args) {
assertResultEquals(result, 1, msgTemplate, args);
}
protected static final <E extends Throwable> void assertUpdateOneRowOrThrow(int result, Function<Integer, E> e)
throws E {
assertResultEqualsOrThrow(result, 1, e);
}
protected static final <T> SqlParameterSource[] buildSqlParameterSourceArray(
T[] c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
if (c == null || c.length == 0) {
return new SqlParameterSource[] {};
}
return buildSqlParameterSourceArray(Arrays.stream(c), paramSourceBuilder);
}
protected static final <T> SqlParameterSource[] buildSqlParameterSourceArray(
Collection<T> c,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
if (c == null || c.isEmpty()) {
return new SqlParameterSource[] {};
}
return buildSqlParameterSourceArray(c.stream(), paramSourceBuilder);
}
protected static final <T> SqlParameterSource[] buildSqlParameterSourceArray(
Stream<T> stream,
@Nonnull Function<T, SqlParameterSource> paramSourceBuilder) {
Objects.requireNonNull(stream);
Objects.requireNonNull(paramSourceBuilder);
return stream.map(paramSourceBuilder).toArray(SqlParameterSource[]::new);
}
}

View File

@ -15,7 +15,6 @@ import org.springframework.stereotype.Repository;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport; import xyz.zhouxy.plusone.jdbc.JdbcRepositorySupport;
import xyz.zhouxy.plusone.util.AssertResult;
/** /**
* AccountRepository * AccountRepository
@ -41,7 +40,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
new MapSqlParameterSource() new MapSqlParameterSource()
.addValue("id", entity.getId().orElseThrow()) .addValue("id", entity.getId().orElseThrow())
.addValue("version", entity.getVersion())); .addValue("version", entity.getVersion()));
AssertResult.updateOneRow(i); assertUpdateOneRow(i);
} }
@Override @Override
@ -142,7 +141,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
:createdBy, :createTime) :createdBy, :createTime)
""", """,
generateParamSource(id, entity)); generateParamSource(id, entity));
AssertResult.updateOneRow(i); assertUpdateOneRow(i);
this.accountRoleDAO.insertAccountRoleRefs(id, entity.getRoleIds()); this.accountRoleDAO.insertAccountRoleRefs(id, entity.getRoleIds());
return entity; return entity;
} }
@ -166,7 +165,7 @@ public class AccountRepositoryImpl extends JdbcRepositorySupport<Account, Long>
WHERE id = :id AND deleted = 0 AND "version" = :version WHERE id = :id AND deleted = 0 AND "version" = :version
""", """,
generateParamSource(entity)); generateParamSource(entity));
AssertResult.updateOneRow(i); assertUpdateOneRow(i);
this.accountRoleDAO.saveAccountRoleRefs(entity); this.accountRoleDAO.saveAccountRoleRefs(entity);
return entity; return entity;
} }

View File

@ -1,47 +1,43 @@
package xyz.zhouxy.plusone.system.domain.model.account; package xyz.zhouxy.plusone.system.domain.model.account;
import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport;
import xyz.zhouxy.plusone.util.NumberUtil;
class AccountRoleRefDAO { class AccountRoleRefDAO extends PlusoneJdbcDaoSupport {
private final NamedParameterJdbcTemplate jdbc;
AccountRoleRefDAO(NamedParameterJdbcTemplate jdbc) { AccountRoleRefDAO(@Nonnull NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc; super(jdbc);
} }
Set<Long> selectRoleIdsByAccountId(Long accountId) { Set<Long> selectRoleIdsByAccountId(Long accountId) {
List<Long> roleRefs = this.jdbc.queryForList(""" return queryForStream("""
SELECT r.id FROM sys_role r RIGHT JOIN sys_account_role ar ON r.id = ar.role_id SELECT r.id FROM sys_role r RIGHT JOIN sys_account_role ar ON r.id = ar.role_id
WHERE r.deleted = 0 AND ar.account_id = :accountId; WHERE r.deleted = 0 AND ar.account_id = :accountId;
""", """,
new MapSqlParameterSource("accountId", accountId), "accountId", accountId,
Long.TYPE); Long.TYPE)
return new HashSet<>(roleRefs); .collect(Collectors.toSet());
} }
void clearAccountRoleRefs(Account entity) { void clearAccountRoleRefs(Account entity) {
var param = new MapSqlParameterSource("accountId", entity.getId().orElseThrow()); update("DELETE FROM sys_account_role WHERE account_id = :accountId", "accountId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_account_role WHERE account_id = :accountId", param);
} }
void insertAccountRoleRefs(Long accountId, Set<Long> roleRefs) { void insertAccountRoleRefs(Long accountId, Set<Long> roleRefs) {
String sql = "INSERT INTO sys_account_role (account_id, role_id) VALUES (:accountId, :roleId)"; int i = batchUpdate(
MapSqlParameterSource[] batchArgs = roleRefs "INSERT INTO sys_account_role (account_id, role_id) VALUES (:accountId, :roleId)",
.stream() roleRefs,
.map((Long roleId) -> new MapSqlParameterSource() (Long roleId) -> new MapSqlParameterSource()
.addValue("accountId", accountId) .addValue("accountId", accountId)
.addValue("roleId", roleId)) .addValue("roleId", roleId));
.toArray(MapSqlParameterSource[]::new); assertResultEquals(i, roleRefs.size());
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(roleRefs.size(), NumberUtil.sum(i));
} }
void saveAccountRoleRefs(Account entity) { void saveAccountRoleRefs(Account entity) {

View File

@ -4,48 +4,45 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport;
import xyz.zhouxy.plusone.util.NumberUtil;
class DictValueDAO { class DictValueDAO extends PlusoneJdbcDaoSupport {
private final NamedParameterJdbcTemplate jdbc;
DictValueDAO(NamedParameterJdbcTemplate jdbc) { DictValueDAO(@Nonnull NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc; super(jdbc);
} }
void updateDictValues(Dict entity) { void updateDictValues(Dict entity) {
MapSqlParameterSource deleteParam = new MapSqlParameterSource("dictType", entity.getId().orElseThrow()); update("DELETE FROM sys_dict_value WHERE dict_type = :dictType",
this.jdbc.update("DELETE FROM sys_dict_value WHERE dict_type = :dictType", deleteParam); "dictType", entity.getId().orElseThrow());
int i = insertDictValues(entity.getId().orElseThrow(), entity); int i = insertDictValues(entity.getId().orElseThrow(), entity);
AssertResult.update(i, entity.count()); assertResultEquals(i, entity.count());
} }
int insertDictValues(Long dictId, Dict entity) { int insertDictValues(Long dictId, Dict entity) {
if (Objects.isNull(dictId) || Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getValues())) { if (Objects.isNull(dictId) || Objects.isNull(entity) || CollectionUtils.isEmpty(entity.getValues())) {
return 0; return 0;
} }
int[] i = this.jdbc.batchUpdate( return batchUpdate(
"INSERT INTO sys_dict_value (dict_type, dict_key, label) VALUES (:dictType, :dictKey, :label)", "INSERT INTO sys_dict_value (dict_type, dict_key, label) VALUES (:dictType, :dictKey, :label)",
entity.getValues().stream() entity.getValues(),
.map(dictValue -> new MapSqlParameterSource() dictValue -> new MapSqlParameterSource()
.addValue("dictType", dictId) .addValue("dictType", dictId)
.addValue("dictKey", dictValue.getKey()) .addValue("dictKey", dictValue.getKey())
.addValue("label", dictValue.getLabel())) .addValue("label", dictValue.getLabel()));
.toArray(SqlParameterSource[]::new));
return NumberUtil.sum(i);
} }
Set<DictValue> selectDictValuesByDictId(long id) { Set<DictValue> selectDictValuesByDictId(long id) {
return this.jdbc.queryForStream(""" return queryForStream(
SELECT dict_key, label FROM sys_dict_value WHERE dict_type = :dictType "SELECT dict_key, label FROM sys_dict_value WHERE dict_type = :dictType",
""", new MapSqlParameterSource("dictType", id), "dictType", id,
(rs, rowNum) -> DictValue.of(rs.getInt("dict_key"), rs.getString("label"))) (rs, i) -> DictValue.of(rs.getInt("dict_key"), rs.getString("label")))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
} }

View File

@ -39,15 +39,14 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
.map(action -> action.getId().orElseThrow()) .map(action -> action.getId().orElseThrow())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
if (!ids.isEmpty()) { if (!ids.isEmpty()) {
this.jdbc.update( update("UPDATE sys_action SET deleted = id WHERE resource = :resource AND id NOT IN (:ids) AND deleted = 0",
"UPDATE sys_action SET deleted = id WHERE resource = :resource AND id NOT IN (:ids) AND deleted = 0",
new MapSqlParameterSource() new MapSqlParameterSource()
.addValue("resource", menuId) .addValue("resource", menuId)
.addValue("ids", ids)); .addValue("ids", ids));
} }
// 更新存在的数据 // 更新存在的数据
this.jdbc.batchUpdate(""" batchUpdate("""
UPDATE sys_action UPDATE sys_action
SET resource = :resource, SET resource = :resource,
identifier = :identifier, identifier = :identifier,
@ -56,22 +55,18 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
updated_by = :updatedBy updated_by = :updatedBy
WHERE id = :id AND deleted = 0 WHERE id = :id AND deleted = 0
""", """,
actions.stream() actions.stream().filter(action -> action.getId().isPresent()),
.filter(action -> action.getId().isPresent()) action -> generateParamSource(menuId, action));
.map(action -> generateParamSource(menuId, action))
.toArray(MapSqlParameterSource[]::new));
// 插入新添加的数据 // 插入新添加的数据
this.jdbc.batchUpdate(""" batchUpdate("""
INSERT INTO sys_action INSERT INTO sys_action
(id, resource, identifier, "label", create_time, created_by) (id, resource, identifier, "label", create_time, created_by)
VALUES VALUES
(:id, :resource, :identifier, :label, :createTime, :createdBy) (:id, :resource, :identifier, :label, :createTime, :createdBy)
""", """,
actions.stream() actions.stream().filter(action -> action.getId().isEmpty()),
.filter(action -> action.getId().isEmpty()) action -> generateParamSource(menuId, IdUtil.getSnowflakeNextId(), action));
.map(action -> generateParamSource(menuId, IdUtil.getSnowflakeNextId(), action))
.toArray(MapSqlParameterSource[]::new));
} }
List<Action> selectActionsByMenuId(long menuId) { List<Action> selectActionsByMenuId(long menuId) {
@ -80,7 +75,8 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
FROM sys_action a FROM sys_action a
JOIN (SELECT id, resource FROM sys_menu WHERE id = :menuId AND deleted = 0) m ON a.resource = m.id JOIN (SELECT id, resource FROM sys_menu WHERE id = :menuId AND deleted = 0) m ON a.resource = m.id
WHERE a.deleted = 0 WHERE a.deleted = 0
""", new MapSqlParameterSource("menuId", menuId)); """,
"menuId", menuId);
} }
Collection<Action> selectActionsByIdIn(Collection<Long> actionIds) { Collection<Action> selectActionsByIdIn(Collection<Long> actionIds) {
@ -92,7 +88,8 @@ class ActionDAO extends JdbcEntityDaoSupport<Action, Long> {
FROM sys_action a FROM sys_action a
LEFT JOIN sys_menu m ON a.resource = m.id LEFT JOIN sys_menu m ON a.resource = m.id
WHERE a.id IN (:actionIds) AND a.deleted = 0 WHERE a.id IN (:actionIds) AND a.deleted = 0
""", new MapSqlParameterSource("actionIds", actionIds)); """,
"actionIds", actionIds);
} }
private SqlParameterSource generateParamSource(Long menuId, Action action) { private SqlParameterSource generateParamSource(Long menuId, Action action) {

View File

@ -3,43 +3,38 @@ package xyz.zhouxy.plusone.system.domain.model.role;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport;
import xyz.zhouxy.plusone.util.NumberUtil;
class RoleMenuRefDAO { class RoleMenuRefDAO extends PlusoneJdbcDaoSupport {
private final NamedParameterJdbcTemplate jdbc; public RoleMenuRefDAO(@Nonnull NamedParameterJdbcTemplate jdbc) {
super(jdbc);
public RoleMenuRefDAO(NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc;
} }
Set<MenuRef> selectMenuRefsByRoleId(long roleId) { Set<MenuRef> selectMenuRefsByRoleId(long roleId) {
return this.jdbc.queryForList("SELECT menu_id FROM sys_role_menu WHERE role_id = :roleId", return queryForStream("SELECT menu_id FROM sys_role_menu WHERE role_id = :roleId",
new MapSqlParameterSource("roleId", roleId), "roleId", roleId,
Long.TYPE) Long.TYPE)
.stream()
.map(MenuRef::of) .map(MenuRef::of)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
void clearRoleMenuRefs(Role entity) { void clearRoleMenuRefs(Role entity) {
MapSqlParameterSource param = new MapSqlParameterSource("roleId", entity.getId().orElseThrow()); update("DELETE FROM sys_role_menu WHERE role_id = :roleId", "roleId", entity.getId().orElseThrow());
this.jdbc.update("DELETE FROM sys_role_menu WHERE role_id = :roleId", param);
} }
void saveRoleMenuRefs(Long roleId, Role entity) { void saveRoleMenuRefs(Long roleId, Role entity) {
String sql = "INSERT INTO sys_role_menu(role_id, menu_id) VALUES (:roleId, :menuId)"; int i = batchUpdate(
MapSqlParameterSource[] batchArgs = entity.getMenus() "INSERT INTO sys_role_menu(role_id, menu_id) VALUES (:roleId, :menuId)",
.stream() entity.getMenus(),
.map(menuRef -> new MapSqlParameterSource() menuRef -> new MapSqlParameterSource()
.addValue("roleId", roleId) .addValue("roleId", roleId)
.addValue("menuId", menuRef.menuId())) .addValue("menuId", menuRef.menuId()));
.toArray(MapSqlParameterSource[]::new); assertResultEquals(i, entity.getMenus().size());
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(entity.getMenus().size(), NumberUtil.sum(i));
} }
} }

View File

@ -3,43 +3,39 @@ package xyz.zhouxy.plusone.system.domain.model.role;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import xyz.zhouxy.plusone.util.AssertResult; import xyz.zhouxy.plusone.jdbc.PlusoneJdbcDaoSupport;
import xyz.zhouxy.plusone.util.NumberUtil;
class RolePermissionRefDAO { class RolePermissionRefDAO extends PlusoneJdbcDaoSupport {
private final NamedParameterJdbcTemplate jdbc;
public RolePermissionRefDAO(NamedParameterJdbcTemplate jdbc) { protected RolePermissionRefDAO(@Nonnull NamedParameterJdbcTemplate jdbc) {
this.jdbc = jdbc; super(jdbc);
} }
Set<ActionRef> selectPermissionRefsByRoleId(long roleId) { Set<ActionRef> selectPermissionRefsByRoleId(long roleId) {
return this.jdbc.queryForList("SELECT permission_id FROM sys_role_permission WHERE role_id = :roleId", return queryForStream("SELECT permission_id FROM sys_role_permission WHERE role_id = :roleId",
new MapSqlParameterSource("roleId", roleId), "roleId", roleId,
Long.TYPE) Long.TYPE)
.stream()
.map(ActionRef::of) .map(ActionRef::of)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
void clearRolePermissionRefs(Role entity) { void clearRolePermissionRefs(Role entity) {
MapSqlParameterSource param = new MapSqlParameterSource("roleId", entity.getId().orElseThrow()); update("DELETE FROM sys_role_permission WHERE role_id = :roleId",
this.jdbc.update("DELETE FROM sys_role_permission WHERE role_id = :roleId", param); "roleId", entity.getId().orElseThrow());
} }
void saveRolePermissionRefs(Long roleId, Role entity) { void saveRolePermissionRefs(Long roleId, Role entity) {
String sql = "INSERT INTO sys_role_permission(role_id, permission_id) VALUES (:roleId, :permissionId)"; int i = batchUpdate(
SqlParameterSource[] batchArgs = entity.getPermissions() "INSERT INTO sys_role_permission(role_id, permission_id) VALUES (:roleId, :permissionId)",
.stream() entity.getPermissions(),
.map(menuRef -> new MapSqlParameterSource() actionRef -> new MapSqlParameterSource()
.addValue("roleId", roleId) .addValue("roleId", roleId)
.addValue("permissionId", menuRef.actionId())) .addValue("permissionId", actionRef.actionId()));
.toArray(MapSqlParameterSource[]::new); assertResultEquals(i, entity.getMenus().size());
int[] i = this.jdbc.batchUpdate(sql, batchArgs);
AssertResult.update(entity.getMenus().size(), NumberUtil.sum(i));
} }
} }