From fbf9430dff9f59e6ee8fc7c29520be1c722f107a Mon Sep 17 00:00:00 2001 From: mtak0235 Date: Sat, 29 Jul 2023 00:11:28 +0900 Subject: [PATCH] #4 --- .../DictionaryOfJava" | 1 + ...4_\354\266\224\354\203\201\355\231\224.md" | 685 ++++++++++++++++++ ...04\353\241\234\354\240\235\355\212\270.md" | 33 + .../.gradle/8.1.1/checksums/checksums.lock | Bin 17 -> 17 bytes .../.gradle/8.1.1/checksums/md5-checksums.bin | Bin 32347 -> 32547 bytes .../8.1.1/checksums/sha1-checksums.bin | Bin 82967 -> 83507 bytes .../executionHistory/executionHistory.bin | Bin 167613 -> 167613 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .../.gradle/8.1.1/fileHashes/fileHashes.bin | Bin 25247 -> 26447 bytes .../.gradle/8.1.1/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../8.1.1/fileHashes/resourceHashesCache.bin | Bin 26011 -> 27167 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes spring/tobby/tobby/.gradle/file-system.probe | Bin 8 -> 8 bytes spring/tobby/tobby/.idea/vcs.xml | 2 +- .../com/example/tobby/TobbyApplication.class | Bin 652 -> 828 bytes .../main/com/example/tobby/dip/Bulb.class | Bin 0 -> 163 bytes .../com/example/tobby/dip/BulbFactory.class | Bin 0 -> 666 bytes .../main/com/example/tobby/dip/Lamp.class | Bin 0 -> 641 bytes .../com/example/tobby/dip/SwitchService.class | Bin 0 -> 732 bytes .../Exception/DuplicateUserIdException.class | Bin 0 -> 471 bytes .../tobby/user/UserLevelUpgradePolicy.class | Bin 0 -> 329 bytes .../example/tobby/user/UserService$1.class | Bin 0 -> 800 bytes .../com/example/tobby/user/UserService.class | Bin 0 -> 2915 bytes .../user/dao/DuplicateUserIdException.class | Bin 459 -> 0 bytes .../com/example/tobby/user/dao/UserDao.class | Bin 472 -> 508 bytes .../example/tobby/user/dao/UserDaoJdbc.class | Bin 2795 -> 3028 bytes .../com/example/tobby/user/domain/Level.class | Bin 2108 -> 2353 bytes .../com/example/tobby/user/domain/User.class | Bin 2027 -> 2806 bytes .../UserServiceTest$TestUserService.class | Bin 0 -> 1105 bytes ...ServiceTest$TestUserServiceException.class | Bin 0 -> 497 bytes .../example/tobby/user/UserServiceTest.class | Bin 0 -> 4775 bytes .../example/tobby/user/dao/UserDaoTest.class | Bin 8976 -> 9487 bytes .../example/tobby/user/domain/UserTest.class | Bin 0 -> 2616 bytes ...om.example.tobby.user.dao.UserDaoTest.html | 201 ++++- .../tobby/build/reports/tests/test/index.html | 50 +- .../packages/com.example.tobby.user.dao.html | 36 +- .../tobby/tobby/build/resources/main/test.xml | 3 + ...com.example.tobby.user.dao.UserDaoTest.xml | 170 ++++- .../build/test-results/test/binary/output.bin | Bin 2800 -> 2987 bytes .../test-results/test/binary/output.bin.idx | Bin 333 -> 366 bytes .../test-results/test/binary/results.bin | Bin 444 -> 12287 bytes .../TobbyApplication.class.uniqueId0 | Bin 0 -> 652 bytes .../compileJava/previous-compilation-data.bin | Bin 26278 -> 28943 bytes .../stash-dir/UserDaoTest.class.uniqueId0 | Bin 8963 -> 0 bytes ...erviceTest$TestUserService.class.uniqueId2 | Bin 0 -> 1105 bytes ...t$TestUserServiceException.class.uniqueId0 | Bin 0 -> 497 bytes .../stash-dir/UserServiceTest.class.uniqueId1 | Bin 0 -> 4775 bytes .../previous-compilation-data.bin | Bin 43389 -> 43715 bytes .../com/example/tobby/TobbyApplication.java | 3 +- .../com/example/tobby/dip/SwitchService.java | 45 ++ .../java/com/example/tobby/test/Test.java | 27 + .../DuplicateUserIdException.java | 14 +- .../tobby/user/UserLevelUpgradePolicy.java | 8 + .../com/example/tobby/user/UserService.java | 48 ++ .../com/example/tobby/user/dao/UserDao.java | 2 + .../example/tobby/user/dao/UserDaoJdbc.java | 5 + .../com/example/tobby/user/domain/Level.java | 10 +- .../com/example/tobby/user/domain/User.java | 54 +- .../tobby/tobby/src/main/resources/test.xml | 3 + .../example/tobby/user/UserServiceTest.java | 113 +++ .../example/tobby/user/dao/UserDaoTest.java | 17 + .../example/tobby/user/domain/UserTest.java | 37 + 62 files changed, 1434 insertions(+), 133 deletions(-) create mode 160000 "java/JAVA\354\235\230\354\240\225\354\204\235/DictionaryOfJava" create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/Bulb.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/BulbFactory.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/Lamp.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/SwitchService.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/Exception/DuplicateUserIdException.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserLevelUpgradePolicy.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserService$1.class create mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserService.class delete mode 100644 spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/dao/DuplicateUserIdException.class create mode 100644 spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/UserServiceTest$TestUserService.class create mode 100644 spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/UserServiceTest$TestUserServiceException.class create mode 100644 spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/UserServiceTest.class create mode 100644 spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/domain/UserTest.class create mode 100644 spring/tobby/tobby/build/tmp/compileJava/compileTransaction/stash-dir/TobbyApplication.class.uniqueId0 delete mode 100644 spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserDaoTest.class.uniqueId0 create mode 100644 spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest$TestUserService.class.uniqueId2 create mode 100644 spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest$TestUserServiceException.class.uniqueId0 create mode 100644 spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest.class.uniqueId1 create mode 100644 spring/tobby/tobby/src/main/java/com/example/tobby/dip/SwitchService.java create mode 100644 spring/tobby/tobby/src/main/java/com/example/tobby/test/Test.java rename spring/tobby/tobby/src/main/java/com/example/tobby/user/{dao => Exception}/DuplicateUserIdException.java (77%) create mode 100644 spring/tobby/tobby/src/main/java/com/example/tobby/user/UserLevelUpgradePolicy.java create mode 100644 spring/tobby/tobby/src/main/java/com/example/tobby/user/UserService.java create mode 100644 spring/tobby/tobby/src/test/java/com/example/tobby/user/UserServiceTest.java create mode 100644 spring/tobby/tobby/src/test/java/com/example/tobby/user/domain/UserTest.java diff --git "a/java/JAVA\354\235\230\354\240\225\354\204\235/DictionaryOfJava" "b/java/JAVA\354\235\230\354\240\225\354\204\235/DictionaryOfJava" new file mode 160000 index 0000000..c785dee --- /dev/null +++ "b/java/JAVA\354\235\230\354\240\225\354\204\235/DictionaryOfJava" @@ -0,0 +1 @@ +Subproject commit c785deecad0369c1f419c20a05750e25905990ce diff --git "a/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/5_\354\204\234\353\271\204\354\212\244_\354\266\224\354\203\201\355\231\224.md" "b/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/5_\354\204\234\353\271\204\354\212\244_\354\266\224\354\203\201\355\231\224.md" index ac25748..3bc4f16 100644 --- "a/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/5_\354\204\234\353\271\204\354\212\244_\354\266\224\354\203\201\355\231\224.md" +++ "b/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/5_\354\204\234\353\271\204\354\212\244_\354\266\224\354\203\201\355\231\224.md" @@ -139,3 +139,688 @@ public class UserDaoJdbc implements UserDao { ## 1.2 사용자 수정 기능 추가 +수정할 정보가 담긴 User 오 브젝트를 전달하면 id를 참고해서 사용자를 찾아 필드 정보를 UPDATE 문을 이용해 모두 변경해주는 메소드를 하나 만들겠다. + +### 수정 가능 테스트 추가 + +```java + @Test + public void update() { + dao.deleteAll(); + dao.add(user1); + user1.setName("루삥뽕"); + user1.setPassword("0000"); + user1.setLevel(Level.GOLD); + user1.setLogin(1000); + user1.setRecommend(999); + dao.update(user1); + User user1update = dao.get(user1.getId()); + checkSameUser(user1, user1update); + } +``` + +### UserDao와 UserDaoJdbc 수정 + +```java +@Override + public void update(User user) { + this.jdbcTemplate.update("update users set name=?, password=?, level=?, login=?, recomment=? where id=?", user.getName(), user.getPassword(), user.getLevel().intValue(), user.getLogin(), user.getRecommend(), user.getId()); + } +``` + +### 수정 테스트 보완 + +만약, 쿼리에서 where문이 빠지면 지금 Test문으론 못 잡는다. 수정한 레코드는 변경사항이 잘 반영 되었는지 확인을 하는데, 다른 레코드는 여전히 바뀌지 않았는지 확인하지 않기 때문이다. 어카노? + +1. jdbcTemplate의 update()가 돌려주는 리턴 값을 확인한다. + * jdbcTemplate의 update()는 update, delete같이 테이블에 영향을 주는 SQL을 실행하면서 몇개의 row가 영향을 받았는지 리턴한다. +2. 테스트를 보강해서 원하는 사용자 외의 정보가 그대로가 맞는지 확인한다. + +## 1.3 UserService.upgradeLevels() + + UserDao의 getAll() 메소드로 사용자를 다 가져와서 사용 자별로 레벨 업그레이드 작업을 진행하면서 UserDao의 update()를 호출해 DB에 결과를 넣어주면 된다. + +### UserService 클래스와 빈 등록 + +```java +package com.example.tobby.user; + +import com.example.tobby.user.dao.UserDao; + +public class UserService { + UserDao userDao; + + public void setUserDao(UserDao userDao) { + this.userDao = userDao; + } +} + +``` + +```xml + + + +``` + +### UserServiceTest class + +```java +package com.example.tobby.user; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@ExtendWith(SpringExtension.class) +@ContextConfiguration(locations = "/test.xml") +class UserServiceTest { + + @Autowired + UserService userService; + + @Test + void bean() { + assertThat(this.userService).isNotNull(); + } +} +``` + +### upgradeLevels() + +```java +package com.example.tobby.user; + +import com.example.tobby.user.dao.UserDao; +import com.example.tobby.user.domain.Level; +import com.example.tobby.user.domain.User; + +import java.util.List; + +public class UserService { + UserDao userDao; + + public void setUserDao(UserDao userDao) { + this.userDao = userDao; + } + + public void upgradeLevels() { + List users = userDao.getAll(); + for (User user : users) { + Boolean changed = null; + if (user.getLevel() == Level.BASIC && user.getLogin() >= 50) { + user.setLevel(Level.SILVER); + changed = true; + } else if (user.getLevel() == Level.SILVER && user.getRecommend() >= 30) { + user.setLevel(Level.GOLD); + changed = true; + } else if (user.getLevel() == Level.GOLD) { + changed = false; + } else { + changed = false; + } + + if (changed) { + userDao.update(user); + } + } + } +} + +``` + +### upgradeLevels() test + +레벨 basic, silver, gold 중 변경이 일어나는 basic, silver 고려해서 총 5가지 케이스틑 테스트 해야 한다. + +```java +package com.example.tobby.user; + +import com.example.tobby.user.dao.UserDao; +import com.example.tobby.user.domain.Level; +import com.example.tobby.user.domain.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.Arrays; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +@ExtendWith(SpringExtension.class) +@ContextConfiguration(locations = "/test.xml") +class UserServiceTest { + + @Autowired + UserService userService; + @Autowired + UserDao userDao; + List users; + + @BeforeEach + public void setUp() { + users = Arrays.asList( + new User("bumjin", "박범진", "p1", Level.BASIC, 49, 0), + new User("joytouch", "강명성", "p2", Level.BASIC, 50, 0), + new User("erwins", "신승한", "p3", Level.SILVER, 60, 29), + new User("madnite1", "이상호", "p4", Level.SILVER, 60, 30), + new User("green", "오민규", "p5", Level.GOLD, 100, 100) + ); + } + + @Test + void bean() { + assertThat(this.userService).isNotNull(); + } + + @Test + public void upgradeLevels() { + userDao.deleteAll(); + for (User user : users) userDao.add(user); + userService.upgradeLevels(); + checkLevel(users.get(0), Level.BASIC); + checkLevel(users.get(1), Level.SILVER); + checkLevel(users.get(2), Level.SILVER); + checkLevel(users.get(3), Level.GOLD); + checkLevel(users.get(4), Level.GOLD); + } + + private void checkLevel(User user, Level expectedLevel) { + User userUpdate = userDao.get(user.getId()); + assertThat(userUpdate.getLevel()).isEqualTo(expectedLevel); + } +} +``` + +## 1.4 UserService.add() + + 처음 가입하 는 사용자는 기본적으로 BASIC 레벨이어야 한다는 부분이 필요하다. + +🤔User 클래스에서 아예 level 필드를 Level.BASIC으로 초기화하는 것은 어 떨까? +처음 가입할 때를 빼고는 필요 없는 정보인데 굳이? + +😎UserService 에 add()하나 파서 넣자! + +```java + @Test + public void add() { + userDao.deleteAll(); + User userWithLevel = users.get(4); // GOLD 레벨 + User userWithoutLevel = users.get(0); + userWithoutLevel.setLevel(null); + userService.add(userWithLevel); + userService.add(userWithoutLevel); + User userWithLevelRead = userDao.get(userWithLevel.getId()); + User userWithoutLevelRead = userDao.get(userWithoutLevel.getId()); + assertThat(userWithLevelRead.getLevel()).isEqualTo(userWithLevel.getLevel()); + assertThat(userWithoutLevelRead.getLevel()).isEqualTo(Level.BASIC); + } +``` + +```java + public void add(User user) { + if (user.getLevel() == null) user.setLevel(Level.BASIC); + userDao.add(user); + } +``` + +### 1.5 코드 개선 + +### upgradeLevels( ) 메소드 코드의 문제점 + +for 루프 속에 들어 있는 if/elseif/else 블록들이 읽기 불편하다 + 만약 새로운 레벨이 추가된다면 Level 이늄도 수정해야 하고, upgradeLevels()의 레벨 업그레이드 로직을 담은 코드에 if 조건식과 블록을 추가해줘야 한다. + +😎변경이 잦은 내용이 추상적인 로직의 흐름과 함께 섞여 있다. + +### upgradeLevels( ) 리팩토링 + +레벨을 업그레이드 하는 작업의 기본 흐름만 먼저 만들어보자. + +```java + public void upgradeLevels() { + List users = userDao.getAll(); + for (User user : users) { + if (canUpgradeLevel(user)) upgradeLevel(user); + } + } +``` + +```java + private void upgradeLevel(User user) { + if (user.getLevel() == Level.BASIC) user.setLevel(Level.SILVER); + else if (user.getLevel() == Level.SILVER) user.setLevel(Level.GOLD); + userDao.update(user); + } + + private boolean canUpgradeLevel(User user) { + Level currentLevel = user.getLevel(); + switch (currentLevel) { + case BASIC: + return (user.getLogin() >= 50); + case SILVER: + return (user.getRecommend() >= 30); + case GOLD: + return false; + default: + throw new IllegalArgumentException("Unknown Level: " + + currentLevel); + } + } +``` + +🤔upgradeLevel() 메소드 코드는 마음에 안 든다. +사용자 오브젝트의 레벨정보를 다음 단계로 변경하고, 변경된 오브젝트를 DB에 업데이트하는 두 가지 작업을 수행하고 있다.. +레벨이 늘어나면 if 문이 점점 길어질 것이고, 레벨 변경 시 사용 자 오브젝트에서 level 필드 외의 값도 같이 변경해야 한다면 if 조건 뒤에 붙는 내용도 점점 길어질 것이다. + +😎먼저 레벨의 순서와 다음 단계 레벨이 무엇인지를 결정하는 일은 Level에게 맡기자. + +```java +package com.example.tobby.user.domain; + +public enum Level { + GOLD(3, null), SILVER(2, GOLD), BASIC(1, SILVER); + private final int value; + private final Level next; + + public int intValue() { + return value; + } + + Level(int value, Level next) { + this.value = value; + this.next = next; + } + + public static Level valueOf(int value) { + return switch (value) { + case 1 -> BASIC; + case 2 -> SILVER; + case 3 -> GOLD; + default -> throw new AssertionError("Unknown value: " + value); + }; + } +} + +``` + +😎사용자 정보가 바뀌는 부분을 UserService 메소드에서 User로 옮겨보자 + +```java +package com.example.tobby.user.domain; + +public class User { + String id; + String name; + + Level level; + int login; + int recommend; + String password; + + public User() { + } + + public User(String id, String name, String password, Level level, + int login, int recommend) { + this.id = id; + this.name = name; + this.password = password; + this.level = level; + this.login = login; + this.recommend = recommend; + } + +... + public void upgradeLevel() { + Level nextLevel = this.level.nextLevel(); + if (nextLevel == null) { + throw new IllegalStateException(this.level + "은 업그레이드가 불가능합니다"); + } else { + this.level = nextLevel; + } + } +} + +``` + +UserService 의 canUpgradeLevel() 메소드에서 업그레이드 가능 여부를 미리 판단해주기는 하지만, User 오브젝트를 UserService만 사용하는 건 아니므로 스스로 예외상황에 대한 검증 기 능을 갖고 있는 편이 안전하다. + +```java + private void upgradeLevel(User user) { + user.upgradeLevel(); + userDao.update(user); + } +``` + +간결해졌다! + +😎 UserService, User, Level이 내부 정보를 다루는 자신의 책임에 충실한 기능을 갖고 있으면서 필요가 생기면 이런 작업을 수행해 달라고 서로 요청하는 구조다. + +처음 구현했던 UserService의 upgradeLevels() 메소드는 User 오브젝트에서 데이 터를 가져와서 그것을 가지고 User 오브젝트나 Level 이늄이 해야 할 작업을 대신 수행 하고 직접 User 오브젝트의 데이터를 변경해버린다. 이보다는 UserService는 User에게 “레벨 업그레이드 작업을 해달라”고 요청하고, 또 User는 Level에게 “다음 레벨이 무엇인 지 알려달라”고 요청하는 방식으로 동작하게 하는 것이 바람직하다. + +### User test + +upgradeLevel()을 테스트하자. + +```java +package com.example.tobby.user.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UserTest { + User user; + + @BeforeEach + public void setUp() { + user = new User(); + } + + @Test + void upgradeLevel() { + Level[] levels = Level.values(); + for (Level level : levels) { + if (level.nextLevel() == null) continue; + user.setLevel(level); + user.upgradeLevel(); + assertThat(user.getLevel()).isEqualTo(level.nextLevel()); + } + } + + @Test + public void cannotUpgradeLevel() { + Level[] levels = Level.values(); + for (Level level : levels) { + if (level.nextLevel() != null) continue; + user.setLevel(level); + assertThrows(IllegalStateException.class, () -> user.upgradeLevel()); + } + } +} +``` + +### UserServiceTest 개선 + +Level이 갖고 있어야 할 다음 레벨이 무엇인가 하는 정보를 테스트에 직접 넣어둘 이유가 없다. 리팩토링 ㄱㄱ + +```java + @Test + public void upgradeLevels() { + userDao.deleteAll(); + for (User user : users) userDao.add(user); + userService.upgradeLevels(); + checkLevelUpgraded(users.get(0), false); + checkLevelUpgraded(users.get(1), true); + checkLevelUpgraded(users.get(2), false); + checkLevelUpgraded(users.get(3), true); + checkLevelUpgraded(users.get(4), false); + } + + private void checkLevelUpgraded(User user, boolean upgraded) { + User userUpdate = userDao.get(user.getId()); + if (upgraded) { + assertThat(userUpdate.getLevel()).isEqualTo(user.getLevel().nextLevel()); + } + else { + assertThat(userUpdate.getLevel()).isEqualTo(user.getLevel()); + } + } +``` + +🤔코드에 나타난 중복을 제거해보자. 업그레이드 조건인 로그인 횟수와 추천 횟 수가 애플리케이션 코드와 테스트 코드에 중복돼서 나타난다 + +```java +case BASIC: return (user.getLogin() >= 50); // UserService +new User("joytouch", "강명성", "p2", Level.BASIC, 50, 0) // UserServiceTest +``` + +상수 값을 중복하는 건 바람직하지 못하다. 기준이 되는 최소 로그인 횟수가 변경될 때도 한 번만 수정할 수 있도록 만들자. + +```java + public static final int MIN_LOGCOUNT_FOR_SILVER = 50; + public static final int MIN_RECCOMEND_FOR_GOLD = 30; + private boolean canUpgradeLevel(User user) { + Level currentLevel = user.getLevel(); + switch (currentLevel) { + case BASIC: + return (user.getLogin() >= MIN_LOGCOUNT_FOR_SILVER); + case SILVER: + return (user.getRecommend() >= MIN_RECCOMEND_FOR_GOLD); + case GOLD: + return false; + default: + throw new IllegalArgumentException("Unknown Level: " + + currentLevel); + } + } +``` + +```java + @BeforeEach + public void setUp() { + users = Arrays.asList( + new User("bumjin", "박범진", "p1", Level.BASIC, MIN_LOGCOUNT_FOR_SILVER-1, 0), + new User("joytouch", "강명성", "p2", Level.BASIC, MIN_LOGCOUNT_FOR_SILVER, 0), + new User("erwins", "신승한", "p3", Level.SILVER, 60, MIN_RECCOMEND_FOR_GOLD-1), + new User("madnite1", "이상호", "p4", Level.SILVER, 60, MIN_RECCOMEND_FOR_GOLD), + new User("green", "오민규", "p5", Level.GOLD, 100, Integer.MAX_VALUE) + ); + } +``` + +레벨을 업그레이드하는 정책을 유연하게 변경할 수 있도록 개선해보자. + +사용자 업그레이드 정책을 UserService에서 분리하기 위해 분리된 업그레이드 정책을 담은 오브젝트는 DI를 통해 UserService에 주입한다. + +업그레이드 정책을 담은 인터페이스 + +```java +package com.example.tobby.user; + +import com.example.tobby.user.domain.User; + +public interface UserLevelUpgradePolicy { + boolean canUpgradeLevel(User user); + void upgradeLevel(User user); +} + +``` + +# 2. 트랜잭션 서비스 추상화 + +🤔“정기 사용자 레벨 관리 작업을 수행하는 도중에 네트워크가 끊기거나 서버에 장애가 생겨서 작업을 완료할 수 없다면, +그때까지 변경된 사용자의 레벨은 그대로 둘까요? 아니 면 모두 초기 상태로 되돌려 놓아야 할까요?" + +😎그때까지 진행된 변경 작업도 모두 취소 시켜야지 그걸 말이라고 함? + +## 2.1 모 아니면 도 + +지금 코드로 사용자 레벨 업그레이드가 중간에 중단되면 어케될까? + +### 테스트용 UserService대역 + +작업 중간에 예외를 강제로 만들 수 있을까? +가장 쉬운 방법은 예외를 강제로 발 생시키도록 애플리케이션 코드를 수정하는 것은 다매다요. + +보통 UserService를 대신해서 테스트의 목적에 맞게 동작하는 클래스를 만들어 사용한다. 그럼 어떻게 만들까? UserService상속해다가 필요한 메소드만 오버라이딩 하면 되지 뭐. + +```java + static class TestUserService extends UserService { + private String id; + private TestUserService(String id) { + this.id = id; + } + protected void upgradeLevel(User user) { + if (user.getId().equals(this.id)) throw new TestUserServiceException(); + super.upgradeLevel(user); + } + + + } + static class TestUserServiceException extends RuntimeException { + } +``` + +### 강제 예외 발생을 통한 테스트 + +사용자 레벨 업그레이드를 시도하다가 중간 에 예외가 발생했을 경우, 그 전에 업그레이드했던 사용자도 다시 원래 상태로 돌아갔는 지를 확인하는 것이다 + +```java + @Test + public void upgradeAllorNothing() { + TestUserService testUserService = new TestUserService(users.get(3).getId()); + testUserService.setUserDao(this.userDao); + userDao.deleteAll(); + for (User user : users) userDao.add(user); + try { + testUserService.upgradeLevels(); + fail("err"); + } catch (TestUserServiceException e) { + } + checkLevelUpgraded(users.get(1), false); + } + + static class TestUserService extends UserService { + private final String id; + + private TestUserService(String id) { + this.id = id; + } + + protected void upgradeLevel(User user) { + if (user.getId().equals(this.id)) throw new TestUserServiceException(); + super.upgradeLevel(user); + } + } + + static class TestUserServiceException extends RuntimeException { + } +``` + +어림도 없지 롤백 안됐었네! + +### 테스트 실패의 원인 + +트랜잭션이 적용 안된게 문제다. + +> 트랜잭션 +> +> * 더 이상 나눌 수 없는 단위 작업 +> * 전체가 다 성공하든지 아니면 전체가 다 실패 + +## 2.2 트랜잭션 경계 설정 + +DB는 그 자체로 완벽한 트랜잭션을 지원한다 + +하나의 SQL 명령을 처리하는 경우는 DB가 트랜잭션을 보장해준다고 믿을 수 있다. + +하지만 여러 개의 SQL이 사용되는 작업을 하나의 트랜잭션으로 취급해야 하는 경우 도 있다. +여기서 트랜잭션 안에서 문제가 생기면 앞에서 진행한 작업을 취소해야 하는데 이응 transaction rollback이라고 한다. +모든 SQL 수행 작업이 다 성공적으로 마무리됐다고 DB에 알려줘서 작업을 확정시켜야 하는데 이를 트랜잭션 커밋 transaction commit이라고 한다. + +> 롤백 : 모든 작업을 무효화 +> 커밋: 모든 작업을 다 확정 +> 트랜잭션의 경계 : 트랜잭션이 시작하고 끝나는 위치 + +### JDBC 트랜잭션 경계 설정 + +모든 트랜잭션은 시작하는 지점과 끝나는 지점이 있다. +시작하는 방법은 한 가지이지만 끝나는 방법은 두 가지다. +모든 작업을 무효화하는 롤백과 모든 작업을 다 확정하는 커밋이다. + +JDBC의 트랜잭션은 하나의 Connection을 가져와 사용하다가 닫는 사이에서 일어난다. + +JDBC 에서 +트랜잭션을 시작하려면 자동커밋 옵션을 false로 만들어주면 된다. +트랜잭션을 종료하려면 commit() 또는 rollback()을 하면 작업 결과가 DB에 반영 되거나 취소된다. + +```java + Connection c = new SimpleDriverDataSource().getConnection(); + c.setAutoCommit(false); //transaction 시작! + try { + PreparedStatement st1 = c.prepareStatement("update users set .."); + st1.executeUpdate(); + PreparedStatement st2 = c.prepareStatement("delete users ..."); + st2.executeUpdate(); + c.commit(); //transaction commit! + } catch (Exception e) { + c.rollback(); + } + c.close(); +``` + +DB 커넥션 안에서 만들어지는 트랜잭션을 로컬 트랜잭션local transaction이라 한다. + +### UserService와 UserDao의 트랜잭션 문제 + +🤔어째서 userService의 upgradeLevels()에는 트랜잭션이 적용되지 않았나? +바로 트랜잭션의 경계를 설정하는 코드가 없었기 때문이다. +그래서 Dao method 를 호출할 때 마다 하나의 새로운 트랜잭션이 만들어졌다! +~~그러게 UserDao에서 connection 매번 새로 만들라디?~~ + +### 비즈니스 로직 내의 트랜잭션 경계 설정 + +🤔upgradeLevels()... 실행할 쿼리가 많은데 매 쿼리마다 트랜잭션이 만들어지는 이 놈을, Dao안에 넣어서 위에 코드 처럼 하나의 트랜잭션으로 처리하는건 어떨까? + +😎비즈니스 로직이랑 데이터 로직이 한데 섞이잖아.. 안돼. +결국 트랜잭션 경계 설정 작업을 UserService쪽에서 해야겠군. 그렇다면,,, DB 커넥션도 이 문제의 upgradeLevels() 안에서 만들고 종료해야겠군? + +```java +//UserService.java +public void upgradeLevels() throws Exception { + (1) DB Connection 생성 + (2) 트랜잭션 시작 + try { + (3) DAO 메소드 호출 + (4) 트랜잭션 커밋 + } + catch(Exception e) { + (5) 트랜잭션 롤백 + throw e; + } + finally { + (6) DB Connection 종료 + } +} +``` + +```java +public interface UserDao { +public void add(Connection c, User user); +public User get(Connection c, String id); +... +public void update(Connection c, User user1); +} +``` + +![Image](https://github.com/mtak0235/TIL/assets/48946398/b48acb10-60ec-4711-a27f-9edb3b774dd8) + +### UserService 트랜잭션 경계 설정의 문제점 + +1. DB connection을 비롯한 리소스를 깔끔하게 정리할 수 있게 해 준 JDBC Template을 더이상 사용할 수 없다. +2. DAO의 메소드와 비즈니스 로직을 담고 있는 UserService의 메소드에 Connection parameter가 매번 계속 전달되야 한다. + 싱글톤으로 만든 UserService에 Connection 을 미리 만들어 둘수도 없는게, 멀티쓰레드 환경에서 정보를 서로 덮어쓰는 일이 발생하기 때문이다. +3. Connection parameter가 UserDao 인터페이스 메소드에 추가되면 UserDao는 더 이상 데이터 접근 기술에 독립적일 수 없다. +4. Dao method에 Connectin parameter를 받게 하면 이제는 테스트 코드에서도 직접 Connection obj를 일일이 만들어서 Dao method를 호출하게 모두 변경해야 한다. + +## 2.3 트랜잭션 동기화 + +### Connection parameter제거 + diff --git "a/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/9_\354\212\244\355\224\204\353\247\201_\355\224\204\353\241\234\354\240\235\355\212\270.md" "b/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/9_\354\212\244\355\224\204\353\247\201_\355\224\204\353\241\234\354\240\235\355\212\270.md" index e69de29..bb0408e 100644 --- "a/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/9_\354\212\244\355\224\204\353\247\201_\355\224\204\353\241\234\354\240\235\355\212\270.md" +++ "b/spring/tobby/1_\354\212\244\355\224\204\353\247\201\354\235\230_\354\235\264\355\225\264\354\231\200_\354\233\220\353\246\254/9_\354\212\244\355\224\204\353\247\201_\355\224\204\353\241\234\354\240\235\355\212\270.md" @@ -0,0 +1,33 @@ +```mermaid +classDiagram +class SwitchService +class Lamp +SwitchService-->Lamp +``` + +````mermaid +classDiagram +class Bulb +class SwitchService +class BulbFactory +class Lamp +class Candle +Bulb <|..Lamp +Bulb <|..Candle +SwitchService -->Bulb +Bulb<--BulbFactory +SwitchService <--> BulbFactory + +```` + +````mermaid +sequenceDiagram +actor main +participant sa as SpringApplication +main->>sa : run(Class primarySource, String... args) : ApplicationContext +sa->>sa: createBootStrapContext() +sa->>sa: +```` + + + diff --git a/spring/tobby/tobby/.gradle/8.1.1/checksums/checksums.lock b/spring/tobby/tobby/.gradle/8.1.1/checksums/checksums.lock index 4f91296e374ba26df3cadcbcb742aad45fd6401b..8ad9e77a129f60750f797dd9ed9eed4ad99b0038 100644 GIT binary patch literal 17 VcmZSnaI#lB@5O^#3}C<_2LME%1*ZT2 literal 17 VcmZSnaI#lB@5O^#3}C>*0{}#h1(g5* diff --git a/spring/tobby/tobby/.gradle/8.1.1/checksums/md5-checksums.bin b/spring/tobby/tobby/.gradle/8.1.1/checksums/md5-checksums.bin index 3d369e01303500c54cd6da99d05ad7344718764a..0c3bb782a04855eccced4d71d5d856213162d237 100644 GIT binary patch delta 271 zcmccphjH;g#tkMCjFOX0B|P~vQhmB554tmeL0$CbQi+Fb{GR?HWv}~-po051`^ukS z6JT|^w9?jon-x^_<7Qs91zZA!FAS$Yk<>f_746-;)L=3rW9CN16{4FRJ*3RkjDa$m zK&%MD0uEO5t~Kp;tksOWH}T*(;f)LojGYtKEESo2Fk4FE;m^(^cNTf^hXL delta 46 zcmV+}0MY-W{sG(k0kAX}0Tq)q7)i617}y50h9AEMvt1^b3bPF{iva-%u^|W+vq4B2 EHmE5N?EnA( diff --git a/spring/tobby/tobby/.gradle/8.1.1/checksums/sha1-checksums.bin b/spring/tobby/tobby/.gradle/8.1.1/checksums/sha1-checksums.bin index 9a782b115a5bf4e09de46e8a7c452063ef592dad..7f1ecda79b2728a427f5056780fdebdcd40d7fbd 100644 GIT binary patch delta 679 zcmbQ`w^(%-_3KS zX7cb~*gvIqGxJi2pv%t9y6Ufln3N1RCt4Y=Vyxdh^+^G%0NV2eK#NdD8M3M_WSrVt(ugNP*L&8XTJsrn7_5@UB8RP466V5X3=j4 zIry_b{yZecKNYI7dGXnQOacjKPCOT|vKEF4zTbM3@gNibjgr+sn4B{tY-HgsZTwWCh+r*|K*JaZ-FL&6qrs<%pz<;{ZjsUF1;OW8Sj`+ zn@^Sxi(Ya*b{f=#Xo%B=lQ2D8yh!3a)8$;h_TAH_|J}#l@KQVbGQ{N{|3Gv}+$2hu eAV?d~xhtN*v`s&2$EYPRVa-Ybh=}+ZkU;=N=;BfU delta 114 zcmV-&0FD2%j0Km71+X+20co=}7$E_(ZW&Mkv(_4r46}YG;SvHN>60n*g|nVI_Nf7Q zvz6p<1+yLM$p^Fk@dpHx9rj3*9XuJcmiC|slLkT;vt|F_0h4V*c(>I70YL(jPDL2E UMg##u1OZX8A;1i`p%ejjFOWMenE(I) diff --git a/spring/tobby/tobby/.gradle/8.1.1/executionHistory/executionHistory.bin b/spring/tobby/tobby/.gradle/8.1.1/executionHistory/executionHistory.bin index 1b5b693a9e9b5bb4f06805655e85ff42bc7a0de8..26d54f7c0aef398c70723ae9bf7f1cc63797ea34 100644 GIT binary patch delta 5201 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 aygB1D(;VCNDy!UL^j*hf6z$vzXZ;(@z^H)$ diff --git a/spring/tobby/tobby/.gradle/8.1.1/executionHistory/executionHistory.lock b/spring/tobby/tobby/.gradle/8.1.1/executionHistory/executionHistory.lock index 9e69c686b2e961e035def88019256c36982a424f..d289e80dc6ce6676fe6b5ad0f64f1fdf1b67b379 100644 GIT binary patch literal 17 VcmZR6`aE;T2FA_R3}C?23IIP?1y=w7 literal 17 VcmZR6`aE;T2FA_R3}C>N1OPuZ1vCHv diff --git a/spring/tobby/tobby/.gradle/8.1.1/fileHashes/fileHashes.bin b/spring/tobby/tobby/.gradle/8.1.1/fileHashes/fileHashes.bin index 5c574e9c876e90d863ef6c67b2e8cdec548dee51..b772c483fcd986c6c74d8e73468dbc1f4a45dcdb 100644 GIT binary patch delta 2809 zcmZvec~n!^7Kd{a!ZXAqSCAG0NI*a+71UxG1jPcDh?J0o#DD`+m>wdcR;XYA4O5Y! zN2S06DpHhEWQe-py@z?NP*Jc5f)*E4Aa$s%42lC4%R6`IA5GkA-E-I4>-X)w?>YON zb8EVh{vVMR7ZapLwcex!K~Fr&rpcNoc@*3tYrvQ(4=v+2TlunXRuazWm*BZ+rhVN^ z%CYKNNdn=NJ1mlRcCVeXw)?p{C3U%z*-K)sJ}#^i!wGdJ{VWO>?_^Hp_ZOlLqhkF)P9a8(r>KByp^QMA7b zxRKx0gYetek`aCba`SQY?){KdlShY~NbwusW$_CA{a8<8s2BAJ;gqYv>J{^xhHUV& zMDU96MMnS&OE+|JoE=?nBMByjVIa_Q9A&z^tgQ>%DI!Dm0$UyrW&4;F4^&4h2xm+O z@Zt$jlPLg>+CFn9mE|fW&jI1+1@@*!YL<}75b(8CChESdUYT9~>>S~g&jJhUFHzsj z{`2{oKr&`jENHThL$}3-nkGt0ZW7AqZWU`Kig4n1yEBsfg(GB8u-wKSO&am;V5Fgw zgfG?t_}OG}Jc}+b%(eFuzNqz})8;)Yd%o4`)w`{0cnsBMe**?@Hg?Ws-H=b`OntIL zL)cvwg@WXt{1R;OY`vHZ>xT2A5vmE1EeF1}>IZWVm`#d-HJw!go~d}%I8n{5NP_t0iY_tz zkCgO|jlu0P*^4pMiX^zZu^FA5f=aB_n2ox~^Jl}`I>V2~C#+N-bFe_ZB9UpRgoY%+ zL946;>BE@ef$0YUg?X;=@ygRAF@pmX=S5v2w@hYazS91R+M{rtH2w+QoIo@i2*mFX z5FBU+_Dcl3M0wPAQ~oz3c8gj4p0V6vQb=wy=KJ6w6f&eMgbgDUZ{^%$QHW_7|L9Ny zEEoGy4Jl-(-cp3m8+-Zao{8H7;$J2*1K`1f6WF{%+jtC|jxbUcN?C{=T$ON8wf%_D z(;@ZE6Tgs31HB-Vz)&^ZC2+~&N8ql(jP@E1T66POA~EO|4nP9b$m{@+t;70fP<2g~ zLxtIb7F41gPIO*biv0O#Yq=@c`NPAuHj)}F9o%ys1k5&o75egIkuGm8Z1)~cYl}F} zcVFP*HE9ICgorr==#h3Xrr;ys9LZI%M_9CxcQd0W{~55UX0Ue7%jxu@Ql+g$1Fd_I{~|PxL$0*5mCA&R6=7$!9j~y9&mFnQ`k1zP#}B~ly3Bx zAg1GSfP%7h37?rQy$VQ5xe|AZhmWa=j2O^s3S@J}XBSeFXjus?` z@o7zabDg-`2oYvg;^#jkY6*ghwVYM~ODmggZ%+H(57@sIWCirsm? z+|!TJPbI#jzkoofZ|Ux^jMv4pwI!c#_KEwpC7m5g5``p@rJE$wu}uMP_#b5b5Xavh Qton^4a!6tnz7ePY1Dj|aB>(^b delta 1214 zcmX?qj&c4`#tkMCjP09EB{ncl{wpalSy!rJ@>MB=$+FTFlh;ZgnA|F3F!`)Z!sJ-l z8dk|2R2LL4Wd6g&UKnDoRW~s_3yMf&lpH(0tqUjeOv%ne{#O6*8^i`W&92TJPfZb{KEw`S4)4Iz0CzglIhbo*2QONmv z@^hd<&TzS)D+;fioj>-ai9`v0)?v-HK~>0+hv|m-<>d`xN2<=9Gi1*N#)iDiX zG{4m3g^9wOd%}4cS=wq&XiuISQ5Uq__%ZX3wV_W>Gy7ltvh?{Gkd~&YpXWieFqdFj zf>p=-ujgSpCeM#ln>;zv2$W#XZax{=#>CTBbL2Qgn&t6i#ZckRc`?GQ3KvA5c$_~~ z|NQ$wmgwuHKEUh(%swrgzac7lo&jC!qF~mlvD5rQQ1`TFI+pzZ=I25b@vVa>;(9%q zHA#)7t%YyRWc?(muuTq13_13%d{aLCzs&AkSPfQPmcb8E&BO_$(W32u_N&?wsqmcb ZTg)mq9XhiMtfS`0JBSVrV4yST0RTJ8PQ$YeR}fe!gO$s1UvbDGSjYe+5~Knm8wy=l)>p{(Uh+>~KKXpV@Av=z^9qMB#p9TI ziVj8$>~uQegx}&Jf!T{ka{oRo2ncoh;YXY&4tLiJs-^Io5m2i;0JY~De0?;dUCNkY zARIRj{rvaBShcM@;?)2*yaN=ZvN6RYg(3_CqVV@10pW%<)y4?PRskX2-ld`W>VcAM zs~IT_`$LR8jZL=G&N~xlkODUu|7CO;gUF^RGnwue$;ZPcgcP!XGf5wI2qfC2p8iTCWlSO0pL9hYQt9<5qiFRamHD8S zTo3!U!rp#mX)MHa1^y-tkf*7!(m84@BF+Ml$s9Q}X8kcPq72y;Gg&r$*w*}do<|OH zs|+!iFueyE)>x^(VIXs|TDY_$lKa1vD_XV8+3G}U`Jl)wKwkS}gZ`FwmepbI3HJa3 zd-u9@B};90!QDk{(tX8P?|{xkKF6Q8D1mzaHL!yZ-c2}i>P$wR2*jC)8)##ovlBOm zed0!ybHM>J=L@t^Ha5f5E!}=Mr=V$E8hV?wd*=W9%t@_CKY=L1`3+69t zKx;cijB%=I@Ns(Mu#>AIpkL6i9*Ik+oeCK>K5EwOu16X{H(d(KV|j`q_*%eMR1+P3$NAlZ3$rTy8pL2os7)#_Ekz87Hk6`A3s+dgWK z>q>f`9v(Gl5&sr#`K#5$34ZW;@4J6)h%d)TkwEqRmvB{7*^=?T+m@T5{K5wEg*VNcmJ z)?#RcT(yT(yrJBK88Fd>HdLLvbe>m#z`yi)%JHME&7lo-%aCFVI)A$F4iWLU{ delta 149 zcmV;G0BZlA)B&5z0kAX}0o{`|7{HSa8Nid}8Nrjj8rYMr8!(gh8+en3951u|98dwX zWgdV5v;7~)0h8S!c#~}+V3YkKk&~t)kdsa%NRzH4z_W%Wm;sYECts7@Coq#GC@_<4 zC@_XQlC|LrNRx78I6)dTf)-2bP-7R^uZZ1y&lhrR$0u;%yA@~=uFi-=tK}cF1 D5o|vR diff --git a/spring/tobby/tobby/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/spring/tobby/tobby/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 5b5da112b88d58de611e9d7094fb79f8acd93461..8b2e5e00b06d830415c08cd4bd9bd7f603b9e0cb 100644 GIT binary patch literal 17 VcmZR6@nJz~glcv@0~oL}0{}T51W*6~ literal 17 VcmZR6@nJz~glcv@0~oOE0RTDG1qc8D diff --git a/spring/tobby/tobby/.gradle/file-system.probe b/spring/tobby/tobby/.gradle/file-system.probe index 31e5e13a8abb8fd141cc183fdd251564ebd2957c..121ccfcba47d9cc0c20b4b09f837cedcdadc2868 100644 GIT binary patch literal 8 PcmZQzVCf8J2$};V diff --git a/spring/tobby/tobby/.idea/vcs.xml b/spring/tobby/tobby/.idea/vcs.xml index bc96ac3..f57fb07 100644 --- a/spring/tobby/tobby/.idea/vcs.xml +++ b/spring/tobby/tobby/.idea/vcs.xml @@ -2,6 +2,6 @@ - + \ No newline at end of file diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/TobbyApplication.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/TobbyApplication.class index 49aad8b6fc3a23500b2f20f9864417607c310700..28670d7d17c6d58789376cf8ffdf16f74786ea66 100644 GIT binary patch delta 330 zcmeBS-NVLp>ff$?3=9mm3`!HZ!Ueb(xEQ$E8F+XYcp3N@8MG!ZV3c$SE-1>(OLr_N z$jMAjEXmBzV`N}1Dg}~B8a`QxWr_MZiFxVz&N+$2#n#bCBEcmfeb$DbJt)q(N>_WMBXQ DX~8;Y delta 190 zcmdnP*2Btm>ff$?3=9mm3^EhB!Y8vau3!|Iyq-~tQEc)l#J_c?en+Ku*Nb>@DoD6&n{0z)Mnt?$Zh(Ve$GzuYUWMmLv5Ckd` j0%A6x@xlzE4B|jGt29UkWT6C@lw^6(ov2xrU6XDwlINUwzW v?~8(v3Lyw8W(`d|=h*xJnK31@ literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/BulbFactory.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/BulbFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..ef6422d26b1456df5793250bb8575847879072dd GIT binary patch literal 666 zcmaJ;%TB^T6g>k-u@-swMnQ=SfrU+6xItZL!m7~)hJIr2%W$!>?uEe+Q?0sv&*l{|DP-aG zQZ5N+G`tWk5eU*nB5H$j=7&u{l3Ox>No&6(jlD7;3%r32lV*e~o-VLz`=yOn%D#0WYtSO8@`> literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/Lamp.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/dip/Lamp.class new file mode 100644 index 0000000000000000000000000000000000000000..878751e7be0290e18519574c56423e74de49c4a4 GIT binary patch literal 641 zcmZ{iOHaZ;5Xb)uNDEd$5Fdz&uLx@F(F5v16Hkqp)NpUh0!#WJWkLB^deFp!AHWY~ zoPy5;4?8t3@E8!j6ovMZ$jZqQ-<8~YAWU#6xZ^4<-kuPivbj^#G2P(=2pGa);o&rmY{FIkHk z7VVC#QxEDyYqc2CW-tgHekI0m^G-;oWAbn)9DW?V1j<;Z(J-vioZ_@-JY=nrrqj+M z&%ra;11T|-NJhuN9@a@}lK^aBlPpHCujG?46i7Wn$;~|>^8<*!0>@B{oP<-E2V5;0BBefP}0=bqgA`_Io`0AAp61r7=xTptT43e->JnG6$|4#G}! zqGBUZe6CY%4h0Ikd%ZGBD0`^*ScEUoinCFuKFQHIQK8AA=yTZD3noeqa)_vTu z4W$`(d@QiF`@cbZJsNtI^=Y=&)~R|k8AU38C!>T+qn*Vv>B(H%d``M%s80oUZc)9l zfdlUKNSR^Qe=Bo2Qby%$Et+gFu=>@mk@1HkIi5>by4fU;)oVQ+enV;Bo(J1pqr>yr zKhHpf-6_$5;2rNWZZPXG+L~H$1rZc3;RR1FQT;wGyhm)nC02xt4uAG;3Ro8f wSQkxNwqEL3!8%saBJ-37v`+k)@Z8DvwAyWZDE;MAFv1~-wG!(dk#f+w1~j6O#sB~S literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/Exception/DuplicateUserIdException.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/Exception/DuplicateUserIdException.class new file mode 100644 index 0000000000000000000000000000000000000000..71984ce2dc1b7d9c128a1fb2401f97c7a4b0e4ad GIT binary patch literal 471 zcmbVJ$w~u35PcQ1XpAOC6cIdla{>DtqPe($Fp6l*y=PLGmYM0$>CyOEo&*nmfFC7R zqr{6|?1t)kRgYIozkj^G0XV{H9VN`wP;Q`tDq-_pKWLTe{7zjLxi=Y~P7@w`V{=0F z(B#JV2pc=m53fIR_EE57LBoWD}hZv@-#J2g`nBCWLPE?}}YQCDGCzVeQwM2(1hD zBRjm(PG{`dNx}M!EnLE9CUmy-*E9!VN7zP9RvZq=l_d*W5Y&@5#H)MzFQ8}fN~nts i9|GY8=AwA(Uo14RBuMyJMpKkp;#WvO5MB{mLi-bg0C}ze literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserLevelUpgradePolicy.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserLevelUpgradePolicy.class new file mode 100644 index 0000000000000000000000000000000000000000..3b8371945b07a7f5f59705919029775f069c9d41 GIT binary patch literal 329 zcmb7=J&wXa427Th3xBJn=Kw$fa{xq3#R{YqThKWZ3xXyYG$aVFM!^9%6k@_|gR~Sh zmY((e?9bQR`2t{qj{qgYP}@Ywk&~SfmDw;nseCU^Eq$5ELCkWub{xsVnpmF#R0y3d zA6OYq*J>VaMQ4Oh&FP=y7K{fgANM8M#zqTvoJb~aPpA|p5Zd|g z?)M^p2+ePsJ1x`L2%-Bw%BY~I5eQ}f4xr@8s;GG#cvU6TQNT9Pd}?{oD%@z_0S@O{ Ap8x;= literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserService$1.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserService$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8d0b45b00e3257750b2d5d3ef3ab19147ee809ef GIT binary patch literal 800 zcma)4+iuf95Ix&Cb`o6bmO?|hw6tzX0M!Bs@xVobkV1r$NEpIHpEmZY+2VLB+X?Uk z{0h&2gb+gg06q#aYa+@EqLRHc=Xfq>XZ+*mw<7@eaifMglq?uF$}kx=LpAoqTRuLF zg_o=0@SQiwMCwIq%w^*FVk%+=bIRk1$QT-p=AM6ol)F__P_QiIBKVR-j&4n5+esL!OeXtXk&jelp~TfznvHjDCW^bIt1 mz@>K)<|~ULx_=HB*eU|HDIJ6wbY3f%2CkE>6}riBD!%}8I=m(T literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserService.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/UserService.class new file mode 100644 index 0000000000000000000000000000000000000000..fb3f4599492ef484299fc6e1e839725b0e12211f GIT binary patch literal 2915 zcmbVOYf}?f7=8{3EX0K%A_`VTiItnA+N#wk6$5B$5|lu!+DeyX8&)>E>1Kn_`}IH6 zkNxC~8 z^qPvJ(pXcal-FEcZoaPK4IC${Jdql_ffwNO1Y<2Yi8mFTQgIqFCd($dQkPqiqXHw5 z%x%NXEu^%P)QI@m81b?(B2zDt_gIMda2jqTLd^V81#hW1hcSV^O*~cgqQ0JDJ9)#> z$Tv@zCi)OpF)sDJSnYyg$;C+(7v!Q!0;Y9ZF6vfZL4xPJURw#%)C-z9<`gR2b|;o| zddW3xtAj;(NktMVfn7yyQIFeJPIIps?gGEcu4cJqfm1I!?<${uC3yLkaUH`d#6q}; zDOu{51$OpVE2Vy47Wi3AtH@wRpz-`zCJ`4n^iszsgU_nCig(CJxpw;fF9|j)6Y9E( z8#18+T0Tz(Qi=3ja_T~SYBoJHH#s#umq{eE6Vn2MbhfTBlGV(L9w2kaSiw?ddLka5 zN=>B4J)H|v$#J>M$_>WtJTIhh(y;V&r8uuUGuph#m5!vH)6A^q7;^3}2HgdNY;SsL z)g>a+HN=qRig(d%QIT~w-9VNXZc29-?EGcT(TX}R96D^RFHO#aGKsgq;isu|P8^L= znp*8o--9G)W0WhUwMb7qC41%t2kyBVrL)$ItK}A1dOl@puHraMXuo7a8N1@-^hrZ< z+%B~;)uu2aOF>{;S}(gPT^@u)eBQR*vg>H2DktS|6P80*!AA-{mPPRiNm#ET!&;;2z*zc+rD7c=ta%Sn|e8twC%-8DfVm$)U9k#oFQG$5x-F0ZIxB4Js&6F0STSuZR2l12ASq|XaL!Pf%& zwif06T#Xh7*Z>+>3bGv7zxnRQyLb-*H~HOwInLj&n`>y|9)Aq@o~J~Vqu|&$_z>a; zPbJ5<+y+{Z=Uc4`K*tB12^6qE!%}&aqjcUhIP?>gb#3_v0<_Xin`fb`D&<>{)+JN{ zgHnym84d!sYMAa(Jjk`+NDV(ix4<3j<;Q-3U(uHyJhF;IchD@y zfxG|yAyEV&W9XuP@Q)*e4n(kneXWy?Y^R5)mxM)#a1o|Q-EkjVh<&gKi*Rh}N{rQ& z62Cs=N*IB^v0Xu@f}Z_3FhgNY!Vkhco1J-$I^L*_lzHTzpQ^!rX z#!cA6RO4om_8R10g74!AO~|v((#NsX1DqIM#hHPRnM^?_-u$v$j;!$b(5pyu3N_S8$v@5aAg&` zmi{oW9@&%$?Z^~-QRXqbelR60MmEveKsyuoSF-AdW=z i_ymY9C}#z&e5%mGoG{U29&K^z2(FQkV7wr)g2fL`q;#wR diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/dao/UserDao.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/dao/UserDao.class index 7236cc0743bca7cfb86b8a79aa0633e07df2c697..e6a6ba464f2c778d53afc79595c022cc1d3541b5 100644 GIT binary patch delta 75 zcmcb?{D+zA)W2Q(7#J9A86-AxMKJQSl@_EVmZUN=u$C6578y=XU{q&ho7}jTlojjA#jf;ViK?Eql#2^X)2dxQb diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/dao/UserDaoJdbc.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/dao/UserDaoJdbc.class index 4473f8d1ba244a451f108e77b62f8ab112abcf4b..d6f457594f9121e6cfeb838145f5d03842cc3834 100644 GIT binary patch delta 796 zcmah{O>5Lp6g^3kX-vmj2egi$h8C)}7Ew12IE*eF{HP#AoTgfxvGZ)l&P>K+KGcQ% z10qNkZv6v-MF}G44{+_jaP7j4c-~9RWalF9p8M{(=iPhA&qF_E?eBlSd;?I%i(UJ- zaeHOZYc~4A8H6GTolx|hZlfd0l`~GS5r!i_XiD4`L(x{i-)wcu6(`(X- zJ;o;cws>o5Or%H)Pn5_ntCkTti>o-75viskRcxa@7TH!J9dwn*t9^?*auT@*a4jQH zOa+SY(Hjf+O5ka-I&q0YvUzIp6J`t7W8AFmGSwk<6Gv7UZ)F^rN*xJs-e7k-lg_(JGrf!#|1mQ}Uz*AGi^32Cr{lH3MM`H7OX1nRV?f840 XB56Q@p`wrQj8U31iRVPNLIl8H7*2GP delta 563 zcmYk3OD_Xa7>3^&Grdf!+9uRkASIF1LRhho*eHUPORE_7OHp@a*B>B}$ZY)x4e7$d z53shj7r(#;?>QqgXOcPJcg}g==X~Ee@0qVw>+R>|6~HKN>ejd6E||TcLL5abxizz7 zENjTRsc`%Ko%Qr!Qi7j@lIFLs6B(~E2yJM`^x)zml5J1Wja)=`d`H1Ffq7u;uFsT4+A7G<`;{Z^RfD^BE<|70Nb1e6aOnRz; z=|Y`T9YKdPyqQ_$Mq>VroMOnJ+i`EL9;J{uMV$7Gv@?V}~8&<~Uff))Xh55;P+Du~uE?4m(U?ZObEF|qDl z)%gJ~S!kkw1OrAlto#%DFWedLjE&UAow;-G+;i_aGhc!muKoS@?pFX4DAnx|Kc6e) zXBm3sve8?A60^kg)Ix4%qu#n2#*_KSrL|I~QmU?G7FM4=s;-RXa;kxwTJj^{hhr1;X$M)1ZWW9$GgC>O zmlboeJ)m0U%WLHdLn4`?x`cdZK5tvJaRW;}+*I9f$sxYaZp&Xh&hAN1r1>&KRK`S9 zJ`^sq4;p2my)-1t!v;;JqiuzyVGG2RH(=YA(u?VANX`-=$s9?xy>_ zof>-5-P`ceU3?qyjek%sIQb40x1t4Y2oW&_+e5`v+JIGF6tPB3Nx=2UA&&DT!v(S^ zUGF2CBQtPOv(G8^bbbv}{Cd_q&_K+xscaZ{iaQxdxx@l^DVa>&b zheO1t14(pZ0Ea2(HgTTNBLSDF&W7-W5c58gtD&VDh~YBwwEopHdmv_9HER|#(gfTP zGia;tq^jjhU-G{P^kW`Z8n}ykSRlIxR&-C87Tdw#7EFB{=7Ol|fKLZT1SbV_!2XO= uTWD2pL0?>xFlgl%BpG-^$O5kFNv}n5og6=1T_7vsjxJ#I%J=aAU4H<|9C9N7 delta 803 zcmY*X&rcIU6#iy+r@LLYxLpm6O=$@hEsIjnf+z(npipf^t)f*gJrNBd(HIj?^nwW6$3?t%~K2qCEaAReyu-vTmG2NuY21^9aI7nes{AL*|i7^MmI4ilHROrZKO*to>tM(q{DfHZkfWcX zKp#~(w1;wvY=8)4Z(TC!#gU-Ic{&a0SR{RxXvGOG)6#HNJ^mVbGvb};SM@puTQKX0 zv|!f}-bJz;-N9*~1OJaf0Ms uTxcUCMe9!7R{9w5m9$+6uHy#9H55=JYazmLlhW^EouK?j@1u-IIQb9r31hPW diff --git a/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/domain/User.class b/spring/tobby/tobby/build/classes/java/main/com/example/tobby/user/domain/User.class index d2334c087829ec71ddbbb2e90babc3a195f7d382..1b8c492979c10c2402f0b471b8e9c52d9652aa92 100644 GIT binary patch literal 2806 zcma)8T~8cU7=8}y7u%swK1FPye05nUt5sXuZK;Aqwp}O|N@Kin*gb(Mvoo97p_aSe zm=Jquj9%Ep3r#ffq9&!7n&_p8Kc(P5FvjQ1YxH5zQ?9+Xww>B4Nhg)J3%X&YZgVZrWaI@pvQ^K^u47p1Y31v3 z;f2*0$EaH>w}ikk>Z?0# ztGMpyd08&SRu)rkb3reba}!^-x15}uGgS6kR0^h4aB?(b+iuBq^rBBzsV#!*aoj*Q ziUn1Ei_B;hr(xZ*H)YC)>sREQo^x$yTj1;3jFt_3r}Mg%H)UxgYulS!#dPDnYc&5k zxUyZ80p=gq*!v?YT}x)!#jI|c%Z4k{F)Rrr#lfQog9l%I_I&S`{cm>;9zEIr;+yA> z9}Mn4-J#h3{QJMY{Bi%`&i=#in6r#!NoUq1*|HSHGRI8=2SHbh;>gly9g>=t<5xPjYg3lC#Q_9E_B0V5RV!z*+9zq!g6ldZ#C9I z^AK8*@>ZS^UdJ2UDF^3hp&a}`8KoRk4w4hQh$bg@(V9HFi}qw+XcwKy?(i;pliiVB z^j9Mc@d7|QBb-1BXZCS)@~?~IwwtrG2cziqBG3EY%aIw!yRJer=3Q9f98)tN&E85~ zKIE;`^~2su5fI^3fxZZjD-OUTU?{5ioa7_$7KZs&mr7CktUN*IV=8=B6ltKZAV%KC z`7$HZlwN8S8=ch~`<$L4rUB1Gk8f4ESw#IvF@nMw=3u1|xPW)~uE*5-Qyr$EKui~L zsR2_zb5W0JjF`?Gf=RJh!KAnnNC#r-ug8=O#B@0rQ%z;~JWUZ(>JUsSpA}4g?yg`u zfTw7E?#=~bx{ApLo>V2*^K_n=E*yeMHDLvlsxg6g12MJMW4aWG>Ahe~t@W6uiRtPg znAAY1U{W_KI zDm(E9x_-sTM{56!eU3dOf3Ngavp1`H7!A12d2)lkvux%?{uj1X6MwkeV=?sei|Vm! kJQ0KV8z-ae#%9cM-$cywz8)Fc+{B06#ksnL6|AD~Uk*zT$p8QV literal 2027 zcma)6+fEZv6kVtE3d2Qgu?T9pSlZz-Dk>TjO)yH6ibRxWr*r~C+76i()IajU2Tg2D zeDDMODC62QwUFsld6?OI_MElOzN~Y8{r>S2z+*g2A%cMfq8eg|E6naYb;J5#){kqJ z(Q+!4kH$&Ua*e7}H|>V;mcBx)W}R9!g`4GnuP)27b=e`QA%#IfItO+`L6sz`X&9Dh z%C$&Tw;I(!jAAT-OB%*;Sz+wRJT;A)**Gv>RgSFvmO}iI-LP953Im1Wo{(fTOyG(_ z#I7ogm(LKpE!S=wc-v2ExGHO+4YO_uXj;QH2_%orX7jz{5}IsUEiYk(Lg7M%75B)v z=~OL+(X!pJwomF6%Y9>3YK)ARoqe;mXS%k0cY@K@q1{xN{|~)%d7ah2v|5Kwb;op> zb<1*zOdfQTTqqR(L*uu<1M>UMrj43;N_vQu?ejvR1$qVEJwO@*~Q%hsXxV^ zVWK6`MBn{U#yK0Th$SXwlbJJAy%%mQb;1D!!WT3li~iq0S-kdi%R?fsyQ8o zOrys~+;X|swVE<;yl&mVGSWI$Ok6-_et{jo&mAwSlOfR+a*yD$<;r=0S*+^FnYe^C zhLu@H>QB5KayMjHEl;ICZ})^P>y_6!E;Bs&zdoOy*kT|Z-!qU$Ob!2viL2OPFo%O~ zz&oNLM#5z%l^b&yraG-xS~EpXhNk@S9lt}%N;e!&91Qzy5ghWiOP)-_x4GNmfurn+ zGcJ!D>iEGt)~Q{cx4$|Ka$m?Jzw?3zyf35(2raH|hoLwRbh;IWrKaTe@jf3+N-~=M zFtEk0ql(VX6tJz<#*jRqJ9_4aQpYyKtvMr`$)#cMd7cP%Tposk>P-K2jcYTWv%TRO z-MdEr4$VrG(}hgn`2@aDJH=AL1$iEt6{adv*MnMtA@SCtlB*$2X tJ4IMHBP^hVG7(myESCGlT#D=}NewmJj`S8R(i!q3v4uM%^Q7-0`4gBb6wUwu literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/UserServiceTest$TestUserServiceException.class b/spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/UserServiceTest$TestUserServiceException.class new file mode 100644 index 0000000000000000000000000000000000000000..858afc7643fa6dc8f0a9c65daa1e9c50daad64ce GIT binary patch literal 497 zcmbtRO-lnY5PfOa?z&cMYX$M-K}0>6AK({K6ot}*t-WX0K_k0K+0B;vvpfkN`~m(b zaZ)|>A_xZZ-ptF8H<^5VzP$rD#b%5e>LG$Ame3H`eo|82j9R#A#~; z8YkLlcP3EZKNyFI1kO{NOPZ;Cl96;aNuFg@QX%gchEz;-N+T-Wu7?F};m)9E?@6H5 z*Mm^L&` zLee(rlD5!7oup}-mNv9aLW!|MlI~l&Z+}653*?;s)^l>&((lfUWEl|9{Ggeq`|iE( z-tT_zzBh0G_w}~`+=IUd;ZtyT(#*#6AuXHF=rP;u?L8VR7IZ7Nmyd*Q4H`*3f&glQ zs8ta}NJ0I8HmJoiS}q;i**l;oZ3VR(jhta`Qs8fB><%JQ-EGRuYDUiS9)e2C-ePvZ z$b~RjLHN=uCoi2larw;g5b729@+-oKVpRosRd3g%ad)pHux2lb4Cnk}t~jy44g zgZ_f4&eg|LIdVe+bkygL%4%Uzr&&T1(ZLSGTWQn7pP{N=|VefQL82+PH8bqF6MK50wWiTFy? z!yPI*@F4|tqU2Fp!Gdb+sBlhl#L*c z*4~0`X-V5#M!5#hY#byARbcj5$OokdPs!{Lrm!z z-PT((nL23b4I-%`1zo{phg@Y6ki}%MrP-#XU z*9u+w5bMCEv|lW;Dso_oft(|rUh-Yh%ACv&tFXXg`n6O_;H<`!ieA>z*d2j_qKZKQ zWKuDowzQP)bfkjhJEY<$K1!cyoe|yE(Bb7(xpssFd053Ue4HsI`}O1@$9}Kti=i~! zQYiZ+mM}h{;!!*%+g-OiXgo1pue(Vhk4tDzC|FlXS8u-YR&tlsKB?kU_%v(B)x16| zJgl;TD;u`6$)1)S_8A4+D`RLgvw6+ZdNVpZ#SIxfu36qfQG8Ct=Ov`Dl-r3Zf-m5U zL3~NY37k~0?EmuVY_j&lMJ=<399mx)=#BUGRohO``ihEEI8C$)WwdTuTPFjLXNQA$ zR>9gT=vH(vX^#u!Q6Y<97|+Xz_cbA6MOQA>ob(yS*HwH2-(*K)h+^zCha2pLitZr% z8%8mNZZN zHnMuRQ837+)?CiCHJRcjU*|BZke9>0&(gB`5z{&p>(#YfA=bxcX!q$?9I<>r)LdfflY)J}Fo`^Wxn@?#rbFS~y?S3=0 zi@QF{vqFyaNiyGK*!^BtsW1IEi={?0wIp&>cI%pSyOOM==8C6zi}MsREuNVDtUAHB zC+-ko#rq>2^Nl3TqLtLQ8B)aQdl`Mgy+#Xq%jKjJwn*!_hIFQB$0QWqEqKcsvSSH{ zmRl(IpkG?0GE~-c1u{C;E~AtHCdD7rGDU{5`MT>(SZX3O+=U%q;+3wNZ|RA8&d*hriEJE#E)j8*;THXyvk9GZ-wugrVH?k zz=v~uibG&Fe#oclD&Ra`<39x>H1;{hXT7;&O`$gt-siu_N3362%UtoDjyULuW6>4SRp+p# zJ{8>{;!(7`hSu?*BMb|ekB8Az5%@7L@DffJr~{0ali0wNBw4lTJhqSGz7gEtbG6Uq zs3TJ2V5nF59HYG=*C7v>_gEjP&`J928N&eu9JG$%pn~|4G4v@ojoUdOGk%P4r)Vu5 zL*9ooSN+u*RC(z;~K7*+(LIkhlq670u4}v%7p$@)(%eQO#JVuk6PODtbf6`9Y9F)+@9_9iyul|2sQ++ zN_95tCU|hW2o~dH6dD3M70$YP&QV}O5f%KRjKse5 zOC+@sydbYKQV#Ju$#9qW9Js{q60Kz=;uEeHqu(0E8CE~gIg#xyZxtl)AP(ZJ$KNLM z5$MJ&W<3uNu(JE8ae)8$$wn3*T+aagve?V&P@`oF}lh>CDx8Up{p zsvw44LdSz#Zvr3z{F-V${Kk>qNvCh~|8Hsjy8}>?_&xr>@gF%Z;7|B7=W3~amiNTJ Ta2(}$n3Vl1K|Ra&-w^sAKt?XP literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/dao/UserDaoTest.class b/spring/tobby/tobby/build/classes/java/test/com/example/tobby/user/dao/UserDaoTest.class index b0fadcc55ad5e6046950d8812404c4a1e1cc0a67..e38c2687934436f71b52399f7b22d7217090b01b 100644 GIT binary patch delta 2123 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 literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/reports/tests/test/classes/com.example.tobby.user.dao.UserDaoTest.html b/spring/tobby/tobby/build/reports/tests/test/classes/com.example.tobby.user.dao.UserDaoTest.html index 65c8aec..783642e 100644 --- a/spring/tobby/tobby/build/reports/tests/test/classes/com.example.tobby.user.dao.UserDaoTest.html +++ b/spring/tobby/tobby/build/reports/tests/test/classes/com.example.tobby.user.dao.UserDaoTest.html @@ -23,13 +23,13 @@

