지난주 제이포쿠스에 있을 때 만난 마티 타보넨에서 근무하고 있습니다. Vaadin. 그들은 수년 동안 Java로 리치 인터넷 애플리케이션을 위한 오픈 소스 웹 프레임워크를 제안해 왔으며 정말 잘 해내고 있습니다. 저는 개인적으로 완전한 웹 최신 애플리케이션을 Java로만 작성하게 되어 정말 기쁩니다.
Couchbase에 개체를 저장하는 작동하는 Vaadin CRUD 샘플을 만드는 데 10분이 걸렸습니다. 결과는 다음에서 확인할 수 있습니다. Github. 그 이후로 JPA 기반 샘플도 마이그레이션했습니다. 여기. 작업이 얼마나 적게 필요하며 JPA에서 Couchbase로 전환하는 것이 얼마나 쉬운지 확인할 수 있습니다. diff.
스프링 데이터 카우치베이스와 바아딘의 만남
프로젝트 생성
Spring 프로젝트를 시작할 때 첫 번째 단계는 다음과 같습니다. 스프링 초기화. 여기에서 프로젝트에 원하는 버전과 종속성을 선택할 수 있습니다. Spring Boot 버전 1.4.0(스냅샷)을 선택하고 종속성으로 Vaadin 및 Couchbase를 추가합니다.
이제 프로젝트를 생성하고 원하는 편집기에서 Maven 프로젝트로 가져올 수 있습니다.
기본 개인 엔티티 CRUD
이 CRUD 샘플은 다음을 저장합니다. 고객 객체입니다. 고객이 id, a 이름 및 성. 또한 성은 null이 아니어야 합니다. 이를 엔티티로 표현하려면 엔티티에 문서 주석을 추가합니다, @Id 어노테이션을 필드에 추가하고, 게터와 세터를 생성하면 완료됩니다. null이 아닌 제약 조건을 표현하려면 Java 유효성 검사 어노테이션을 사용하면 됩니다. @NotNull. 엔티티를 작성할 때 이를 선택하도록 하려면 유효성 검사기 빈을 선언해야 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
패키지 hello; 가져오기 자바.활용.개체; 가져오기 자바.활용.UUID; 가져오기 javax.유효성 검사.제약 조건.NotNull; 가져오기 org.스프링 프레임워크.데이터.카우치베이스.핵심.매핑.문서; 가져오기 com.카우치베이스.클라이언트.자바.저장소.주석.Id; @문서 public 클래스 고객 { @Id 비공개 문자열 id = UUID.randomUUID().toString(); 비공개 문자열 이름; @NotNull 비공개 문자열 성; 보호됨 고객() { } public 고객(문자열 이름, 문자열 성) { 이.이름 = 이름; 이.성 = 성; } public 문자열 getId() { 반환 id; } public void setId(문자열 id) { 이.id = id; } public 문자열 getFirstName() { 반환 이름; } public void setFirstName(문자열 이름) { 이.이름 = 이름; } public 문자열 getLastName() { 반환 성; } public void setLastName(문자열 성) { 이.성 = 성; } @오버라이드 public 문자열 toString() { 반환 문자열.형식("Customer[id=%s, firstName='%s', lastName='%s']", id, 이름, 성); } @오버라이드 public int 해시코드() { int 해시 = 7; 해시 = 37 * 해시 + 개체.해시코드(이.id); 반환 해시; } @오버라이드 public 부울 같음(개체 객체) { 만약 (이 == 객체) { 반환 true; } 만약 (객체 == null) { 반환 false; } 만약 (getClass() != 객체.getClass()) { 반환 false; } final 고객 기타 = (고객) 객체; 반환 개체.같음(이.id, 기타.id); } } |
고객 리포지토리
엔티티를 정의한 후에는 관련 리포지토리를 만들어야 합니다. 리포지토리를 확장하는 인터페이스를 만듭니다. 카우치베이스 페이징 및 정렬 저장소. 이 리포지토리는 고객 엔티티에 문자열을 키로 지정합니다.
저는 findAll 메서드를 반환하는 목록 대신 반복 가능 Vaadin 구조와 더 잘 어울리기 때문입니다. 그리고 findAll 메서드는 뷰로 백업됩니다. 뷰가 자동으로 정의되도록 하려면 뷰에 ViewIndexed 주석을 추가합니다. 또한 다음과 같이 설정해야 합니다. spring.data.couchbase.auto-index 속성을 참으로 설정하고 application.properties 파일을 만듭니다.
또한 성으로 찾기(문자열 lastName) 메서드를 입력합니다. 메서드 이름에 따라 적절한 N1QL 쿼리가 자동으로 생성됩니다. 하지만 N1Ql 쿼리를 실행하려면 기본 인덱스가 필요합니다. 이는 또한 @N1QLPrimaryIndexed 어노테이션.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
패키지 hello; 가져오기 자바.활용.목록; 가져오기 org.스프링 프레임워크.데이터.카우치베이스.핵심.쿼리.N1qlPrimaryIndexed; 가져오기 org.스프링 프레임워크.데이터.카우치베이스.핵심.쿼리.인덱싱된 보기; 가져오기 org.스프링 프레임워크.데이터.카우치베이스.저장소.카우치베이스 페이징 및 정렬 저장소; @인덱싱된 보기(디자인 문서 = "customer") @N1qlPrimaryIndexed public 인터페이스 고객 저장소 확장 카우치베이스 페이징 및 정렬 저장소<고객, 문자열> { 목록<고객> findAll(); 목록<고객> 성으로 찾기(문자열 성); } |
구성
스프링 스프링 부팅 스타터 데이터 카우치베이스를 사용하고 있습니다. 자동 구성을 제공합니다. 이 자동 구성은 다음과 같이 설정하여 활성화할 수 있습니다. spring.couchbase.bootstrap-hosts 속성입니다. 지금까지 내 application.properties 는 다음과 같이 보입니다:
1 2 3 |
봄.카우치베이스.부트스트랩-호스트=localhost 봄.데이터.카우치베이스.자동-색인=true |
고객 만들기
이제 저장에 필요한 모든 것을 갖추었습니다. 고객 엔티티를 만듭니다. 이를 쉽게 시도해 볼 수 있습니다. CommandLineRunner:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@스프링 부팅 애플리케이션 public 클래스 애플리케이션 { 비공개 정적 final 로거 로그 = 로거 팩토리.getLogger(애플리케이션.클래스); public 정적 void 메인(문자열[] args) { 스프링 애플리케이션.실행(애플리케이션.클래스); } @Bean public CommandLineRunner 로드데이터(고객 저장소 저장소) { 반환 (args) -> { 저장소.저장(new 고객(null, "Dessler")); }; } @Bean public 유효성 검사기 유효성 검사기() { 반환 new 로컬 유효성 검사기 팩토리 빈(); } } |
앞서 언급한 유효성 검사기 빈도 추가한 것을 보실 수 있습니다. 이 빈은 카우치베이스 이벤트 리스너 유효성 검사 스프링 부팅 자동 구성에 의해 자동으로 선언됩니다.
UI에 Vaadin 사용
백엔드가 준비되었으니 이제 프론트엔드에 대해 생각해 볼 수 있습니다. 고객 목록을 표시하고 목록의 요소를 추가, 편집 또는 제거하는 기능을 갖춘 기본 CRUD 앱을 만들고 싶습니다. 여기 스크린샷이 있습니다:
이를 구축하려면 먼저 사용자가 이름과 성을 입력할 수 있는 양식을 만들어야 합니다. 양식을 확장하는 클래스를 만듭니다. AbstractForm 의 고객. 이 클래스는 Vaadin Core에서 사용할 수 없으므로 추가해야 합니다. 비리틴.
비리틴은 바아딘의 서버 측 개선 라이브러리입니다. 핵심 프레임워크의 일부 잘못된 기본값을 수정하고 기존 컴포넌트를 위한 보다 유창하고 지능적인 API를 제공합니다. 또한 데이터 바인딩에 대한 몇 가지 주요 개선 사항을 제공하며 서버 측 구성으로 만들어진 완전히 새로운 구성 요소를 제공합니다(위젯 세트가 필요 없음).
그리고 예 AbstractForm 클래스가 Spring 데이터 및 유효성 검사기와 깔끔하게 통합되어 있습니다. 우리는 이름 그리고 성 필드의 고객 클래스에서 두 개의 텍스트 필드를 정의합니다. 이름 그리고 성. 고객 필드와 이름이 같아야 합니다. 이 컴포넌트의 또 다른 장점은 엔티티의 유효성 검사 어노테이션을 가져온다는 점입니다. 이렇게 하면 클라이언트와 서버에서 자동 유효성 검사를 수행할 수 있습니다. 그리고 더 복잡한 어노테이션도 지원합니다.@NotNull 같은 @Size 또는 패턴.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
패키지 hello; 가져오기 org.vaadin.비리틴.양식.AbstractForm; 가져오기 org.vaadin.비리틴.레이아웃.MFormLayout; 가져오기 com.vaadin.봄.주석.스프링 컴포넌트; 가져오기 com.vaadin.봄.주석.UIScope; 가져오기 com.vaadin.ui.구성 요소; 가져오기 com.vaadin.ui.텍스트 필드; @스프링 컴포넌트 @UIScope public 클래스 고객 편집자 확장 AbstractForm<고객> { /* 고객 엔터티에서 속성을 편집할 필드 */ 텍스트 필드 이름 = new 텍스트 필드("이름"); 텍스트 필드 성 = new 텍스트 필드("성"); public 고객 편집자() { setVisible(false); } @오버라이드 보호됨 구성 요소 createContent() { 반환 new MFormLayout(이름, 성, getToolbar()); } } |
이제 양식이 준비되었으므로 표 그리드를 표시하는 전체 UI를 구축할 수 있습니다. 이것이 Vaadin 애플리케이션의 주요 구성 요소인 메인 웹 페이지가 될 것입니다. 메인 웹 페이지의 고객 저장소 및 고객 편집자 가 Spring 빈이라면 생성자에서 직접 주입할 수 있습니다. Java UI 작성에 익숙하다면 아래의 주석 처리된 코드는 간단할 것입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
패키지 hello; 가져오기 org.스프링 프레임워크.콩.공장.주석.자동 유선; 가져오기 org.vaadin.비리틴.필드.MTable; 가져오기 org.vaadin.비리틴.레이아웃.MVerticalLayout; 가져오기 com.vaadin.주석.테마; 가져오기 com.vaadin.서버.FontAwesome; 가져오기 com.vaadin.서버.VaadinRequest; 가져오기 com.vaadin.봄.주석.SpringUI; 가져오기 com.vaadin.ui.버튼; 가져오기 com.vaadin.ui.UI; @SpringUI @테마("valo") public 클래스 VaadinUI 확장 UI { 비공개 final 고객 저장소 repo; 비공개 final 고객 편집자 편집기; 비공개 final MTable<고객> 그리드; 비공개 final 버튼 addNewBtn; @자동 유선 public VaadinUI(고객 저장소 repo, 고객 편집자 편집기) { 이.repo = repo; 이.편집기 = 편집기; 이.그리드 = new MTable<>(고객.클래스).와프로퍼티("id", "firstName", "성").withHeight("300px"); 이.addNewBtn = new 버튼("신규 고객", FontAwesome.플러스); } @오버라이드 보호됨 void init(VaadinRequest 요청) { // 선택한 고객을 편집기에 연결하거나 선택한 고객이 없는 경우 숨기기 그리드.추가M값변경 리스너(e -> { 만약 (e.getValue() == null) { 편집기.setVisible(false); } else { 편집기.setEntity(e.getValue()); } }); // 새 고객 즉시 생성 및 편집 새 버튼을 클릭합니다. addNewBtn.추가클릭 리스너(e -> 편집기.setEntity(new 고객("", ""))); // 편집기에서 변경 사항을 수신하고 백엔드에서 데이터를 새로 고칩니다. 편집기.설정된 핸들러(고객 -> { repo.저장(고객); listCustomers(); 편집기.setVisible(false); }); 편집기.설정 재설정 핸들러(고객 -> { 편집기.setVisible(false); listCustomers(); }); 편집기.설정 삭제 핸들러(고객 -> { repo.삭제(고객); listCustomers(); }); // 목록 초기화 listCustomers(); // 빌드 레이아웃 setContent(new MVerticalLayout(addNewBtn, 그리드, 편집기)); } 비공개 void listCustomers() { 그리드.setBeans(repo.findAll()); } } |
이제 모든 준비가 끝났으니 일반적인 Java Spring Boot 애플리케이션으로 실행하기만 하면 됩니다. 꽤 쉽죠?