springboot学习2

本篇是开发实用篇,接《springboot学习1

目录

1. 启动热部署

 2.配置高级

3.测试

4.数据层解决方案

4.1 sql

4.2 NoSql

5.整合第三方技术


1. 启动热部署

重启(restart):自定义开发代码,包括类,页面、配置文件等,加载位置restart类加载器;

重载(reload):jar包,加载位置base类加载器

配置方法1:pom.xml添加依赖,maven刷新

// pom.xml
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-devtools</artifactId>
</dependency>

使用构建项目按钮启动热部署(ctrl+f9 build project),热部署相当于restart过程,正常启动相当于restart+reload

然后需要在设置/compiler勾选build project atuomaitic

 然后快捷键ctrl+shift+alt+/ ,勾选:compile.automake.allow.when.app.running

高版本在file->setting->Advanced Setttings里面勾选。

默认不触发重启的目录列表:/METE-INF/maven,/METE-INF/resources,、resources,/static,/public,/templates;默认是idea丢失焦点5s启动。

如果要修改范围,可自定义重启排除项

spring:
  devtools:
    restart:
      exclude: static/**,public/**,config/application.yml
      enabled: true

关闭热部署:通过设置高优先级属性禁用热部署。优先级可参看上一节的config优先级配置。

 2.配置高级

(1)使用ConfigurationProperties可以为第三方bean绑定属性。

@Bean
@ConfigurationProperties(prefix = "datasource")
public DruidDataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        return ds;
}
// main函数
DruidDataSource ds = ctx.getBean(DruidDataSource.class);
        System.out.println(ds.getDriverClassName());

// application.yml
datasource:
  driverClassName: com.mysql.jdbc.Driver456

(2)EnableConfigurationProperties:注解可以将使用ConfigurationProperties注解的类加入到Spring容器。不能与@Component注解同时使用。

如果出现springboot Configuration Annotation Processor not configured,在pom里面添加依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

@ConfigurationProperties绑定属性支持属性名称松散绑定

@ConfigurationProperties(prefix = "datasource")

绑定的前缀命名规范:只能使用纯小写字母、数字、下划线作为合法字符。

@Value不支持松散绑定。

(3)常用的计量单位:

 也可以在xml里面直接带单位

(4)Bean数据校验

导入JSR303与Hibernate校验框架坐标;

<dependency>
   <groupId>javax.validation</groupId>
   <artifactId>validation-api</artifactId>
</dependency>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

使用@Validated注解启用校验功能;使用具体校验规则规范数据校验格式。

@Component
@Data
@ConfigurationProperties(prefix = "servers")
@Validated
public class ServerConfig {
    private String ipAddress;
    private int port;
    @Max(value=4000,message="最大值不能超过4000")
    private long timeout;
}

(5)yml语法规则

 注意yml文件对数字的定义支持进制书写格式,如需要使用字符串,就添加引号明确标注。

3.测试

在启动测试环境时,可以通过properties/args设置测试环境临时参数,用于小范围测试

@SpringBootTest(properties = {"test.prop=testValue1"},args = {"--test.prop=testValue2"})
class ApplicationTests {
    @Value("${test.prop}")
    private String msg;
    @Test
    void contextLoads() {
        System.out.println(msg);
    }
}

加载测试专用的配置,可使用import

 测试类发起web请求,使用webEnvironment、MockMvcRequestBuilders、MockMvcResultMatchers

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class WebEnviromentTest {
    @Test
    void testRandomPort(){
    }
    @Test
    void  testWeb(@Autowired MockMvc mvc) throws Exception {
        // 创建虚拟请求,当前访问/books
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions actions = mvc.perform(builder);

        // 设定预期值,与真实值进行比较,成功则测试通过,失败则测试失败
        // 定义本次调用的预期值
        StatusResultMatchers status = MockMvcResultMatchers.status();
        // 预计本次调用时成功的状态200
        ResultMatcher ok = status.isOk();
        // 使用本次执行的真实值与预期结果进行比对
        actions.andExpect(ok);
    }
}

以上是状态对比,以下是内容比对的部分

 ContentResultMatchers content = MockMvcResultMatchers.content();
 // 预计本次调用时成功的状态200
 ResultMatcher ok = content.string("springboot");
 // 使用本次执行的真实值与预期结果进行比对
 actions.andExpect(ok);

以下是Json匹配

 请求头的匹配

数据层事务回滚,防止测试的数据保存到数据库。

测试用例数据设定:测试用例数据通常采用随机数进行测试,可使用SpringBoot提供的随机数为其赋值。

testcase:
  book:
    id: ${random.int}  # 随机整数
    id2: ${random.int(10)} # 10以内随机数
    type: ${randowm.int(10,20)} # 10-20的随机数
    uuid: ${random.uuid} # 随机uuid
    name: ${randowm.value} # 随机字符串,MD5字符串,32位
    publishTime: ${random.long} # 随机整数(long范围)

4.数据层解决方案

4.1 sql

数据层解决方案技术选型:druid+mybatis-plus+mysql

数据源:druid;持久化技术:mybatis-plus;数据库:mysql。以下为内置的讲解。

(1)SpringBoot提供了3种内嵌的数据源对象供开发者选择: HikariCP(默认使用),Tomcat提供的DataSource, Commons DBCP.

hikaricp的配置方法。 

Druid配置。

 也可以使用这样的方式。

 (2)jdbcTemplate,这个是内置的持久化方案。通过传入rm参数,格式化返回数据格式。

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-jdbc</artifactId>
 </dependency>

 jdbcTemplate也有参数,可在application.yml设置。

(3)SpringBoot提供了3种内嵌数据库:H2,HSQL, Derby,内存级数据库,开发阶段测试用。

server:
  port: 8010
spring:
  h2:
    console:
      enabled: true
      path: /h2   # 访问用户名sa, 默认密码123456
  datasource:
    url: jdbc:h2:~/test
    hikari:
      driver-class-name: org.h2.Driver
      username: sa
      password: 123456
#  datasource:
#    druid:   // 或者采用druid等数据源
#      url: jdbc:h2:~/test
#      driver-class-name: org.h2.Driver
#      username: sa
#      password: 123456

运行程序, 访问localhost:8010/h2就可以进入h2面板

4.2 NoSql

常见的NoSql解决方案有:redis、Mongo、ES

(1)Redis是一款Key-Value存储结构的内存级NoSql数据库。支持多种数据存储格式,支持持久化,支持集群。

windows版本的安装包可直接解压安装或一键式安装。

服务端启动命令:redis-server.exe redis.windows.conf

客户端启动命令:redis-cli.exe

启动服务端可能存在bug,可先执行redis-cli.exe 然后 shutdown;然后exit;然后再使用redis-server.exe redis.windows.conf就可以了。

 出现这个界面代表执行成功了。

常用命令:hset key field value:例如hset keya a1 aa1;hget key field:例如 hget keya a1;

keys *;springBoot整合redis: yml里面可不配置

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

RedisTemplate提供操作各种数据存储类型的接口API

 客户端:RedisTemplate以对象作为key和value,内部对数据进行序列化

客户端:StringRedisTemplate以字符串作为key和value,与Redis客户端(redis-cli.exe)操作效果一致.xxxOperations<String,String>带泛型。

jedis:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

需要在yml里面指定client-type: jedis,默认是lettuce

jedis连接redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案是通过配置连接池使每个连接可用,这样整体性能就大受影响。

lettuce基于Netty框架进行与Redis服务器连接,底层设计采用StateRedisConnection。StateRedisConnection是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettuce也支持多连接实例一起工作。

(2)Mongodb:

mongodb是一个开源、高性能、无模式的文档型数据库。NoSql数据库产品里面最像关系型数据库的非关系型数据库。

服务端启动:mongod --dbpath=..\data\db

客户端启动:mongo -- host=127.0.0.1 --port=27017

如果出现找不到vcrruntime140_1.dll。搜索下载dll文件;拷贝到system32目录下;执行regsvr32 vcruntime140_1.dll注册对应dll文件。

可视化客户端-rebo 3T。新建数据库,新建集合。

新增:db.集合名称.insert/save/insertOne(文档)

删除:db.集合名称.remove(条件)

修改:db.集合名称.update(条件,{操作种类:{文档}).

 springboot整合mongodb

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring:
  data:
     mongodb:
        url: mongodb://localhost/itheima

(3)Elasticsearch(ES)

es是一个分布式全文搜索引擎。原理:数据库分词,对应某些id(也就是倒排索引),这些id对应对应的简要文档数据数组(创建文档),搜索时(使用文档)出来搜索结果;

 启动:elasticsearch.bat,时间比较长。

常用索引操作:get、put、delete/ 地址是 localhost:9200/xxx,这样的索引没有匹配规则,需要在put时添加Body/raw内容,此处用到分词器:elasticsearch-analysis-ik,下好插件解压缩放在安装目录下的plugins里面,目录名为ik,重新启动。

 创建文档常用操作:

添加:

 查询:

条件查询: 

 删除文档:

 全量修改:

 部分修改:

和springboot整合

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
elasticsearch:
   rest:
      url: http://localhost:9200

接口使用elasticsearchRestTemplate. 

elasticsearch提供了两种级别的客户端接口(以上为低级别,默认的;以下采用高级别的)

<dependency>
     <groupId>org.elasticsearch.client</groupId>
     <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

高版本的yml不需要配置(springboot未提供)

创建索引,需要创建客户端和关闭客户端 

也可以把创建和关闭客户端抽取出来,setUp和tearDown

简化后的操作,直接使用client

设置请求里面的参数(索引参数)

json = "xxx";  // 将参数从postman拷贝过来就可以,也就是上面mappings参数体。包括mappings
request.source(json,XContentType.JSON)

创建文档(单个创建)

 创建文档(批处理),用到client.bulk()

 使用文档(查询)

按照id查询

 按条件查询

 其中JSON.toStringfy和JSON.parseObject使用的是fastjson,需要添加依赖。

5.整合第三方技术

缓存、任务、邮件、消息。

缓存

缓存是一种介于数据永久存储介质和数据应用中间的数据临时存储介质,有效减少数据读取次数,提高性能。比如下方定义在service里面的catch,提供了一个临时数据存储空间。

 springboot提供的cache:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

在applicion.java类上添加注解

@SpringBootApplication
@EnableCaching

需要用的地方使用注解@Cacheable

@Cacheable(value = "cacheSpace",key = "#id")
    public boolean gettById(Integer id) {
        return bookDao.selectById(id)>0;
}

springboot除了提供默认的缓存方案,还对其他缓存技术做了整合,统一接口,方便管理。常见的缓存技术有:Generic,JCache,Ehcache,Hazelcast,infinispan,Couchbase,redis,Caffenine,Simple(默认),memcached.

(1)simple

一个简单的生成验证码的工具方法

@Component
public class CodeUtils {
    private String[] patch = {"00000","0000","000","00","0",""};
    public String generator(String tel){
        int hash = tel.hashCode ();
        int encryption = 20220317;
        long result = hash ^ encryption;
        long now = System.currentTimeMillis ();
        result = result ^ now;
        long code =result % 1000000;
        code = code<0?-code:code;
        String codeStr = code + "";
        int len = codeStr.length();
        return patch[len-1] + codeStr;
    }
    @Cacheable(value="smsCode",key="#tel")
    public String get(String tel){
        return null;
    }
    public static void  main(String[] args){
        System.out.println (new CodeUtils ().generator ("18666699911"));
    }
}

使用该方法,同时使用缓存。使用Cacheput,防止每次发出的验证码都是一个值

@Autowired
    private CodeUtils codeUtils;

 @Override
//    @Cacheable(value = "smsCode",key = "#tel")
@CachePut(value = "smsCode",key = "#tel")
public String sendCodeToSMS(String tel) {
    String code = codeUtils.generator (tel);
    return code;
}

@Override
public Boolean checkCode(SMSCode smsCode) {
    String code = smsCode.getCode ();
    String cacheCode = codeUtils.get (smsCode.getTel ());
    return code.equals (cacheCode);
}

在controller里面就可以使用了

@RestController
@RequestMapping("/sms")
public class SMSCodeController {
    @Autowired
    private SMSCodeService smsCodeService;

    @GetMapping
    public String getCode(String tel){
        String code = smsCodeService.sendCodeToSMS (tel);
        return code;
    }
    @PostMapping
    public boolean checkCode(SMSCode smsCode){
        return  smsCodeService.checkCode (smsCode);
    }
}

postman里面使用post:localhost:8082/sms?tel=xxx&code=xxx就可以了。

(2)Ehcache

PS:时隔半个多月再次开始更新,结合这半个月的工作经历,结论是:学习一定要一气呵成,不能三天打鱼两天晒网,不然断断续续的学习忘得太快,成本太高。

<dependency>
     <groupId>net.sf.ehcache</groupId>
     <artifactId>ehcache</artifactId>
</dependency>
# application.yml
 cache:
    type: ehcache
    ehcache:
      config: ehcache.xml

 

java代码和simple一样,不需要修改。

 (3)Redis

数据淘汰机制:LRU:Least Recent used;LFU:Least Frequently used

添加依赖:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.yml

cache:
    type: redis
    redis:
      use-key-prefix: true
      key-prefix: ssm_
      cache-null-values: true
      time-to-live: 10s
redis:
    host: localhost
    port: 6379

java代码不需要改

(4)memcached

<dependency>
   <groupId>com.googlecode.xmemcached</groupId>
   <artifactId>xmemcached</artifactId>
   <version>2.4.7</version>
</dependency>

由于springboot未集成,也不需要在application.yml里面设置,直接硬编码

创建客户端配置类

// XMemcachedConfig.java
@Configuration
public class XMemcachedConfig {
    @Autowired
    private XMemcachedProperties  memcachedProperties;

    @Bean
    public MemcachedClient getMemcached() throws IOException {
        MemcachedClientBuilder memcachedClientBuilder = new XMemcachedClientBuilder(memcachedProperties.getServers());
        memcachedClientBuilder.setConnectionPoolSize(memcachedProperties.getPoolSize());
        memcachedClientBuilder.setOpTimeout(memcachedProperties.getOpTimeout());
        MemcachedClient client = memcachedClientBuilder.build();
        return client;
    }
}
// XMemcachedProperties.java
@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XMemcachedProperties {
    private String servers;
    private int poolSize;
    private long opTimeout;
}

在application.yml里面设置参数

memcached:
  servers: localhost:11211
  pool-size: 10
  op-timeout: 3000

使用:

 

(5)jetcache

jetCache对springcache进行了封装,在原有基础上实现了多级缓存,缓存统计,异步调用,自动刷新,数据报表等功能。是一个底层框架。支持①本地缓存:LinkedHashMap,Caffeine和②远程缓存:redis,tair

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.6.2</version>
</dependency>
jetcache:
  statIntervalMinutes: 15  # 非必须 缓存报告
  areaInCacheName: false  # 非必须
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
      limit: 100  # 非必须
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      keyConvertor: fastjson # 非必须
      valueEncoder: java  # 非必须
      valueDecoder: java  # 非必须
      poolConfig:
        maxTotal: 50
        minIdle: 5  # 非必须
        maxIdle: 20  # 非必须
    sms:
      type: redis
        host: localhost
        port: 6379
        poolConfig:
          maxTotal: 50
// 开启jetcache注解支持
@SpringBootApplication
@EnableCreateCacheAnnotation
public class Application {}
@CreateCache(area = "default",name = "jetCache_",expire = 200,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.BOTH)
    private Cache<String, String> jetCache;

使用:

 使用方法缓存

@SpringBootApplication
@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.itheima")
public class Application {}

 注意,缓存对象必须要可序列化,在实体类上添加 implements Serializable

(6)j2Cache

添加依赖

 更多的j2Cache配置,参看jar包里面的实例配置文件

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值