느린 것을 걱정하지 말고, 멈춰서는 것을 걱정하라

기존의 계획은 Spring Boot에 관한 책을 모두 읽고 이해하여 API 서버를 구축하는 계획을 갖고 있었느나 책 중간중간에 내용이 미흡한 부분이 많아서 인터넷을 참고하여 SpringBoot Rest API서버를 구축하였다. 그래도 확실히 책을 읽고나서 통찰력을 얻고나서 인터넷의 Reference를 참고하는 것과 그냥 참고하는 것과는 다르다는게 느껴지는게 소스를 보자마자 어떠한 기능을 하는지 대략적으로 이해가 갔다.

 

다음과 같은 절차를 통해 소스코드를 구현하였다.

 

1. 데이터베이스 생성 및 테이블 생성

2. 데이터 베이스에 연동할 properties값 설정

3. 소스코드 작성에 필요한 라이브러리들을 얻기 위한 Dependency 설정

4. 테이블과 매핑 객체 생성

5. DB에 데이터 접근을 위한 Repository 및 상세한 로직을 담기위한 Service 생성

6. URL 분기를 위한 Controller 구성

 

 

1. 데이터베이스 생성 및 테이블 생성

 

객체와 매핑할 테이블을 생성한다.

CREATE TABLE `items` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(100) NOT NULL,
   `price` int(11) NOT NULL,
   `img_path` text NOT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
 INSERT INTO items(name,price,img_path) VALUES
(1, '주현태', 100, 'apple.jpg'),
(2, '김두한', 200, 'banana.jpg'),
(3, '시라소니', 300, 'mikan.jpg'),
(4, '구마적', 400, 'glape.jpg');

 

 

2. 데이터 베이스에 연동할 properties값 설정

 

Database와의 연결을 위한 데이터베이스의 정보(url, id, password)를 입력합니다.

[application.properties]

# MySQL \uC124\uC815
spring.datasource.url=jdbc:mysql://[url]/[db명]?serverTimezone=UTC
spring.datasource.username=[id]
spring.datasource.password=[password]
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database=mysql
#spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true 

 

 

3. 소스코드 작성에 필요한 라이브러리들을 얻기 위한 Dependency 설정

 

의존관계 설정을 통해 필요한 라이브러리들을 갖고온다.

[pom.xml]

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
			<version>2.1.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
			<version>2.1.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.16</version>
		</dependency>
</dependencies>

 

 

 

4. 테이블과 매핑 객체 생성

 

[Item.java]

package com.copocalypse.rest.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@Entity
@Table(name="items")
public class Item {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name="id")
	int id;
	
	@Column(name="name")
	String name;
	
	@Column(name="price")
	int price;
	
	@Column(name="img_path")
	String img_path;

	@Builder
	public Item(int id, String name, int price, String imgPath) {
		super();
		this.id = id;
		this.name = name;
		this.price = price;
		this.img_path = imgPath;
	}
}

 

 

 

5. DB에 데이터 접근을 위한 Repository 및 상세한 로직을 담기위한 Service 생성

 

[ItemRepository.java]

package com.copocalypse.rest.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.copocalypse.rest.model.Item;

public interface ItemRepository extends JpaRepository<Item, Integer> {	

}

 

[ItemService.java]

package com.copocalypse.rest.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.copocalypse.rest.model.Item;
import com.copocalypse.rest.repository.ItemRepository;

@Service
public class ItemService {

	@Autowired
	ItemRepository itemRepository;

	public List<Item> findAll() {
		List<Item> list = itemRepository.findAll();

		for (Item item : list) {
			System.out.println(item.toString());
		}

		return list;
	}

	public Item findOne(int id) {
		Item item = itemRepository.getOne(id);
		System.out.println(item);
		return item;
	}

	public void updateItem(long id, Item item) {
		System.err.println("ItemService createItem");
		System.out.println(item.toString());

		itemRepository.findById((int) id).map(items -> {
			items.setName(item.getName());
			items.setPrice(item.getPrice());
			items.setImg_path(item.getImg_path());
			return itemRepository.save(items);
		}).orElseGet(() -> {
			item.setId((int) id);
			return itemRepository.save(item);
		});
	}
	public void deleteItem(int id) {
		System.err.println("ItemService deleteItem");
		itemRepository.deleteById(id);
	}

	public Item createItem(Item item) {
		System.err.println("ItemService createItem");
		System.out.println(item.toString());
		Item res = itemRepository.save(item);
		System.out.println(res.toString());
		return res; 
	}
}

 

 

6. URL 분기를 위한 Controller 구성

[ItemService.java]

package com.copocalypse.rest;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;

import com.copocalypse.rest.model.Item;
import com.copocalypse.rest.service.ItemService;

@RestController
@RequestMapping(path = "/api")
public class ItemController {
    @Autowired
    ItemService itemService;
    

    @RequestMapping(value = "/items", method = RequestMethod.GET)
    public List<Item> getItems() {
    	System.err.println("ItemController getItems");
        List<Item> customers = itemService.findAll();
        return customers;
    }
    
    @GetMapping(path = "/items/{id}")
    public Item getOneItem(@PathVariable("id") long id) {
    	System.err.println("ItemController getOneItem");
    	Integer select_id = (int)id;
    	return itemService.findOne(select_id);
    }
    
    
    @PostMapping("/items")
    public Item createItem(@RequestBody final Item item, final UriComponentsBuilder ucBuilder) {
    	System.err.println("ItemController createItem");
    	Item res = new Item();
    	res = itemService.createItem(item);
    	return res;
    }
    
    
    @PutMapping("/items/{id}")
    public Item updateItem(@PathVariable("id") long id,
    		@RequestBody final Item item,
    		final UriComponentsBuilder ucBuilder) {
    	System.err.println("ItemController updateItem");
    	itemService.updateItem(id, item);
    	return itemService.findOne((int)id);
    }
    
    
    @DeleteMapping("/items/{id}")
    public void deleteItem(@PathVariable("id") long id) {
    	System.err.println("ItemController deleteItem");
    	itemService.deleteItem((int)id);
    }
}

 

위의 코드를 참고하면 충분히 CRUD기능을 구현할 수 있을 것이라 생각한다. 그리고 현재 황금돼지 로또 도우미 및 기타 프로젝트에서는 findAll을 이용해서 위치정보를 구현하는 기능만 필요하기 때문에 위의 정보로 충분할 것으로 보인다. 나중에 페이징이라던지 기타 파라미터를 처리해야할 경우가 있을 경우 책을 통해서 다른 공부를 진행하도록 할 것이다. 

 

 최근 공부의 범위가 너무 넓고 깊어지면서 블로그에 Skill관련 포스팅을 하던지 아니면 프로그래밍 하는 시간이 너무 줄어들었던 것 같다. 오늘 저녁 혹은 내일 아침즈음에 위의 소스코드를 기반으로 테이블 설계및 객체설계를 하여서 위치정보 API 서버를 구축하도록 하여야겠다.

profile

느린 것을 걱정하지 말고, 멈춰서는 것을 걱정하라

@주현태

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!