补充文档注释

pull/1/head
ZhouXY108 2024-11-02 10:55:23 +08:00
parent bd08be5928
commit 6b5bcf0b5c
6 changed files with 718 additions and 71 deletions

View File

@ -16,49 +16,78 @@
package xyz.zhouxy.jdbc;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import javax.annotation.Nonnull;
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import xyz.zhouxy.plusone.commons.collection.AbstractMapWrapper;
import xyz.zhouxy.plusone.commons.util.AssertTools;
import xyz.zhouxy.plusone.commons.util.OptionalTools;
import xyz.zhouxy.plusone.commons.util.StringTools;
import java.util.*;
/**
* DbRecord
*
* <p>
* Map<String, Object> DB
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @since 1.0.0
*/
@Beta
public class DbRecord extends AbstractMapWrapper<String, Object, DbRecord> {
public DbRecord() {
super(new HashMap<>(), k -> Preconditions.checkArgument(StringTools.isNotBlank(k), "Key must has text."), null);
super(new HashMap<>(),
k -> AssertTools.checkArgument(StringTools.isNotBlank(k), "Key must has text."),
null);
}
public DbRecord(Map<String, Object> map) {
super(map, k -> Preconditions.checkArgument(StringTools.isNotBlank(k), "Key must has text."), null);
super(map,
k -> AssertTools.checkArgument(StringTools.isNotBlank(k), "Key must has text."),
null);
}
/**
* {@link String} {@link Optional}
* {@code key} {@link Optional#empty()}
*/
public Optional<String> getValueAsString(String key) {
return this.getAndConvert(key);
}
public <T> List<T> getValueAsList(String key) {
return this.<Collection<T>>getAndConvert(key)
.map(l -> (l instanceof List) ? (List<T>) l : new ArrayList<>(l))
.orElse(Collections.emptyList());
}
public <T> Set<T> getValueAsSet(String key) {
return this.<Collection<T>>getAndConvert(key)
.map(l -> (l instanceof Set) ? (Set<T>) l : new HashSet<>(l))
.orElse(Collections.emptySet());
}
/**
* {@code int} {@link OptionalInt}
* {@code key} {@link OptionalInt#empty()}
*/
@Nonnull
public OptionalInt getValueAsInt(String key) {
return OptionalTools.toOptionalInt(this.getAndConvert(key));
}
/**
* {@code long} {@link OptionalLong}
* {@code key} {@link OptionalLong#empty()}
*/
@Nonnull
public OptionalLong getValueAsLong(String key) {
return OptionalTools.toOptionalLong(this.getAndConvert(key));
}
/**
* {@code double} {@link OptionalDouble}
* {@code key} {@link OptionalDouble#empty()}
*/
@Nonnull
public OptionalDouble getValueAsDouble(String key) {
return OptionalTools.toOptionalDouble(this.getAndConvert(key));
}

View File

@ -35,9 +35,28 @@ import javax.annotation.Nullable;
import com.google.common.base.CaseFormat;
import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
/**
* DefaultBeanRowMapper
*
* <p>
* {@link ResultSet} Java Bean {@link RowMapper}
* </p>
*
* <p>
* <b>NOTE: 使使 {@code setter}
* 使 {@link RowMapper}</b>
* </p>
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @since 1.0.0
*/
public class DefaultBeanRowMapper<T> implements RowMapper<T> {
/** Bean 的无参构造器 */
private final Constructor<T> constructor;
/** 列名到属性的映射 */
private final Map<String, PropertyDescriptor> colPropertyMap;
private DefaultBeanRowMapper(Constructor<T> constructor, Map<String, PropertyDescriptor> colPropertyMap) {
@ -45,10 +64,29 @@ public class DefaultBeanRowMapper<T> implements RowMapper<T> {
this.colPropertyMap = colPropertyMap;
}
/**
* DefaultBeanRowMapper
*
* @param <T> Bean
* @param beanType Bean
* @return DefaultBeanRowMapper
* @throws SQLException DefaultBeanRowMapper
*/
@StaticFactoryMethod(DefaultBeanRowMapper.class)
public static <T> DefaultBeanRowMapper<T> of(Class<T> beanType) throws SQLException {
return of(beanType, null);
}
/**
* DefaultBeanRowMapper
*
* @param <T> Bean
* @param beanType Bean
* @param propertyColMap Bean key value
* @return DefaultBeanRowMapper
* @throws SQLException DefaultBeanRowMapper
*/
@StaticFactoryMethod(DefaultBeanRowMapper.class)
public static <T> DefaultBeanRowMapper<T> of(Class<T> beanType, @Nullable Map<String, String> propertyColMap)
throws SQLException {
try {
@ -60,6 +98,7 @@ public class DefaultBeanRowMapper<T> implements RowMapper<T> {
BeanInfo beanInfo = Introspector.getBeanInfo(beanType);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
// Bean 的属性名为小驼峰,对应的列名为下划线
Function<? super PropertyDescriptor, String> keyMapper;
if (propertyColMap == null || propertyColMap.isEmpty()) {
keyMapper = p -> CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, p.getName());
@ -84,13 +123,17 @@ public class DefaultBeanRowMapper<T> implements RowMapper<T> {
}
}
/** {@inheritDoc} */
@Override
public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
try {
// 调用无参构造器创建实例
T newInstance = this.constructor.newInstance();
ResultSetMetaData metaData = rs.getMetaData();
// 遍历结果的每一列
for (int i = 1; i <= metaData.getColumnCount(); i++) {
String colName = metaData.getColumnName(i);
// 获取查询结果列名对应的属性,调用 setter
PropertyDescriptor propertyDescriptor = this.colPropertyMap.get(colName);
if (propertyDescriptor != null) {
Method setter = propertyDescriptor.getWriteMethod();

View File

@ -27,12 +27,21 @@ import java.util.OptionalLong;
import java.util.function.Function;
import java.util.stream.Collectors;
import com.google.common.base.Preconditions;
import xyz.zhouxy.plusone.commons.collection.CollectionTools;
import xyz.zhouxy.plusone.commons.util.ArrayTools;
import xyz.zhouxy.plusone.commons.util.AssertTools;
import xyz.zhouxy.plusone.commons.util.OptionalTools;
/**
* ParamBuilder
*
* <p>
* JDBC {@code Object[]} {@link PreparedStatement}
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @since 1.0.0
*/
public class ParamBuilder {
public static final Object[] EMPTY_OBJECT_ARRAY = {};
@ -60,8 +69,8 @@ public class ParamBuilder {
}
public static <T> List<Object[]> buildBatchParams(final Collection<T> c, final Function<T, Object[]> func) {
Preconditions.checkNotNull(c, "The collection can not be null.");
Preconditions.checkNotNull(func, "The func can not be null.");
AssertTools.checkNotNull(c, "The collection can not be null.");
AssertTools.checkNotNull(func, "The func can not be null.");
if (CollectionTools.isEmpty(c)) {
return Collections.emptyList();
}

View File

@ -19,7 +19,21 @@ package xyz.zhouxy.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* ResultHandler
*
* <p>
* {@link ResultSet}
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @since 1.0.0
*/
@FunctionalInterface
public interface ResultHandler<T> {
/**
* {@link ResultSet}
*/
T handle(ResultSet resultSet) throws SQLException;
}

View File

@ -22,10 +22,21 @@ import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
/**
* RowMapper
*
* <p>
* {@link ResultSet}
* </p>
*
* @author <a href="http://zhouxy.xyz:3000/ZhouXY108">ZhouXY</a>
* @since 1.0.0
*/
@FunctionalInterface
public interface RowMapper<T> {
T mapRow(ResultSet rs, int rowNumber) throws SQLException;
/** 每一行数据转换为 {@link HashMap} */
public static final RowMapper<Map<String, Object>> HASH_MAP_MAPPER = (rs, rowNumber) -> {
Map<String, Object> result = new HashMap<>();
ResultSetMetaData metaData = rs.getMetaData();
@ -37,13 +48,16 @@ public interface RowMapper<T> {
return result;
};
/** 每一行数据转换为 {@link DbRecord} */
public static final RowMapper<DbRecord> RECORD_MAPPER =
(rs, rowNumber) -> new DbRecord(HASH_MAP_MAPPER.mapRow(rs, rowNumber));
/** 默认实现的将 {@link ResultSet} 转换为 Java Bean 的 {@link RowMapper}。 */
public static <T> RowMapper<T> beanRowMapper(Class<T> beanType) throws SQLException {
return DefaultBeanRowMapper.of(beanType);
}
/** 默认实现的将 {@link ResultSet} 转换为 Java Bean 的 {@link RowMapper}。 */
public static <T> RowMapper<T> beanRowMapper(Class<T> beanType, Map<String, String> propertyColMap)
throws SQLException {
return DefaultBeanRowMapper.of(beanType, propertyColMap);

File diff suppressed because it is too large Load Diff