Spring-boot官方案例分析之data-jpa


package sample.data.jpa;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
 * Integration test to run the
application.
 *
 * @author Oliver
Gierke
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
@WebAppConfiguration
@ActiveProfiles("scratch")
// Separate profile for web tests to avoid clashing databases
public class SampleDataJpaApplicationTests {

@Autowired
   private WebApplicationContext
context;

private MockMvc mvc;

@Before
   public void setUp() {
      this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
   }

@Test
   public void testHome() throws Exception
{

this.mvc.perform(get("/")).andExpect(status().isOk())
            .andExpect(content().string("Bath"));
   }
}

  1. 首先测试类中选择了要使用的配置文件

@ActiveProfiles(“scratch”)

对应的properties为application-scratch.properties

内容为:

spring.datasource.url: jdbc:hsqldb:mem:scratchdb

定义了数据源的url;

@Autowired
private WebApplicationContext context;

注入应用上下文context;

定义MockMvc,然后@Before注解执行初始化容器

@Before
public void setUp() {
  
   this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}

然后模拟发送请求测试:

类图关系:

根据这个测试用例来走一遍请求处理过程:

this.mvc.perform(get("/")).andExpect(status().isOk())
      .andExpect(content().string("Bath"));

get请求处理:到SampleController

@Autowired
   private CityService cityService;    @RequestMapping("/")
   @ResponseBody
   @Transactional(readOnly = true)
   public String helloWorld() {
      return this.cityService.getCity("Bath", "UK").getName();
   }
}

注入了CityService组件属性,事务类型为只读。

然后执行服务组件CityService中的getCity()方法;

并且传入参数name=”Bath”,country=”UK”,然后调用getname方法获取name值。

public interface CityService {

   Page<City> findCities(CitySearchCriteria criteria, Pageable pageable);

   City getCity(String name, String country);

   Page<HotelSummary> getHotels(City city, Pageable pageable);

}

该接口中定义了查询方法;

把返回值存在Page对象中

在实现类中,标记为组件并设置id=cityService;这样程序执行会找到impl类;

@Component("cityService")
@Transactional
class CityServiceImpl implements CityService {    private final CityRepository cityRepository;    private final HotelRepository hotelRepository;    @Autowired
   public CityServiceImpl(CityRepository cityRepository, HotelRepository hotelRepository) {
      this.cityRepository = cityRepository;
      this.hotelRepository = hotelRepository;
   }    @Override
   public Page<City> findCities(CitySearchCriteria criteria, Pageable pageable) {       Assert.notNull(criteria, "Criteria must not be null");
      String name = criteria.getName();       if (!StringUtils.hasLength(name)) {
         return this.cityRepository.findAll(null);
      }       String country = "";
      int splitPos = name.lastIndexOf(",");       if (splitPos >= 0) {
         country = name.substring(splitPos + 1);
         name = name.substring(0, splitPos);
      }       return this.cityRepository
            .findByNameContainingAndCountryContainingAllIgnoringCase(name.trim(),
                  country.trim(), pageable);
   }    @Override
   public City getCity(String name, String country) {
      Assert.notNull(name, "Name must not be null");
      Assert.notNull(country, "Country must not be null");
      return this.cityRepository.findByNameAndCountryAllIgnoringCase(name, country);
   }    @Override
   public Page<HotelSummary> getHotels(City city, Pageable pageable) {
      Assert.notNull(city, "City must not be null");
      return this.hotelRepository.findByCity(city, pageable);
   }
}
由于执行的是事务操作所以要加上@Transactional

通过构造函数注入其他组件;

@Override
public City getCity(String name, String country) {
   Assert.notNull(name, "Name must not be null");
   Assert.notNull(country, "Country must not be null");
   return this.cityRepository.findByNameAndCountryAllIgnoringCase(name, country);
}

