前文我們使用SPRING INITIALIZR快速構建了一個空的Spring Boot項目,並增加web模塊實現了HTTP請求。
這一篇繼續在該demo的基礎上,增加JPA的功能。
JPA全稱Java Persistence API.JPA通過JDK 5.0注解或XML描述對象關系表的映射關系,並將運行時的實體對象持久化到數據庫中。
引入JPA模塊
1.在POM文件中添加:
<!-- JPA模塊 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2.在application.properties屬性文件中定義好數據源(傳統做法,這里不演示了)
2.(我們使用Spring推薦的yml來配置)新建application.yml文件,內容如下:
server:
port: 8000
spring:
application:
name: demo
jpa:
properties:
hibernate:
cache:
use_second_level_cache: false
use_query_cache: false
generate_statistics: true
cache.region.factory_class: org.hibernate.cache.ehcache.EhCacheRegionFactory
generate-ddl: false
hibernate:
ddl-auto: update
show-sql: true
datasource:
platform: mysql
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8
username: root
password: 你的數據庫密碼
# schema: classpath:schema.sql
# data: classpath:data.sql
logging:
level:
root: info
相應的,在本地創建一個叫demo的數據庫,用於我們的測試。
定義2個實體
1.新建包com.v5ent.demo.domain
2.在這個包下新建兩個實體類Tag和Note,代碼如下
/* * Copyright 2012-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.v5ent.demo.domain; import java.util.List; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.SequenceGenerator; @Entity public class Note { @Id @SequenceGenerator(name="note_generator", sequenceName="note_sequence", initialValue = 5) @GeneratedValue(generator = "note_generator") private long id; private String title; private String body; @ManyToMany private List<Tag> tags; protected Note() {}; public Note(String title, String body) { this.title = title; this.body = body; } public long getId() { return this.id; } public void setId(long id) { this.id = id; } public String getTitle() { return this.title; } public void setTitle(String title) { this.title = title; } public String getBody() { return this.body; } public void setBody(String body) { this.body = body; } public List<Tag> getTags() { return this.tags; } public void setTags(List<Tag> tags) { this.tags = tags; } }
Tag:
/* * Copyright 2012-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.v5ent.demo.domain; import java.util.List; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.SequenceGenerator; @Entity public class Tag { @Id @SequenceGenerator(name="tag_generator", sequenceName="tag_sequence", initialValue = 4) @GeneratedValue(generator = "tag_generator") private long id; private String name; @ManyToMany(mappedBy = "tags") private List<Note> notes; public long getId() { return this.id; } public void setId(long id) { this.id = id; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public List<Note> getNotes() { return this.notes; } public void setNotes(List<Note> notes) { this.notes = notes; } }
這里我們定義了兩個多對多的實體,筆記和標簽。
定義2個實體的Jpa
1.新建包com.v5ent.demo.repository
2.在這個包下新建兩個Jpa類TagRepository和NoteRepository,代碼如下
package com.v5ent.demo.repository; import org.springframework.data.jpa.repository.JpaRepository; import com.v5ent.demo.domain.Tag; /** * Spring Data JPA repository for the Tag entity. */ public interface TagRepository extends JpaRepository<Tag,Long> { }
package com.v5ent.demo.repository; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import com.v5ent.demo.domain.Note; /** * Spring Data JPA repository for the Note entity. */ public interface NoteRepository extends JpaRepository<Note,Long> { }
至此,所有的工作就完成了。
大家可以看一下倉庫類的父類,常用的數據庫訪問操作都默認實現了。
JPA的查詢方法
在JPA中有三種方式可以進行數據的查詢(1,方法命名查詢 2,@NamedQuery查詢 3,@Query查詢),
第一種:方法命名查詢
1. Spring Data JPA支持通過定義在Repository接口的方法來定義查詢,方法名字是根據實體類的屬性名來確定的,示例如下:
/** * Spring Data JPA repository for the Note entity. */ public interface NoteRepository extends JpaRepository<Note,Long> { List<Note> findByBody(String body);
List<Note> findByTitleAndBody(String title,String body);
}
從代碼可以看出,使用findBy這樣的關鍵字,就可以直接實現根據字段查詢。(這里的findBy也可以用find,getBy,query,read代替)而And就相當於sql語句中的and。
/* *查詢符合條件的前十條記錄 */ List<Note> findFirst10ByTitle(String title) /* *查詢符合條件的前30條記錄 */ List<Note> findTop30ByTitle(String title);
第二種:@NamedQuery查詢
Spring Data JPA 支持@NameQuery來定義查詢方法,即一個名稱映射一個查詢語句(要在實體類上寫,不是接口里寫),示例如下:
@Entity @NamedQuery(name="Note.findByTitle", query="select p from Note p where p.title=?1") public class Note{ }
如果要將多個方法都進行重新定義,可以使用@NameQueries標簽,示例如下:
@Entity @NamedQueries({ @NamedQuery(name="Note.findByTitle", query="select p from Note p where p.title=?1"), @NamedQuery(name = "Note.withTitleAndBodyQuery", query = "select p from Note p where p.title=?1 and body=?2") }) public class Note{ }
這個時候,接口里定義的findByName方法就是上面的方法了,不再是方法命名查詢的方法了。
第三種:@Query查詢
Spring Data JPA 支持@Query來定義查詢方法,使用方法是將@Query寫在接口的方法上面,示例如下:
public interface NoteRepository extends JpaRepository<Note, Long> { @Query("select p from Note p where p.title like ?1 ") List<Note> anyQuery(String title); }
這里的參數是根據索引號來進行查詢的。
當然我們也是可以根據名稱來進行匹配,然后進行查詢的,示例如下:
public interface NoteRepository extends JpaRepository<Note, Long> { @Query("select p from Note p where p.title like :title") List<Note> anyQuery(@Param("title")String title); }
如果是模糊匹配呢,這么寫:
@Query("select p from Note p where p.title like %:title%")
List<Note> anyQuery(@Param("title")String title);
我們再來看看更新是如何寫的。
Spring Data JPA支持使用@Modifying和@Query注解組合來進行更新查詢,示例如下:
@Modifying @Transcational @Query("update Note p set p.title=?1 ") int setTitle(String title);
int表示的是更新語句所影響的行數。
來測試看看
1.我們不准使用之前的測試類,我准備直接在啟動的時候測試。首先在DemoApplication中增加如下測試代碼:
@Bean public CommandLineRunner demo(final NoteRepository repository) { return new CommandLineRunner() { @Override public void run(String... args) throws Exception { // save a couple of Notes repository.save(new Note("Have a nice Day", "Don’t let mental blocks control you. Set yourself free. Confront your fear and turn the mental blocks into building blocks.")); repository.save(new Note("x-Notes", "Chloe O'Brian,Kim Bauer")); repository.save(new Note("Some Others", "No news is good news")); // fetch all Notes log.info("Notes found with findAll():"); log.info("-------------------------------"); for (Note note : repository.findAll()) { log.info(note.toString()); } // fetch an individual note by ID Note note = repository.findOne(1L); log.info("Note found with findOne(1L):"); log.info("--------------------------------"); log.info(note.toString()); // fetch Notes by last name log.info("Note found with anyQuery(\"Some\"):"); log.info("--------------------------------------------"); for (Note bauer : repository.anyQuery("Some")) { log.info(bauer.toString()); } } }; }
2.執行main方法跑起來,我們可以看到控制台輸出了我們的操作日志。
2017-05-18 11:48:07.820 INFO 12460 --- [ main] com.v5ent.demo.DemoApplication : Note found with findOne(1L): 2017-05-18 11:48:07.820 INFO 12460 --- [ main] com.v5ent.demo.DemoApplication : -------------------------------- 2017-05-18 11:48:07.820 INFO 12460 --- [ main] com.v5ent.demo.DemoApplication : com.v5ent.demo.domain.Note@7893c715 2017-05-18 11:48:07.820 INFO 12460 --- [ main] com.v5ent.demo.DemoApplication : Note found with anyQuery("Some"): 2017-05-18 11:48:07.820 INFO 12460 --- [ main] com.v5ent.demo.DemoApplication : --------------------------------------------
補充
不得不提,在此基礎上,實現Rest化API很簡單。下面來展開實驗:
在當前的情況下,我們看一下mvc方面的日志:
2017-05-18 12:13:45.980 INFO 12664 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello]}" onto public java.lang.String com.v5ent.demo.web.HelloController.index() 2017-05-18 12:13:45.985 INFO 12664 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2017-05-18 12:13:45.985 INFO 12664 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2017-05-18 12:13:46.024 INFO 12664 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-05-18 12:13:46.024 INFO 12664 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-05-18 12:13:46.078 INFO 12664 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-05-18 12:13:46.354 INFO 12664 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-05-18 12:13:46.421 INFO 12664 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http)
可以看到/hello這個我們之前實現的controller,如果我們要實現note和tag的對外api,當然也要自己寫controller。但是Sring就是專門把這些固定的做法實現的機構,所以Spring已經封裝了rest風格api所需要的controller實現。
簡單來講,我們只需要在pom文件中增加:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency>
ok,現在啟動看看日志:
2017-05-18 12:55:36.876 INFO 7124 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@72a7c7e0: startup date [Thu May 18 12:55:30 CST 2017]; root of context hierarchy 2017-05-18 12:55:36.954 INFO 7124 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello]}" onto public java.lang.String com.v5ent.demo.web.HelloController.index() 2017-05-18 12:55:36.958 INFO 7124 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest) 2017-05-18 12:55:36.959 INFO 7124 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 2017-05-18 12:55:36.994 INFO 7124 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-05-18 12:55:36.995 INFO 7124 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-05-18 12:55:37.010 INFO 7124 --- [ main] .m.m.a.ExceptionHandlerExceptionResolver : Detected @ExceptionHandler methods in repositoryRestExceptionHandler 2017-05-18 12:55:37.102 INFO 7124 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler] 2017-05-18 12:55:37.262 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@72a7c7e0: startup date [Thu May 18 12:55:30 CST 2017]; root of context hierarchy 2017-05-18 12:55:37.275 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/ || ],methods=[OPTIONS],produces=[application/hal+json || application/json]}" onto public org.springframework.http.HttpEntity<?> org.springframework.data.rest.webmvc.RepositoryController.optionsForRepositories() 2017-05-18 12:55:37.276 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/ || ],methods=[HEAD],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositoryController.headForRepositories() 2017-05-18 12:55:37.277 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/ || ],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.http.HttpEntity<org.springframework.data.rest.webmvc.RepositoryLinksResource> org.springframework.data.rest.webmvc.RepositoryController.listRepositories() 2017-05-18 12:55:37.280 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}],methods=[DELETE],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositoryEntityController.deleteItemResource(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,org.springframework.data.rest.webmvc.support.ETag) throws org.springframework.data.rest.webmvc.ResourceNotFoundException,org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.280 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}],methods=[PATCH],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryEntityController.patchItemResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.PersistentEntityResource,java.io.Serializable,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,org.springframework.data.rest.webmvc.support.ETag,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException,org.springframework.data.rest.webmvc.ResourceNotFoundException 2017-05-18 12:55:37.280 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositoryEntityController.optionsForCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.281 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}],methods=[HEAD],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositoryEntityController.headCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.support.DefaultedPageable) throws org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.281 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.hateoas.Resources<?> org.springframework.data.rest.webmvc.RepositoryEntityController.getCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.support.DefaultedPageable,org.springframework.data.domain.Sort,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) throws org.springframework.data.rest.webmvc.ResourceNotFoundException,org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.281 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}" onto public org.springframework.hateoas.Resources<?> org.springframework.data.rest.webmvc.RepositoryEntityController.getCollectionResourceCompact(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.support.DefaultedPageable,org.springframework.data.domain.Sort,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) throws org.springframework.data.rest.webmvc.ResourceNotFoundException,org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.281 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}],methods=[POST],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.PersistentEntityResource,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.282 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositoryEntityController.optionsForItemResource(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.282 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}],methods=[HEAD],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositoryEntityController.headForItemResource(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) throws org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.282 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.Resource<?>> org.springframework.data.rest.webmvc.RepositoryEntityController.getItemResource(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,org.springframework.http.HttpHeaders) throws org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.283 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}],methods=[PUT],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<? extends org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryEntityController.putItemResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.PersistentEntityResource,java.io.Serializable,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,org.springframework.data.rest.webmvc.support.ETag,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException 2017-05-18 12:55:37.285 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}/{property}],methods=[DELETE],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<? extends org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.deletePropertyReference(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,java.lang.String) throws java.lang.Exception 2017-05-18 12:55:37.286 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}/{property}],methods=[GET],produces=[application/x-spring-data-compact+json || text/uri-list]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.followPropertyReferenceCompact(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,java.lang.String,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) throws java.lang.Exception 2017-05-18 12:55:37.286 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}/{property}],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.followPropertyReference(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,java.lang.String,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) throws java.lang.Exception 2017-05-18 12:55:37.286 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}/{property}/{propertyId}],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.followPropertyReference(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,java.lang.String,java.lang.String,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) throws java.lang.Exception 2017-05-18 12:55:37.286 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}/{property}/{propertyId}],methods=[DELETE],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.deletePropertyReferenceId(org.springframework.data.rest.webmvc.RootResourceInformation,java.io.Serializable,java.lang.String,java.lang.String) throws java.lang.Exception 2017-05-18 12:55:37.287 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/{id}/{property}],methods=[PATCH || PUT || POST],consumes=[application/json || application/x-spring-data-compact+json || text/uri-list],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<? extends org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController.createPropertyReference(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.http.HttpMethod,org.springframework.hateoas.Resources<java.lang.Object>,java.io.Serializable,java.lang.String) throws java.lang.Exception 2017-05-18 12:55:37.288 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.data.rest.webmvc.RepositorySearchesResource org.springframework.data.rest.webmvc.RepositorySearchController.listSearches(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.288 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search/{search}],methods=[HEAD],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.data.rest.webmvc.RepositorySearchController.headForSearch(org.springframework.data.rest.webmvc.RootResourceInformation,java.lang.String) 2017-05-18 12:55:37.289 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search/{search}],methods=[GET],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<?> org.springframework.data.rest.webmvc.RepositorySearchController.executeSearch(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.util.MultiValueMap<java.lang.String, java.lang.Object>,java.lang.String,org.springframework.data.rest.webmvc.support.DefaultedPageable,org.springframework.data.domain.Sort,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,org.springframework.http.HttpHeaders) 2017-05-18 12:55:37.289 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search],methods=[HEAD],produces=[application/hal+json || application/json]}" onto public org.springframework.http.HttpEntity<?> org.springframework.data.rest.webmvc.RepositorySearchController.headForSearches(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.290 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search/{search}],methods=[OPTIONS],produces=[application/hal+json || application/json]}" onto public org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.data.rest.webmvc.RepositorySearchController.optionsForSearch(org.springframework.data.rest.webmvc.RootResourceInformation,java.lang.String) 2017-05-18 12:55:37.291 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search/{search}],methods=[GET],produces=[application/x-spring-data-compact+json]}" onto public org.springframework.hateoas.ResourceSupport org.springframework.data.rest.webmvc.RepositorySearchController.executeSearchCompact(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.http.HttpHeaders,org.springframework.util.MultiValueMap<java.lang.String, java.lang.Object>,java.lang.String,java.lang.String,org.springframework.data.rest.webmvc.support.DefaultedPageable,org.springframework.data.domain.Sort,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler) 2017-05-18 12:55:37.291 INFO 7124 --- [ main] o.s.d.r.w.RepositoryRestHandlerMapping : Mapped "{[/{repository}/search],methods=[OPTIONS],produces=[application/hal+json || application/json]}" onto public org.springframework.http.HttpEntity<?> org.springframework.data.rest.webmvc.RepositorySearchController.optionsForSearches(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.294 INFO 7124 --- [ main] o.s.d.r.w.BasePathAwareHandlerMapping : Mapped "{[/profile],methods=[GET]}" onto org.springframework.http.HttpEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.ProfileController.listAllFormsOfMetadata() 2017-05-18 12:55:37.295 INFO 7124 --- [ main] o.s.d.r.w.BasePathAwareHandlerMapping : Mapped "{[/profile],methods=[OPTIONS]}" onto public org.springframework.http.HttpEntity<?> org.springframework.data.rest.webmvc.ProfileController.profileOptions() 2017-05-18 12:55:37.295 INFO 7124 --- [ main] o.s.d.r.w.BasePathAwareHandlerMapping : Mapped "{[/profile/{repository}],methods=[GET],produces=[application/alps+json || */*]}" onto org.springframework.http.HttpEntity<org.springframework.data.rest.webmvc.RootResourceInformation> org.springframework.data.rest.webmvc.alps.AlpsController.descriptor(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.295 INFO 7124 --- [ main] o.s.d.r.w.BasePathAwareHandlerMapping : Mapped "{[/profile/{repository}],methods=[OPTIONS],produces=[application/alps+json]}" onto org.springframework.http.HttpEntity<?> org.springframework.data.rest.webmvc.alps.AlpsController.alpsOptions() 2017-05-18 12:55:37.296 INFO 7124 --- [ main] o.s.d.r.w.BasePathAwareHandlerMapping : Mapped "{[/profile/{repository}],methods=[GET],produces=[application/schema+json]}" onto public org.springframework.http.HttpEntity<org.springframework.data.rest.webmvc.json.JsonSchema> org.springframework.data.rest.webmvc.RepositorySchemaController.schema(org.springframework.data.rest.webmvc.RootResourceInformation) 2017-05-18 12:55:37.465 INFO 7124 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-05-18 12:55:37.602 INFO 7124 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8000 (http)
發現多了很多rest api的映射,這表示成功了。
訪問http://localhost:8000/notes/1,可以看到rest api已經直接可用了。hal+json 的格式,如果有疑問可留言。
