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>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<artifactId>db-common-lib</artifactId>
|
<artifactId>db-common-lib</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
@ -50,6 +50,18 @@
|
|||||||
<version>${geck.common.version}</version>
|
<version>${geck.common.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -66,4 +66,15 @@ public interface GenericDao {
|
|||||||
|
|
||||||
int execute(String namedSql, SqlParameterSource parameterSource, int expectedRowsAffected, NamedParameterJdbcTemplate namedParameterJdbcTemplate, KeyHolder keyHolder) throws DaoException;
|
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 javax.sql.DataSource;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport implements GenericDao {
|
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,
|
protected Condition appendDateTimeRangeConditions(Condition condition,
|
||||||
Field<LocalDateTime> field,
|
Field<LocalDateTime> field,
|
||||||
Optional<LocalDateTime> fromTime,
|
Optional<LocalDateTime> fromTime,
|
||||||
@ -235,7 +308,13 @@ public abstract class AbstractGenericDao extends NamedParameterJdbcDaoSupport im
|
|||||||
MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
|
MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
|
||||||
for (Map.Entry<String, Param<?>> entry : params.entrySet()) {
|
for (Map.Entry<String, Param<?>> entry : params.entrySet()) {
|
||||||
Param<?> param = entry.getValue();
|
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);
|
sqlParameterSource.addValue(entry.getKey(), param.getValue(), Types.OTHER);
|
||||||
} else {
|
} else {
|
||||||
sqlParameterSource.addValue(entry.getKey(), param.getValue());
|
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