![JAR search and dependency download from the Maven repository](/logo.png)
win.doyto.query.core.JdbcDataAccess Maven / Gradle / Ivy
package win.doyto.query.core;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import win.doyto.query.entity.Persistable;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Transient;
import static win.doyto.query.core.Constant.SEPARATOR;
/**
* JdbcDataAccess
*
* @author f0rb
*/
public final class JdbcDataAccess, I extends Serializable, Q extends PageQuery> implements DataAccess {
private static final Map classRowMapperMap = new ConcurrentHashMap<>();
private final JdbcOperations jdbcOperations;
private final RowMapper rowMapper;
private final CrudBuilder crudBuilder;
private final String[] columnsForSelect;
private final boolean isGeneratedId;
private final BiFunction setIdFunc;
@SuppressWarnings("unchecked")
public JdbcDataAccess(JdbcOperations jdbcOperations, Class entityClass, Class idClass, RowMapper rowMapper) {
this.jdbcOperations = jdbcOperations;
this.rowMapper = rowMapper;
crudBuilder = new CrudBuilder<>(entityClass);
columnsForSelect = Arrays
.stream(FieldUtils.getAllFields(entityClass))
.filter(JdbcDataAccess::shouldRetain)
.map(CommonUtil::selectAs)
.toArray(String[]::new);
Field[] idFields = FieldUtils.getFieldsWithAnnotation(entityClass, Id.class);
isGeneratedId = idFields.length == 1 && idFields[0].isAnnotationPresent(GeneratedValue.class);
if (idClass.isAssignableFrom(Integer.class)) {
setIdFunc = (e, key) -> {
e.setId((I) (Integer) key.intValue());
return null;
};
} else if (idClass.isAssignableFrom(Long.class)) {
setIdFunc = (e, key) -> {
e.setId((I) (Long) key.longValue());
return null;
};
} else {
setIdFunc = (e, key) -> {
e.setId((I) key);
return null;
};
}
}
private static boolean shouldRetain(Field field) {
return !field.getName().startsWith("$") // $jacocoData
&& !Modifier.isStatic(field.getModifiers()) // static field
&& !field.isAnnotationPresent(Transient.class) // Transient field
;
}
@Override
public final List query(Q q) {
return queryColumns(q, rowMapper, columnsForSelect);
}
@Override
@SuppressWarnings("unchecked")
public final List queryColumns(Q q, Class clazz, String... columns) {
columns = StringUtils.join(columns, SEPARATOR).split(",");
RowMapper customRowMapper;
if (Map.class.isAssignableFrom(clazz)) {
customRowMapper = new ColumnMapRowMapper();
} else {
customRowMapper = classRowMapperMap.computeIfAbsent(clazz, columns.length == 1 ? SingleColumnRowMapper::new : BeanPropertyRowMapper::new);
}
return queryColumns(q, customRowMapper, columns);
}
private List queryColumns(Q q, RowMapper rowMapper, String... columns) {
SqlAndArgs sqlAndArgs = crudBuilder.buildSelectColumnsAndArgs(q, columns);
return jdbcOperations.query(sqlAndArgs.sql, sqlAndArgs.args, rowMapper);
}
@Override
public final long count(Q q) {
SqlAndArgs sqlAndArgs = crudBuilder.buildCountAndArgs(q);
return jdbcOperations.queryForObject(sqlAndArgs.sql, sqlAndArgs.args, Long.class);
}
@Override
public final int delete(Q q) {
return doUpdate(crudBuilder.buildDeleteAndArgs(q));
}
@Override
public final E get(I id) {
return getEntity(crudBuilder.buildSelectById(id, columnsForSelect));
}
@Override
public final int delete(I id) {
return jdbcOperations.update(crudBuilder.buildDeleteById(), id);
}
@Override
public final E get(E e) {
return getEntity(crudBuilder.buildSelectById(e, columnsForSelect));
}
private E getEntity(SqlAndArgs sqlAndArgs) {
List list = jdbcOperations.query(sqlAndArgs.sql, sqlAndArgs.args, rowMapper);
return list.isEmpty() ? null : list.get(0);
}
@Override
public final int delete(E e) {
return jdbcOperations.update(crudBuilder.buildDeleteById(e), e.getId());
}
@Override
public final void create(E e) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy