diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/BeanHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/BeanHandler.java index 471739172..4734af427 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/handler/BeanHandler.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/BeanHandler.java @@ -12,8 +12,9 @@ package org.dromara.hutool.db.handler; +import org.dromara.hutool.db.handler.row.BeanRowHandler; + import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; /** @@ -39,14 +40,19 @@ public class BeanHandler implements RsHandler{ return new BeanHandler<>(beanType); } + /** + * 构造 + * @param beanType Bean类型 + */ public BeanHandler(final Class beanType) { this.elementBeanType = beanType; } @Override public E handle(final ResultSet rs) throws SQLException { - final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); - return rs.next() ? ResultSetUtil.toBean(columnCount, meta, rs, this.elementBeanType) : null; + if(rs.next()){ + return new BeanRowHandler<>(rs.getMetaData(), elementBeanType, true).handle(rs); + } + return null; } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityHandler.java index bd244a935..3d5f6366a 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityHandler.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityHandler.java @@ -13,9 +13,9 @@ package org.dromara.hutool.db.handler; import org.dromara.hutool.db.Entity; +import org.dromara.hutool.db.handler.row.EntityRowHandler; import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; /** @@ -56,9 +56,10 @@ public class EntityHandler implements RsHandler{ @Override public Entity handle(final ResultSet rs) throws SQLException { - final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); + if(rs.next()){ + return new EntityRowHandler(rs.getMetaData(), this.caseInsensitive, true).handle(rs); + } - return rs.next() ? ResultSetUtil.toEntity(columnCount, meta, rs, this.caseInsensitive) : null; + return null; } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityListHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityListHandler.java index 5d09a9450..ce3caf708 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityListHandler.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntityListHandler.java @@ -12,11 +12,13 @@ package org.dromara.hutool.db.handler; +import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.db.Entity; +import org.dromara.hutool.db.handler.row.EntityRowHandler; import java.sql.ResultSet; +import java.sql.ResultSetMetaData; import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; /** @@ -56,6 +58,14 @@ public class EntityListHandler implements RsHandler>{ @Override public List handle(final ResultSet rs) throws SQLException { - return ResultSetUtil.toEntityList(rs, new ArrayList<>(), this.caseInsensitive); + final ResultSetMetaData meta = rs.getMetaData(); + final EntityRowHandler rowHandler = new EntityRowHandler(meta, caseInsensitive, true); + + final List result = ListUtil.of(); + while (rs.next()){ + result.add(rowHandler.handle(rs)); + } + + return result; } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntitySetHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntitySetHandler.java index 1ce2258c9..22cc2c421 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntitySetHandler.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/EntitySetHandler.java @@ -13,6 +13,7 @@ package org.dromara.hutool.db.handler; import org.dromara.hutool.db.Entity; +import org.dromara.hutool.db.handler.row.EntityRowHandler; import java.sql.ResultSet; import java.sql.SQLException; @@ -55,6 +56,14 @@ public class EntitySetHandler implements RsHandler>{ @Override public LinkedHashSet handle(final ResultSet rs) throws SQLException { - return ResultSetUtil.toEntityList(rs, new LinkedHashSet<>(), this.caseInsensitive); + final EntityRowHandler rowHandler = + new EntityRowHandler(rs.getMetaData(), caseInsensitive, true); + + final LinkedHashSet result = new LinkedHashSet<>(); + while (rs.next()){ + result.add(rowHandler.handle(rs)); + } + + return result; } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/ResultSetUtil.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/ResultSetUtil.java index 57c28591a..98f6f31b7 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/handler/ResultSetUtil.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/ResultSetUtil.java @@ -12,28 +12,20 @@ package org.dromara.hutool.db.handler; -import org.dromara.hutool.core.bean.BeanUtil; -import org.dromara.hutool.core.bean.PropDesc; import org.dromara.hutool.core.convert.Convert; import org.dromara.hutool.core.lang.Assert; -import org.dromara.hutool.core.reflect.ConstructorUtil; -import org.dromara.hutool.core.reflect.method.MethodUtil; -import org.dromara.hutool.core.reflect.TypeUtil; import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.db.DbRuntimeException; import org.dromara.hutool.db.Entity; +import org.dromara.hutool.db.handler.row.*; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; -import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Map; /** * 数据结果集处理辅助类 @@ -45,157 +37,35 @@ public class ResultSetUtil { /** * 处理单条数据 * - * @param Bean类型 - * @param columnCount 列数 - * @param meta ResultSetMetaData - * @param rs 数据集 - * @param bean 目标Bean - * @return 每一行的Entity - * @throws SQLException SQL执行异常 - * @since 3.3.1 - */ - public static T toBean(final int columnCount, final ResultSetMetaData meta, final ResultSet rs, final T bean) throws SQLException { - return toEntity(columnCount, meta, rs).toBeanIgnoreCase(bean); - } - - /** - * 处理单条数据 - * - * @param Bean类型 - * @param columnCount 列数 - * @param meta ResultSetMetaData - * @param rs 数据集 - * @param beanClass 目标Bean类型 + * @param Bean类型 + * @param meta ResultSetMetaData + * @param rs 数据集 + * @param beanClass 目标Bean类型 * @return 每一行的Entity * @throws SQLException SQL执行异常 * @since 3.3.1 */ @SuppressWarnings("unchecked") - public static T toBean(final int columnCount, final ResultSetMetaData meta, final ResultSet rs, final Class beanClass) throws SQLException { + public static T toBean(final ResultSetMetaData meta, final ResultSet rs, final Class beanClass) throws SQLException { Assert.notNull(beanClass, "Bean Class must be not null !"); if (beanClass.isArray()) { //返回数组 - final Class componentType = beanClass.getComponentType(); - final Object[] result = ArrayUtil.newArray(componentType, columnCount); - for (int i = 0, j = 1; i < columnCount; i++, j++) { - result[i] = getColumnValue(rs, j, meta.getColumnType(j), componentType); - } - return (T) result; + return (T) new ArrayRowHandler<>(meta, beanClass.getComponentType()).handle(rs); } else if (Iterable.class.isAssignableFrom(beanClass)) { //集合 - final Object[] objRow = toBean(columnCount, meta, rs, Object[].class); + final Object[] objRow = toBean(meta, rs, Object[].class); return Convert.convert(beanClass, objRow); } else if (beanClass.isAssignableFrom(Entity.class)) { //Entity的父类都可按照Entity返回 - return (T) toEntity(columnCount, meta, rs); + return (T) new EntityRowHandler(meta, false, true).handle(rs); } else if (String.class == beanClass) { //字符串 - final Object[] objRow = toBean(columnCount, meta, rs, Object[].class); + final Object[] objRow = toBean(meta, rs, Object[].class); return (T) StrUtil.join(", ", objRow); } - //普通bean - final T bean = ConstructorUtil.newInstanceIfPossible(beanClass); - //忽略字段大小写 - final Map propMap = BeanUtil.getBeanDesc(beanClass).getPropMap(true); - String columnLabel; - PropDesc pd; - Method setter; - Object value; - for (int i = 1; i <= columnCount; i++) { - columnLabel = meta.getColumnLabel(i); - pd = propMap.get(columnLabel); - if (null == pd) { - // 尝试驼峰命名风格 - pd = propMap.get(StrUtil.toCamelCase(columnLabel)); - } - setter = (null == pd) ? null : pd.getSetter(); - if (null != setter) { - value = getColumnValue(rs, i, meta.getColumnType(i), TypeUtil.getFirstParamType(setter)); - MethodUtil.invokeWithCheck(bean, setter, value); - } - } - return bean; - } - - /** - * 处理单条数据 - * - * @param columnCount 列数 - * @param meta ResultSetMetaData - * @param rs 数据集 - * @return 每一行的Entity - * @throws SQLException SQL执行异常 - */ - public static Entity toEntity(final int columnCount, final ResultSetMetaData meta, final ResultSet rs) throws SQLException { - return toEntity(columnCount, meta, rs, false); - } - - /** - * 处理单条数据 - * - * @param columnCount 列数 - * @param meta ResultSetMetaData - * @param rs 数据集 - * @param caseInsensitive 是否大小写不敏感 - * @return 每一行的Entity - * @throws SQLException SQL执行异常 - * @since 4.5.16 - */ - public static Entity toEntity(final int columnCount, final ResultSetMetaData meta, final ResultSet rs, final boolean caseInsensitive) throws SQLException { - return toEntity(new Entity(null, caseInsensitive), columnCount, meta, rs, true); - } - - /** - * 处理单条数据 - * - * @param Entity及其子对象 - * @param row Entity对象 - * @param columnCount 列数 - * @param meta ResultSetMetaData - * @param rs 数据集 - * @param withMetaInfo 是否包含表名、字段名等元信息 - * @return 每一行的Entity - * @throws SQLException SQL执行异常 - * @since 3.3.1 - */ - public static T toEntity(final T row, final int columnCount, final ResultSetMetaData meta, final ResultSet rs, final boolean withMetaInfo) throws SQLException { - int type; - String columnLabel; - for (int i = 1; i <= columnCount; i++) { - type = meta.getColumnType(i); - columnLabel = meta.getColumnLabel(i); - if("rownum_".equalsIgnoreCase(columnLabel)){ - // issue#2618@Github - // 分页时会查出rownum字段,此处忽略掉读取 - continue; - } - row.put(columnLabel, getColumnValue(rs, i, type, null)); - } - if (withMetaInfo) { - try { - row.setTableName(meta.getTableName(1)); - } catch (final SQLException ignore) { - //issue#I2AGLU@Gitee - // Hive等NoSQL中无表的概念,此处报错,跳过。 - } - row.setFieldNames(row.keySet()); - } - return row; - } - - /** - * 处理单条数据 - * - * @param rs 数据集 - * @return 每一行的Entity - * @throws SQLException SQL执行异常 - */ - public static Entity toEntity(final ResultSet rs) throws SQLException { - final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); - return toEntity(columnCount, meta, rs); + return new BeanRowHandler<>(meta, beanClass, true).handle(rs); } /** @@ -207,14 +77,7 @@ public class ResultSetUtil { * @since 5.1.6 */ public static List handleRowToList(final ResultSet rs) throws SQLException { - final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); - final List row = new ArrayList<>(columnCount); - for (int i = 1; i <= columnCount; i++) { - row.add(getColumnValue(rs, i, meta.getColumnType(i), null)); - } - - return row; + return new ListRowHandler<>(rs.getMetaData(), Object.class).handle(rs); } /** @@ -242,11 +105,10 @@ public class ResultSetUtil { * @since 4.5.16 */ public static > T toEntityList(final ResultSet rs, final T collection, final boolean caseInsensitive) throws SQLException { - final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); + final RowHandler rowHandler = new EntityRowHandler(rs.getMetaData(), caseInsensitive, true); while (rs.next()) { - collection.add(toEntity(columnCount, meta, rs, caseInsensitive)); + collection.add(rowHandler.handle(rs)); } return collection; @@ -266,12 +128,9 @@ public class ResultSetUtil { */ public static > T toBeanList(final ResultSet rs, final T collection, final Class elementBeanType) throws SQLException { final ResultSetMetaData meta = rs.getMetaData(); - final int columnCount = meta.getColumnCount(); - while (rs.next()) { - collection.add(toBean(columnCount, meta, rs, elementBeanType)); + collection.add(toBean(meta, rs, elementBeanType)); } - return collection; } @@ -295,20 +154,18 @@ public class ResultSetUtil { return generatedKey; } - // -------------------------------------------------------------------------------------------------------------- Private method start - /** * 获取字段值
* 针对日期时间等做单独处理判断 * * @param rs {@link ResultSet} - * @param columnIndex 字段索引 + * @param columnIndex 字段索引,从1开始计数 * @param type 字段类型,默认Object * @param targetColumnType 结果要求的类型,需进行二次转换(null或者Object不转换) * @return 字段值 * @throws SQLException SQL异常 */ - private static Object getColumnValue(final ResultSet rs, final int columnIndex, final int type, final Type targetColumnType) throws SQLException { + public static Object getColumnValue(final ResultSet rs, final int columnIndex, final int type, final Type targetColumnType) throws SQLException { Object rawValue = null; switch (type) { case Types.TIMESTAMP: @@ -333,5 +190,4 @@ public class ResultSetUtil { return Convert.convert(targetColumnType, rawValue); } } - // -------------------------------------------------------------------------------------------------------------- Private method end } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/ValueListHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/ValueListHandler.java index 5e280d2e8..e326d5186 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/handler/ValueListHandler.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/ValueListHandler.java @@ -12,6 +12,8 @@ package org.dromara.hutool.db.handler; +import org.dromara.hutool.db.handler.row.ListRowHandler; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -35,9 +37,10 @@ public class ValueListHandler implements RsHandler>>{ @Override public List> handle(final ResultSet rs) throws SQLException { + final ListRowHandler listRowHandler = new ListRowHandler<>(rs.getMetaData(), Object.class); final ArrayList> result = new ArrayList<>(); while (rs.next()) { - result.add(ResultSetUtil.handleRowToList(rs)); + result.add(listRowHandler.handle(rs)); } return result; } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/AbsRowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/AbsRowHandler.java new file mode 100644 index 000000000..7d618a21f --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/AbsRowHandler.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * 将{@link ResultSet}结果中的某行处理为List + * + * @param 一行数据处理后的结果类型 + * @author looly + */ +public abstract class AbsRowHandler implements RowHandler { + + protected final ResultSetMetaData meta; + protected final int columnCount; + + /** + * 构造 + * + * @param meta {@link ResultSetMetaData} + * @throws SQLException SQL异常 + */ + public AbsRowHandler(final ResultSetMetaData meta) throws SQLException { + this.meta = meta; + this.columnCount = meta.getColumnCount(); + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/ArrayRowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/ArrayRowHandler.java new file mode 100644 index 000000000..cf8638bb9 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/ArrayRowHandler.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import org.dromara.hutool.core.array.ArrayUtil; +import org.dromara.hutool.db.handler.ResultSetUtil; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * 将{@link ResultSet}结果中的某行处理为数组 + * + * @param 数组元素类型 + * @author looly + */ +public class ArrayRowHandler extends AbsRowHandler { + + private final Class componentType; + + /** + * 构造 + * + * @param meta {@link ResultSetMetaData} + * @param componentType 数组元素类型 + * @throws SQLException SQL异常 + */ + public ArrayRowHandler(final ResultSetMetaData meta, final Class componentType) throws SQLException { + super(meta); + this.componentType = componentType; + } + + @SuppressWarnings("unchecked") + @Override + public E[] handle(final ResultSet rs) throws SQLException { + final E[] result = ArrayUtil.newArray(componentType, columnCount); + for (int i = 0, j = 1; i < columnCount; i++, j++) { + result[i] = (E) ResultSetUtil.getColumnValue(rs, j, meta.getColumnType(j), componentType); + } + return result; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/BeanRowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/BeanRowHandler.java new file mode 100644 index 000000000..3507abd1b --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/BeanRowHandler.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import org.dromara.hutool.core.bean.BeanUtil; +import org.dromara.hutool.core.bean.PropDesc; +import org.dromara.hutool.core.reflect.ConstructorUtil; +import org.dromara.hutool.core.reflect.TypeUtil; +import org.dromara.hutool.core.reflect.method.MethodUtil; +import org.dromara.hutool.core.text.StrUtil; +import org.dromara.hutool.db.handler.ResultSetUtil; + +import java.lang.reflect.Method; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.Map; + +/** + * 将{@link ResultSet}结果中的某行处理为Bean对象 + * + * @param Bean类型 + * @author looly + */ +public class BeanRowHandler extends AbsRowHandler { + + private final Class beanType; + private final boolean caseInsensitive; + + /** + * 构造 + * + * @param meta {@link ResultSetMetaData} + * @param beanType Bean类型 + * @param caseInsensitive 是否大小写不敏感 + * @throws SQLException SQL异常 + */ + public BeanRowHandler(final ResultSetMetaData meta, final Class beanType, final boolean caseInsensitive) throws SQLException { + super(meta); + this.beanType = beanType; + this.caseInsensitive = caseInsensitive; + } + + + @Override + public T handle(final ResultSet rs) throws SQLException { + //普通bean + final T bean = ConstructorUtil.newInstanceIfPossible(beanType); + final Map propMap = BeanUtil.getBeanDesc(beanType).getPropMap(this.caseInsensitive); + String columnLabel; + PropDesc pd; + Method setter; + Object value; + for (int i = 1; i <= columnCount; i++) { + columnLabel = meta.getColumnLabel(i); + pd = propMap.get(columnLabel); + if (null == pd) { + // 尝试驼峰命名风格 + pd = propMap.get(StrUtil.toCamelCase(columnLabel)); + } + setter = (null == pd) ? null : pd.getSetter(); + if (null != setter) { + value = ResultSetUtil.getColumnValue(rs, i, meta.getColumnType(i), TypeUtil.getFirstParamType(setter)); + MethodUtil.invokeWithCheck(bean, setter, value); + } + } + return bean; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/EntityRowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/EntityRowHandler.java new file mode 100644 index 000000000..1ee046eac --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/EntityRowHandler.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import org.dromara.hutool.db.Entity; +import org.dromara.hutool.db.handler.ResultSetUtil; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * 将{@link ResultSet}结果中的某行处理为{@link Entity}对象 + * + * @author looly + */ +public class EntityRowHandler extends AbsRowHandler { + + private final boolean caseInsensitive; + private final boolean withMetaInfo; + + /** + * 构造 + * + * @param meta {@link ResultSetMetaData} + * @param caseInsensitive 是否大小写不敏感 + * @param withMetaInfo 是否包含表名、字段名等元信息 + * @throws SQLException SQL异常 + */ + public EntityRowHandler(final ResultSetMetaData meta, final boolean caseInsensitive, final boolean withMetaInfo) throws SQLException { + super(meta); + this.caseInsensitive = caseInsensitive; + this.withMetaInfo = withMetaInfo; + } + + @Override + public Entity handle(final ResultSet rs) throws SQLException { + final Entity entity = new Entity(null, caseInsensitive); + return fillEntity(entity, rs); + } + + /** + * 处理单条数据 + * + * @param Entity及其子对象 + * @param row Entity对象 + * @param rs 数据集 + * @return 每一行的Entity + * @throws SQLException SQL执行异常 + * @since 3.3.1 + */ + private T fillEntity(final T row, final ResultSet rs) throws SQLException { + int type; + String columnLabel; + for (int i = 1; i <= columnCount; i++) { + type = meta.getColumnType(i); + columnLabel = meta.getColumnLabel(i); + if("rownum_".equalsIgnoreCase(columnLabel)){ + // issue#2618@Github + // 分页时会查出rownum字段,此处忽略掉读取 + continue; + } + row.put(columnLabel, ResultSetUtil.getColumnValue(rs, i, type, null)); + } + if (withMetaInfo) { + try { + row.setTableName(meta.getTableName(1)); + } catch (final SQLException ignore) { + //issue#I2AGLU@Gitee + // Hive等NoSQL中无表的概念,此处报错,跳过。 + } + row.setFieldNames(row.keySet()); + } + return row; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/ListRowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/ListRowHandler.java new file mode 100644 index 000000000..40803b92a --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/ListRowHandler.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import org.dromara.hutool.db.handler.ResultSetUtil; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * 将{@link ResultSet}结果中的某行处理为List + * + * @param 元素类型 + * @author looly + */ +public class ListRowHandler extends AbsRowHandler> { + + private final Class elementType; + + /** + * 构造 + * + * @param meta {@link ResultSetMetaData} + * @param elementType 列表元素类型 + * @throws SQLException SQL异常 + */ + public ListRowHandler(final ResultSetMetaData meta, final Class elementType) throws SQLException { + super(meta); + this.elementType = elementType; + } + + @SuppressWarnings("unchecked") + @Override + public List handle(final ResultSet rs) throws SQLException { + final List row = new ArrayList<>(columnCount); + for (int i = 1; i <= columnCount; i++) { + row.add((E) ResultSetUtil.getColumnValue(rs, i, meta.getColumnType(i), elementType)); + } + + return row; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/RowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/RowHandler.java new file mode 100644 index 000000000..1a4d43548 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/RowHandler.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * 行处理器,用于处理一行数据 + * + * @param 一行数据处理后的结果类型 + * @author looly + * @since 6.0.0 + */ +@FunctionalInterface +public interface RowHandler { + + /** + * 处理一行数据 + * + * @param rs {@link ResultSet},传入前,须调用{@link ResultSet#next()}定位到行。 + * @return 处理行结果对象 + * @throws SQLException SQL异常 + */ + R handle(ResultSet rs) throws SQLException; +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/StringRowHandler.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/StringRowHandler.java new file mode 100644 index 000000000..286856331 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/StringRowHandler.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.db.handler.row; + +import org.dromara.hutool.core.text.StrUtil; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** + * 将{@link ResultSet}结果中的某行处理为数组 + * + * @author looly + */ +public class StringRowHandler implements RowHandler { + + private final ArrayRowHandler arrayRowHandler; + private final String delimiter; + + /** + * 构造 + * + * @param meta {@link ResultSetMetaData} + * @param delimiter 分隔符 + * @throws SQLException SQL异常 + */ + public StringRowHandler(final ResultSetMetaData meta, final String delimiter) throws SQLException { + this.arrayRowHandler = new ArrayRowHandler<>(meta, Object.class); + this.delimiter = delimiter; + } + + @Override + public String handle(final ResultSet rs) throws SQLException { + return StrUtil.join(delimiter, arrayRowHandler.handle(rs)); + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/package-info.java b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/package-info.java new file mode 100644 index 000000000..b9c5c7966 --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/handler/row/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * 结果集中一行的处理 + * + * @author looly + */ +package org.dromara.hutool.db.handler.row;