在启动测试环境时可以通过properties参数设置测试环境专用的属性
@SpringBootTest(poperties = {"test.prop=testValue1"})
public class PropertiesAndArgsTest {@Value("${test.prop}")private String msg;@Testvoid testProperties(){System.out.println(msg);}
}
在启动测试环境时可以通过args参数设置测试环境专用的传入参数
@SpringBootTest(args = {"--test.prop=testValue2"})
public class PropertiesAndArgsTest {@Value("${test.arg}")private String msg;@Testvoid testProperties(){System.out.println(msg);}
}
使用@Import注解加载当前测试类专用的配置
@Configuration
public class MsgConig {@Beanpublic String msg() {return "bean msg";}
}
@SpringBootTest
@Import(MsgConfig.class)
public class ConfigurationTest {@Autowiredprivate String msg;@Testvoid testConfiguration(){System.out.println(msg);}
}
总结:
加载测试范围配置应用于小范围测试环境
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
public class WebTest {@Testvoid testRandomPort () {}
}
@RestController
@RequestMapping("/books")
public class BookController {@GetMappingpublic String getById(){System.out.println("getById is running......");return "springboot";}
}
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {@Test//注入虚拟MVC调用对象void testRandomPort (@Autowired MockMvc mvc) throws Exception {//创建虚拟请求,当前访问/booksMockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");//执行请求mvc.perform(builder);}
}
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {@Test//注入虚拟MVC调用对象void testRandomPort (@Autowired MockMvc mvc) throws Exception {//创建虚拟请求,当前访问/booksMockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");//执行请求ResultActions action = mvc.perform(builder);//匹配执行状态(是否预期值)//定义执行状态匹配器StatusResultMatchers status = MockMvcResultMatchers.status();//定义预期执行状态ResultMatcher ok = status.isOk();//使用本次真实执行结果与预期结果进行对比action.andExpect(ok);}
}
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {@Test//注入虚拟MVC调用对象void testRandomPort (@Autowired MockMvc mvc) throws Exception {//创建虚拟请求,当前访问/booksMockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");//执行请求ResultActions action = mvc.perform(builder);//匹配执行结果(是否预期值)//定义执行结果匹配器ContentResultMatchers content = MockMvcResultMatchers.content();//定义预期执行结果ResultMatcher result = content.string("springboot");//使用本次真实执行结果与预期结果进行对比action.andExpect(ok);}
}
虚拟请求体(json)匹配
@Data
public class Book {private int id;private String name;private String type;private String description;
}
@RestController
@RequestMapping("/books")
public class BookController {@GetMappingpublic String getById(){System.out.println("getById is running......");Book book = new Book();book.setId(1);book.setName("springboot");book.setType("springboot");book.setDescription("springboot");return book;}
}
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {@Test//注入虚拟MVC调用对象void testRandomPort (@Autowired MockMvc mvc) throws Exception {//创建虚拟请求,当前访问/booksMockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");//执行请求ResultActions action = mvc.perform(builder);//匹配执行结果(是否预期值)//定义执行结果匹配器ContentResultMatchers content = MockMvcResultMatchers.content();//定义预期执行结果ResultMatcher result = content.json("{\"id\":1,\"name\":\"SpringBoot2\"}");//使用本次真实执行结果与预期结果进行对比action.andExpect(ok);}
}
虚拟请求头匹配
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {@Test//注入虚拟MVC调用对象void testRandomPort (@Autowired MockMvc mvc) throws Exception {//创建虚拟请求,当前访问/booksMockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");//执行请求ResultActions action = mvc.perform(builder);//匹配执行结果(是否预期值)//定义执行结果匹配器HeaderResultMatchers content = MockMvcResultMatchers.header();//定义预期执行结果ResultMatcher result = content.string("Content-Type","application/json");//使用本次真实执行结果与预期结果进行对比action.andExpect(ok);}
}
总结:
web环境模拟测试
为测试用例添加事务,SpringBoot会对测试用例对应的事务操作进行回滚
@SpringBootTest
@Transactional
public class DaoTest {@Autowiredprivate BookService bookService;
}
如果想在测试用例中提交事务,可以通过@Rollback注解设置
@SpringBootTest
@Transactional
@Rollback(false)
public class DaoTest {
}
总结:
测试用例回滚事务
测试用例数据通常采用随机值进行测试,使用SpringBoot提供的随机数为其赋值
testcase:book:id: ${random.int} #随机数id2: ${random.int(10)} #10以内随机数type: ${random.int(10,20)} #10到20随机数uuid: ${random.uuid} #随机uuidname: ${random.value} #随机字符串,MD5字符串,32位publishTime: ${random.long} #随机整数(Long范围)
现有数据层解决方案技术选型
Druid + MyBatis-Plus + MySQL
格式一:
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTCusername: rootpassword: roottype: com.alibaba.druid.pool.DruidDataSource
格式二:
spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTCusername: rootpassword: root
SpringBoot提供了3种内嵌的数据源对象供开发者选择
spring:datasource:url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTChikari:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: root
注意:这个url跟hikari是同一级别
内置持久化解决方案-JdbcTemplate
@SpringBootTest
class SpringbootSSqlApplicationTest {@Autowiredprivate JdbcTemplate jdbcTemplate;@Testvoid testJdbc(){String sql = "select * from tbl_book where id = 1";List query = jdbcTemplate.query(sql, new RowMapper() {@Overridepublic Book mapRow(ResultSet rs,int rowNum) throws SQLException {Book temp = new Book();temp.setId(rs.getInt("id");temp.setName(rs.getString("name");temp.setType(rs.getString("type");temp.setDescription(rs.getString("description"));return temp;}});System.out.println(query);}
}
使用JdbcTemplate得引入依赖:
org.springframework.book spring-boot-starter-jdbc
JdbcTemplate配置:
spring:jdbc:template:query-timeout: -1 # 查询超时时间max-rows: 500 # 最大行数fetch-size: -1 # 批处理数量
总结:
1.SpringBoot内置JdbcTemplate持久化解决方案
2.使用JdbcTemplate需要导入spring-boot-starter-jdbc
SpringBoot提供了3种内嵌数据库供开发者选择,提高开发测试效率
设置当前项目为web工程,并配置H2管理控制台参数
server:port: 80
spring: datasource:url: jdbc:h2:~/testhikari:driver-class-name: org.h2.Driverusername: sapassword: 123456h2:console:path: /2enabled: true
访问用户名sa,默认密码123456
浏览器,打开地址 localhost/h2 即可在浏览器中看h2数据库
操作数据库(创建表)
create table tbl_book(id int,name varchar,type varchar,description varchar)
H2数据库控制台仅用于开发阶段,线上项目请务必关闭控制台功能
server:port: 80
spring:h2:console:path: /h2enabled: false
总结:
现有数据层解决方案技术选型
Druid + MyBatis-Plus + MySQL
数据源 | 持久化 | 数据库 |
---|---|---|
Druid | MyBatis-Plus | MySQL |
HiKari | MyBatis | H2 |
JdbcTemplate |
SQL
NoSQL
市面上常见的NoSQL解决方案
Redis是一款key-value存储结构的内存级NoSQL数据库
Redis下载(Windows版)
Redis安装与启动(Windows版)
redis-server.exe redis.windows.conf
redis-cli.exe
总结:
1.Redis安装(Windows版)
2.Redis基本操作
1.导入SpringBoot整合Redis坐标
org.springframework.boot spring-boot-starter-data-redis
2.配置Redis坐标(采用默认配置)
spring:redis:host: localhost # 127.0.0.1port: 6379
3.RedisTemplate提供操纵各种数据存储类型的接口API
4.客户端: RedisTemplate
@SpringBootTest
class SpringbootNosqlApplicationTests {@Testvoid set(@Autowired RedisTemplate redisTemplate) {ValueOperations ops = redisTemplate.opsForValue();ops.set("testKey","testValue");}@Testvoid set(@Autowired RedisTemplate redisTemplate) {ValueOperations ops = redisTemplate.opsForValue();Object val = ops.get("testKey");System.out.println(val);}
}
@SpringBootTest
class SpringbootNosqlApplicationTests {@Testvoid set(@Autowired RedisTemplate redisTemplate) {HashOperations ops = redisTemplate.opsForHash();opsH.set("testKeyH","testFieldH","testValueH");}@Testvoid set(@Autowired RedisTemplate redisTemplate) {HashOperations opsH = redisTemplate.opsForHash();Object valH = opsH.get("testKeyH","testFieldH");System.out.println(valH);}
}
总结:
SpringBoot整合Redis
客户端: RedisTemplate以对象作为key和value,内部对数据进行序列化
@SpringBootTest
class SpringbootNosqlApplicationTests {@Testvoid set(@Autowired RedisTemplate redisTemplate) {ValueOperations ops = redisTemplate.opsForValue();ops.set("testKey","testValue");}@Testvoid set(@Autowired RedisTemplate redisTemplate) {ValueOperations ops = redisTemplate.opsForValue();Object val = ops.get("testKey");System.out.println(val);}
}
客户端:StringRediTemplate以字符串作为key和value,与Redis客户端操作等效
@SpringBootTest
class SpringbootNosqlApplicationTests {@Testvoid set(@Autowired StringRedisTemplate redisTemplate) {ValueOperations ops = redisTemplate.opsForValue();ops.set("testKey","testValue");}@Testvoid set(@Autowired StringRedisTemplate redisTemplate) {ValueOperations ops = redisTemplate.opsForValue();Object val = ops.get("testKey");System.out.println(val);}
}
总结:
1.RedisTemplate
2.StringRedisTemplate(常用)
SpringBoot操作Redis客户端实现技术切换(jedis)
客户端选择:jedis
redis.clients jedis
配置客户端
spring:redis:host: localhost # 127.0.0.1port: 6379clent-type: lettuce
用jedis, clent-type就指定jedis,用lettuce,客户端类型就指定lettuce(也可不指定,默认就是lettuce)
配置客户端专用属性
spring:redis:host: localhost # 127.0.0.1port: 6379clent-type: lettucelettuce:pool:max-active: 16jedis:pool:max-active: 16
lettcus与jedis区别
总结:
SpringBoot整合Redis客户端选择
MongoDB是一个开源、高性能、无模式的文档型数据库。NoSQL数据库产品中的一种,是最像关系型数据库的非关系型数据库
应用场景:
淘宝用户数据
游戏装备数据、游戏道具数据
直播数据、打赏数据、粉丝数据
物联网数据
总结:
Mongodb应用场景
Windows版Mongo下载
Window版Mongo安装
Windows版Mongo启动
- 服务端启动
mongod --dbpath=//\data\db
- 客户端启动
mongo -- host=12.0.0.1 --port=2701
Windows版Mongo安装问题及解决方案
由于找不到VCRUNTIMEE140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题。
步骤一: 下载对应的dll文件(通过互联网搜索即可)
步骤二: 拷贝到windows安装路径下的system32目录中
步骤三: 执行命令注册对应dll文件
regsve32 vcruntime140_1.dll
总结:
新增
db.集合名称.insert/sava/insertOne(文档)
修改
db.集合名称.remove(条件)
删除
db.集合名称.update(条件,{操作种类:{文件}})
1.基础查询
2.条件查询
总结:
Mongodb基础CRUD
导入Mongodb驱动
org.springframework.boot spring-boot-starter-data-mongodb
配置客户端
spring:data:mondodb:url: mongodb://localhost/luxifa
客户端读写Mongodb
@Test
void testSave(@Autowired MongoTemplate mongoTemplate) {Book boo = new Book();book.setId(1);book.setType("springboot");book.setName("springboot");book.setDescription("springboot");mongoTemplate.save(book);
}@Test
void testFind(@Autowired MongoTemplate mongoTemplate) {List all = mongoTemplate.findAll(Book.class);System.out.println(all);
}
总结:
SpringBoot整合Mongodb
- 导入缓存技术对应的starter
org.springframework.boot spring-boot-starter-cache
- 启用缓存
@SpringBootApplication
@EnableCaching
public class SpringbootCacheApplication {public static void main(String[] args) {SpringApplication.run(SpringbootCacheApplication.class,args);}
}
- 设置当前操作的结果数据进入缓存
@Cacheable(value="cacheSpace",key="#id")
public Book getById(Integer id) {return bookDao.selectById(id);
}
总结:
SpringBoot启动缓存的方式
- @EnableCaching
- Cacheable
net.sf.ehcache ehcache
spring:cache:type: ehcaheehcache:config: ehcache.xml
总结:
变更缓存供应商为Ehcache
检测易失数据(可能会过期的数据集server.db[i].expires)
org.springframework.boot spring-boot-starter-data-redis
spring:redis:host: localhostport: 6379cache:type: redis
spring:redis:host: localhostport: 6379cache:type: redisredis:use-key-prefix: true #是否使用前缀名(系统定义前缀名)key-prefix: sms_ #追加自定义前缀名time-to-live: 10s #有效时长cache-null-value: false #是否允许存储空值
总结:
变更供应商为Redis
安装memcached
安装
memcached.exe -d install
运行memcached
mamcached.exe -d start
memcached.exe -d stop
com.googlecode.xmemcached xmemcached 2.4.7
memcached:# memcached服务器地址servers: localhost:11211# 连接池的数量poolSize: 10# 设置默认操作超时opTimeout: 3000
@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XMemcachedProperties {private String servers;private Integer poolSize;private Long opTimeout;
}
@Configuration
public class XMemcachedConfig {@Autowiredprivate XMemcachedProperties xMemcachedProperties;@Beanpublic MemcachedClient getMemcachedClient() throws IOException{MemcachedClientBuilder builder = new XMemcachedClientBuilder(xMemcachedProperties.getServers());MemcachedClient memcachedClient = builder.build();return memcachedClient;}
}
@Service
public class SMSCodeServiceMemcacheImpl implements SMSCodeService {@Autowiredprivate CodeUtils codeUtils;@Autowiredprivate MemcachedClient memcachedClient;@Ovrridepublic String sendCodeToSMS(String tele) {String code = this.codeUtils.generator(tele);//将数据加入memcachetry {memcachedClient.set(tele,0,code); //key,timeout,value} catch (Exception e) {e.printStackTrace();}return code;}public String checkCode(CodeMsg codeMsg) {String value = null;try {value = memcachedClient.get((code.getTele()).toString(); //key,timeout,value} catch (Exception e) {e.printStackTrace();}return codeMsg.getCode().equals(value);}
}
总结:
1.xmemcache客户端加载方式(bean初始化)
2.xmemcache客户端使用方式(set & get)
jetCache对SpringCache进行了封装,在原有功能基础上实现了多级缓存、缓存统计、自动刷新、异步调用、数据报表等功能
jetCache设定了本地缓存与远程缓存的多级缓存解决方案
本地缓存(local):linkedHashMap、Caffeine
远程缓存(remote): Redis、 Tair
加入jetcache坐标
com.alicp.jetcache jetcache-starter-redis 2.6.2
jetcache:remote:default:type: redishost: localhostport: 6379poolConfig:maxTotal: 50sms:type: redishost: localhostport: 6379poolConfig:maxTotal: 50
jetcache:local:default:type: linkedhashmapkeyConvertor: fastjson
jetcache:statIntervalMinutes: 15areaInCacheName: falselocal:default:type: linkedhashmapkeyConvertor: fastjsonlimit: 100remote:default:host: localhostport: 6379type: rediskeyConvertor: fastjsonvalueEncoder: javavalueDecoder: javapoolConfig:minIdle: 5maxIdle: 20maxTotal: 50
属性 | 默认值 | 说明 |
---|---|---|
jetcache.statIntervalMinutes | 0 | 统计间隔,0表示不统计 |
jetcache.hiddenPackages | 无 | 自动生成name时,隐藏指定的包名前缀 |
jetcache.(local或remote).${area}.type | 无 | 缓存类型,本地支持linkedhashmap、caffeine,远程支持redis、tair |
jetcache.(local或remote).${area}.keyConvertor | 无 | key转换器,当前仅支持fastjson |
jetcache.(local或remote).${area}.valueEncoder | java | 仅remote类型的缓存需要指定,可选java和kryo |
jetcache.(local或remote).${area}.valueDecoder | java | 仅remote类型的缓存需要指定,可选java和kryo |
jetcache.(local或remote).${area}.limit | 100 | 仅local类型的缓存需要指定,缓存实例最大元素数 |
jetcache.(local或remote).${area}.expireAfterWriteInMillis | 无穷大 | 默认过期时间,毫秒单位 |
jetcache.${area}.expireAfterAccessInmillis | 0 | 仅local类型的缓存有效,毫秒单位,最大不活动间隔 |
@SpringBootApplication
@EnableCreateCacheAnnotation
public class SpringbootCacheApplication {public static void main(String[] args) {SpringApplication.run(SpringbootCacheApplication.class,args);}
}
@Service
public class SMSCodeServiceImpl implements SMSCodeService {@Autowiredprivate CodeUtils codeUtils;@CreateCache(name = "smsCache" , expire = 3600)private Cache jetSMSCache;
}
@Service
public class SMSCodeServiceImpl implements SMSCodeService {@Overridepublic String sendCodeToSMS(String tele) {String code = this.codeUtils.generator(tele);jetSMSCache.put(telw,code);return code;}@Overridepublic boolean checkCode(CodeMsg codeMsg) {String value = jetSMSCache.get(codeMsg.getTele());return codeMsg.getCode().equals(value);}
}
总结:
1、jetcache简介
2、jetcache远程缓存使用方式
3、jetcache本地缓存使用方式
@SpringBootApplication
@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.ithema")
public class SpringBootJetCacheApplication {public static void main(String[] args) {SpringApplication.run(SpringBootJetCacheApplication.class,args);}
}
@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;@Cache(name = "smsCache_",key = "#id", expire = 3600)@CacheRefresh(refresh = 10,timeUnit = TimeUnit.SECONDS)public Book getById(Integer id) {return bookDao.selectById(id);}
}
@Service
public class BookServiceImpl implement BookService {@CacheUpdate(name = "smsCache_", key = "#book.id", value = "#book")public boolean update(Book book) {return bookDao.updateById(book) > 0;} @CacheInvalidate(name = "smsCache_", key = "#id")public boolean delete(Integer id) {return bookDao.deleteById(id) > 0;}
}
@Data
public class Book implements Serializable {
}
jetcache:remote:default:type: rediskeyConvertor: fastjsonvalueEncoder: javavalueDecoder: java
总结:
jetcache方法注解使用方式
net.oschina.j2cache j2cache-spring-boot2-starter 2.8.0-release
net.oschina.j2cache j2cache-core 2.8.4-release
net.sf.ehcache jehcache
j2cache:config-location: j2cache.properties
# 配置1级缓存
j2cache.L1.provider_class = ehcache
ehcache.configXml = ehcache.xml# 配置1级缓存数据到2级缓存的广播方式:可以使用redis提供的消息订阅模式,也可以使用groupd多播实现
j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy# 配置2级缓存
j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section = redis
redis.hosts = localhost:6379
@Service
public class SMSCodeServiceImpl implements SMSCodeService {@Autowiredprivate CodeUtils codeUtils;@Autowiredprivate CacheChannel cacheChannel;
}
@Service
public class SMSCodeServiceImpl implements SMSCodeService {@Overridepublic String sendCodeToSMS(String tele) {String code = codeUtils.generator(tele);cacheChannel.set("sms",tele,code);return code;}@Overridepublic boolean checkCode(SMSCode smsCode) {String code = cacheChannel.get("sms",smsCode.getTele()).asString();return smsCode.getCode().equals(code);}
}
总结:
j2cache缓存的基础使用
小结:
1.spring-cache
simple
ehcache
redis
memcached
2.jetcache
3.j2cache