在该方法中进行断言判断是否为空,然后执行Dao查询;在jpa中会通过不同的关键字在接口中定义方法名来映射为sql查询语句,上面方法相当于select * from city c where name=”bath”  返回的是一个city对象,前提是name值唯一确定。

Spring-boot官方案例分析之data-jpa的更多相关文章

  1. 精尽Spring Boot源码分析 - Jar 包的启动实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  2. 精尽Spring Boot源码分析 - 剖析 @SpringBootApplication 注解

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  3. 精尽Spring Boot源码分析 - Condition 接口的扩展

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  4. Spring Boot 入门详细分析

    推荐阅读: 我们为什么要学习 Spring Boot 我们搭建 Spring Boot 项目,可以使用 Spring 为我们提供的初始化网站,那个可能不太方便,今天呢,我们就来说说如何使用 IDEA ...

  5. Spring-boot官方案例分析之log4j

    Spring-boot官方案例分析之log4j 运行单元测试分析: @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfigur ...

  6. Spring Boot源码分析-配置文件加载原理

    在Spring Boot源码分析-启动过程中我们进行了启动源码的分析,大致了解了整个Spring Boot的启动过程,具体细节这里不再赘述,感兴趣的同学可以自行阅读.今天让我们继续阅读源码,了解配置文 ...

  7. Spring Boot源码分析-启动过程

    Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...

  8. 精尽Spring Boot源码分析 - 序言

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  9. 精尽Spring Boot源码分析 - 文章导读

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

随机推荐

  1. jQuery获取table表中的td标签

    首先我来介绍一下我遇到的问题 1.当有一个table表包含了<tr>标签,<td>标签,大致可以认为是这样的: <tr> <td> @scene.ID ...

  2. 1、v1 与 v2的比较

    1.路由的迁移 /* --- v1 ----*/ .config(function($stateProvider){ $stateProvider .state('main', { url: '/', ...

  3. ssh整合(spring + struts2 + hibernate)xml版

    1.1分层 1.2jar节点 <dependencies> <dependency> <groupId>junit</groupId> <arti ...

  4. Python进阶篇四:Python文件和流

    摘要: Python对于文件和流的操作与其他编程语言基本差不多,甚至语句上比其他语言更为简洁.文件和流函数针对的对象除了这两者之外还有,类文件(file-like),即python中只支持读却不支持写 ...

  5. VC++中对数据类型的限制limits.h文件内容

    limits.h文件中规定了是IDE在OS中规定了每个数据类型的最大值和最小值以及在程序源代码中编译时候所占用的字节数,这这样做有利于帮助程序员在编写程序的时候有效控制在选择合适数据类型的显示范围值. ...

  6. windows RT开发笔记:WinRT DLL及其调用研究

    一. 几个概念: WinRT : Windows Runtime, windows运行时.创建Windows运行时(WinRT)是为了在Windows上给用户提供一种流畅且安全的应用体验.WinRT会 ...

  7. Java—集合框架List

    集合的概念 现实生活中:很多的事物凑在一起 数学中的集合:具有共同属性的事物的总和 Java中的集合类:是一种工具类,就像是容器,存储任意数量的具有共同属性的对象 集合的作用 在类的内部,对数据进行组 ...

  8. BIEE入门(三)业务模型层

    正如它的名字所示(Business Model and Mapping Layer),业务逻辑层需要把物理层的数据源以一种业务用户的视角来重新组织物理层的各个数据源(所谓的Mapping),同时在业务 ...

  9. 【NLP_Stanford课堂】正则表达式

    或者 [Ww]oods,方括号里的是或的关系,符合其一即被提出.用来匹配单个字符 [A-Z]:表示所有的大写字母之一 [a-z]:表示所有的小写字母之一 [0-9]:表示所有的0-9的数字之一 否定: ...

  10. JUnit报错:java.lang.ClassNotFoundException: com.mogodb.test.test

    最近在使用JUnit做单元测试时,发现新写好的测试类运行总是出错,报找不到类异常. Class not found com.mogodb.test.test java.lang.ClassNotFou ...