UserDaoTest

-
9
+
10

tests

-
0
+
1

failures

@@ -41,7 +41,7 @@

UserDaoTest

-
1.894s
+
2.016s

duration

@@ -50,8 +50,8 @@

UserDaoTest

-
-
100%
+
+
90%

successful

@@ -61,13 +61,131 @@

UserDaoTest

+

Failed tests

+
+ +

update()

+ +
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [update users set name=?, password=?, level=?, login=? recomment=? where id=?]
+	at app//org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:101)
+	at app//org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70)
+	at app//org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1580)
+	at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:675)
+	at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:968)
+	at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1023)
+	at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1033)
+	at app//com.example.tobby.user.dao.UserDaoJdbc.update(UserDaoJdbc.java:88)
+	at app//com.example.tobby.user.dao.UserDaoTest.update(UserDaoTest.java:220)
+	at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
+	at java.base@17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base@17.0.2/java.lang.reflect.Method.invoke(Method.java:568)
+	at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727)
+	at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
+	at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
+	at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156)
+	at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147)
+	at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86)
+	at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103)
+	at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
+	at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
+	at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
+	at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
+	at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
+	at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
+	at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86)
+	at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213)
+	at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138)
+	at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
+	at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
+	at java.base@17.0.2/java.util.ArrayList.forEach(ArrayList.java:1511)
+	at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
+	at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
+	at java.base@17.0.2/java.util.ArrayList.forEach(ArrayList.java:1511)
+	at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
+	at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
+	at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
+	at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
+	at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
+	at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
+	at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
+	at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
+	at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
+	at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
+	at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
+	at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
+	at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
+	at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
+	at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
+	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110)
+	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90)
+	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85)
+	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
+	at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
+	at java.base@17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.base@17.0.2/java.lang.reflect.Method.invoke(Method.java:568)
+	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
+	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
+	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
+	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
+	at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
+	at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
+	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
+	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
+	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
+	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
+	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
+	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
+	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
+	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
+Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'recomment=999 where id='a'' at line 1
+	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121)
+	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
+	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916)
+	at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061)
+	at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009)
+	at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320)
+	at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994)
+	at org.springframework.jdbc.core.JdbcTemplate.lambda$update$2(JdbcTemplate.java:973)
+	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:656)
+	... 89 more
+
+
+
+
+

