실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 자바 스프링에서는 테스트용 생성자 메서드가 있어도, 매번 일일히 null을 넣어준다거나 하는 문제점들이 있어서 결국 Builder를 사용했었는데 코틀린에서는 롬복 Builder가 지원되지 않는다고 해서 엄청 고민 중이였습니다 근데 이번 강의 보니까 그냥 온전한 객체 만들어주는 팩터리 메서드 하나 만들어놓고 테스트용으로 필요한 인자 값들만 설정해주면 되는 거였군요 진짜 미쳤다.. 갓틀린.. 잘 배워갑니다..
@PostMapping("/items/{id}/edit") public String updateItem(@PathVariable Long id, @ModelAttribute Item item) { Item findItem = itemService.findById(item.getId()); //더티 체킹 findItem.setId(item.getId()); findItem.setName(item.getName()); findItem.setPrice(item.getPrice()); findItem.setStockQuantity(item.getStockQuantity()); findItem.setAuthor(item.getAuthor()); findItem.setIsbn(item.getIsbn()); return "redirect:/items"; } 강의를 보지 않고 스스로 코드를 짜보고 있는데 이렇게 하니까 수정내역이 반영 되지 않더라구요 스스로 생각해봤을 때는 다음 2가지 이유 중 하나일 것 같은데 이유가 이유가 무엇인가요 ㅠㅠ? findItem은 영속성 컨텍스트가 관리하지 않는 객체가 된 것이다. 따라서 더티체킹이 되지 않는다. 영속성 컨텍스트가 관리하는 엔티티는 맞지만 Controller에는 트랜잭션이 없어서 반영이 안되는 것이다.
@EntityGraph(attributePaths = "team") List<Member> findEntityGraphByUsername(@Param("username")String username); 이번 강의를 복습하다 보니까 강사님께서 @Param을 사용하셨더라구요.(강의 20:59) findByAge(), findOptionalByUsername()과 같은 메소드는 @Param 애노테이션 없이도 잘 동작 했는데 따로 특별한 이유가 있는 것일까요?
List<Member> result = queryFactory .selectFrom(member) .join(member.team, team) .where(team.name.eq("teamA")) .fetch(); 위의 QueryDSL문을 sql문으로 번역하면 select * from member as m join team as t on m.team _id = t.team _id where t.name ='teamA' 가 맞나요? 관계형DB를 객체 다루듯이 사용하기 위해 Member안에는 Team 클래스가 있고, Team 클래스 안에는 Member 클래스가 있지만 실제로는 .join(member.team, team) 와 같은 코드를 작성하면 내부적으론 DB의 테이블에 가서 외래키와 기본키를 비교해서 값을 가져오는 건가요 ?
JsonSerializable은 상속이 가능해서 class User { final id; final nickname; ... } class UserDetail extends User { final age; UserDetail({super.id,... this.age}) } 이런식으로 처리가 가능한데, Freezed는 상속이 불가능하더라구요. 실무에서 위처럼 상속으로 모델을 사용하는경우가 별로없을까요?
QueryDSL까지 강의를 다 듣고 난 이후에 게시판이나 쇼핑몰 같은 포트폴리오를 만들기전에 자그맣게 배운걸 써보고 싶은데 html,css,js를 모르다보니 view쪽을 처리할 수가 없더라구요. 그래서 혹시 활용1편에 제공되는 HelloShop view단 파일을 사용해도 될지 궁금합니다. 깃허브에 올리려고 하고 백엔드단 코드는 전부 스스로 짤 생각입니다.!
즉시로딩을 사용하면 Member 객체를 불러 올 때 1+N문제가 발생하고 Lazy로딩을 사용하면 Team 객체를 사용할 때 쿼리문이 나가서 즉시로딩이든 지연로딩이든 결국 1+N 문제가 생기는 게 맞나요 ? 이 1+N 문제의 해결방법으로 fetchJoin이 나온 것 같은데 지연 로딩, 즉시 로딩보다 무조건 fetchJoin이 이점이 있는 것 아닌가요? 왜 디폴트값으로 지연로딩으로 설정하고 fetchJoin을 선택해서 사용하는지 궁금합니다. 기본적으로 fetchJoin을 사용하고 연관관계에 있는 객체를 사용하지 않을 것 같은 경우에만 지연로딩을 선택적으로 사용하는게 더 편하지 않나요? 사용하지 않는 객체를 가져오는 fetchJoin의 쿼리문 몇 줄이 성능에 그렇게 큰 영향을 미치나요?
Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); teamRepository.save(teamA); teamRepository.save(teamB); memberRepository.save(new Member("member1", 10, teamA)); memberRepository.save(new Member("member2", 10, teamB)); 강의에서 이렇게 한번에 하려다가 Member를 생성해주고 따로 save를 해주던데 한번에 하면 안되는 이유가 있을까요 ?
PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Direction.DESC, "username")); int age = 10; //when Page<Member> page = memberRepository.findByAge(age, pageRequest); PageRequest.of 코드에서 첫 번째 파라미터가 무엇을 의미하는지 헷갈립니다. PageRequest.of 의 2번째 파라미터는 한 페이지의 element 개수이고(limit), 3번째 파라미터는 정렬 조건이 맞나요? List<Member> content = page.getContent(); assertThat(content.size()).isEqualTo(3); assertThat(page.getTotalElements()).isEqualTo(5); assertThat(page.getNumber()).isEqualTo(0); assertThat(page.getTotalPages()).isEqualTo(2); assertThat(page.isFirst()).isTrue(); assertThat(page.hasNext()).isTrue(); page.getContent()는 현재 페이지의 데이터를 가져오는 메소드인가요? page.getNumber()는 현재 페이지를 가져오는 메소드인가요? Page는 책처럼 0,1,2,3 ... 이렇게 페이지가 있는 거고 Content는 그 Page안에 있는 데이터를 의미하는 건가요? List<List<data>> 와 같은 구조로 되어 있는 것일까요? Page와 Content의 자료 구조가 어떻게 되어있는지가 궁금합니다.
[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
안녕하세요. 안드로이드 스튜디오에서 프로젝트 생성 후 코드수정없이 바로 실행했는데, 아래와 같은 오류가 발생합니다. 도와주세요. Oops; flutter has exited unexpectedly: "Null check operator used on a null value". A crash report has been written to C:\Users\IHC\AndroidStudioProjects\dataprogram_flutter\flutter_01.log. 아래는 flutter_01.log 파일안의 내용입니다. Flutter crash report. Please report a bug at https://github.com/flutter/flutter/issues . ## command flutter --no-color run --machine --track-widget-creation --device-id=emulator-5554 --start-paused --dart-define=flutter.inspector.structuredErrors=true lib\main.dart ## exception _TypeError: Null check operator used on a null value ``` #0 AndroidStudioJavaGradleConflictMigration.migrate (package:flutter_tools/src/android/migrations/android_studio_java_gradle_conflict_migration.dart:107:39) #1 ProjectMigration.run (package:flutter_tools/src/base/project_migrator.dart:84:16) #2 AndroidGradleBuilder.buildGradleApp (package:flutter_tools/src/android/gradle.dart:280:15) #3 AndroidGradleBuilder.buildApk (package:flutter_tools/src/android/gradle.dart:208:11) #4 AndroidDevice.startApp (package:flutter_tools/src/android/android_device.dart:578:29) <asynchronous suspension> #5 FlutterDevice.runHot (package:flutter_tools/src/resident_runner.dart:468:33) <asynchronous suspension> #6 Future.wait.<anonymous closure> (dart:async/future.dart:525:21) <asynchronous suspension> #7 HotRunner.run (package:flutter_tools/src/run_hot.dart:421:34) <asynchronous suspension> #8 AppDomain.launch.<anonymous closure> (package:flutter_tools/src/commands/daemon.dart:649:9) <asynchronous suspension> #9 AppDomain.launch (package:flutter_tools/src/commands/daemon.dart:647:5) <asynchronous suspension> #10 RunCommand.runCommand (package:flutter_tools/src/commands/run.dart:638:15) <asynchronous suspension> #11 FlutterCommand.run .<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1294:27) <asynchronous suspension> #12 AppContext.run .<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19) <asynchronous suspension> #13 CommandRunner.runCommand (package:args/command_runner.dart:212:13) <asynchronous suspension> #14 FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:296:9) <asynchronous suspension> #15 AppContext.run .<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19) <asynchronous suspension> #16 FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:244:5) <asynchronous suspension> #17 run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:91:9) <asynchronous suspension> #18 AppContext.run .<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19) <asynchronous suspension> #19 main (package:flutter_tools/executable.dart:91:3) <asynchronous suspension> ``` ## flutter doctor ``` [✓] Flutter (Channel master, 3.10.0-17.0.pre.31, on Microsoft Windows [Version 10.0.19044.1288], locale ko-KR) • Flutter version 3.10.0-17.0.pre.31 on channel master at C:\flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 3ed5f51208 (81 minutes ago), 2023-04-30 05:42:24 -0400 • Engine revision e99f31f443 • Dart version 3.1.0 (build 3.1.0-56.0.dev ) • DevTools version 2.23.1 [✓] Windows Version (Installed version of Windows is version 10 or higher) [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2) • Android SDK at C:\Users\IHC\AppData\Local\Android\sdk • Platform android-33, build-tools 33.0.2 • Java binary at: c:\Program Files\Android\Android Studio\jbr\bin\java • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694) • All Android licenses accepted. [✓] Chrome - develop for the web • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe [✗] Visual Studio - develop for Windows ✗ Visual Studio not installed; this is necessary for Windows development. Download at https://visualstudio.microsoft.com/downloads/ . Please install the "Desktop development with C++" workload, including all of its default components [✓] Android Studio (version 2022.2) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694) [✓] Android Studio • Android Studio at c:\Program Files\Android\Android Studio • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • android-studio-dir = c:\Program Files\Android\Android Studio • Java version OpenJDK Runtime Environment (build 17.0.6+0-b2043.56-9586694) [✓] Connected device (4 available) • sdk gphone x86 64 (mobile) • emulator-5554 • android-x64 • Android 13 (API 33) (emulator) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.19044.1288] • Chrome (web) • chrome • web-javascript • Google Chrome 112.0.5615.138 • Edge (web) • edge • web-javascript • Microsoft Edge 92.0.902.67 [✓] Network resources • All expected network resources are available. ! Doctor found issues in 1 category. ```
[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
안녕하세요 강의 잘 보고 있습니다 감사합니다 ! 혹시 이중 리스트 처리를 어떻게 하시는지 궁금해요 SliverList안에 listView shrinkWrap true 하면 쉽게 해결이 되지만, 성능 이슈가 있더라구요 (버벅거림) (shrinkWrap true 하지 말고, SliverList 사용해라 라는 내용을 보았어요) 그래서 SliverList 안에 SliverList를 넣는 법도 검색해봤는데 안되는 것 같구요,,, 혹시 선생님은 이런 경험이 있으실까요~