This commit is contained in:
Looly 2022-09-30 23:00:15 +08:00
parent 00fad42926
commit d6be80f8ea
22 changed files with 173 additions and 130 deletions

View File

@ -1,20 +1,21 @@
package cn.hutool.core.io.file;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.func.Wrapper;
import cn.hutool.core.util.CharsetUtil;
import java.io.File;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
/**
* 文件包装器扩展文件对象
*
* @author Looly
*
*/
public class FileWrapper implements Serializable{
public class FileWrapper implements Wrapper<File>, Serializable{
private static final long serialVersionUID = 1L;
protected File file;
@ -40,7 +41,8 @@ public class FileWrapper implements Serializable{
* 获得文件
* @return 文件
*/
public File getFile() {
@Override
public File getRaw() {
return file;
}

View File

@ -0,0 +1,17 @@
package cn.hutool.core.lang.func;
/**
* 包装接口
*
* @param <T> 原始对象类型
* @author looly
* @since 6.0.0
*/
public interface Wrapper<T> {
/**
* 获取原始对象
*
* @return 原始对象
*/
T getRaw();
}

View File

@ -3,6 +3,7 @@ package cn.hutool.core.map;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Wrapper;
import cn.hutool.core.reflect.ClassUtil;
import cn.hutool.core.text.StrUtil;
import cn.hutool.core.util.ObjUtil;
@ -33,6 +34,7 @@ import java.util.stream.Collectors;
* 也可以在获取到{@link TreeEntry}使用节点本身的方法对数进行操作或访问
*
* @param <K> key类型
* @param <V> 值类型
* @author huangchengxing
*/
public class LinkedForestMap<K, V> implements ForestMap<K, V> {
@ -48,11 +50,11 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
private final boolean allowOverrideParent;
/**
* 构建{@link LinkedForestMap}
* 构建{@code LinkedForestMap}
*
* @param allowOverrideParent 当指定节点已经与其他节点构成了父子关系是否允许将该节点的父节点强制替换为指定节点
*/
public LinkedForestMap(boolean allowOverrideParent) {
public LinkedForestMap(final boolean allowOverrideParent) {
this.allowOverrideParent = allowOverrideParent;
this.nodes = new LinkedHashMap<>();
}
@ -86,7 +88,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 是否
*/
@Override
public boolean containsKey(Object key) {
public boolean containsKey(final Object key) {
return nodes.containsKey(key);
}
@ -97,7 +99,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 是否
*/
@Override
public boolean containsValue(Object value) {
public boolean containsValue(final Object value) {
return nodes.containsValue(value);
}
@ -108,7 +110,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 节点
*/
@Override
public TreeEntry<K, V> get(Object key) {
public TreeEntry<K, V> get(final Object key) {
return nodes.get(key);
}
@ -126,7 +128,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 删除的且引用关系已经改变的节点若key没有对应节点则返回null
*/
@Override
public TreeEntry<K, V> remove(Object key) {
public TreeEntry<K, V> remove(final Object key) {
final TreeEntryNode<K, V> target = nodes.remove(key);
if (ObjUtil.isNull(target)) {
return null;
@ -189,7 +191,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
/**
* {@link TreeEntryNode}包装为{@link EntryNodeWrapper}
*/
private Map.Entry<K, TreeEntry<K, V>> wrap(Map.Entry<K, TreeEntryNode<K, V>> nodeEntry) {
private Map.Entry<K, TreeEntry<K, V>> wrap(final Map.Entry<K, TreeEntryNode<K, V>> nodeEntry) {
return new EntryNodeWrapper<>(nodeEntry.getValue());
}
@ -207,7 +209,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 节点若key已有对应节点则返回具有旧值的节点否则返回null
*/
@Override
public TreeEntryNode<K, V> putNode(K key, V value) {
public TreeEntryNode<K, V> putNode(final K key, final V value) {
TreeEntryNode<K, V> target = nodes.get(key);
if (ObjUtil.isNotNull(target)) {
final V oldVal = target.getValue();
@ -238,7 +240,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param childValue 子节点的值
*/
@Override
public void putLinkedNodes(K parentKey, V parentValue, K childKey, V childValue) {
public void putLinkedNodes(final K parentKey, final V parentValue, final K childKey, final V childValue) {
linkNodes(parentKey, childKey, (parent, child) -> {
parent.setValue(parentValue);
child.setValue(childValue);
@ -257,7 +259,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param childValue 子节点的值
*/
@Override
public void putLinkedNodes(K parentKey, K childKey, V childValue) {
public void putLinkedNodes(final K parentKey, final K childKey, final V childValue) {
linkNodes(parentKey, childKey, (parent, child) -> child.setValue(childValue));
}
@ -269,7 +271,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param consumer 对父节点和子节点的操作允许为null
*/
@Override
public void linkNodes(K parentKey, K childKey, BiConsumer<TreeEntry<K, V>, TreeEntry<K, V>> consumer) {
public void linkNodes(final K parentKey, final K childKey, BiConsumer<TreeEntry<K, V>, TreeEntry<K, V>> consumer) {
consumer = ObjUtil.defaultIfNull(consumer, (parent, child) -> {
});
final TreeEntryNode<K, V> parentNode = nodes.computeIfAbsent(parentKey, t -> new TreeEntryNode<>(null, t));
@ -315,7 +317,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param childKey 子节点
*/
@Override
public void unlinkNode(K parentKey, K childKey) {
public void unlinkNode(final K parentKey, final K childKey) {
final TreeEntryNode<K, V> childNode = nodes.get(childKey);
if (ObjUtil.isNull(childNode)) {
return;
@ -369,7 +371,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param parent 节点的父节点
* @param key 节点的key
*/
public TreeEntryNode(TreeEntryNode<K, V> parent, K key) {
public TreeEntryNode(final TreeEntryNode<K, V> parent, final K key) {
this(parent, key, null);
}
@ -380,7 +382,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param key 节点的key
* @param value 节点的value
*/
public TreeEntryNode(TreeEntryNode<K, V> parent, K key, V value) {
public TreeEntryNode(final TreeEntryNode<K, V> parent, final K key, final V value) {
this.parent = parent;
this.key = key;
this.value = value;
@ -432,7 +434,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 节点的旧value
*/
@Override
public V setValue(V value) {
public V setValue(final V value) {
final V oldVal = getValue();
this.value = value;
return oldVal;
@ -449,7 +451,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 遍历到的最后一个节点
*/
TreeEntryNode<K, V> traverseParentNodes(
boolean includeCurrent, Consumer<TreeEntryNode<K, V>> consumer, Predicate<TreeEntryNode<K, V>> breakTraverse) {
final boolean includeCurrent, final Consumer<TreeEntryNode<K, V>> consumer, Predicate<TreeEntryNode<K, V>> breakTraverse) {
breakTraverse = ObjUtil.defaultIfNull(breakTraverse, n -> false);
TreeEntryNode<K, V> curr = includeCurrent ? this : this.parent;
while (ObjUtil.isNotNull(curr)) {
@ -504,7 +506,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 指定父节点当不存在时返回null
*/
@Override
public TreeEntryNode<K, V> getParent(K key) {
public TreeEntryNode<K, V> getParent(final K key) {
return traverseParentNodes(false, p -> {
}, p -> p.equalsKey(key));
}
@ -516,7 +518,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param nodeConsumer 对节点的处理
*/
@Override
public void forEachChild(boolean includeSelf, Consumer<TreeEntry<K, V>> nodeConsumer) {
public void forEachChild(final boolean includeSelf, final Consumer<TreeEntry<K, V>> nodeConsumer) {
traverseChildNodes(includeSelf, (index, child) -> nodeConsumer.accept(child), null);
}
@ -526,7 +528,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param key 要比较的key
* @return 是否key一致
*/
public boolean equalsKey(K key) {
public boolean equalsKey(final K key) {
return ObjUtil.equals(getKey(), key);
}
@ -541,7 +543,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 遍历到的最后一个节点
*/
TreeEntryNode<K, V> traverseChildNodes(
boolean includeCurrent, BiConsumer<Integer, TreeEntryNode<K, V>> consumer, BiPredicate<Integer, TreeEntryNode<K, V>> breakTraverse) {
final boolean includeCurrent, final BiConsumer<Integer, TreeEntryNode<K, V>> consumer, BiPredicate<Integer, TreeEntryNode<K, V>> breakTraverse) {
breakTraverse = ObjUtil.defaultIfNull(breakTraverse, (i, n) -> false);
final Deque<List<TreeEntryNode<K, V>>> keyNodeDeque = ListUtil.ofLinked(ListUtil.of(this));
boolean needProcess = includeCurrent;
@ -577,7 +579,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param child 子节点
* @throws IllegalArgumentException 当要添加的子节点已经是其自身父节点时抛出
*/
void addChild(TreeEntryNode<K, V> child) {
void addChild(final TreeEntryNode<K, V> child) {
if (containsChild(child.key)) {
return;
}
@ -605,7 +607,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
*
* @param key 子节点
*/
void removeDeclaredChild(K key) {
void removeDeclaredChild(final K key) {
final TreeEntryNode<K, V> child = children.get(key);
if (ObjUtil.isNull(child)) {
return;
@ -629,7 +631,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 节点
*/
@Override
public TreeEntryNode<K, V> getChild(K key) {
public TreeEntryNode<K, V> getChild(final K key) {
return traverseChildNodes(false, (i, c) -> {
}, (i, c) -> c.equalsKey(key));
}
@ -673,7 +675,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @return 是否
*/
@Override
public boolean equals(Object o) {
public boolean equals(final Object o) {
if (this == o) {
return true;
}
@ -701,8 +703,8 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @param value 复制的节点的值
* @return 节点
*/
TreeEntryNode<K, V> copy(V value) {
TreeEntryNode<K, V> copiedNode = new TreeEntryNode<>(this.parent, this.key, ObjUtil.defaultIfNull(value, this.value));
TreeEntryNode<K, V> copy(final V value) {
final TreeEntryNode<K, V> copiedNode = new TreeEntryNode<>(this.parent, this.key, ObjUtil.defaultIfNull(value, this.value));
copiedNode.children.putAll(children);
return copiedNode;
}
@ -718,10 +720,10 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
* @see #entrySet()
* @see #values()
*/
public static class EntryNodeWrapper<K, V, N extends TreeEntry<K, V>> implements Map.Entry<K, TreeEntry<K, V>> {
public static class EntryNodeWrapper<K, V, N extends TreeEntry<K, V>> implements Map.Entry<K, TreeEntry<K, V>>, Wrapper<N> {
private final N entryNode;
EntryNodeWrapper(N entryNode) {
EntryNodeWrapper(final N entryNode) {
this.entryNode = entryNode;
}
@ -736,9 +738,14 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
}
@Override
public TreeEntry<K, V> setValue(TreeEntry<K, V> value) {
public TreeEntry<K, V> setValue(final TreeEntry<K, V> value) {
throw new UnsupportedOperationException();
}
@Override
public N getRaw() {
return entryNode;
}
}
}

View File

@ -1,6 +1,7 @@
package cn.hutool.core.map;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.func.Wrapper;
import cn.hutool.core.util.ObjUtil;
import java.io.IOException;
@ -21,7 +22,7 @@ import java.util.function.Supplier;
* @author looly
* @since 4.3.3
*/
public class MapWrapper<K, V> implements Map<K, V>, Iterable<Map.Entry<K, V>>, Serializable, Cloneable {
public class MapWrapper<K, V> implements Map<K, V>, Iterable<Map.Entry<K, V>>, Wrapper<Map<K, V>>, Serializable, Cloneable {
private static final long serialVersionUID = -7524578042008586382L;
/**
@ -64,6 +65,7 @@ public class MapWrapper<K, V> implements Map<K, V>, Iterable<Map.Entry<K, V>>, S
*
* @return Map
*/
@Override
public Map<K, V> getRaw() {
return this.raw;
}

View File

@ -1,5 +1,7 @@
package cn.hutool.crypto;
import cn.hutool.core.lang.func.Wrapper;
import javax.crypto.Cipher;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
@ -18,7 +20,7 @@ import java.security.spec.AlgorithmParameterSpec;
* @author looly
* @since 5.7.17
*/
public class CipherWrapper {
public class CipherWrapper implements Wrapper<Cipher> {
private final Cipher cipher;
/**
@ -85,7 +87,8 @@ public class CipherWrapper {
*
* @return {@link Cipher}
*/
public Cipher getCipher() {
@Override
public Cipher getRaw() {
return this.cipher;
}

View File

@ -289,7 +289,7 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @since 5.4.3
*/
public Cipher getCipher() {
return this.cipherWrapper.getCipher();
return this.cipherWrapper.getRaw();
}
/**
@ -364,6 +364,6 @@ public class AsymmetricCrypto extends AbstractAsymmetricCrypto<AsymmetricCrypto>
* @throws InvalidKeyException 异常KEY错误
*/
private Cipher initMode(final int mode, final Key key) throws InvalidAlgorithmParameterException, InvalidKeyException {
return this.cipherWrapper.initMode(mode, key).getCipher();
return this.cipherWrapper.initMode(mode, key).getRaw();
}
}

View File

@ -166,7 +166,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @return 加密或解密
*/
public Cipher getCipher() {
return cipherWrapper.getCipher();
return cipherWrapper.getRaw();
}
/**
@ -242,7 +242,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @since 5.6.8
*/
public byte[] update(final byte[] data) {
final Cipher cipher = cipherWrapper.getCipher();
final Cipher cipher = cipherWrapper.getRaw();
lock.lock();
try {
return cipher.update(paddingDataWithZero(data, cipher.getBlockSize()));
@ -383,7 +383,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
private SymmetricCrypto initParams(final String algorithm, AlgorithmParameterSpec paramsSpec) {
if (null == paramsSpec) {
byte[] iv = Opt.ofNullable(cipherWrapper)
.map(CipherWrapper::getCipher).map(Cipher::getIV).get();
.map(CipherWrapper::getRaw).map(Cipher::getIV).get();
// 随机IV
if (StrUtil.startWithIgnoreCase(algorithm, "PBE")) {
@ -412,7 +412,7 @@ public class SymmetricCrypto implements SymmetricEncryptor, SymmetricDecryptor,
* @throws InvalidAlgorithmParameterException 无效算法
*/
private Cipher initMode(final int mode) throws InvalidKeyException, InvalidAlgorithmParameterException {
return this.cipherWrapper.initMode(mode, this.secretKey).getCipher();
return this.cipherWrapper.initMode(mode, this.secretKey).getRaw();
}
/**

View File

@ -17,7 +17,7 @@ import cn.hutool.db.sql.Query;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.SqlExecutor;
import cn.hutool.db.sql.SqlUtil;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
import javax.sql.DataSource;
import java.io.Serializable;
@ -33,6 +33,7 @@ import java.util.Map;
* 通过给定的数据源执行给定SQL或者给定数据源和方言执行相应的CRUD操作<br>
* 提供抽象方法getConnection和closeConnection用于自定义数据库连接的打开和关闭
*
* @param <R> return this类型
* @author looly
*/
public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnectionHolder implements Serializable {
@ -925,19 +926,19 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
* @since 4.0.0
*/
public R setWrapper(final Character wrapperChar) {
return setWrapper(new Wrapper(wrapperChar));
return setWrapper(new QuoteWrapper(wrapperChar));
}
/**
* 设置包装器包装器用于对表名字段名进行符号包装例如双引号防止关键字与这些表名或字段冲突
*
* @param wrapper 包装器null表示取消包装
* @param quoteWrapper 包装器null表示取消包装
* @return this
* @since 4.0.0
*/
@SuppressWarnings("unchecked")
public R setWrapper(final Wrapper wrapper) {
this.runner.setWrapper(wrapper);
public R setWrapper(final QuoteWrapper quoteWrapper) {
this.runner.setWrapper(quoteWrapper);
return (R) this;
}
@ -949,7 +950,7 @@ public abstract class AbstractDb<R extends AbstractDb<R>> extends DefaultConnect
* @since 4.5.7
*/
public R disableWrapper() {
return setWrapper((Wrapper) null);
return setWrapper((QuoteWrapper) null);
}
// ---------------------------------------------------------------------------- Getters and Setters end

View File

@ -13,7 +13,7 @@ import cn.hutool.db.sql.Query;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.SqlExecutor;
import cn.hutool.db.sql.SqlUtil;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
import java.io.Serializable;
import java.sql.Connection;
@ -428,16 +428,16 @@ public class DialectRunner implements Serializable {
* @param wrapperChar 包装字符字符会在SQL生成时位于表名和字段名两边null时表示取消包装
*/
public void setWrapper(final Character wrapperChar) {
setWrapper(new Wrapper(wrapperChar));
setWrapper(new QuoteWrapper(wrapperChar));
}
/**
* 设置包装器包装器用于对表名字段名进行符号包装例如双引号防止关键字与这些表名或字段冲突
*
* @param wrapper 包装器null表示取消包装
* @param quoteWrapper 包装器null表示取消包装
*/
public void setWrapper(final Wrapper wrapper) {
this.dialect.setWrapper(wrapper);
public void setWrapper(final QuoteWrapper quoteWrapper) {
this.dialect.setWrapper(quoteWrapper);
}
//---------------------------------------------------------------------------- Getters and Setters end

View File

@ -5,7 +5,7 @@ import cn.hutool.db.Page;
import cn.hutool.db.sql.Order;
import cn.hutool.db.sql.Query;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
import java.io.Serializable;
import java.sql.Connection;
@ -24,14 +24,14 @@ public interface Dialect extends Serializable {
/**
* @return 包装器
*/
Wrapper getWrapper();
QuoteWrapper getWrapper();
/**
* 设置包装器
*
* @param wrapper 包装器
* @param quoteWrapper 包装器
*/
void setWrapper(Wrapper wrapper);
void setWrapper(QuoteWrapper quoteWrapper);
// -------------------------------------------- Execute

View File

@ -13,7 +13,7 @@ import cn.hutool.db.dialect.DialectName;
import cn.hutool.db.sql.Condition;
import cn.hutool.db.sql.Query;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -29,21 +29,21 @@ import java.util.Set;
public class AnsiSqlDialect implements Dialect {
private static final long serialVersionUID = 2088101129774974580L;
protected Wrapper wrapper = new Wrapper();
protected QuoteWrapper quoteWrapper = new QuoteWrapper();
@Override
public Wrapper getWrapper() {
return this.wrapper;
public QuoteWrapper getWrapper() {
return this.quoteWrapper;
}
@Override
public void setWrapper(final Wrapper wrapper) {
this.wrapper = wrapper;
public void setWrapper(final QuoteWrapper quoteWrapper) {
this.quoteWrapper = quoteWrapper;
}
@Override
public PreparedStatement psForInsert(final Connection conn, final Entity entity) throws SQLException {
final SqlBuilder insert = SqlBuilder.of(wrapper).insert(entity, this.dialectName());
final SqlBuilder insert = SqlBuilder.of(quoteWrapper).insert(entity, this.dialectName());
return StatementUtil.prepareStatement(conn, insert);
}
@ -54,7 +54,7 @@ public class AnsiSqlDialect implements Dialect {
throw new DbRuntimeException("Entities for batch insert is empty !");
}
// 批量根据第一行数据结构生成SQL占位符
final SqlBuilder insert = SqlBuilder.of(wrapper).insert(entities[0], this.dialectName());
final SqlBuilder insert = SqlBuilder.of(quoteWrapper).insert(entities[0], this.dialectName());
final Set<String> fields = CollUtil.filter(entities[0].keySet(), StrUtil::isNotBlank);
return StatementUtil.prepareStatementForBatch(conn, insert.build(), fields, entities);
}
@ -68,7 +68,7 @@ public class AnsiSqlDialect implements Dialect {
// 对于无条件删除语句直接抛出异常禁止防止误删除
throw new SQLException("No 'WHERE' condition, we can't prepared statement for delete everything.");
}
final SqlBuilder delete = SqlBuilder.of(wrapper).delete(query.getFirstTableName()).where(where);
final SqlBuilder delete = SqlBuilder.of(quoteWrapper).delete(query.getFirstTableName()).where(where);
return StatementUtil.prepareStatement(conn, delete);
}
@ -83,7 +83,7 @@ public class AnsiSqlDialect implements Dialect {
throw new SQLException("No 'WHERE' condition, we can't prepare statement for update everything.");
}
final SqlBuilder update = SqlBuilder.of(wrapper).update(entity).where(where);
final SqlBuilder update = SqlBuilder.of(quoteWrapper).update(entity).where(where);
return StatementUtil.prepareStatement(conn, update);
}
@ -100,7 +100,7 @@ public class AnsiSqlDialect implements Dialect {
throw new DbRuntimeException("Table name must be not empty !");
}
final SqlBuilder find = SqlBuilder.of(wrapper).query(query);
final SqlBuilder find = SqlBuilder.of(quoteWrapper).query(query);
return psForPage(conn, find, query.getPage());
}

View File

@ -40,7 +40,7 @@ public class H2Dialect extends AnsiSqlDialect {
public PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws SQLException {
Assert.notEmpty(keys, "Keys must be not empty for H2 MERGE SQL.");
SqlBuilder.validateEntity(entity);
final SqlBuilder builder = SqlBuilder.of(wrapper);
final SqlBuilder builder = SqlBuilder.of(quoteWrapper);
final StringBuilder fieldsPart = new StringBuilder();
final StringBuilder placeHolder = new StringBuilder();
@ -54,15 +54,15 @@ public class H2Dialect extends AnsiSqlDialect {
placeHolder.append(", ");
}
fieldsPart.append((null != wrapper) ? wrapper.wrap(field) : field);
fieldsPart.append((null != quoteWrapper) ? quoteWrapper.wrap(field) : field);
placeHolder.append("?");
builder.addParams(value);
}
});
String tableName = entity.getTableName();
if (null != this.wrapper) {
tableName = this.wrapper.wrap(tableName);
if (null != this.quoteWrapper) {
tableName = this.quoteWrapper.wrap(tableName);
}
builder.append("MERGE INTO ").append(tableName)
// 字段列表

View File

@ -6,7 +6,7 @@ import cn.hutool.db.Page;
import cn.hutool.db.StatementUtil;
import cn.hutool.db.dialect.DialectName;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -21,7 +21,7 @@ public class MysqlDialect extends AnsiSqlDialect{
private static final long serialVersionUID = -3734718212043823636L;
public MysqlDialect() {
wrapper = new Wrapper('`');
quoteWrapper = new QuoteWrapper('`');
}
@Override
@ -51,7 +51,7 @@ public class MysqlDialect extends AnsiSqlDialect{
@Override
public PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws SQLException {
SqlBuilder.validateEntity(entity);
final SqlBuilder builder = SqlBuilder.of(wrapper);
final SqlBuilder builder = SqlBuilder.of(quoteWrapper);
final StringBuilder fieldsPart = new StringBuilder();
final StringBuilder placeHolder = new StringBuilder();
@ -67,7 +67,7 @@ public class MysqlDialect extends AnsiSqlDialect{
updateHolder.append(", ");
}
field = (null != wrapper) ? wrapper.wrap(field) : field;
field = (null != quoteWrapper) ? quoteWrapper.wrap(field) : field;
fieldsPart.append(field);
updateHolder.append(field).append("=values(").append(field).append(")");
placeHolder.append("?");
@ -76,8 +76,8 @@ public class MysqlDialect extends AnsiSqlDialect{
});
String tableName = entity.getTableName();
if (null != this.wrapper) {
tableName = this.wrapper.wrap(tableName);
if (null != this.quoteWrapper) {
tableName = this.quoteWrapper.wrap(tableName);
}
builder.append("INSERT INTO ").append(tableName)
// 字段列表

View File

@ -7,7 +7,7 @@ import cn.hutool.db.Entity;
import cn.hutool.db.StatementUtil;
import cn.hutool.db.dialect.DialectName;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
import java.sql.Connection;
import java.sql.PreparedStatement;
@ -23,7 +23,7 @@ public class PostgresqlDialect extends AnsiSqlDialect{
private static final long serialVersionUID = 3889210427543389642L;
public PostgresqlDialect() {
wrapper = new Wrapper('"');
quoteWrapper = new QuoteWrapper('"');
}
@Override
@ -35,7 +35,7 @@ public class PostgresqlDialect extends AnsiSqlDialect{
public PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) throws SQLException {
Assert.notEmpty(keys, "Keys must be not empty for Postgres.");
SqlBuilder.validateEntity(entity);
final SqlBuilder builder = SqlBuilder.of(wrapper);
final SqlBuilder builder = SqlBuilder.of(quoteWrapper);
final StringBuilder fieldsPart = new StringBuilder();
final StringBuilder placeHolder = new StringBuilder();
@ -51,7 +51,7 @@ public class PostgresqlDialect extends AnsiSqlDialect{
updateHolder.append(", ");
}
final String wrapedField = (null != wrapper) ? wrapper.wrap(field) : field;
final String wrapedField = (null != quoteWrapper) ? quoteWrapper.wrap(field) : field;
fieldsPart.append(wrapedField);
updateHolder.append(wrapedField).append("=EXCLUDED.").append(field);
placeHolder.append("?");
@ -60,8 +60,8 @@ public class PostgresqlDialect extends AnsiSqlDialect{
});
String tableName = entity.getTableName();
if (null != this.wrapper) {
tableName = this.wrapper.wrap(tableName);
if (null != this.quoteWrapper) {
tableName = this.quoteWrapper.wrap(tableName);
}
builder.append("INSERT INTO ").append(tableName)
// 字段列表

View File

@ -4,7 +4,7 @@ import cn.hutool.core.text.StrUtil;
import cn.hutool.db.Page;
import cn.hutool.db.dialect.DialectName;
import cn.hutool.db.sql.SqlBuilder;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
/**
* SQLServer2012 方言
@ -17,7 +17,7 @@ public class SqlServer2012Dialect extends AnsiSqlDialect {
public SqlServer2012Dialect() {
//双引号和中括号适用双引号更广泛
wrapper = new Wrapper('"');
quoteWrapper = new QuoteWrapper('"');
}
@Override

View File

@ -1,7 +1,7 @@
package cn.hutool.db.dialect.impl;
import cn.hutool.db.dialect.DialectName;
import cn.hutool.db.sql.Wrapper;
import cn.hutool.db.sql.QuoteWrapper;
/**
* SqlLite3方言
@ -12,9 +12,9 @@ public class Sqlite3Dialect extends AnsiSqlDialect{
private static final long serialVersionUID = -3527642408849291634L;
public Sqlite3Dialect() {
wrapper = new Wrapper('[', ']');
quoteWrapper = new QuoteWrapper('[', ']');
}
@Override
public String dialectName() {
return DialectName.SQLITE3.name();

View File

@ -2,6 +2,7 @@ package cn.hutool.db.ds;
import cn.hutool.core.exceptions.CloneRuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.func.Wrapper;
import javax.sql.DataSource;
import java.io.Closeable;
@ -21,7 +22,7 @@ import java.util.logging.Logger;
* @author looly
* @since 4.3.2
*/
public class DataSourceWrapper implements DataSource, Closeable, Cloneable {
public class DataSourceWrapper implements Wrapper<DataSource>, DataSource, Closeable, Cloneable {
private final DataSource ds;
private final String driver;
@ -62,6 +63,7 @@ public class DataSourceWrapper implements DataSource, Closeable, Cloneable {
*
* @return 原始数据源
*/
@Override
public DataSource getRaw() {
return this.ds;
}

View File

@ -12,12 +12,12 @@ import java.util.Collection;
import java.util.Map.Entry;
/**
* 包装器<br>
* 字段和表明包装器<br>
* 主要用于字段名的包装在字段名的前后加字符例如反引号来避免与数据库的关键字冲突
*
* @author Looly
*/
public class Wrapper implements Serializable {
public class QuoteWrapper implements Serializable {
private static final long serialVersionUID = 1L;
/**
@ -29,7 +29,10 @@ public class Wrapper implements Serializable {
*/
private Character sufWrapQuote;
public Wrapper() {
/**
* 构造
*/
public QuoteWrapper() {
}
/**
@ -37,7 +40,7 @@ public class Wrapper implements Serializable {
*
* @param wrapQuote 单包装字符
*/
public Wrapper(final Character wrapQuote) {
public QuoteWrapper(final Character wrapQuote) {
this.preWrapQuote = wrapQuote;
this.sufWrapQuote = wrapQuote;
}
@ -48,7 +51,7 @@ public class Wrapper implements Serializable {
* @param preWrapQuote 前置包装符号
* @param sufWrapQuote 后置包装符号
*/
public Wrapper(final Character preWrapQuote, final Character sufWrapQuote) {
public QuoteWrapper(final Character preWrapQuote, final Character sufWrapQuote) {
this.preWrapQuote = preWrapQuote;
this.sufWrapQuote = sufWrapQuote;
}

View File

@ -39,11 +39,11 @@ public class SqlBuilder implements Builder<String> {
/**
* 创建SQL构建器
*
* @param wrapper 包装器
* @param quoteWrapper 包装器
* @return SQL构建器
*/
public static SqlBuilder of(final Wrapper wrapper) {
return new SqlBuilder(wrapper);
public static SqlBuilder of(final QuoteWrapper quoteWrapper) {
return new SqlBuilder(quoteWrapper);
}
/**
@ -112,14 +112,14 @@ public class SqlBuilder implements Builder<String> {
/**
* 包装器
*/
private Wrapper wrapper;
private QuoteWrapper quoteWrapper;
// --------------------------------------------------------------- Constructor start
public SqlBuilder() {
}
public SqlBuilder(final Wrapper wrapper) {
this.wrapper = wrapper;
public SqlBuilder(final QuoteWrapper quoteWrapper) {
this.quoteWrapper = quoteWrapper;
}
// --------------------------------------------------------------- Constructor end
@ -172,7 +172,7 @@ public class SqlBuilder implements Builder<String> {
placeHolder.append(", ");
}
fieldsPart.append((null != wrapper) ? wrapper.wrap(field) : field);
fieldsPart.append((null != quoteWrapper) ? quoteWrapper.wrap(field) : field);
if (isOracle && OracleDialect.isNextVal(value)) {
// Oracle的特殊自增键通过字段名.nextval获得下一个值
placeHolder.append(value);
@ -192,9 +192,9 @@ public class SqlBuilder implements Builder<String> {
}
String tableName = entity.getTableName();
if (null != this.wrapper) {
if (null != this.quoteWrapper) {
// 包装表名 entity = wrapper.wrap(entity);
tableName = this.wrapper.wrap(tableName);
tableName = this.quoteWrapper.wrap(tableName);
}
sql.append(tableName)
.append(" (").append(fieldsPart).append(") VALUES (")//
@ -214,9 +214,9 @@ public class SqlBuilder implements Builder<String> {
throw new DbRuntimeException("Table name is blank !");
}
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装表名
tableName = wrapper.wrap(tableName);
tableName = quoteWrapper.wrap(tableName);
}
sql.append("DELETE FROM ").append(tableName);
@ -235,9 +235,9 @@ public class SqlBuilder implements Builder<String> {
validateEntity(entity);
String tableName = entity.getTableName();
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装表名
tableName = wrapper.wrap(tableName);
tableName = quoteWrapper.wrap(tableName);
}
sql.append("UPDATE ").append(tableName).append(" SET ");
@ -246,7 +246,7 @@ public class SqlBuilder implements Builder<String> {
if (paramValues.size() > 0) {
sql.append(", ");
}
sql.append((null != wrapper) ? wrapper.wrap(field) : field).append(" = ? ");
sql.append((null != quoteWrapper) ? quoteWrapper.wrap(field) : field).append(" = ? ");
this.paramValues.add(value);// 更新不对空做处理因为存在清空字段的情况
}
});
@ -280,9 +280,9 @@ public class SqlBuilder implements Builder<String> {
if (CollUtil.isEmpty(fields)) {
sql.append("*");
} else {
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装字段名
fields = wrapper.wrap(fields);
fields = quoteWrapper.wrap(fields);
}
sql.append(CollUtil.join(fields, StrUtil.COMMA));
}
@ -321,9 +321,9 @@ public class SqlBuilder implements Builder<String> {
throw new DbRuntimeException("Table name is blank in table names !");
}
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装表名
tableNames = wrapper.wrap(tableNames);
tableNames = quoteWrapper.wrap(tableNames);
}
sql.append(" FROM ").append(ArrayUtil.join(tableNames, StrUtil.COMMA));
@ -369,7 +369,7 @@ public class SqlBuilder implements Builder<String> {
*/
@SuppressWarnings("unchecked")
public <T> SqlBuilder in(final String field, final T... values) {
sql.append(wrapper.wrap(field)).append(" IN ").append("(").append(ArrayUtil.join(values, StrUtil.COMMA)).append(")");
sql.append(quoteWrapper.wrap(field)).append(" IN ").append("(").append(ArrayUtil.join(values, StrUtil.COMMA)).append(")");
return this;
}
@ -381,9 +381,9 @@ public class SqlBuilder implements Builder<String> {
*/
public SqlBuilder groupBy(String... fields) {
if (ArrayUtil.isNotEmpty(fields)) {
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装字段名
fields = wrapper.wrap(fields);
fields = quoteWrapper.wrap(fields);
}
sql.append(" GROUP BY ").append(ArrayUtil.join(fields, StrUtil.COMMA));
@ -436,9 +436,9 @@ public class SqlBuilder implements Builder<String> {
boolean isFirst = true;
for (final Order order : orders) {
field = order.getField();
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装字段名
field = wrapper.wrap(field);
field = quoteWrapper.wrap(field);
}
if (StrUtil.isBlank(field)) {
continue;
@ -473,9 +473,9 @@ public class SqlBuilder implements Builder<String> {
if (null != join) {
sql.append(StrUtil.SPACE).append(join).append(" JOIN ");
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装表名
tableName = wrapper.wrap(tableName);
tableName = quoteWrapper.wrap(tableName);
}
sql.append(tableName);
}
@ -623,9 +623,9 @@ public class SqlBuilder implements Builder<String> {
return StrUtil.EMPTY;
}
if (null != wrapper) {
if (null != quoteWrapper) {
// 包装字段名
conditions = wrapper.wrap(conditions);
conditions = quoteWrapper.wrap(conditions);
}
return ConditionBuilder.of(conditions).build(this.paramValues);

View File

@ -1,5 +1,7 @@
package cn.hutool.db.sql;
import cn.hutool.core.lang.func.Wrapper;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
@ -35,7 +37,7 @@ import java.util.Calendar;
* @author looly
* @since 4.1.0
*/
public class StatementWrapper implements PreparedStatement {
public class StatementWrapper implements PreparedStatement, Wrapper<PreparedStatement> {
private final PreparedStatement rawStatement;
@ -544,4 +546,8 @@ public class StatementWrapper implements PreparedStatement {
rawStatement.setNClob(parameterIndex, reader);
}
@Override
public PreparedStatement getRaw() {
return rawStatement;
}
}

View File

@ -1,5 +1,7 @@
package cn.hutool.json.serialize;
import cn.hutool.core.lang.func.Wrapper;
/**
* {@code JSONString}接口定义了一个{@code toJSONString()}<br>
* 实现此接口的类可以通过实现{@code toJSONString()}方法来改变转JSON字符串的方式
@ -8,7 +10,7 @@ package cn.hutool.json.serialize;
*
*/
@FunctionalInterface
public interface JSONString {
public interface JSONString extends Wrapper<Object> {
/**
* 自定义转JSON字符串的方法
@ -22,6 +24,7 @@ public interface JSONString {
*
* @return 原始对象
*/
@Override
default Object getRaw() {
return this;
}

View File

@ -1,8 +1,5 @@
package cn.hutool.json;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.serialize.JSONDeserializer;
import cn.hutool.json.serialize.JSONObjectSerializer;
import lombok.Data;
@ -39,14 +36,14 @@ public class Issue2555Test {
public static class MySerializer implements JSONObjectSerializer<MyType> {
@Override
public void serialize(JSONObject json, MyType bean) {
public void serialize(final JSONObject json, final MyType bean) {
json.set("addr", bean.getAddress());
}
}
public static class MyDeserializer implements JSONDeserializer<MyType> {
@Override
public MyType deserialize(JSON json) {
public MyType deserialize(final JSON json) {
final MyType myType = new MyType();
myType.setAddress(((JSONObject)json).getStr("addr"));
return myType;