Tests

@@ -79,37 +197,37 @@

Tests

- + - + - + - + - + - + - + @@ -118,13 +236,18 @@

Tests

+ + + + + - +
UserDaoXMLTest()0.063s0.064s passed
addAndGet()0.118s0.133s passed
add_get()0.053s0.054s passed
count()0.160s0.161s passed
duplicateKey()0.068s0.058s passed
getAll()0.188s0.190s passed
getUserFailure()1.123s1.133s passed
passed
update()0.098sfailed
userDaoReturnSameObj()0.019s0.023s passed
-
+

Standard output

@@ -136,37 +259,39 @@ 

Standard output

=========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.1.1) -2023-07-24T15:14:22.403+09:00 INFO 2424 --- [ Test worker] com.example.tobby.user.dao.UserDaoTest : Starting UserDaoTest using Java 17.0.2 with PID 2424 (started by 192293 in C:\Users\192293\TIL\spring\tobby\tobby) -2023-07-24T15:14:22.405+09:00 INFO 2424 --- [ Test worker] com.example.tobby.user.dao.UserDaoTest : No active profile set, falling back to 1 default profile: "default" -2023-07-24T15:14:22.659+09:00 INFO 2424 --- [ Test worker] com.example.tobby.user.dao.UserDaoTest : Started UserDaoTest in 0.494 seconds (process running for 1.445) -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@5cf8676a -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@15605d83 -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@3d104c9b -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@34a20f16 +2023-07-27T22:24:38.920+09:00 INFO 19280 --- [ Test worker] com.example.tobby.user.dao.UserDaoTest : Starting UserDaoTest using Java 17.0.2 with PID 19280 (started by 192293 in C:\Users\192293\TIL\spring\tobby\tobby) +2023-07-27T22:24:38.923+09:00 INFO 19280 --- [ Test worker] com.example.tobby.user.dao.UserDaoTest : No active profile set, falling back to 1 default profile: "default" +2023-07-27T22:24:39.213+09:00 INFO 19280 --- [ Test worker] com.example.tobby.user.dao.UserDaoTest : Started UserDaoTest in 0.537 seconds (process running for 1.579) +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@68b366e2 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@6da54910 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@22f02996 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@6c951ada succeed c c 탁민경 0000 succeedc -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@34136bd1 -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@578a5ce8 -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@63e5b8aa -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@2407a36c +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@6a09484c +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@486bd064 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@723e2d08 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@4def7d36 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@5b8853 succeed c c 탁민경 0000 succeedc -context = org.springframework.web.context.support.GenericWebApplicationContext@377c68c6, started on Mon Jul 24 15:14:22 KST 2023 -this = com.example.tobby.user.dao.UserDaoTest@21e5f0b6 +context = org.springframework.web.context.support.GenericWebApplicationContext@238ad8c, started on Thu Jul 27 22:24:39 KST 2023 +this = com.example.tobby.user.dao.UserDaoTest@58d4238e
@@ -178,7 +303,7 @@

