origoni's Blog from Millky

origoni의 스프링 블로그 입니다.

[블로그개발_02] Spring Boot 와 Spring Data (JPA) 를 이용한 간단한 DB 입출력

블로그개발 시리즈 - 다른글 : http://millky.com/@origoni/folder/30/post/list

라이브 데모 : http://blog.millky.com/post/list

자바 웹 개발 시작하기 : http://www.slideshare.net/origoni/presentations




프로젝트를 시작했으니 모든 웹 프로그래밍의 가장 기본이 되는 DB 입출력에 대해 다뤄 볼까 한다.

얼마전까지 ORM 은 시작하기 어려운 기술중에 하나였다.

나 역시 처음 접근할때 지금까지 사용하던 RDB의 느낌을 지우는데 오랜 시간이 걸렸고, SQL 문을 바로 사용 하지 못하는데서 느끼는 어려움이 큰 문제였지만.. 초기 세팅도 문제였다. 뭔가 스프링과 하이버네이트 등을 연동하기에 아이바티스보다 어려움을 느끼고 있었으며 HQL, Criteria 등 배우기 쉽지 않은것은 사실이었다.

하지만. 지금은...

스프링 데이타(SpringData)라는 정말 간단한 방법이 있으니...


시작해보자.


우선 build.gradle 파일에 몇가지 dependency를 확인해보자.

