15강 질문 드립니다!
528
작성한 질문수 2
15강 람다식 질문 드립니다!
선생님 안녕하세요!
15강에서 작성해주신 람다식이 있는데
람다식을 사용하지 않은 코드도 댓글로 알려주실 수 있으실까요~!
자바 공부를 시작한 지 얼마 되지 않아서 혼자 해보려 해도 잘 안되네요..! 부탁 드리겠습니다!! 감사합니다!
답변 1
4
안녕하세요 한솔님! 질문 남겨주셔서 감사드립니다!! 😊
람다식 부분을 조금 더 알고 싶으셨군요~!! 👍 제가 Step 별로 조금 더 설명드려 보겠습니다.
[1. query 시그니처 살펴보기]
먼저 우리는 우리가 사용하고 싶은 라이브러리의 기능을 확인해보아야 해요!! 즉, JdbcTemplate.query 라는 메소드가 어떻게 생겼는지 알아야~ 해댱 기능을 사용할 수 있죠!
우리가 사용한 JdbcTemplate.query 를 눌러 보면 다음과 같은 메소드 시그니처를 갖고 있습니다. 메소드 시그니처란, 메소드의 이름, 메소드가 받는 매개변수, 반환 결과 등을 의미합니다!!
@Override
public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args) throws DataAccessException {
// 생략
}
보시면 JdbcTemplate 클래스의 query 메소드는 String 타입의 문자열과 RowMapper 타입의 객체, 그리고 Object...인 가변인자를 받고 있습니다! 여기서 가변인자란, 같은 타입의 값을 여러개 받을 수 있다는 의미입니다.
예를 들어,
public void doSomething(String... strs) {
}라는 함수가 있으면 우리는 doSomething("A", "B", "C") 와 같이 문자열 여러개를 마음껏 넣을 수 있습니다.
자~ 다음 포인트는 RowMapper 인데요! RowMapper 타입의 객체를 넣어줘야 하죠~ RowMapper도 어떻게 생겼는지 코드를 눌러 확인해보면, 다음과 같이 생긴걸 알 수 있습니다.
@FunctionalInterface
public interface RowMapper<T> {
@Nullable
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
제네릭과 같이 어려운 부분도 있지만, 가장 직관적으로 알 수 있는 부분은 RowMapper 는 인터페이스이고! mapRow 라는 하나의 메소드를 가지고 있다는 겁니다!! 이제 우리가 사용할 query가 어떻게 생겼는지 알았으니, 이 기능을 한 번 사용해볼게요!
[2. 가장 원시적인 형태로 query를 호출해보기 작성해보기]
@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
String readSql = "SELECT * FROM user WHERE id = ?";
jdbcTemplate.query(readSql, [ 여기가 바로 RowMapper가 들어갈 자리 ]], request.getId()).isEmpty();
}우선 질문주신 RowMapper 부분을 빼놓고 코드를 작성해보았습니다! 여기까지는 이해하시는데 크게 어렵지 않으실거에요~
그럼 이제 RowMapper 를 넣어주어야죠!! 우리가 어떤 타입의 객체를 집어 넣을 때 해당타입의 인스턴스를 집어넣을 수도 있고 그 타입의 하위 클래스의 인스턴스를 집어 넣을 수도 있습니다. 객체의 다형성이죠~ 여기서 RowMapper 는 인터페이스이기 때문에 인터페이스의 인스턴스를 바로 집어 넣을 수 없고, 하위 클래스를 만들어준다음 그 클래스의 인스턴스를 넣어야 합니다.
자 그러면 이렇게 코드를 작성해볼 수 있겠네요
// UserController와는 아예 다른 파일에 위치한 클래스입니다!
// 여기서 <Integer>의 의미는 mapRow의 결과로 Integer를 반환하겠다는 의미입니다.
public class UserFindRowMapper implements RowMapper<Integer> {
@Override
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return 0; // readSQL의 결과가 있으면 0으로 바꿔치기한다.
}
}@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
String readSql = "SELECT * FROM user WHERE id = ?";
RowMapper<Integer> mapper = new UserFindRowMapper();
jdbcTemplate.query(readSql, mapper], request.getId()).isEmpty();
}우리는 RowMapper를 넣어주어야 하는데, RowMapper를 바로 넣을 수 없으니 (인터페이스라서요!) RowMapper를 implements 하는 클래스를 만들고 그 클래스의 인스턴스를 넣어주었습니다!
[3. 익명 클래스를 사용해 query 호출해보기]
자 그런데~ 당연히 이런 방법은 번거롭습니다! 새로운 클래스 파일을 만들기 얼마나 귀찮습니까~~ 그래서 바로 "익명 클래스"라는게 등장합니다! 익명 클래스란, 새로운 클래스를 만들지 않고도 어떤 인터페이스를 implements하는 클래스의 인스턴스를 만들어주는 문법입니다. 이걸 적용해보면 코드는 다음과 같이 바뀌게 됩니다.
@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
String readSql = "SELECT * FROM user WHERE id = ?";
// 여기가 바꼈습니다!!!!!
RowMapper<Integer> mapper = new RowMapper<Integer>() {
@Override
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return 0;
}
};
jdbcTemplate.query(readSql, mapper, request.getId()).isEmpty();
}new 인터페이스 이름으로 익명 클래스를 사용해주었고요~ 아까 새로운 클래스 파일을 하나 만드는 것보다는 훨~~씬 낫습니다!!
[4. 람다식을 사용해 query 호출해보기]
자 하지만 개발자들은 여기서 만족하지 않았습니다. 이 조차도 너무너무 귀찮은거죠! 😅 그래서 어떤 인터페이스의 함수가 하나만 있는 경우는, "람다식"이란걸 쓸 수 있게 합니다.
예를 들어 RowMapper 는 T mapRow(Result rs, int rowNum) 함수를 하나만 가지고 있죠!! 그러면 그냥~ 이렇게 @Override 쓰고~ return 0; 쓰고~ 할 필요 없이
RowMapper<Integer> mapper = new RowMapper<Integer>() {
@Override
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return 0;
}
};이 코드를
RowMapper<Integer> mapper = (rs, rowNum) -> 0;이렇게!
바꿔버렸습니다. 어차피 함수도 하나니까~ rs만 보더라도 매개변수 ResultSet rs 이란걸 알 수 있고 rowNum 만 보더라도 int rowNum 이란걸 알 수 있죠. 또한 { return 0; } 도 너무 귀찮아서 -> 0 으로 바꿔버렸습니다.
그래서 코드를 다시 한 번 작성해보면,
@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
String readSql = "SELECT * FROM user WHERE id = ?";
// 여기가 바꼈습니다!!!!!
RowMapper<Integer> mapper = (rs, rowNum) -> 0;
jdbcTemplate.query(readSql, mapper, request.getId()).isEmpty();
}이렇게 쓸 수 있고요!! 여기서 변수로 굳이 만들지 않고 바로 값을 넣어주면~
@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
String readSql = "SELECT * FROM user WHERE id = ?";
// 여기가 바꼈습니다!!!!!
jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
}이렇게 바뀝니다 ㅎㅎㅎ
또 궁금한 점 있으시면 편하게 질문 남겨주세요!! 👍👍👍
감사합니다~!! 🙇🙇
패키지 구분에 대해 궁금한게 있습니다
0
20
2
리액트 관련 질문이 있습니다.
0
64
2
스프링부트 버전
0
73
2
7강 강의를 들으려고 했는데 오류가 나서 서버가 안 켜지는거 같아요.
0
59
2
33강. UserLoanHistory의 관계성에 대한 질문
1
56
2
Java JDK 버전 문의의 건
0
133
2
ec2 에서 Linux버전이 달라져서 설치가 안되는것 같은데 자료 최신화좀 해주세요.
0
89
3
h2 console 접속했을 테이블 질문
1
65
1
ec2 서버에서 스프링 실행도 되고 인바운드 설정까지 했는데 index.html 안됨
0
75
2
15강. updateUser() 질문
0
55
2
깃허브 질
0
82
2
여기까지 다 끝냈다고 하셨는데
0
79
2
왜안될까요
0
70
2
MySQL 창이안ㄴ뜹니다
0
59
2
포스트맨
0
50
1
spring 개념적인 질문
0
71
2
인텔리제이 샘플코드 실행 안됨 오류
0
140
2
aws 배포할때 .env 파일에 저장한 환경변수에 관하여 여쭤볼게 있습니다
0
85
1
마이그레이션 오류입니다.
0
171
3
Whitelabel Error Page 오류가 났습니다.
0
163
2
안녕하십니까! 오류가 났습니다.. 도와주세요 ㅜㅜ
1
93
3
궁금한게 있습니다.
0
60
2
DTO 관련
0
70
2
궁금한게 있습니다!
0
68
2