Standard output

Generated by -Gradle 8.1.1 at 2023. 7. 24. 오후 3:14:24

+Gradle 8.1.1 at 2023. 7. 27. 오후 10:24:41

diff --git a/spring/tobby/tobby/build/reports/tests/test/index.html b/spring/tobby/tobby/build/reports/tests/test/index.html index f930e82..3ef7c29 100644 --- a/spring/tobby/tobby/build/reports/tests/test/index.html +++ b/spring/tobby/tobby/build/reports/tests/test/index.html @@ -20,13 +20,13 @@

Test Summary

-
9
+
10

tests

-
0
+
1

failures

@@ -38,7 +38,7 @@

Test Summary

-
1.894s
+
2.016s

duration

@@ -47,8 +47,8 @@

Test Summary

-
-
100%
+
+
90%

successful

@@ -58,13 +58,25 @@

Test Summary

+

Failed tests

+ +
+

Packages

@@ -79,19 +91,19 @@

Packages

- - - + + - - + +
+ com.example.tobby.user.dao 90101 01.894s100%2.016s90%
-
+

Classes

@@ -106,14 +118,14 @@

Classes

- - - + + - - + +
+ com.example.tobby.user.dao.UserDaoTest 90101 01.894s100%2.016s90%
@@ -126,7 +138,7 @@

