![JAR search and dependency download from the Maven repository](/logo.png)
win.doyto.query.jdbc.JdbcDataAccess Maven / Gradle / Ivy
The newest version!
/*
* Copyright © 2019-2024 Forb Yuan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package win.doyto.query.jdbc;
import org.apache.commons.lang3.reflect.FieldUtils;
import win.doyto.query.annotation.GeneratedValue;
import win.doyto.query.annotation.Id;
import win.doyto.query.config.GlobalConfiguration;
import win.doyto.query.core.DataAccess;
import win.doyto.query.core.DoytoQuery;
import win.doyto.query.core.IdWrapper;
import win.doyto.query.core.PageList;
import win.doyto.query.entity.Persistable;
import win.doyto.query.jdbc.rowmapper.BeanPropertyRowMapper;
import win.doyto.query.jdbc.rowmapper.ColumnMapRowMapper;
import win.doyto.query.jdbc.rowmapper.RowMapper;
import win.doyto.query.jdbc.rowmapper.SingleColumnRowMapper;
import win.doyto.query.sql.EntityMetadata;
import win.doyto.query.sql.SqlAndArgs;
import win.doyto.query.sql.SqlBuilder;
import win.doyto.query.sql.SqlBuilderFactory;
import win.doyto.query.util.BeanUtil;
import win.doyto.query.util.ColumnUtil;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* JdbcDataAccess
*
* @author f0rb
*/
public final class JdbcDataAccess, I extends Serializable, Q extends DoytoQuery> implements DataAccess {
private static final Map, RowMapper>> classRowMapperMap;
static {
classRowMapperMap = new ConcurrentHashMap<>();
classRowMapperMap.put(Map.class, new ColumnMapRowMapper());
}
private final DatabaseOperations databaseOperations;
private final RowMapper rowMapper;
private final SqlBuilder sqlBuilder;
private final String[] columnsForSelect;
private final boolean isGeneratedId;
private final SingleColumnRowMapper idRowMapper;
private final Class idClass;
private final String idColumn;
private final JdbcDataQueryClient jdbcDataQueryClient;
private final EntityMetadata entityMetadata;
public JdbcDataAccess(DatabaseOperations databaseOperations, Class entityClass) {
this(databaseOperations, entityClass, new BeanPropertyRowMapper<>(entityClass));
}
public JdbcDataAccess(DatabaseOperations databaseOperations, Class entityClass, RowMapper rowMapper) {
classRowMapperMap.put(entityClass, rowMapper);
this.databaseOperations = databaseOperations;
this.rowMapper = rowMapper;
this.sqlBuilder = SqlBuilderFactory.create(entityClass);
this.columnsForSelect = EntityMetadata.buildViewColumns(entityClass).split(", ");
Field[] idFields = FieldUtils.getFieldsWithAnnotation(entityClass, Id.class);
this.isGeneratedId = idFields.length == 1 && idFields[0].isAnnotationPresent(GeneratedValue.class);
this.idColumn = idFields[0].getName();
this.idClass = BeanUtil.getIdClass(entityClass, idColumn);
this.idRowMapper = new SingleColumnRowMapper<>(idClass);
this.jdbcDataQueryClient = new JdbcDataQueryClient(databaseOperations);
this.entityMetadata = EntityMetadata.build(entityClass);
}
@Override
public List query(Q query) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildSelectColumnsAndArgs(query, columnsForSelect);
List mainEntities = databaseOperations.query(sqlAndArgs, rowMapper);
jdbcDataQueryClient.querySubEntities(mainEntities, query, entityMetadata);
return mainEntities;
}
@Override
public PageList page(Q query) {
query.forcePaging();
return new PageList<>(query(query), count(query));
}
@Override
public List queryColumns(Q query, Class clazz, String... columns) {
if (columns.length == 0) {
columns = columnsForSelect;
}
boolean isSingle = ColumnUtil.isSingleColumn(columns);
@SuppressWarnings("unchecked")
RowMapper localRowMapper = (RowMapper) classRowMapperMap.computeIfAbsent(
clazz, c -> isSingle ? new SingleColumnRowMapper<>(clazz) : new BeanPropertyRowMapper<>(clazz));
return queryColumns(query, localRowMapper, columns);
}
private List queryColumns(Q q, RowMapper rowMapper, String... columns) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildSelectColumnsAndArgs(q, columns);
return databaseOperations.query(sqlAndArgs, rowMapper);
}
@Override
public long count(Q q) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildCountAndArgs(q);
return databaseOperations.count(sqlAndArgs);
}
@Override
public int delete(Q q) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildDeleteAndArgs(q);
return databaseOperations.update(sqlAndArgs);
}
@Override
public E get(IdWrapper w) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildSelectById(w, columnsForSelect);
List list = databaseOperations.query(sqlAndArgs, rowMapper);
return list.isEmpty() ? null : list.get(0);
}
@Override
public int delete(IdWrapper w) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildDeleteById(w);
return databaseOperations.update(sqlAndArgs);
}
@Override
public void create(E e) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildCreateAndArgs(e);
if (isGeneratedId) {
String keyColumn = GlobalConfiguration.dialect().resolveKeyColumn(idColumn);
I id = databaseOperations.insert(sqlAndArgs, idClass, keyColumn).get(0);
e.setId(id);
} else {
databaseOperations.update(sqlAndArgs);
}
}
@Override
public int batchInsert(Iterable entities, String... columns) {
if (!entities.iterator().hasNext()) {
return 0;
}
if (GlobalConfiguration.dialect().supportMultiGeneratedKeys()) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildCreateAndArgs(entities, columns);
String keyColumn = GlobalConfiguration.dialect().resolveKeyColumn(idColumn);
List ids = databaseOperations.insert(sqlAndArgs, idClass, keyColumn);
int i = 0;
for (E entity : entities) {
entity.setId(ids.get(i++));
}
return ids.size();
} else {
SqlAndArgs sqlAndArgs = sqlBuilder.buildCreateAndArgs(entities, columns);
return databaseOperations.update(sqlAndArgs);
}
}
@Override
public int update(E e) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildUpdateAndArgs(e);
return databaseOperations.update(sqlAndArgs);
}
@Override
public int patch(E e) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildPatchAndArgsWithId(e);
return databaseOperations.update(sqlAndArgs);
}
@Override
public int patch(E e, Q q) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildPatchAndArgs(e, q);
return databaseOperations.update(sqlAndArgs);
}
@Override
public List queryIds(Q q) {
SqlAndArgs sqlAndArgs = sqlBuilder.buildSelectIdAndArgs(q);
return databaseOperations.query(sqlAndArgs, idRowMapper);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy