目录
3、将redis的实现技术改为jedis(默认为lettuce)
3、整合ElasticSearch (high level Client)
一、热部署
1、手动启动热部署
- 导入开发者工具
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
- 用构建工程的方式激活热部署(ctrl+f9)build project
2、自动启动热部署
打开自动build project
允许自动构建项目
3、配置热部署的范围
或自己定义
spring: devtools: restart: exclude: ../static/**
4、禁用热部署的启用
设置java的环境变量(优先级较高),防止设置冲突
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled","false");
SpringApplication.run(Springboot03SsmpApplication.class, args);
}
二、bean的属性绑定
1、自定义的bean绑定
将配置文件的值与bean绑定
读取
2、第三方bean的属性绑定
或
3、松散绑定
只有@ConfiguurationProperties绑定的属性名有松散绑定,而用@Value和前缀名是没有的,
前缀名的命名规范:只能使用纯小写字母、数字、下划线作为合法字符。
4、常用的计量单位类
5、对bean数据校验
导入工具类
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> </dependency>
使用
@Data
@Component
@ConfigurationProperties("server1")
@Validated
public class Config1 {
//指定规则,规则由自己定义
@Max(value = 8888,message = "最大值为8888")
private long port;
private String servername;
private String outtime;
}
三、测试相关的技术
1、加载测试相关的临时专用属性
可用于更小范围的测试环境
//@SpringBootTest(args = {"--servers.prot = 83"}) 优先级更高,相当于命令行的临时变量
//@SpringBootTest(properties = {"servers.prot = 82"})
class Springboot0101StartApplicationTests {
@Value("${servers.prot}")
private String prot;
@Test
void contextLoads() {
System.out.println(prot);
}
2、在测试环境中测试web环境
- 启动web测试环境
//RANDOM_PORT为随机端口,DEFINED_PORT为默认端口
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class Springboot0402TestApplicationTests {
@Autowired
private String S;
@Test
void contextLoads() {
System.out.println(S);
}
- 发起MVC的虚拟请求调用
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
//开启虚拟mvc调用
@AutoConfigureMockMvc
class Springboot0402TestApplicationTests {
@Autowired
private String S;
//注入虚拟MVC调用对象
@Autowired
private MockMvc mvc;
@Test
void contextLoads() throws Exception {
//创建虚拟请求,当前访问/books/小鸭
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/小鸭");
//执行请求
mvc.perform(builder);
}
3、匹配结果
匹配调用结果与预期值是否一致的一些方法
- 匹配执行的状态
//接收执行的结果
ResultActions actions = mvc.perform(builder);
//定义执行状态匹配器
StatusResultMatchers status = MockMvcResultMatchers.status();
//定义预期的状态
ResultMatcher ok = status.isOk();
//使用真实的结果与预期的结果进行匹配
actions.andExpect(ok);
- 匹配执行返回的内容
void testbody() throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/小鸭");
//接收执行的结果
ResultActions actions = mvc.perform(builder);
//定义执行状态匹配器
ContentResultMatchers content = MockMvcResultMatchers.content();
//定义预期的内容
ResultMatcher string = content.string("success8");
//使用真实的结果与预期的结果进行匹配
actions.andExpect(string);
}
- 匹配json串
@Test
void testJson() throws Exception {
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books/小鸭");
//接收执行的结果
ResultActions actions = mvc.perform(builder);
//定义内容匹配器
ContentResultMatchers content = MockMvcResultMatchers.content();
//定义预期的内容
ResultMatcher string = content.json("{\"id\":1,\"name\":\"小鸭y\",\"decripution\":\"小鸭是屌毛\"}");
//使用真实的结果与预期的结果进行匹配
actions.andExpect(string);
}
4、不让测试类进行事务提交
加上@Transactional注解,让spring接管事务管理,如果为测试类则默认事务不提交,如要提交则可以加上@Rollback(false)注解。
5、在测试类的测试用例中使用随机的数据
通常使用多环境,进行配置(application-test.yml)
四、sql数据源解决方案
1、内置数据源
springBoot提供了三种内嵌的数据源对象供开发者选择
- HikariCP (默认) 当前轻量级数据源中速度最快的
- Tomcat提供Datasource 如HikariCP不可用时在web环境下将使用该数据源
- Commons DBCP 当以上两种都不可以用时,使用
2、jdbc的使用
需要导jdbc的包
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
void contextLoads() {
String sql = "select * from book";
RowMapper<Book> rowMapper = new RowMapper<Book>() {
@Override
//创建一个实体类与数据库字段的映射,常用的方法
public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
Book temp = new Book();
temp.setId(rs.getInt("id"));
temp.setName(rs.getString("name"));
temp.setDescription(rs.getString("description"));
temp.setType(rs.getString("type"));
return temp;
}
};
List<Book> query = jdbcTemplate.query(sql, rowMapper);
System.out.println(query);
3、H2数据库
通常是开发人员使用
是springBoot中内嵌的数据库用到的jar包有
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
- 安装h2(内存级数据库)
- 配置yml文件
spring: h2: console: enabled: true path: /h2
2.运行tomcat服务器访问http://localhost:8080/h2进入到h2的配置页面,密码为123456
获取到url等信息
3、在继续配置yml文件,重启tomcat,安装后可不写
datasource: driver-class-name: org.h2.Driver url: jdbc:h2:~/test username: sa password: 123456
4、进入到h2管理器中,进行数据库操作
5、用的时候记得关闭管理器
五、redis的整合(nosql)
1、redis的整合
- 在启动redis-server.exe后在yml中作如下的配置
spring: redis: host: localhost port: 6379
- 操作普通数据
@Autowired
private RedisTemplate redisTemplate;
@Test
void testSet(){
//选择要操作的数据类型,普通数据
ValueOperations ops = redisTemplate.opsForValue();
ops.set("data1","123");
}
@Test
void testGet(){
ValueOperations ops = redisTemplate.opsForValue();
String data1 = (String) ops.get("data1");
System.out.println(data1);
}
- 操作hash数据
@Test
void testSetHash(){
//选择要操作的数据类型,Hash数据
HashOperations ops = redisTemplate.opsForHash();
ops.put("data","data1","1");
ops.put("data","data2","2");
}
@Test
void testGetHash(){
HashOperations ops = redisTemplate.opsForHash();
String data1 = (String) ops.get("data","data1");
System.out.println(data1);
String data2 = (String) ops.get("data", "data2");
System.out.println(data2);
}
2、StringRedisTemplate操作Redis
由于用RedisTemplate是用对象的形式来操作的,所以进行了序列化
而StringRedisTemplate是以字符串的形式作为key和value的,所以就没有进行序列化
@Autowired
private StringRedisTemplate redisTemplate;
@Test
void testSet(){
//选择要操作的数据类型,普通数据
ValueOperations ops = redisTemplate.opsForValue();
ops.set("data1","123");
}
@Test
void testGet(){
ValueOperations ops = redisTemplate.opsForValue();
String data1 = (String) ops.get("data1");
System.out.println(data1);
}
3、将redis的实现技术改为jedis(默认为lettuce)
- 导入jedis的jar包
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
- 在yml文件中进行配置
client-type: jedis jedis: pool: max-active: 16 #设置最大连接数为16
六、Mongodb数据库的整合(nosql)
mongodb是一个开源、高性能、无模式的文档型数据库。是nosql数据库的一种,是最像关系型数据库的非关系型数据库,适合在修改频度很高的环境下使用,且支持结构化的数据存储。。
- 再将mongodb的started导进来以后,在yml中作以下配置
spring: data: mongodb: uri: mongodb://localhost/xiaojiang
基本的操作
@Autowired
private MongoTemplate mongoTemplate;
@Test
//插入操作
void contextLoads() {
Book book = new Book();
book.setId(3);
book.setType("springboot4");
book.setDescription("springboot5");
book.setName("springboot26");
mongoTemplate.save(book);
}
@Test
//查询操作
void mongodbTest(){
List<Book> bookList = mongoTemplate.findAll(Book.class);
System.out.println(bookList);
}
七、Elasticsearch(ES)的整合
是一个分布式全文搜索引擎
1、索引的一些操作
创建索引(put)
localhost:9200/book
创建分词器(put)
body的json
{
"mappings":{
"properties":{
"id":{
"type":"keyword"
},
"name":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"type":{
"type":"keyword"
},
"description":{
"type":"text",
"analyzer":"ik_max_word",
"copy_to":"all"
},
"all":{
"type":"text",
"analyzer":"ik_max_word"
}
}
}
}
2、对文档的一些操作
- 创建文档(post请求)
localhost:9200/books/_doc/1(id)
在body传json串,不用id字段
localhost:9200/books/_create/1(id)
//这种形式系统会自动分配随机id,buchangy
localhost:9200/books/_doc
- 查询文档(get请求)
//按id查询单个文档
localhost:9200/books/_doc/1
//查询所有文档
localhost:9200/books/_search
//条件查询
localhost:9200/books/_search?q=name:springboot
- 删除文档(delete请求)
//按id删除单个文档
localhost:9200/books/_doc/1
- 更新文档(put请求)
//全量修改
localhost:9200/books/_doc/1
如果json为
{
"name":"springboot2",
}
则会抹去剩余的值只保留name的值
//部分修改(post)
localhost:9200/books/_update/1
//json的格式
{
"doc":{
"name":"springboot3"
}
}
3、整合ElasticSearch (high level Client)
由于springb没有整合high level Client所以要自己手动配置
导包
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
- 配置
RestHighLevelClient client;
@BeforeEach
void setup(){
HttpHost host = HttpHost.create("http://localhost:9200");
RestClientBuilder builder = RestClient.builder(host);
client = new RestHighLevelClient(builder);
}
- 基本使用
//创建客户端操作
//org.elasticsearch.client.indices
CreateIndexRequest books = new CreateIndexRequest("books");
//执行创建索引的操作
client.indices().create(books, RequestOptions.DEFAULT);
System.out.println(bookMapper.selectById(2));
- 创建带分词器的索引
//创建客户端操作
//org.elasticsearch.client.indices
CreateIndexRequest request = new CreateIndexRequest("books");
String json = "{\n" +
"\n" +
" \"mappings\":{\n" +
"\n" +
" \"properties\":{\n" +
"\n" +
" \"id\":{\n" +
"\n" +
" \"type\":\"keyword\"\n" +
"\n" +
" },\n" +
"\n" +
" \"name\":{\n" +
"\n" +
" \"type\":\"text\",\n" +
"\n" +
" \"analyzer\":\"ik_max_word\",\n" +
"\n" +
" \"copy_to\":\"all\"\n" +
"\n" +
" },\n" +
"\n" +
" \"type\":{\n" +
"\n" +
" \"type\":\"keyword\"\n" +
"\n" +
" },\n" +
"\n" +
" \"description\":{\n" +
"\n" +
" \"type\":\"text\",\n" +
"\n" +
" \"analyzer\":\"ik_max_word\",\n" +
"\n" +
" \"copy_to\":\"all\"\n" +
"\n" +
" },\n" +
"\n" +
" \"all\":{\n" +
"\n" +
" \"type\":\"text\",\n" +
"\n" +
" \"analyzer\":\"ik_max_word\"\n" +
"\n" +
" }\n" +
"\n" +
" }\n" +
"\n" +
" }\n" +
"\n" +
"}";
request.source(json, XContentType.JSON);
//执行创建索引的操作
client.indices().create(request, RequestOptions.DEFAULT);
}
- 批量从数据库导入文档
List<Book> books = bookMapper.selectList(null);
BulkRequest bulkRequest = new BulkRequest();
for(Book book : books) {
IndexRequest request = new IndexRequest("books").id(book.getId().toString());
String json = JSON.toJSONString(book);
request.source(json, XContentType.JSON);
bulkRequest.add(request);
}
client.bulk(bulkRequest,RequestOptions.DEFAULT);
- 按条件查询
//创建请求
SearchRequest request = new SearchRequest("books");
//创建条件
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.termQuery("name","spring"));
request.source(builder);
//执行查询
SearchResponse search = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = search.getHits();
//遍历查询结果
for (SearchHit hit:hits){
Book book = JSON.parseObject(hit.getSourceAsString(), Book.class);
System.out.println(book);
}