Classes

Generated by -Gradle 8.1.1 at 2023. 7. 24. 오후 3:14:24

+Gradle 8.1.1 at 2023. 7. 27. 오후 10:24:41

diff --git a/spring/tobby/tobby/build/reports/tests/test/packages/com.example.tobby.user.dao.html b/spring/tobby/tobby/build/reports/tests/test/packages/com.example.tobby.user.dao.html index 9f25873..aff35aa 100644 --- a/spring/tobby/tobby/build/reports/tests/test/packages/com.example.tobby.user.dao.html +++ b/spring/tobby/tobby/build/reports/tests/test/packages/com.example.tobby.user.dao.html @@ -22,13 +22,13 @@

Package com.example.tobby.user.dao

-
9
+
10

tests

-
0
+
1

failures

@@ -40,7 +40,7 @@

Package com.example.tobby.user.dao

-
1.894s
+
2.016s

duration

@@ -49,8 +49,8 @@

Package com.example.tobby.user.dao

-
-
100%
+
+
90%

successful

@@ -60,10 +60,22 @@

Package com.example.tobby.user.dao

+

Failed tests

+ +
+

Classes

@@ -77,14 +89,14 @@

Classes

- - - + + - - + +
+ UserDaoTest 90101 01.894s100%2.016s90%
@@ -96,7 +108,7 @@

