1 数据访问
1.1 SQL
1.1.1 数据源自动配置
首先在pom中导入场景依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
该场景会自动引入数据源、jdbc、事务
接着需要根据业务需求导入对应的驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
版本由spring-boot-starter-parent决定
需要注意使用的数据库版本和驱动版本对应
同样SpringBoot对jdbc场景做了默认配置 可以在spring-boot-autoconfigure中找到名为jdbc的包 常用的一些功能,在这里都有默认配置,如:
DataSourceAutoConfiguration: 数据源自动配置,默认使用Hikar
DataSourceTransactionManagerAutoConfiguration: 事务管理器自动配置
JdbcTemplateAutoConfiguration: jdbcTemplate自动配置 可以crud
...
在DataSourceAutoConfiguration中,配置如数据库连接池 如果自己没有配置DataSource和XADataSource,就会使用默认的数据库连接池 再观察DataSourceAutoConfiguration类上的注解 其中最重要的是@EnableConfigurationProperties注解 标明了自定义配置对应DataSourceProperties类 DataSourceProperties类带有注解@ConfigurationProperties标明prefix属性 即可以在properties文件或yaml文件中通过spring.datasource属性来配置数据源一些属性
1.1.2 使用Druid数据源
对于数据源,spring-boot-starter-data-jdbc默认使用Hikar作为数据源 Hikar有着高效的性能,但是国内开发大都采用阿里的Druid Druid提供了一整套数据源的解决方案 在SpringBoot中想要使用Druid,有两种方式
一是在容器中创建Druid的Bean,有了自定义的DataSource,容器中就不会创建Hikar数据源
导入依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.7</version>
</dependency>
数据源配置:
@Configuration(proxyBeanMethods = true)
public class MyDataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
}
yaml配置:
spring:
datasource:
url: jdbc:mysql://localhost:3306/db_books
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
另一是使用专用的starter
引入druid-strater:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
druid扩展配置也可以由spring.datasource绑定
spring:
datasource:
url: jdbc:mysql://localhost:3306/db_books
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
druid:
filters: stat,wall
# 配置druid的监控页面功能
stat-view-servlet:
enabled: true
login-username: root
login-password: 123456
reset-enable: false
# web监控配置
web-stat-filter:
enabled: true
url-pattern:
1.1.3 整合Mybatis
开发中常用Mybatis而不是JdbcTemplate,需要整合到SpringBoot中 首先需要导入对应的starter
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
在starter导入的mybatis-spring-boot-autoconfigure中的MybatisAutoConfiguration类上 @EnableConfigurationProperties注解对应的绑定了MybatisProperties类 为此可以在yaml中以mybatis开头来进行配置 采用注解来在SpringBoot中使用Mybatis: 1,首先创建DTO实例和对应的Mapper接口
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Account {
private Long id;
private String userId;
private Integer money;
}
@Mapper
public interface AccountMapper {
@Select("SELECT * FROM account WHERE id=#{id}")
public Account getAccountById(Long id);
@Insert("INSERT INTO account('id', 'userId', 'money') values(#{id}, #{userId}, #{money})")
@Options(useGeneratedKeys = true, keyProperty = "id")
public void insertAccount(Account account);
}
2,创建Service,并在Controller层调用
@Service
public class AccountService {
@Autowired
AccountMapper accountMapper;
public Account getAccountById(Long id) {
return accountMapper.getAccountById(id);
}
}
@Controller
public class AccountController {
@Autowired
AccountMapper accountMapper;
@GetMapping("/account")
@ResponseBody
public Account getAccountById(@RequestParam(value = "id") Long id) {
return accountMapper.getAccountById(id);
}
}
在Mybatis的基础上,还可以使用增强的Mybatis-Plus Mybatis-Plus提供了简单的CRUD功能
1,pom中引入mybatis-plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
2,创建DTO和对应的Mapper
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Account {
private Long id;
private String userId;
private Integer money;
}
@Mapper
public interface AccMapper extends BaseMapper<Account> {
}
继承的BaseMapper提供了对<T>的CRUD功能
会在DB中找到对应的名为T的表
3,创建Service接口并实现且在Controller层调用
操作account表的接口:
public interface AccService extends IService<Account> {
}
接口实现:
@Service
public class AccServiceImpl extends ServiceImpl<AccMapper, Account> implements AccService {
}
在Controller层调用:
@Controller
public class AccController {
@Autowired
AccService accService;
@GetMapping("/acc")
@ResponseBody
public Account getAccountById(@RequestParam(value = "id") Long id) {
return accService.getById(id);
}
}
1.2 NoSQL
1.2.1 SpringBoot整合Redis
首先在pom中导入redis的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
官方提供的starter的自动配置都在spring-boot-autoconfigure中 Redis的自动配置项绑定的前缀是spring.redis,可以在yaml中自行修改配置 并准备好了连接工厂,自动导入了Lettuce客户端和Jedis客户端 且自动注入了RedisTemplate<Object,Object>和StringRedisTemplate<String, String>
在yaml中配置redis相关:
spring:
redis:
url: redis://coisini:123456@:r-bp1mcreqpidxx.redis.rds.aliyuncs.com:6379
ssl: true
1.2.2 配置操作Redis
完成必要配置后,使用StringRedisTemplate操作Redis中的KV进行测试:
@SpringBootTest
public class TemplateTest {
@Autowired
StringRedisTemplate stringRedisTemplate;
@Test
void testRedis() {
ValueOperations<String, String> stringStringValueOperations = stringRedisTemplate.opsForValue();
stringStringValueOperations.set("hello", "world");
String val1 = stringStringValueOperations.get("hello");
}
}
上述操作使用的是StringRedisTemplate,也可以采用其他客户端操作,如Jedis和Lettuce 如想要切换到Jedis,在pom中导入Jedis依赖且在yaml中声明使用Jedis客户端即可
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
无需声明版本,starter中完成了版本控制
如想要使用Lettuce客户端,只需在client-type中修改即可
同时可以修改一些特性
spring:
redis:
url: redis://coisini:123456@:r-bp1mcreqpidxx.redis.rds.aliyuncs.com:6379
client-type: jedis
jedis:
pool:
max-active: 10
min-idle: 5
2 单元测试
2.1 Junit5简介
SpringBoot2.2.0开始引入Junit5作为单元测试默认库 Junit5和之前版本的Junit框架有很大不同,由三个不同子项目的几个不同模块组成 Junit5 = Junit Platform + Junit Jupiter + Junit Vintage
Junit Platform: 是在JVM上启动测试框架的基础,支持Junit自制的测试引擎,也可以接入其他引擎
JUnit Jupiter: Junit Jupiter提供Junit5新的编程模型,是JUnit5新特性的核心
内部包含了一个测试引擎,用于在Junit Platform上运行
Junit Vintage: 为了兼容老项目,Junit vintage提供了兼容Junit4和Junit3的测试引擎
新版本SpringBoot使用Junit5也非常简单,只需要在pom中导入test-starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
在测试类上使用@SpringBootTest,并在测试方法上加@Test即可 同时也可以提供@Transactional功能,结束完测试后自动回滚,保持数据一致性
2.2 Junit5常用注解
@Test: 表示方法是测试方法
@ParameterizedTest: 表示方法是参数化测试
@RepeatedTest: 表示方法可重复执行
@DisplayName: 为测试类或测试方法设置展示名称
@BeforeEach: 表示在每个单元测试之前执行
@AfterEach: 表示在每个单元测试后执行
@BeforeAll: 表示在所有单元测试之前执行
@AfterAll: 表示在所有单元测试之后执行
@Tag: 表示单元测试类别
@Disabled: 表示测试类或测试方法不执行
@Timeout: 表示测试方法运行如果超过指定时间会报错
@ExtendWith: 为测试类或测试方法提供扩展类引用
测试@DisplayName: 测试@BeforeEach和@AfterEach: 测试@BeforeAll和@AfterAll,使用这两个注解的方法必须是静态方法:
2.3 断言
断言(Assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证 这些断言方法都是org.junit.jupiter.api.Assertions的静态方法 用来检查业务逻辑返回的数据是否合理,所有测试结束后,会有一个详细报告 同一个方法内前面的断言失败则后续代码不执行
简单断言方法:
assertEquals: 判断两个对象或两个原始类型是否相等
assertNotEquals: 判断两个对象或两个原始类型是否不相等
assertSame: 判断两个对象引用是否指向同一个对象
assertNotSame: 判断两个对象引用是否指向不同对象
assertTrue: 判断得到的布尔值是否为真
assertFalse: 判断得到的布尔值是否为假
assertNull: 判断给定的对象引用是否为null
assertNotNull: 判断给定的对象引用是不是null
简单断言使用: 断言机制还提供组合断言,即通过assertAll判断所有断言 通过Lambda表达式写出多条断言,全部成功则断言成功,有一个失败此断言失败: 还有异常断言,断定业务逻辑会出现某种异常,如果出现则通过,未出现断言失败: 还可以通过fail方法快速失败,即遇到某种条件时终止测试
@Test
void testAssert() {
if(cal(2, 3) != 5) {
Assertions.fail("cal方法有误");
}
}
2.4 前置条件
JUnit5中的前置条件Assumptions类似断言,但不同之处在于 不满足断言会使得测试方法失败,而不满足前置条件会使得测试方法执行终止 前置条件可以看做执行测试方法的前提,当前提不满足就没必要继续执行
2.5 参数化测试
参数化测试是JUnit5的一个新特性,它使得用不同的参数多次运行测试成为可能 利用@ValueSource等注解,指定入参,可以使用不同参数进行多次单元测试 而不需要每新增一个参数就新增一个单元测试,省去了很多冗余代码
@ValueSource: 为参数化测试指定入参来源,支持八大基础类型以及String、Class类型
@NullSource: 为参数化测试提供一个null作为入参
@EnumSource: 为参数化测试提供一个枚举的入参
@CsvFileSource: 表示读取Csv文件内容作为参数化测试入参
@MethodSource: 表示读取方法的返回值作为参数化测试入参
参数化测试使用: 使用某个方法的返回值作为入参,提供参数的方法必须是静态的且返回Stream:
|