diff --git a/src/main/java/ru/nbch/credit_tracker/component/RepositoryTimingAspect.java b/src/main/java/ru/nbch/credit_tracker/component/RepositoryTimingAspect.java new file mode 100644 index 0000000..55dd410 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/component/RepositoryTimingAspect.java @@ -0,0 +1,28 @@ +package ru.nbch.credit_tracker.component; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +@Aspect +@Slf4j +@Component +public class RepositoryTimingAspect { + @Around("within(@org.springframework.stereotype.Repository *)") + public Object timeMapper(ProceedingJoinPoint pjp) throws Throwable { + long start = System.nanoTime(); + try { + return pjp.proceed(); + } finally { + long tookMs = (System.nanoTime() - start) / 1_000_000; + String method = pjp.getSignature().toShortString(); + if (tookMs > 1000) { + log.warn("Slow jdbc template call {} took {} ms", method, tookMs); + } else { + log.debug("Jdbc template call {} took {} ms", method, tookMs); + } + } + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/mapper/indic/PhoneMapper.java b/src/main/java/ru/nbch/credit_tracker/mapper/indic/PhoneMapper.java deleted file mode 100644 index 791a4c6..0000000 --- a/src/main/java/ru/nbch/credit_tracker/mapper/indic/PhoneMapper.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.nbch.credit_tracker.mapper.indic; - -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; -import ru.nbch.credit_tracker.service.indic.PhoneService; - -import java.util.List; - -@Mapper -public interface PhoneMapper { - List findFids(@Param("phones") List phones); -} diff --git a/src/main/java/ru/nbch/credit_tracker/repository/PhoneRepository.java b/src/main/java/ru/nbch/credit_tracker/repository/PhoneRepository.java new file mode 100644 index 0000000..de2a326 --- /dev/null +++ b/src/main/java/ru/nbch/credit_tracker/repository/PhoneRepository.java @@ -0,0 +1,78 @@ +package ru.nbch.credit_tracker.repository; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.time.LocalDate; +import java.util.List; + +@Repository +public class PhoneRepository { + + private static final String SELCT_FIDS = """ + SELECT + pn.number, + pn.fid, + pn.file_since_dt + FROM PHONE_NORM pn + JOIN (SELECT DISTINCT fid FROM NAME) nf + ON nf.fid = pn.fid + WHERE number in (:phones) + ORDER BY + pn.number ASC, + pn.file_since_dt DESC, + pn.fid DESC + WITH UR + """; + + private final NamedParameterJdbcTemplate jdbcTemplate; + + public PhoneRepository(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + + public List findFids(List phones) { + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("phones", phones); + + return jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) -> + new PhoneRepository.FidsData(rs.getInt("fid"), rs.getString("number"), rs.getObject("file_since_dt", LocalDate.class)) + ); + } + + public List findFidsLong(List phones) { + MapSqlParameterSource params = new MapSqlParameterSource(); + params.addValue("phones", phones); + + return jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) -> + new PhoneRepository.FidsDataLong(rs.getInt("fid"), Long.parseLong(rs.getString("number")), rs.getObject("file_since_dt", LocalDate.class)) + ); + } + + @Getter + @Setter + @AllArgsConstructor + @NoArgsConstructor + public static class FidsData { + private Integer fid; + private String phone; + private LocalDate fileSinceDate; + } + + @Getter + @Setter + @AllArgsConstructor + @NoArgsConstructor + public static class FidsDataLong { + private Integer fid; + private Long phone; + private LocalDate fileSinceDate; + } +} diff --git a/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService.java b/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService.java index 26787b5..814af62 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService.java +++ b/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService.java @@ -1,17 +1,10 @@ package ru.nbch.credit_tracker.service.indic; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Service; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; +import ru.nbch.credit_tracker.repository.PhoneRepository; -import java.time.LocalDate; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -21,26 +14,10 @@ import java.util.Map; @Service public class PhoneService { - private static final String SELCT_FIDS = """ - SELECT - pn.number, - pn.fid, - pn.file_since_dt - FROM PHONE_NORM pn - JOIN (SELECT DISTINCT fid FROM NAME) nf - ON nf.fid = pn.fid - WHERE number in (:phones) - ORDER BY - pn.number ASC, - pn.file_since_dt DESC, - pn.fid DESC - WITH UR - """; + private final PhoneRepository phoneRepository; - private final NamedParameterJdbcTemplate jdbcTemplate; - - public PhoneService(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; + public PhoneService(PhoneRepository phoneRepository) { + this.phoneRepository = phoneRepository; } /** @@ -60,12 +37,7 @@ public class PhoneService { ) ); - MapSqlParameterSource params = new MapSqlParameterSource(); - params.addValue("phones", phones); - - List phonesByFid = jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) -> - new FidsData(rs.getInt("fid"), Long.parseLong(rs.getString("number")), rs.getObject("file_since_dt", LocalDate.class)) - ); + List phonesByFid = phoneRepository.findFidsLong(phones); log.debug("Start merging fids"); Map phoneFidMap = merger(subjects, phonesByFid); @@ -74,7 +46,7 @@ public class PhoneService { return phoneFidMap; } - private Map merger(List subjects, List phonesByFid) { + private Map merger(List subjects, List phonesByFid) { Map phoneFidMap = new HashMap<>(); if (phonesByFid.isEmpty()) { @@ -86,7 +58,7 @@ public class PhoneService { Long normalizedPhone = Long.parseLong("9" + subject.getPhone()); while (index < phonesByFid.size()) { - FidsData currentFidData = phonesByFid.get(index); + PhoneRepository.FidsDataLong currentFidData = phonesByFid.get(index); if (currentFidData.getPhone() < normalizedPhone) { index++; @@ -109,13 +81,4 @@ public class PhoneService { return phoneFidMap; } - @Getter - @Setter - @AllArgsConstructor - @NoArgsConstructor - public static class FidsData { - private Integer fid; - private Long phone; - private LocalDate fileSinceDate; - } } diff --git a/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java b/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java index aebc4e5..eb4d08e 100644 --- a/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java +++ b/src/main/java/ru/nbch/credit_tracker/service/indic/PhoneService2.java @@ -1,44 +1,21 @@ package ru.nbch.credit_tracker.service.indic; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Service; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; +import ru.nbch.credit_tracker.repository.PhoneRepository; -import java.time.LocalDate; import java.util.*; @Slf4j @Service public class PhoneService2 { - private static final String SELCT_FIDS = """ - SELECT - pn.number, - pn.fid, - pn.file_since_dt - FROM PHONE_NORM pn - JOIN (SELECT DISTINCT fid FROM NAME) nf - ON nf.fid = pn.fid - WHERE number in (:phones) - ORDER BY - pn.number ASC, - pn.file_since_dt DESC, - pn.fid DESC - WITH UR - """; + private final PhoneRepository phoneRepository; - private final NamedParameterJdbcTemplate jdbcTemplate; - - public PhoneService2(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; + public PhoneService2(PhoneRepository phoneRepository) { + this.phoneRepository = phoneRepository; } /** @@ -60,15 +37,10 @@ public class PhoneService2 { ) ); - MapSqlParameterSource params = new MapSqlParameterSource(); - params.addValue("phones", phones); - - List phonesByFid = jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) -> - new FidsData(rs.getInt("fid"), rs.getString("number"), rs.getObject("file_since_dt", LocalDate.class)) - ); + List phonesByFid = phoneRepository.findFids(phones); Map phoneToFidsMap = new HashMap<>(); - for (FidsData fidsData : phonesByFid) { + for (PhoneRepository.FidsData fidsData : phonesByFid) { if (!phoneToFidsMap.containsKey(fidsData.getPhone())) { phoneToFidsMap.put(fidsData.getPhone(), fidsData.getFid()); } @@ -88,11 +60,11 @@ public class PhoneService2 { return phoneFidMap; } - private Map merger(List subjects, List phonesByFid) { + private Map merger(List subjects, List phonesByFid) { Map phoneFidMap = new HashMap<>(); - Iterator iterator = phonesByFid.iterator(); + Iterator iterator = phonesByFid.iterator(); String lastUniquePhone = null; - FidsData fidsData = null; + PhoneRepository.FidsData fidsData = null; for (PhoneFidMap phoneFid : subjects) { String normalizedPhone = 9 + phoneFid.getPhone(); while (iterator.hasNext()) { @@ -116,13 +88,4 @@ public class PhoneService2 { return phoneFidMap; } - @Getter - @Setter - @AllArgsConstructor - @NoArgsConstructor - public static class FidsData { - private Integer fid; - private String phone; - private LocalDate fileSinceDate; - } } diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 20aa7c4..8fb6f4e 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -68,6 +68,12 @@ + + + + + + diff --git a/src/main/resources/mybatis/mapper/indic/PhoneMapper.xml b/src/main/resources/mybatis/mapper/indic/PhoneMapper.xml deleted file mode 100644 index 856a06d..0000000 --- a/src/main/resources/mybatis/mapper/indic/PhoneMapper.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/java/ru/nbch/credit_tracker/service/PhoneService2Test.java b/src/test/java/ru/nbch/credit_tracker/service/PhoneService2Test.java index b57542d..7588d3f 100644 --- a/src/test/java/ru/nbch/credit_tracker/service/PhoneService2Test.java +++ b/src/test/java/ru/nbch/credit_tracker/service/PhoneService2Test.java @@ -5,10 +5,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; +import ru.nbch.credit_tracker.repository.PhoneRepository; import ru.nbch.credit_tracker.service.indic.PhoneService2; import java.time.LocalDate; @@ -18,21 +16,20 @@ import java.util.List; import java.util.Map; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class PhoneService2Test { @Mock - NamedParameterJdbcTemplate jdbcTemplate; + PhoneRepository phoneRepository; @Test public void defineFidByPhoneTest() { - PhoneService2 phoneService = new PhoneService2(jdbcTemplate); + PhoneService2 phoneService = new PhoneService2(phoneRepository); fidsDataWithEqualSinceDt.sort(byDbOrder); - when(jdbcTemplate.query(anyString(), any(MapSqlParameterSource.class), any(RowMapper.class))).thenReturn(fidsDataWithEqualSinceDt); + when(phoneRepository.findFids(any())).thenReturn(fidsDataWithEqualSinceDt); List phoneFidMap = new ArrayList<>(); phoneFidMap.add(PhoneFidMap.builder().phone("1111").build()); @@ -49,19 +46,19 @@ public class PhoneService2Test { Assertions.assertEquals("1115", res.get(127).getPhone()); } - private final List fidsDataWithEqualSinceDt = new ArrayList<>( + private final List fidsDataWithEqualSinceDt = new ArrayList<>( List.of( - new PhoneService2.FidsData(123, "91111", LocalDate.of(2025, 9, 10)), - new PhoneService2.FidsData(124, "91111", LocalDate.of(2025, 9, 10)), - new PhoneService2.FidsData(125, "91112", LocalDate.of(2024, 10, 10)), - new PhoneService2.FidsData(126, "91114", LocalDate.of(2024, 10, 11)), - new PhoneService2.FidsData(127, "91115", LocalDate.of(2025, 9, 11)), - new PhoneService2.FidsData(128, "91115", LocalDate.of(2025, 9, 10)) + new PhoneRepository.FidsData(123, "91111", LocalDate.of(2025, 9, 10)), + new PhoneRepository.FidsData(124, "91111", LocalDate.of(2025, 9, 10)), + new PhoneRepository.FidsData(125, "91112", LocalDate.of(2024, 10, 10)), + new PhoneRepository.FidsData(126, "91114", LocalDate.of(2024, 10, 11)), + new PhoneRepository.FidsData(127, "91115", LocalDate.of(2025, 9, 11)), + new PhoneRepository.FidsData(128, "91115", LocalDate.of(2025, 9, 10)) ) ); - Comparator byDbOrder = - Comparator.comparing(PhoneService2.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC - .thenComparing(PhoneService2.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC - .thenComparing(PhoneService2.FidsData::getFid, Comparator.reverseOrder()); + Comparator byDbOrder = + Comparator.comparing(PhoneRepository.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC + .thenComparing(PhoneRepository.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC + .thenComparing(PhoneRepository.FidsData::getFid, Comparator.reverseOrder()); } diff --git a/src/test/java/ru/nbch/credit_tracker/service/PhoneServiceTest.java b/src/test/java/ru/nbch/credit_tracker/service/PhoneServiceTest.java index 303c41d..1b9f5fa 100644 --- a/src/test/java/ru/nbch/credit_tracker/service/PhoneServiceTest.java +++ b/src/test/java/ru/nbch/credit_tracker/service/PhoneServiceTest.java @@ -5,10 +5,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; -import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import ru.nbch.credit_tracker.entities.dto.PhoneFidMap; +import ru.nbch.credit_tracker.repository.PhoneRepository; import ru.nbch.credit_tracker.service.indic.PhoneService; import java.time.LocalDate; @@ -18,21 +16,20 @@ import java.util.List; import java.util.Map; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) public class PhoneServiceTest { @Mock - NamedParameterJdbcTemplate jdbcTemplate; + PhoneRepository phoneRepository; @Test public void defineFidByPhoneTest() { - PhoneService phoneService = new PhoneService(jdbcTemplate); + PhoneService phoneService = new PhoneService(phoneRepository); fidsDataWithEqualSinceDt.sort(byDbOrder); - when(jdbcTemplate.query(anyString(), any(MapSqlParameterSource.class), any(RowMapper.class))).thenReturn(fidsDataWithEqualSinceDt); + when(phoneRepository.findFidsLong(any())).thenReturn(fidsDataWithEqualSinceDt); List phoneFidMap = new ArrayList<>(); phoneFidMap.add(PhoneFidMap.builder().phone("1111").build()); @@ -49,19 +46,19 @@ public class PhoneServiceTest { Assertions.assertEquals("1115", res.get(127).getPhone()); } - private final List fidsDataWithEqualSinceDt = new ArrayList<>( + private final List fidsDataWithEqualSinceDt = new ArrayList<>( List.of( - new PhoneService.FidsData(123, 91111L, LocalDate.of(2025, 9, 10)), - new PhoneService.FidsData(124, 91111L, LocalDate.of(2025, 9, 10)), - new PhoneService.FidsData(125, 91112L, LocalDate.of(2024, 10, 10)), - new PhoneService.FidsData(126, 91114L, LocalDate.of(2024, 10, 11)), - new PhoneService.FidsData(127, 91115L, LocalDate.of(2025, 9, 11)), - new PhoneService.FidsData(128, 91115L, LocalDate.of(2025, 9, 10)) + new PhoneRepository.FidsDataLong(123, 91111L, LocalDate.of(2025, 9, 10)), + new PhoneRepository.FidsDataLong(124, 91111L, LocalDate.of(2025, 9, 10)), + new PhoneRepository.FidsDataLong(125, 91112L, LocalDate.of(2024, 10, 10)), + new PhoneRepository.FidsDataLong(126, 91114L, LocalDate.of(2024, 10, 11)), + new PhoneRepository.FidsDataLong(127, 91115L, LocalDate.of(2025, 9, 11)), + new PhoneRepository.FidsDataLong(128, 91115L, LocalDate.of(2025, 9, 10)) ) ); - Comparator byDbOrder = - Comparator.comparing(PhoneService.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC - .thenComparing(PhoneService.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC - .thenComparing(PhoneService.FidsData::getFid, Comparator.reverseOrder()); + Comparator byDbOrder = + Comparator.comparing(PhoneRepository.FidsDataLong::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC + .thenComparing(PhoneRepository.FidsDataLong::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC + .thenComparing(PhoneRepository.FidsDataLong::getFid, Comparator.reverseOrder()); }