๐จ๐จ๐ฆ๐ฆ SpringInAction Group Study [์ด์ฑ๋ฏผ, ๊ถํ๊ตฌ, ์ต์ฌํธ, ๊ณฝํ๊ธฐ, ๊น์์ฒ ]
group - GIT : https://github.com/euncheol-kim/SpringInActionGroupStudy
์ด์ฑ๋ฏผ ๋ : https://github.com/CokeLee777
๊ถํ๊ตฌ ๋ : https://github.com/Hashtae9
์ต์ฌํธ ๋ : https://github.com/jaero0725
๊ณฝํ๊ธฐ ๋ : https://github.com/nicebyy
๊น์์ฒ (๋ณธ์ธ): https://github.com/euncheol-kim
์์ฑ์ : ๊น์์ฒ
goal
jdbc ํ๋ ์์ํฌ์ธ mybatis์ Database(mySQL)์ ์ด์ฉํด ๊ธฐ๋ณธ์ ์ธ CRUD๋ฅผ ์ดํดํ๋ค.
- mybatis ํ๋ก์ ํธ ์ค๋ช
- mybatis_2 ํ๋ก์ ํธ ์ค๋ช
- mybatis์ด๋ก
Euncheol-Kim ์๊ฒฉ๋ธ๋์น ์ค์ต ํ๋ก์ ํธ ํ์ผ ๊ตฌ์ฑ
ํ๋ก์ ํธ๋ช | ์ค๋ช |
mybatis | class ๋ด๋ถ์์์ ๋ฐ์ดํฐ ์์ฑ/์ญ์ /์์ /์ ๊ฑฐ์ RestAPI (JDBC ํ๋ก๊ทธ๋๋ฐ์ ์๋) |
mybatis_2 | ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๋ฐ mabatis๋ฅผ ์ด์ฉํ RestAPI CRUD |
์ค์ตํ์ผ ํ์ผ GIT
GitHub - euncheol-kim/SpringInActionGroupStudy: SpringInAction ์คํฐ๋ ์ ์ฅ์์ ๋๋ค.
SpringInAction ์คํฐ๋ ์ ์ฅ์์ ๋๋ค. Contribute to euncheol-kim/SpringInActionGroupStudy development by creating an account on GitHub.
github.com
1. ํ์ผ๋ช : mybatis
[1] ๊ฐ์
Database๋ฅผ ์ฐ๊ฒฐํ์ง ์๊ณ class ๋ด๋ถ์์์ ๋ฐ์ดํฐ ์์ฑ / ์ญ์ / ์์ / ์ ๊ฑฐ์ RestAPI๋ฅผ ์์ฑํ๋ค.
[2] ํ๋ก์ ํธ ์์ฑ์ ์ข ์์ฑ ์ค์
- Spring Web
- Spring Data jdbc
- lombok
- Spring Boot DevTools
- MySQL Driver
[3] ์ค์ ๊ตฌ์ฑ
ํจํค์ง | ํ์ผ๋ช | ์ค๋ช |
src/main/java/resources | application.properties | mysql๋๋ผ์ด๋ฒ ์ค์ ๋ฐ mysql ์ฐ๊ฒฐ |
pom.xml | jdbc์์กด์ฑ์ค์ mySQL์์กด์ฑ์ค์ |
- pom.xml
<!-- mySQL JDBC ์ข
์์ฑ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- mySQL์ข
์์ฑ -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- application.properties
# Load the mysql driver (Database ์ข
๋ฅ๋ง๋ค ์ฐ์ธก์ ๋ค์ด๊ฐ๋ ๋ด์ฉ์ด ์์ด)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Connect the mysql database (Database ์ข
๋ฅ๋ง๋ค ์ฐ์ธก์ ๋ค์ด๊ฐ๋ ๋ด์ฉ์ด ์์ด)
spring.datasource.url=jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=UTF-8
# mysql username
spring.datasource.username=root
# mysql password
spring.datasource.password=1234
* ์ค์ ์ํ๋ฉฐ ํด๊ฒฐ์ด ๋์ง ์์๋ ๊ถ๊ธ์ฆ
mysql์ ์ฌ์ฉํ์ง ์๋ ์ค์ต์ด๋ผ pom.xml
์ mysql dependency ์ญ์ application.properties
์ jdbc๋ฅผ ์ ์ธํ ๋ชจ๋ ๋ด์ฉ์ ์ญ์ ํ๊ณ ์คํํ๋๋ error
๊ฐ ๋์์ต๋๋ค.
์ ๊ฐ ์๊ฐํ๊ธฐ์ mysql๊ณผ ๊ด๋ จ๋ ๋ด์ฉ์ ์์กด์ฑ์ ์ง์์ฃผ๊ณ ์๋น์ค๋ฅผ ์คํํ์ ๋, ๋ฌธ์ ์์ด ๋์ํด์ผํ๋ ๊ฒ ์๋๊ฐ์?
[4] mybatis์ ํ์ผ ๊ตฌ์ฑ
ํจํค์ง | ํ์ผ | ์ค๋ช |
src/main/java/com.example.mybatis | UserController.java | RestFull CRUD์ ๊ธฐ๋ฅ์ ๋ด์ ํ์ผ |
src/main/java/mybatis.model | User | Model |
- User.java
package mybatis.model;
import lombok.Data;
import lombok.RequiredArgsConstructor;
@Data // lombok annotation : ๋ณ์์ ๋ํ getter & setter์์ฑ
public class User {
private String id;
private String name;
private String phone;
private String address;
public User(String id, String name, String phone, String address) {
super();
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
}
}
- UserController.java
package com.example.mybatis;
import mybatis.model.User;
import org.springframework.web.bind.annotation.*;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
// RestAPI ์์ฑ - class๋ด๋ถ์์ ๋ฐ์ดํฐ ์์ฑ/์ญ์ /์์ /์ ๊ฑฐ
@RestController
public class UserController {
private Map<String, User> userMap;
@PostConstruct // ์ด๊ธฐํ ์งํ
public void init() {
userMap = new HashMap<String, User>();
userMap.put("1", new User("1", "ํ๊ธธ๋", "111-1111", "์์ธ์ ๊ฐ๋จ๊ตฌ ๋์น1๋"));
userMap.put("2", new User("2", "ํ๊ธธ์", "111-1112", "์์ธ์ ๊ฐ๋จ๊ตฌ ๋์น2๋"));
userMap.put("3", new User("3", "ํ๊ธธ์", "111-1113", "์์ธ์ ๊ฐ๋จ๊ตฌ ๋์น3๋"));
}
@GetMapping("/user/{id}") // id๊ฐ์ ํตํ ๋ฐ์ดํฐ ๋ฐํ
public User getUser(@PathVariable("id") String id) {
return userMap.get(id);
}
@GetMapping("/user/all") // ๋ชจ๋ ๋ฐ์ดํฐ ๋ฐํ
public List<User> getUserList() {
return new ArrayList<User>(userMap.values()); // https://docs.oracle.com/javase/8/docs/api/java/util/Map.html -> Map์ ๋ฐ์ดํฐ๋ค์ ArrayList๋ก ๋ฐ๊พผ๋ค.
}
@PutMapping("/user/{id}") //๋ฐ์ดํฐ ์์ฑ
public void putUser(@PathVariable("id") String id, @RequestParam("name") String name, @RequestParam("phone") String phone, @RequestParam("address") String address){
User user = new User(id, name, phone, address);
userMap.put(id, user);
}
@PostMapping("/user/{id}") //๋ฐ์ดํฐ ์์
public void postUser(@PathVariable("id") String id, @RequestParam("name") String name, @RequestParam("phone") String phone, @RequestParam("address") String address){
User user = userMap.get(id);
user.setName(name);
user.setPhone(phone);
user.setAddress(address);
}
@DeleteMapping("/user/{id}") //๋ฐ์ดํฐ ์ญ์
public void deleteUser(@PathVariable("id") String id){
userMap.remove(id);
}
}
- @PathVariable
(ex) -> @PathVariable "id" String id
์ฌ์ฉ์ ์ ๋ ฅ("id"์ ํด๋น)์ id๋งค๊ฐ๋ณ์๋ก ๋ฐ์์ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌ
- @RequestParam
(ex) -> @RequestParam("address") String address
๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
2. ํ์ผ๋ช : mybatis_2
[1] ๊ฐ์
mysql์ spring๊ณผ ์ฐ๊ฒฐํ์ฌ mybatis framework๋ฅผ ํตํด CRUD๋ฅผ ์งํํ๋ค.
- mybatis frameowrk = ORM framework (๊ฐ์ฒด์ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฅผ ๋งคํํ๊ธฐ ์ํ ๊ธฐ์ )
- mabatis๋ ์๋ฐ ์ค๋ธ์ ํธ์ SQL์ฌ์ด์ ์๋ ๋งคํ ๊ธฐ๋ฅ์ ์ง์ํ๋ค.
[2] ํ๋ก์ ํธ ์์ฑ์ ์ข ์์ฑ ์ค์
- Spring Web
- Spring Data jdbc
- lombok
- Spring Boot DevTools
- MySQL Driver
[3] ์ค์ ๊ตฌ์ฑ
ํจํค์ง | ํ์ผ๋ช | ์ค๋ช |
src/main/java/resources | application.properties | mysql๋๋ผ์ด๋ฒ ์ค์ ๋ฐ mysql ์ฐ๊ฒฐ |
pom.xml | jdbc์์กด์ฑ์ค์ mySQL์์กด์ฑ์ค์ |
- pom.xml
<!-- mySQL JDBC ์ข
์์ฑ -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- mySQL์ข
์์ฑ -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
- application.properties <enviroment>
# Load the mysql driver (Database ์ข
๋ฅ๋ง๋ค ์ฐ์ธก์ ๋ค์ด๊ฐ๋ ๋ด์ฉ์ด ์์ด)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# Connect the mysql database (Database ์ข
๋ฅ๋ง๋ค ์ฐ์ธก์ ๋ค์ด๊ฐ๋ ๋ด์ฉ์ด ์์ด)
spring.datasource.url=jdbc:mysql://localhost:3306/user?serverTimezone=UTC&characterEncoding=UTF-8
# mysql username
spring.datasource.username=root
# mysql password
spring.datasource.password=1234
[4] mybatis_2์ ํ์ผ ๊ตฌ์ฑ
ํจํค์ง | ํ์ผ | ์ค๋ช |
src/main/java/com.example.mybatis | UserController.java | RestFull CRUD์ ๊ธฐ๋ฅ์ ๋ด์ ํ์ผ |
src/main/java/mybatis.model | User | Model |
src/main/java/mapper | UserMapper | mybatis framework๋ฅผ ์ด์ฉํด ๊ตฌ์ฑํ interface |
- User.java <typeAlias ์ค์ >
package mybatis.model;
import lombok.Data;
@Data // lombok annotation : ๋ณ์์ ๋ํ getter & setter์์ฑ
public class User {
private String id;
private String name;
private String phone;
private String address;
public User(String id, String name, String phone, String address) {
super();
this.id = id;
this.name = name;
this.phone = phone;
this.address = address;
}
}
- UserMapper.java <mapper๋ฑ๋ก>
package com.example.mybatis_2.mapper;
import mybatis.model.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper //Mapper ์ธํฐํ์ด์ค
public interface UserMapper {
@Select("SELECT * FROM User WHERE id=#{id}")
User getUser(@Param("id") String id); //์ ๋ฌ๋ id๋ฅผ ๊ฐ์ง๊ณ database์์ ์กฐํ๋ฅผํด์ User ๊ฐ์ฒด๋ก ๋ฐํํ๋ api
// @Param์ด๋
ธํ
์ด์
๋๋ถ์ ๋งค๊ฐ๋ณ์ id๊ฐ #{id}์ ๋งคํ์ด ๋๋ค.
@Select("SELECT * FROM User")
List<User> getUserList();
@Insert("INSERT INTO User VALUES(#{id}, #{name}, #{phone}, #{address})")
int insertUser(@Param("id") String id, @Param("name") String name, @Param("phone") String phone, @Param("address") String address);
@Update("UPDATE User SET name=#{name}, phone=#{phone}, address=#{address} WHERE id=#{id}")
int updateUser(@Param("id") String id, @Param("name") String name, @Param("phone") String phone, @Param("address") String address);
@Delete("DELETE FROM User WHERE id=#{id}")
int deleteUser(@Param("id") String id);
}
- @Mapper
๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค(RDBMS)๋ฅผ ์๋ฐ์ ๊ฐ์ฒด ์งํฅ ๋ชจ๋ธ๋ก ๋งคํํ๊ฒ ๋์์ฃผ๋ ์ธํฐํ์ด์ค๋ค.
- #{....}
์ฌ์ฉ์์ ์ ๋ ฅ๊ฐ์ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋งคํ์ํค๊ธฐ ์ํด์ ์ฌ์ฉํ๋ค.
- @Param
(ex) -> @Select("SELECT * FROM User WHERE id=#{id}")
User getUser(@Param("id") String id);@Param์ด๋ ธํ ์ด์ ๋๋ถ์ ๋งค๊ฐ๋ณ์ id๊ฐ #{id}์ ๋งคํ์ด ๋๋ค.
- UserController.java
package com.example.mybatis_2;
import com.example.mybatis_2.mapper.UserMapper;
import mybatis.model.User;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class UserController {
private UserMapper mapper;
public UserController(UserMapper mapper) {
this.mapper = mapper;
}
@GetMapping("/user/{id}")
public User getUser(@PathVariable("id") String id) {
return mapper.getUser(id);
}
@GetMapping("/user/all")
public List<User> getUserList() {
return mapper.getUserList();
}
@PutMapping("/user/{id}") //๋ฐ์ดํฐ ์์ฑ
public void putUser(@PathVariable("id") String id, @RequestParam("name") String name, @RequestParam("phone") String phone, @RequestParam("address") String address){
mapper.insertUser(id, name, phone, address);
}
@PostMapping("/user/{id}") //๋ฐ์ดํฐ ์์
public void postUser(@PathVariable("id") String id, @RequestParam("name") String name, @RequestParam("phone") String phone, @RequestParam("address") String address){
mapper.updateUser(id, name, phone, address);
}
@DeleteMapping("/user/{id}") //๋ฐ์ดํฐ ์ญ์
public void deleteUser(@PathVariable("id") String id){
mapper.deleteUser(id);
}
}
- @PathVariable
mabatis ํ๋ก์ ํธ์ ์ค๋ช
3. mybatis3 framework ์ด๋ก
[1] mybatis3 ๋?
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๋ก๊ทธ๋๋ฐ์ ์ข ๋ ์ฝ๊ฒ ํ ์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์์ํฌ
- ๊ธฐ์กด JDBC(์๋ฐ ํ๋ก๊ทธ๋จ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ๋์ด ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๊ฒ ํด์ฃผ๋ ํ๋ก๊ทธ๋๋ฐ ์ธํฐํ์ด์ค)๋ฅผ ์กฐ๊ธ ๋ ์ฝ๊ณ ์ ์ฐํ๊ณ ํธํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด ๊ฐ๋ฐ๋์๋ค.
[2] mybatis3 ์ ์ฅ์
- ํ๋ก๊ทธ๋จ ์ฝ๋์ SQL์ฟผ๋ฆฌ์ ๋ถ๋ฆฌ๋ก ์ฝ๋์ ๊ฐ๊ฒฐ์ฑ ๋ฐ ์ ์ง๋ณด์์ฑ ํฅ์
- ๋น ๋ฅธ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํ๋ฉฐ ์์ฐ์ฑ์ด ํฅ์๋๋ค.
[3] mybatis3 ๊ตฌ์กฐ
mybatis3์ ๊ตฌ์ฑ
mybatis3์ ๊ตฌ์ฑ์ ๊ดํ ๋ง๋ง ์ด๋ ค์ด๊ฒ ๊ฐ์ต๋๋ค.
typeAlias, enviroment, mapper ์ค๋ช
์ ํด๋น๋๋ ์ฝ๋๋ค์ด๋ ํ์ธํ์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
์คํฐ๋๋ฅผ ์งํํ๋ฉฐ ๋์๋ ์ง๋ฌธ
1. mybatis_2 ํ๋ก์ ํธ์์, ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ id๋ก ์์ฒญํ์ ๋์ ๊ฒฐ๊ณผ?
- ๋น ํ ํ๋ฆฟ์ผ๋ก ์ถ๋ ฅ๋๋ค.
- ๋ง์ฝ ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํ์ฌ ์ถ๋ ฅํ๋ค๋ฉด NullPointerException ๋ฐ์ํ๊ฒ ๋๋ค.
@Slf4j
@RestController
public class UserController {
private UserMapper mapper;
public UserController(UserMapper mapper) {
this.mapper = mapper;
}
@GetMapping("/user/{id}") // ํน์ ๋ฐ์ดํฐ ์กฐํ
public User getUser(@PathVariable("id") String id) {
User a = mapper.getUser(id);
log.info("user a={}", a.getId());
return mapper.getUser(id);
}
...
...
์ดํ์๋ต
...
...
...
2. mybatis_2 ํ๋ก์ ํธ์์, @Select์ Insert๋ฌธ์ ๋ฃ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋๋์?
- UserMapper.javaํ์ผ์ ์ง๋ฌธ์ ํ ๋๋ก ์์ฑ
@Mapper //Mapper ์ธํฐํ์ด์ค
public interface UserMapper {
@Insert("SELECT * FROM User WHERE id=#{id}")
User getUser(@Param("id") String id); //์ ๋ฌ๋ id๋ฅผ ๊ฐ์ง๊ณ database์์ ์กฐํ๋ฅผํด์ User ๊ฐ์ฒด๋ก ๋ฐํํ๋ api
// @Param์ด๋
ธํ
์ด์
๋๋ถ์ ๋งค๊ฐ๋ณ์ id๊ฐ #{id}์ ๋งคํ์ด ๋๋ค.
...
...
์ดํ์๋ต
...
-๊ฒฐ๊ณผ๊ฐ : unexpected error ๋ฐ์