03/26
2015
[블로그개발_02] Spring Boot 와 Spring Data (JPA) 를 이용한 간단한 DB 입출력
블로그개발 시리즈 - 다른글 : http://millky.com/@origoni/folder/30/post/list
- [블로그개발_01] STS로 Spring Boot 웹 프로젝트 시작하기
- [블로그개발_02] Spring Boot 와 Spring Data (JPA) 를 이용한 간단한 DB 입출력
- [블로그개발_03] STS에서 GitHub에 있는 메이븐 프로젝트 받아서 시작해보기. (+ gradle to maven)
- [블로그개발_04] 스프링 부트(Spring Boot)의 세가지 뷰 (JSP, Velocity, Thymeleaf)
- [블로그개발_05] STS에서 GitHub에 있는 메이븐 프로젝트 받아서 시작해보기. (for Windows User)
- [블로그개발_06] webjars를 이용한 bootstrap, jquery 적용해보기 (Spring Boot)
- [블로그개발_07] Blog theme 적용해보기 (+bower, +webjars)
- [블로그개발_08] 블로그 글 저장 및 표시 해보기 (Spring Boot + Spring Data JPA + H2)
- [블로그개발_09] WYSIWYG 에디터 붙이기
- [블로그개발_10] 글에 부제목 추가 (Post Entity 모델링 +lombok, @Valid)
- [블로그개발_11] 글 수정, 삭제... (+Date 부분 변경)
- [블로그개발_12] 소셜 로그인 붙이기 (spring-social-facebook)
- [블로그개발_13] 글 목록 페이징 및 정렬 (SpringData Pageable, Page)
- [블로그개발_14] 스프링 WebMvc 설정 (Interceptor, ArgumentResolver)
- [블로그개발_15] 카테고리 추가 (@ManyToOne, stream())
라이브 데모 : 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
다시 리스트를 보면
이게 먼가 싶을 정도로 간단하게 DB 입출력이 가능하다.
자세한 사항은 http://projects.spring.io/spring-data-jpa/ 를 참고하면 되다.
역시 문서가 너무 잘 되어있어서.;;;;; 그럼 나는 왜 이런 글을 쓰고 있나~~ 하면.. 지금으 시작이라 이렇지만 막상 블로그를 만들려면 여러가지 고민해야 할 사항도 많고. 그에 대해 내가 고민한 부분들을 앞으로 풀어 갈 수 있을 것이라 생각한다.
앞으로 작업의 결과물을 https://github.com/origoni/Spring-Blog 에 올릴 예정이니 참고 바란다.
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.