지난번 글을(http://millky.com/@origoni/post/10001100) 보았다면 세팅이 되어있을 것이고 아니라면 아래 부분이 정의되어있나 확인해보자.

compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-jdbc")
runtime("com.h2database:h2")


해당 부분이 있다면 바로 시작해 볼 수 있다.


우선 간단한 입출력을 테스트 해보기 위해 Hello라는 객체를 만들어보겠다.

package com.millky.blog.domain.model.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Hello {
	@Id
	@GeneratedValue
	int id;

	String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
정말 단순하게 아이디와 이름을 정의하였다.

@Entity, @Id, @GeneratedValue 등의 어노테이션이 있다는 것만 확인하고 일단 넘어가자.


그리고 이번에는 JpaRepository를 상혹받은 인터페이스 하나를 만들어 보자.

package com.millky.blog.infrastructure.dao;

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

import com.millky.blog.domain.model.entity.Hello;

public interface HelloDao extends JpaRepository <Hello, Integer> {

}


그리고 컨트롤러를 만든다. (지난시간에 만들었던것에 추가한다.)

<hello><hello>package com.millky.blog.presentation.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.millky.blog.domain.model.entity.Hello;
import com.millky.blog.infrastructure.dao.HelloDao;

@RestController
public class HelloRestController {

	@Autowired
	private HelloDao helloDao;

	@RequestMapping("/add")
	public Hello add(Hello hello) {

		Hello helloData = helloDao.save(hello);

		return helloData;
	}

	@RequestMapping("/list")
	public List<hello> list(Model model) {

		List<hello> helloList = helloDao.findAll();

		return helloList;
	}

	@RequestMapping("/")
	public String index() {
		return "helloworld!";
	}
}</hello></hello>
</hello></hello>


이렇게 만들고 프로젝트를 실행해본다.



그 후 아래와 같이 방문해보면

http://localhost:8080/add?name=a


방금 추가한 이름을 볼 수 있다.

그리고 리스트를 보면

http://localhost:8080/list


다시 한번 

http://localhost:8080/add?name=%E3%85%A0

다시 리스트를 보면

http://localhost:8080/list


이게 먼가 싶을 정도로 간단하게 DB 입출력이 가능하다.

자세한 사항은 http://projects.spring.io/spring-data-jpa/ 를 참고하면 되다.

역시 문서가 너무 잘 되어있어서.;;;;; 그럼 나는 왜 이런 글을 쓰고 있나~~ 하면.. 지금으 시작이라 이렇지만 막상 블로그를 만들려면 여러가지 고민해야 할 사항도 많고. 그에 대해 내가 고민한 부분들을 앞으로 풀어 갈 수 있을 것이라 생각한다.


앞으로 작업의 결과물을 https://github.com/origoni/Spring-Blog 에 올릴 예정이니 참고 바란다.


eo1999 2015-08-29 12:11:39

안녕하세요 정말 좋은 블로그네요
질문이 있습니다 ㅠ
sts에서 github로 프로젝트 다운받았는데
소스부분에서 64개의 에러가 나오네요
대부분은 log 인스턴스가 없다는 "log cannot be resolved" 고 나머지는 정의된 함수를 찾을수 없다고 빨갛게 나오는데 무슨 문제일 까요

eo1999 2015-08-29 12:54:59

아 해결 했습니다. lombom ? 문제였군요
3시간 정도 삽실했씁니다. ㅠ

bumjin 2016-05-24 10:50:13

List<hello> 는 List<Hello> 가 되어야 할 거 같습니다.

jerrygo2 2016-11-07 11:40:34

스프링 초보입니다. ㅡ.ㅡ;;
염치 불구하고 여기에 질문을 올립니다.
일단 본문에 있는 설정과 소스코드를 작성하고 이클립스에서 구동해 보니 아래와 같은 에러가 발생을 하고 있는데, 어디서 무엇을 확인해 봐야 하는지 좀 알려주시면 감사하겠습니다.
---------------------------------------------------------------------------------

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.1.RELEASE)

2016-11-07 11:29:28.092 INFO 18636 --- [ main] com.example.SpringBlogApplication : Starting SpringBlogApplication on int_jerrygo2 with PID 18636 (E:\TestApp\SpringBlog\bin started by jerrygo2 in E:\TestApp\SpringBlog)
2016-11-07 11:29:28.094 INFO 18636 --- [ main] com.example.SpringBlogApplication : No active profile set, falling back to default profiles: default
2016-11-07 11:29:28.132 INFO 18636 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5e0e82ae: startup date [Mon Nov 07 11:29:28 KST 2016]; root of context hierarchy
2016-11-07 11:29:29.544 INFO 18636 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2016-11-07 11:29:29.649 INFO 18636 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [class org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$4098dc36] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2016-11-07 11:29:30.115 INFO 18636 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-11-07 11:29:30.129 INFO 18636 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2016-11-07 11:29:30.130 INFO 18636 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.5
2016-11-07 11:29:30.254 INFO 18636 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2016-11-07 11:29:30.254 INFO 18636 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2125 ms
2016-11-07 11:29:30.425 INFO 18636 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2016-11-07 11:29:30.430 INFO 18636 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-11-07 11:29:30.430 INFO 18636 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-11-07 11:29:30.430 INFO 18636 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-11-07 11:29:30.430 INFO 18636 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2016-11-07 11:29:30.759 INFO 18636 --- [ main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2016-11-07 11:29:30.774 INFO 18636 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2016-11-07 11:29:30.847 INFO 18636 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.0.11.Final}
2016-11-07 11:29:30.849 INFO 18636 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2016-11-07 11:29:30.851 INFO 18636 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2016-11-07 11:29:30.892 INFO 18636 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2016-11-07 11:29:31.174 INFO 18636 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2016-11-07 11:29:31.367 INFO 18636 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2016-11-07 11:29:31.370 INFO 18636 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2016-11-07 11:29:31.406 INFO 18636 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2016-11-07 11:29:31.424 WARN 18636 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'helloRestController': Unsatisfied dependency expressed through field 'helloDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.milky.blog.infrastructure.dao.HelloDao]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2016-11-07 11:29:31.425 INFO 18636 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2016-11-07 11:29:31.425 INFO 18636 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2016-11-07 11:29:31.426 INFO 18636 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2016-11-07 11:29:31.431 INFO 18636 --- [ main] o.apache.catalina.core.StandardService : Stopping service Tomcat
2016-11-07 11:29:31.447 INFO 18636 --- [ main] utoConfigurationReportLoggingInitializer :

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2016-11-07 11:29:31.535 ERROR 18636 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :

***************************
APPLICATION FAILED TO START
***************************

Description:

Field helloDao in com.example.blog.HelloRestController required a bean of type 'com.milky.blog.infrastructure.dao.HelloDao' that could not be found.


Action:

Consider defining a bean of type 'com.milky.blog.infrastructure.dao.HelloDao' in your configuration.
back to top