mirror of
https://github.com/valitydev/db-common-lib.git
synced 2024-11-06 00:25:21 +00:00
parent
ceff55f491
commit
0174048cf4
14
pom.xml
14
pom.xml
@ -13,7 +13,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>db-common-lib</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>0.0.2-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@ -50,6 +50,18 @@
|
||||
<version>${geck.common.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.28.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -66,4 +66,15 @@ public interface GenericDao {
|
||||
|
||||
int execute(String namedSql, SqlParameterSource parameterSource, int expectedRowsAffected, NamedParameterJdbcTemplate namedParameterJdbcTemplate, KeyHolder keyHolder) throws DaoException;
|
||||
|
||||
long batchExecute(List<Query> queries) throws DaoException;
|
||||
|
||||
long batchExecute(List<Query> queries, int expectedRowsPerQueryAffected) throws DaoException;
|
||||
|
||||
long batchExecute(List<Query> queries, int expectedRowsPerQueryAffected, NamedParameterJdbcTemplate namedParameterJdbcTemplate) throws DaoException;
|
||||
|
||||
long batchExecute(String namedSql, List<SqlParameterSource> parameterSources) throws DaoException;
|
||||
|
||||
long batchExecute(String namedSql, List<SqlParameterSource> parameterSources, int expectedRowsPerQueryAffected) throws DaoException;
|
||||
|
||||
long batchExecute(String namedSql, List<SqlParameterSource> parameterSources, int expectedRowsPerQueryAffected, NamedParameterJdbcTemplate namedParameterJdbcTemplate) throws DaoException;
|
||||
}
|
||||
|
@ -17,9 +17,12 @@ import org.springframework.jdbc.support.KeyHolder;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport implements GenericDao {
|
||||
|
||||
@ -217,6 +220,76 @@ public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport im
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long batchExecute(List<Query> queries) throws DaoException {
|
||||
return batchExecute(queries, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long batchExecute(List<Query> queries, int expectedRowsAffected) throws DaoException {
|
||||
return batchExecute(queries, expectedRowsAffected, getNamedParameterJdbcTemplate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long batchExecute(List<Query> queries, int expectedRowsAffected, NamedParameterJdbcTemplate namedParameterJdbcTemplate) throws DaoException {
|
||||
AtomicLong affectedRowCounter = new AtomicLong();
|
||||
queries.stream()
|
||||
.collect(
|
||||
Collectors.groupingBy(
|
||||
query -> query.getSQL(ParamType.NAMED),
|
||||
LinkedHashMap::new,
|
||||
Collectors.mapping(query -> toSqlParameterSource(query.getParams()), Collectors.toList())
|
||||
)
|
||||
)
|
||||
.forEach(
|
||||
(namedSql, parameterSources) -> {
|
||||
long affectedRowCount = batchExecute(
|
||||
namedSql,
|
||||
parameterSources,
|
||||
expectedRowsAffected,
|
||||
namedParameterJdbcTemplate
|
||||
);
|
||||
affectedRowCounter.getAndAccumulate(affectedRowCount, Long::sum);
|
||||
}
|
||||
);
|
||||
return affectedRowCounter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long batchExecute(String namedSql, List<SqlParameterSource> parameterSources) throws DaoException {
|
||||
return batchExecute(namedSql, parameterSources, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long batchExecute(String namedSql, List<SqlParameterSource> parameterSources, int expectedRowsAffected) throws DaoException {
|
||||
return batchExecute(namedSql, parameterSources, expectedRowsAffected, getNamedParameterJdbcTemplate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long batchExecute(String namedSql, List<SqlParameterSource> parameterSources, int expectedRowsAffected, NamedParameterJdbcTemplate namedParameterJdbcTemplate) throws DaoException {
|
||||
try {
|
||||
int[] rowsPerBatchAffected = namedParameterJdbcTemplate.batchUpdate(namedSql, parameterSources.toArray(new SqlParameterSource[0]));
|
||||
|
||||
if (rowsPerBatchAffected.length != parameterSources.size()) {
|
||||
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(namedSql, parameterSources.size(), rowsPerBatchAffected.length);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
for (int i : rowsPerBatchAffected) {
|
||||
count += i;
|
||||
}
|
||||
if (expectedRowsAffected != -1) {
|
||||
if (count != expectedRowsAffected) {
|
||||
throw new JdbcUpdateAffectedIncorrectNumberOfRowsException(namedSql, expectedRowsAffected, count);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
} catch (NestedRuntimeException ex) {
|
||||
throw new DaoException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected Condition appendDateTimeRangeConditions(Condition condition,
|
||||
Field<LocalDateTime> field,
|
||||
Optional<LocalDateTime> fromTime,
|
||||
@ -235,7 +308,13 @@ public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport im
|
||||
MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
|
||||
for (Map.Entry<String, Param<?>> entry : params.entrySet()) {
|
||||
Param<?> param = entry.getValue();
|
||||
if (param.getValue() instanceof LocalDateTime || param.getValue() instanceof EnumType) {
|
||||
Class<?> type = param.getDataType().getType();
|
||||
if (String.class.isAssignableFrom(type)) {
|
||||
String value = Optional.ofNullable(param.getValue())
|
||||
.map(stringValue -> ((String) stringValue).replace("\u0000", "\\u0000"))
|
||||
.orElse(null);
|
||||
sqlParameterSource.addValue(entry.getKey(), value);
|
||||
} else if (LocalDateTime.class.isAssignableFrom(type) || EnumType.class.isAssignableFrom(type)) {
|
||||
sqlParameterSource.addValue(entry.getKey(), param.getValue(), Types.OTHER);
|
||||
} else {
|
||||
sqlParameterSource.addValue(entry.getKey(), param.getValue());
|
||||
|
112
test/java/com/rbkmoney/dao/impl/AbstractGenericDaoTest.java
Normal file
112
test/java/com/rbkmoney/dao/impl/AbstractGenericDaoTest.java
Normal file
@ -0,0 +1,112 @@
|
||||
package com.rbkmoney.dao.impl;
|
||||
|
||||
import com.rbkmoney.dao.DaoException;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Param;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AbstractGenericDaoTest {
|
||||
|
||||
private TestDao testDaoSpy;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
testDaoSpy = spy(new TestDao(mock(DataSource.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void batchExecuteTest() {
|
||||
final NamedParameterJdbcTemplate namedParameterJdbcTemplateMock = mock(NamedParameterJdbcTemplate.class);
|
||||
int[] rowPerBatchAffected = { 1, 1 };
|
||||
when(namedParameterJdbcTemplateMock.batchUpdate(anyString(), any(SqlParameterSource[].class))).thenReturn(rowPerBatchAffected);
|
||||
when(testDaoSpy.getNamedParameterJdbcTemplate()).thenReturn(namedParameterJdbcTemplateMock);
|
||||
|
||||
final Map<String, Param<?>> firstParamMap = paramMapMock("testString", "testValue", String.class);
|
||||
firstParamMap.putAll(paramMapMock("testDate", LocalDateTime.now(), LocalDateTime.class));
|
||||
|
||||
final Query firstQueryMock = mock(Query.class);
|
||||
when(firstQueryMock.getSQL(ParamType.NAMED)).thenReturn("test sql");
|
||||
when(firstQueryMock.getParams()).thenReturn(firstParamMap);
|
||||
|
||||
final Map<String, Param<?>> secondParamMap = paramMapMock("testInteger", 12345, Integer.class);
|
||||
secondParamMap.putAll(paramMapMock("testLong", 12345L, Long.class));
|
||||
|
||||
final Query secondQueryMock = mock(Query.class);
|
||||
when(secondQueryMock.getSQL(ParamType.NAMED)).thenReturn("test sql");
|
||||
when(secondQueryMock.getParams()).thenReturn(secondParamMap);
|
||||
|
||||
final List<Query> queryList = Arrays.asList(firstQueryMock, secondQueryMock);
|
||||
final long rowsAffected = testDaoSpy.batchExecute(queryList, 2);
|
||||
Assert.assertEquals(2, rowsAffected);
|
||||
}
|
||||
|
||||
@Test(expected = DaoException.class)
|
||||
public void batchExceptionTest() {
|
||||
final NamedParameterJdbcTemplate namedParameterJdbcTemplateMock = mock(NamedParameterJdbcTemplate.class);
|
||||
int[] rowPerBatchAffected = { 1 };
|
||||
when(namedParameterJdbcTemplateMock.batchUpdate(anyString(), any(SqlParameterSource[].class))).thenReturn(rowPerBatchAffected);
|
||||
when(testDaoSpy.getNamedParameterJdbcTemplate()).thenReturn(namedParameterJdbcTemplateMock);
|
||||
|
||||
final Map<String, Param<?>> firstParamMap = paramMapMock("testString", "testValue", String.class);
|
||||
firstParamMap.putAll(paramMapMock("testDate", LocalDateTime.now(), LocalDateTime.class));
|
||||
|
||||
final Query firstQueryMock = mock(Query.class);
|
||||
when(firstQueryMock.getSQL(ParamType.NAMED)).thenReturn("test sql");
|
||||
when(firstQueryMock.getParams()).thenReturn(firstParamMap);
|
||||
|
||||
final List<Query> queryList = Collections.singletonList(firstQueryMock);
|
||||
final long rowsAffected = testDaoSpy.batchExecute(queryList, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toSqlParameterSourceNullByteTest() {
|
||||
final Map<String, Param<?>> paramMap = paramMapMock("test", "\u0000", String.class);
|
||||
final SqlParameterSource sqlParameterSource = testDaoSpy.toSqlParameterSource(paramMap);
|
||||
Assert.assertEquals("\\u0000", sqlParameterSource.getValue("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toSqlParameterSourceDateTest() {
|
||||
final LocalDateTime dateTime = LocalDateTime.now();
|
||||
final Map<String, Param<?>> paramMap = paramMapMock("testDate", dateTime, LocalDateTime.class);
|
||||
final SqlParameterSource sqlParameterSource = testDaoSpy.toSqlParameterSource(paramMap);
|
||||
Assert.assertEquals(dateTime, sqlParameterSource.getValue("testDate"));
|
||||
Assert.assertEquals(Types.OTHER, sqlParameterSource.getSqlType("testDate"));
|
||||
}
|
||||
|
||||
private Map<String, Param<?>> paramMapMock(String key, Object value, Class<?> dataType) {
|
||||
final Param paramMock = mock(Param.class);
|
||||
final DataType dataTypeMock = mock(DataType.class);
|
||||
when(dataTypeMock.getType()).thenReturn(dataType);
|
||||
when(paramMock.getDataType()).thenReturn(dataTypeMock);
|
||||
when(paramMock.getValue()).thenReturn(value);
|
||||
final Map<String, Param<?>> paramMap = new HashMap<>();
|
||||
paramMap.put(key, paramMock);
|
||||
|
||||
return paramMap;
|
||||
}
|
||||
|
||||
private class TestDao extends AbstractGenericDao {
|
||||
|
||||
TestDao(DataSource dataSource) {
|
||||
super(dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user