Classes

Generated by -Gradle 8.1.1 at 2023. 7. 24. 오후 3:14:24

+Gradle 8.1.1 at 2023. 7. 27. 오후 10:24:41

diff --git a/spring/tobby/tobby/build/resources/main/test.xml b/spring/tobby/tobby/build/resources/main/test.xml index 791b8d8..2eac020 100644 --- a/spring/tobby/tobby/build/resources/main/test.xml +++ b/spring/tobby/tobby/build/resources/main/test.xml @@ -12,4 +12,7 @@ + + + \ No newline at end of file diff --git a/spring/tobby/tobby/build/test-results/test/TEST-com.example.tobby.user.dao.UserDaoTest.xml b/spring/tobby/tobby/build/test-results/test/TEST-com.example.tobby.user.dao.UserDaoTest.xml index d58dff5..a7a802e 100644 --- a/spring/tobby/tobby/build/test-results/test/TEST-com.example.tobby.user.dao.UserDaoTest.xml +++ b/spring/tobby/tobby/build/test-results/test/TEST-com.example.tobby.user.dao.UserDaoTest.xml @@ -1,14 +1,122 @@ - + - - - - - - - - + + + + + + org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [update users set name=?, password=?, level=?, login=? recomment=? where id=?] + at app//org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:101) + at app//org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) + at app//org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1580) + at app//org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:675) + at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:968) + at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1023) + at app//org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1033) + at app//com.example.tobby.user.dao.UserDaoJdbc.update(UserDaoJdbc.java:88) + at app//com.example.tobby.user.dao.UserDaoTest.update(UserDaoTest.java:220) + at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base@17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base@17.0.2/java.lang.reflect.Method.invoke(Method.java:568) + at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:727) + at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) + at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:156) + at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:147) + at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:86) + at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(InterceptingExecutableInvoker.java:103) + at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) + at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92) + at app//org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:86) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:217) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:213) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:138) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) + at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) + at java.base@17.0.2/java.util.ArrayList.forEach(ArrayList.java:1511) + at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) + at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) + at java.base@17.0.2/java.util.ArrayList.forEach(ArrayList.java:1511) + at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) + at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) + at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) + at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) + at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) + at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) + at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) + at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:110) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:90) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:85) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) + at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base@17.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base@17.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base@17.0.2/java.lang.reflect.Method.invoke(Method.java:568) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) + at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) + at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) + at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) + at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) + at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) +Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'recomment=999 where id='a'' at line 1 + at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121) + at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:916) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320) + at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994) + at org.springframework.jdbc.core.JdbcTemplate.lambda$update$2(JdbcTemplate.java:973) + at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:656) + ... 89 more + + + + + + diff --git a/spring/tobby/tobby/build/test-results/test/binary/output.bin b/spring/tobby/tobby/build/test-results/test/binary/output.bin index b30f2d235bcc53445512dead674b729ff0487911..9cf83c810f45d69c128a481c02a9c90cd676de2f 100644 GIT binary patch literal 2987 zcmd6oTW`}a6vyfAOSSKCw3oH4bsZXrMpXz9xw3S)BdZ4OOZ?~WYZBIs?g3!xmT9}@Q@lKfY@(y^yEn~NZN;N{E z>J(aPB(#fKga_CHArxf_NHkJXw&J55F|=3IGWVTX5vrM4JY|sHPVYojrS8CB0LPOg zicjG&=b3!{qqHs!q$9np^u=U;YY3yb#}wc0`p00F?UD59H|Ia5x7s7m|* zxn}P80PMGuZHUwf=`fdr8YJ@`7 z2{hG8Xz8lm18jm2iZTHt8Y!8!;-hV`w5#hh_U%~_s+p;K>7={eJyunz+b|fw(I`){ z6L`cJm#=@6=7o(+WVV!EZ|1j}WmtB{@H>_>G~I#e3@i&dhP`F<2ZjN#fB5(XSdQgD zr_+Hq(&La894=XYM)S8o*g2wC_To{& zHD=H4-$BgkSi}a;pNiOG137(1gilx&70?tsgcb$l<1CXXG0VY3j^nCLUi?rKI!>=R zYy-k+RF zvkSm7crKoUaVl;G%rl$}#iZLNnWE4@aOS;?m`SJaan=ju# ze^sNahA7HvOyx?pS`Gfy()_0Fg^?+N)~bQ9RuaMWd)OtkClS`Gfv{c@!Lz9w_OSY$ w)vJL}FNt6|hL3GeDKrJdDk*Qz>GXnFH8_X9yV^ZJJ5;13{P-1c0!j^`M~UFtLwxlh7Ylu= AH2?qr diff --git a/spring/tobby/tobby/build/test-results/test/binary/results.bin b/spring/tobby/tobby/build/test-results/test/binary/results.bin index 326de75ba2ce0e57a06559ec30841b8eb1c4df56..a625f6868bde1077c46ca111be76dfcf9a2340de 100644 GIT binary patch literal 12287 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/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 z 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 XU-z`@uczp!EcNMUT;+O_ni=_D%smL( literal 26278 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 z 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 diff --git a/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserDaoTest.class.uniqueId0 b/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserDaoTest.class.uniqueId0 deleted file mode 100644 index 48e04cc50e3e030a23fb9e74135799d8176fe41c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8963 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 DGe*r+ diff --git a/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest$TestUserService.class.uniqueId2 b/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest$TestUserService.class.uniqueId2 new file mode 100644 index 0000000000000000000000000000000000000000..94fa2ea3b6051cc26428c754cd204b35b2d12600 GIT binary patch literal 1105 zcmbVLTW=Ck5dO{rUD$3*MT*6u)rxYnUG>43;N_vQu?ejvR1$qVEJwO@*~Q%hsXxV^ zVWK6`MBn{U#yK0Th$SXwlbJJAy%%mQb;1D!!WT3li~iq0S-kdi%R?fsyQ8o zOrys~+;X|swVE<;yl&mVGSWI$Ok6-_et{jo&mAwSlOfR+a*yD$<;r=0S*+^FnYe^C zhLu@H>QB5KayMjHEl;ICZ})^P>y_6!E;Bs&zdoOy*kT|Z-!qU$Ob!2viL2OPFo%O~ zz&oNLM#5z%l^b&yraG-xS~EpXhNk@S9lt}%N;e!&91Qzy5ghWiOP)-_x4GNmfurn+ zGcJ!D>iEGt)~Q{cx4$|Ka$m?Jzw?3zyf35(2raH|hoLwRbh;IWrKaTe@jf3+N-~=M zFtEk0ql(VX6tJz<#*jRqJ9_4aQpYyKtvMr`$)#cMd7cP%Tposk>P-K2jcYTWv%TRO z-MdEr4$VrG(}hgn`2@aDJH=AL1$iEt6{adv*MnMtA@SCtlB*$2X tJ4IMHBP^hVG7(myESCGlT#D=}NewmJj`S8R(i!q3v4uM%^Q7-0`4gBb6wUwu literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest$TestUserServiceException.class.uniqueId0 b/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest$TestUserServiceException.class.uniqueId0 new file mode 100644 index 0000000000000000000000000000000000000000..38275a16633320638e9dab2fde871cc296b5064d GIT binary patch literal 497 zcmbtRO-lnY5Pj*^Ze6RjwSsu^Afg`35AX{qibCnZ*50%0ppo6A-OZNzvpfkN`~m(b zaZ)|>A_xZZ-ptF8H<^5VzP$rD#b$&Gf)LdPmQWMeeo|8&P%iHn29!^ALPILtu7?F};m&H;-jhJH zrw#SXET(*@;*^zk&n7Azsa*T~N36O>T?kzC{^@%x5DjdZCv>H~S!ba+-|LYdgFwB{ z@wF{nh_=Aq-%JG>H^xxjO;u44cf0l5>#>87$M2Wm%^$$L%#mcCD~GQTFDz6LG5TX* ff)&QbcLDP%X93n2D`;YU&Mj;(M_d!4g%0XpCSimC literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest.class.uniqueId1 b/spring/tobby/tobby/build/tmp/compileTestJava/compileTransaction/stash-dir/UserServiceTest.class.uniqueId1 new file mode 100644 index 0000000000000000000000000000000000000000..0234713a1f9cc3d84e5bf33f2998fbfb5741b13f GIT binary patch literal 4775 zcmbVP`F9i775+w&t;GWvL0D1}NZ4$%sH_G|2*wz2BO8Li4$!2GrLjCl(umQ>m^L&` zLee(rlD5!7oup}-mNv9aLW!|MlI~l&Z+}653*?;s)^l>&((lfUWEl|9{Ggeq`|iE( z-tT_zzBh0G_w}~`+=IUd;ZtyT(#*#6AuXHF=rP;u?L8VR7IZ7Nmyd*Q4H`*3f&glQ zs8ta}NJ0I8HmJoiS}q;i**l;oZ3VR(jhta`Qs8fB><%JQ-EGRuYDUiS9)e2C-ePvZ z$b~RjLHN=uCoi2larw;g5b729@+-oKVpRosRd3g%ad)pHux2lb4Cnk}t~jy44g zgZ_f4&eg|LIdVe+bkygL%4%Uzr&&T1(ZLSGTWQn7pP{N=|VefQL82+PH8bqF6MK50wWiTFy? z!yPI*@F4|tqU2Fp!Gdb+sBlhl#L*c z*4~0`X-V5#M!5#hY#byARbcj5$OokdPs!{Lrm!z z-PT((nL23b4I-%`1zo{phg@Y6ki}%MrP-#XU z*9u+w5bMCEv|lW;Dso_oft(|rUh-Yh%ACv&tFXXg`n6O_;H<`!ieA>z*d2j_qKZKQ zWKuDowzQP)bfkjhJEY<$K1!cyoe|yE(Bb7(xpssFd053Ue4HsI`}O1@$9}Kti=i~! zQYiZ+mM}h{;!!*%+g-OiXgo1pue(Vhk4tDzC|FlXS8u-YR&tlsKB?kU_%v(B)x16| zJgl;TD;u`6$)1)S_8A4+D`RLgvw6+ZdNVpZ#SIxfu36qfQG8Ct=Ov`Dl-r3Zf-m5U zL3~NY37k~0?EmuVY_j&lMJ=<399mx)=#BUGRohO``ihEEI8C$)WwdTuTPFjLXNQA$ zR>9gT=vH(vX^#u!Q6Y<97|+Xz_cbA6MOQA>ob(yS*HwH2-(*K)h+^zCha2pLitZr% z8%8mNZZN zHnMuRQ837+)?CiCHJRcjU*|BZke9>0&(gB`5z{&p>(#YfA=bxcX!q$?9I<>r)LdfflY)J}Fo`^Wxn@?#rbFS~y?S3=0 zi@QF{vqFyaNiyGK*!^BtsW1IEi={?0wIp&>cI%pSyOOM==8C6zi}MsREuNVDtUAHB zC+-ko#rq>2^Nl3TqLtLQ8B)aQdl`Mgy+#Xq%jKjJwn*!_hIFQB$0QWqEqKcsvSSH{ zmRl(IpkG?0GE~-c1u{C;E~AtHCdD7rGDU{5`MT>(SZX3O+=U%q;+3wNZ|RA8&d*hriEJE#E)j8*;THXyvk9GZ-wugrVH?k zz=v~uibG&Fe#oclD&Ra`<39x>H1;{hXT7;&O`$gt-siu_N3362%UtoDjyULuW6>4SRp+p# zJ{8>{;!(7`hSu?*BMb|ekB8Az5%@7L@DffJr~{0ali0wNBw4lTJhqSGz7gEtbG6Uq zs3TJ2V5nF59HYG=*C7v>_gEjP&`J928N&eu9JG$%pn~|4G4v@ojoUdOGk%P4r)Vu5 zL*9ooSN+u*RC(z;~K7*+(LIkhlq670u4}v%7p$@)(%eQO#JVuk6PODtbf6`9Y9F)+@9_9iyul|2sQ++ zN_95tCU|hW2o~dH6dD3M70$YP&QV}O5f%KRjKse5 zOC+@sydbYKQV#Ju$#9qW9Js{q60Kz=;uEeHqu(0E8CE~gIg#xyZxtl)AP(ZJ$KNLM z5$MJ&W<3uNu(JE8ae)8$$wn3*T+aagve?V&P@`oF}lh>CDx8Up{p zsvw44LdSz#Zvr3z{F-V${Kk>qNvCh~|8Hsjy8}>?_&xr>@gF%Z;7|B7=W3~amiNTJ Ta2(}$n3Vl1K|Ra&-w^sAKt?XP literal 0 HcmV?d00001 diff --git a/spring/tobby/tobby/build/tmp/compileTestJava/previous-compilation-data.bin b/spring/tobby/tobby/build/tmp/compileTestJava/previous-compilation-data.bin index 486b490257244361029eb9505fb43f1a7a4f38e2..95eab32d38a4c84c149e7c97b35fef5466c222c9 100644 GIT binary patch literal 43715 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 B^PvC$ literal 43389 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 K{4r?s*#8G&jf8;! diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/TobbyApplication.java b/spring/tobby/tobby/src/main/java/com/example/tobby/TobbyApplication.java index c220aa4..bc7caaf 100644 --- a/spring/tobby/tobby/src/main/java/com/example/tobby/TobbyApplication.java +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/TobbyApplication.java @@ -3,6 +3,7 @@ import com.example.tobby.user.dao.DaoFactory; import com.example.tobby.user.dao.UserDao; import com.example.tobby.user.domain.User; +import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -14,7 +15,7 @@ public class TobbyApplication { public static void main(String[] args) throws SQLException, ClassNotFoundException { -// SpringApplication.run(TobbyApplication.class, args); + SpringApplication.run(TobbyApplication.class, args); } } diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/dip/SwitchService.java b/spring/tobby/tobby/src/main/java/com/example/tobby/dip/SwitchService.java new file mode 100644 index 0000000..79be446 --- /dev/null +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/dip/SwitchService.java @@ -0,0 +1,45 @@ +package com.example.tobby.dip; + +interface Bulb { + void lightOn(); + + void lightOff(); +} + +public class SwitchService { + boolean isOn = false; + Bulb bulb; + + public SwitchService(Bulb bulb) { + this.bulb = bulb; + } + + public void toggle() { + isOn = !isOn; + if (isOn) { + bulb.lightOn(); + } else { + bulb.lightOff(); + } + } +} + +class BulbFactory { + public Bulb bulb() { + return new Lamp(); + } + + public SwitchService switchService() { + return new SwitchService(bulb()); + } +} + +class Lamp implements Bulb { + public void lightOn() { + System.out.println("lamp on"); + } + + public void lightOff() { + System.out.println("lamp off"); + } +} diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/test/Test.java b/spring/tobby/tobby/src/main/java/com/example/tobby/test/Test.java new file mode 100644 index 0000000..58f278d --- /dev/null +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/test/Test.java @@ -0,0 +1,27 @@ +package com.example.tobby.test; + +import org.springframework.jdbc.datasource.SimpleDriverDataSource; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +public class Test { + + public void test1() throws SQLException { + Connection c = new SimpleDriverDataSource().getConnection(); + c.setAutoCommit(false); //transaction 시작! + try { + PreparedStatement st1 = c.prepareStatement("update users set .."); + st1.executeUpdate(); + PreparedStatement st2 = c.prepareStatement("delete users ..."); + st2.executeUpdate(); + c.commit(); //transaction commit! + } catch (Exception e) { + c.rollback(); + } + c.close(); + } + +} diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/DuplicateUserIdException.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/Exception/DuplicateUserIdException.java similarity index 77% rename from spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/DuplicateUserIdException.java rename to spring/tobby/tobby/src/main/java/com/example/tobby/user/Exception/DuplicateUserIdException.java index 00a1454..980d362 100644 --- a/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/DuplicateUserIdException.java +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/Exception/DuplicateUserIdException.java @@ -1,7 +1,7 @@ -package com.example.tobby.user.dao; - -public class DuplicateUserIdException extends RuntimeException { - public DuplicateUserIdException(Throwable cause) { - super(cause); - } -} +package com.example.tobby.user.Exception; + +public class DuplicateUserIdException extends RuntimeException { + public DuplicateUserIdException(Throwable cause) { + super(cause); + } +} diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/UserLevelUpgradePolicy.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/UserLevelUpgradePolicy.java new file mode 100644 index 0000000..f3d2f19 --- /dev/null +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/UserLevelUpgradePolicy.java @@ -0,0 +1,8 @@ +package com.example.tobby.user; + +import com.example.tobby.user.domain.User; + +public interface UserLevelUpgradePolicy { + boolean canUpgradeLevel(User user); + void upgradeLevel(User user); +} diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/UserService.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/UserService.java new file mode 100644 index 0000000..e223114 --- /dev/null +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/UserService.java @@ -0,0 +1,48 @@ +package com.example.tobby.user; + +import com.example.tobby.user.dao.UserDao; +import com.example.tobby.user.domain.Level; +import com.example.tobby.user.domain.User; + +import java.util.List; + +public class UserService { + UserDao userDao; + + public void setUserDao(UserDao userDao) { + this.userDao = userDao; + } + + public void upgradeLevels() { + List users = userDao.getAll(); + for (User user : users) { + if (canUpgradeLevel(user)) upgradeLevel(user); + } + } + + protected void upgradeLevel(User user) { + user.upgradeLevel(); + userDao.update(user); + } + public static final int MIN_LOGCOUNT_FOR_SILVER = 50; + public static final int MIN_RECCOMEND_FOR_GOLD = 30; + private boolean canUpgradeLevel(User user) { + Level currentLevel = user.getLevel(); + switch (currentLevel) { + case BASIC: + return (user.getLogin() >= MIN_LOGCOUNT_FOR_SILVER); + case SILVER: + return (user.getRecommend() >= MIN_RECCOMEND_FOR_GOLD); + case GOLD: + return false; + default: + throw new IllegalArgumentException("Unknown Level: " + + currentLevel); + } + } + + public void add(User user) { + if (user.getLevel() == null) user.setLevel(Level.BASIC); + userDao.add(user); + } +} diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDao.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDao.java index 570a9bc..0cd049c 100644 --- a/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDao.java +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDao.java @@ -14,4 +14,6 @@ public interface UserDao { void deleteAll(); int getCount(); + + void update(User user1); } diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDaoJdbc.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDaoJdbc.java index bdff70b..c2020c4 100644 --- a/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDaoJdbc.java +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/dao/UserDaoJdbc.java @@ -83,6 +83,11 @@ public int getCount() { return this.jdbcTemplate.queryForObject("select count(*) from users", Integer.class); } + @Override + public void update(User user) { + this.jdbcTemplate.update("update users set name=?, password=?, level=?, login=? recomment=? where id=?", user.getName(), user.getPassword(), user.getLevel().intValue(), user.getLogin(), user.getRecommend(), user.getId()); + } + public List getAll() { return this.jdbcTemplate.query("select * from users order by id", userMapper); diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/Level.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/Level.java index ae35eff..6d355ea 100644 --- a/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/Level.java +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/Level.java @@ -1,15 +1,17 @@ package com.example.tobby.user.domain; public enum Level { - BASIC(1), SILVER(2), GOLD(3); + GOLD(3, null), SILVER(2, GOLD), BASIC(1, SILVER); private final int value; + private final Level next; public int intValue() { return value; } - Level(int value) { + Level(int value, Level next) { this.value = value; + this.next = next; } public static Level valueOf(int value) { @@ -20,4 +22,8 @@ public static Level valueOf(int value) { default -> throw new AssertionError("Unknown value: " + value); }; } + + public Level nextLevel() { + return this.next; + } } diff --git a/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/User.java b/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/User.java index 47aa52b..2f6e8ca 100644 --- a/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/User.java +++ b/spring/tobby/tobby/src/main/java/com/example/tobby/user/domain/User.java @@ -7,15 +7,29 @@ public class User { Level level; int login; int recommend; + String password; - public void setLevel(Level level) { + public User() { + } + + public User(String id, String name, String password, Level level, + int login, int recommend) { + this.id = id; + this.name = name; + this.password = password; this.level = level; + this.login = login; + this.recommend = recommend; } public Level getLevel() { return level; } + public void setLevel(Level level) { + this.level = level; + } + public int getLogin() { return login; } @@ -32,42 +46,36 @@ public void setRecommend(int recommend) { this.recommend = recommend; } - public User() { + public String getId() { + return id; } - String password; - - public User(String id, String name, String password, Level level, - int login, int recommend) { + public void setId(String id) { this.id = id; - this.name = name; - this.password = password; - this.level = level; - this.login = login; - this.recommend = recommend; - } - - public String getId() { - return id; } public String getName() { return name; } - public String getPassword() { - return password; - } - - public void setId(String id) { - this.id = id; - } - public void setName(String name) { this.name = name; } + public String getPassword() { + return password; + } + public void setPassword(String password) { this.password = password; } + + public void upgradeLevel() { + Level nextLevel = this.level.nextLevel(); + if (nextLevel == null) { + throw new IllegalStateException(this.level + "은 업그레이드가 불가능합니다"); + } else { + this.level = nextLevel; + } + } } diff --git a/spring/tobby/tobby/src/main/resources/test.xml b/spring/tobby/tobby/src/main/resources/test.xml index 791b8d8..2eac020 100644 --- a/spring/tobby/tobby/src/main/resources/test.xml +++ b/spring/tobby/tobby/src/main/resources/test.xml @@ -12,4 +12,7 @@ + + + \ No newline at end of file diff --git a/spring/tobby/tobby/src/test/java/com/example/tobby/user/UserServiceTest.java b/spring/tobby/tobby/src/test/java/com/example/tobby/user/UserServiceTest.java new file mode 100644 index 0000000..43fe198 --- /dev/null +++ b/spring/tobby/tobby/src/test/java/com/example/tobby/user/UserServiceTest.java @@ -0,0 +1,113 @@ +package com.example.tobby.user; + +import com.example.tobby.user.dao.UserDao; +import com.example.tobby.user.domain.Level; +import com.example.tobby.user.domain.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.Arrays; +import java.util.List; + +import static com.example.tobby.user.UserService.MIN_LOGCOUNT_FOR_SILVER; +import static com.example.tobby.user.UserService.MIN_RECCOMEND_FOR_GOLD; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +@SpringBootTest +@ExtendWith(SpringExtension.class) +@ContextConfiguration(locations = "/test.xml") +class UserServiceTest { + + @Autowired + UserService userService; + @Autowired + UserDao userDao; + List users; + + @BeforeEach + public void setUp() { + users = Arrays.asList( + new User("bumjin", "박범진", "p1", Level.BASIC, MIN_LOGCOUNT_FOR_SILVER - 1, 0), + new User("joytouch", "강명성", "p2", Level.BASIC, MIN_LOGCOUNT_FOR_SILVER, 0), + new User("erwins", "신승한", "p3", Level.SILVER, 60, MIN_RECCOMEND_FOR_GOLD - 1), + new User("madnite1", "이상호", "p4", Level.SILVER, 60, MIN_RECCOMEND_FOR_GOLD), + new User("green", "오민규", "p5", Level.GOLD, 100, Integer.MAX_VALUE) + ); + } + + @Test + void bean() { + assertThat(this.userService).isNotNull(); + } + + @Test + public void upgradeLevels() { + userDao.deleteAll(); + for (User user : users) userDao.add(user); + userService.upgradeLevels(); + checkLevelUpgraded(users.get(0), false); + checkLevelUpgraded(users.get(1), true); + checkLevelUpgraded(users.get(2), false); + checkLevelUpgraded(users.get(3), true); + checkLevelUpgraded(users.get(4), false); + } + + private void checkLevelUpgraded(User user, boolean upgraded) { + User userUpdate = userDao.get(user.getId()); + if (upgraded) { + assertThat(userUpdate.getLevel()).isEqualTo(user.getLevel().nextLevel()); + } else { + assertThat(userUpdate.getLevel()).isEqualTo(user.getLevel()); + } + } + + @Test + public void add() { + userDao.deleteAll(); + User userWithLevel = users.get(4); // GOLD 레벨 + User userWithoutLevel = users.get(0); + userWithoutLevel.setLevel(null); + userService.add(userWithLevel); + userService.add(userWithoutLevel); + User userWithLevelRead = userDao.get(userWithLevel.getId()); + User userWithoutLevelRead = userDao.get(userWithoutLevel.getId()); + assertThat(userWithLevelRead.getLevel()).isEqualTo(userWithLevel.getLevel()); + assertThat(userWithoutLevelRead.getLevel()).isEqualTo(Level.BASIC); + } + + @Test + public void upgradeAllorNothing() { + TestUserService testUserService = new TestUserService(users.get(3).getId()); + testUserService.setUserDao(this.userDao); + userDao.deleteAll(); + for (User user : users) userDao.add(user); + try { + testUserService.upgradeLevels(); + fail("err"); + } catch (TestUserServiceException e) { + } + checkLevelUpgraded(users.get(1), false); + } + + static class TestUserService extends UserService { + private final String id; + + private TestUserService(String id) { + this.id = id; + } + + protected void upgradeLevel(User user) { + if (user.getId().equals(this.id)) throw new TestUserServiceException(); + super.upgradeLevel(user); + } + } + + static class TestUserServiceException extends RuntimeException { + } +} \ No newline at end of file diff --git a/spring/tobby/tobby/src/test/java/com/example/tobby/user/dao/UserDaoTest.java b/spring/tobby/tobby/src/test/java/com/example/tobby/user/dao/UserDaoTest.java index 2e501fb..c6f72ea 100644 --- a/spring/tobby/tobby/src/test/java/com/example/tobby/user/dao/UserDaoTest.java +++ b/spring/tobby/tobby/src/test/java/com/example/tobby/user/dao/UserDaoTest.java @@ -207,4 +207,21 @@ public void sqlExceptionTranslate() { assertThat(set.translate(null, null, sqlEx)).isInstanceOf(DuplicateKeyException.class); } } + @Test + public void update() { + dao.deleteAll(); + dao.add(user1); + dao.add(user2); + user1.setName("루삥뽕"); + user1.setPassword("0000"); + user1.setLevel(Level.GOLD); + user1.setLogin(1000); + user1.setRecommend(999); + dao.update(user1); + User user1update = dao.get(user1.getId()); + checkSameUser(user1, user1update); + User user2same = dao.get(user2.getId()); + checkSameUser(user2, user2same); + } + } \ No newline at end of file diff --git a/spring/tobby/tobby/src/test/java/com/example/tobby/user/domain/UserTest.java b/spring/tobby/tobby/src/test/java/com/example/tobby/user/domain/UserTest.java new file mode 100644 index 0000000..17e581f --- /dev/null +++ b/spring/tobby/tobby/src/test/java/com/example/tobby/user/domain/UserTest.java @@ -0,0 +1,37 @@ +package com.example.tobby.user.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UserTest { + User user; + + @BeforeEach + public void setUp() { + user = new User(); + } + + @Test + void upgradeLevel() { + Level[] levels = Level.values(); + for (Level level : levels) { + if (level.nextLevel() == null) continue; + user.setLevel(level); + user.upgradeLevel(); + assertThat(user.getLevel()).isEqualTo(level.nextLevel()); + } + } + + @Test + public void cannotUpgradeLevel() { + Level[] levels = Level.values(); + for (Level level : levels) { + if (level.nextLevel() != null) continue; + user.setLevel(level); + assertThrows(IllegalStateException.class, () -> user.upgradeLevel()); + } + } +} \ No newline at end of file