[黑马程序员SpringBoot2]——开发实用篇1

news2024/11/20 0:39:21

目录:

  1. 手工启动热部署
  2. 自动启动热部署
  3. 热部署范围配置
  4. 关闭热部署功能
  5. 第三方bean属性绑定
  6. 松散绑定
  7. 常用计量单位应用
  8. bean属性校验
  9. 进制数据转换规则
  10. 加载测试专用属性
  11. 加载测试专用配置
  12. 测试类中启动web环境
  13. 发送虚拟请求
  14. 匹配响应执行状态
  15. 匹配响应体
  16. 匹配响应体(json)
  17. 匹配响应头
  18. 业务层测试事务回滚
  19. 测试用例设置随机数据
  20. 内置数据源
  21. JdbcTemplate
  22. H2数据库
  23. redis下载安装与基本使用
  24. SpringBoot整合Redis
  25. Springboot读写Redis的客户端
  26. Sprintboot操作Redis客户端实现技术切换(jedis)

1.手工启动热部署

开启开发者工具

激活热部署:Ctrl + F9 

关于热部署
  • 重启(Restart):自定义开发代码,包含类、页面、配置文件等,加载位置restart类加载器
  • 重载(ReLoad):jar包,加载位置base类加载器

小结:

  • 开启开发者工具后启用热部署
  • 使用构建项目操作启动热部署(Ctrl+F9)
  • 热部署仅仅加载当前开发者自定义开发的资源,不加载jar资源 

2.自动启动热部署 

设置自动构建项目

ctrl+alt+shift+/ 

激活方式:Idea失去焦点5秒后启动热部署 

热部署Idea专业版spring boot(spring mvc)项目_idea springmvc 热部署-CSDN博客

3.热部署范围配置 

默认不触发重启的目录列表

  • /META-INF/maven
  • /META-INF/resources
  • /resources
  • /static
  • /public
  • /templates

自定义不参与重启排除项 

4.关闭热部署功能

属性加载优先顺序

设置高优先级属性禁用热部署

5.第三方bean属性绑定

使用 @ ConfigurationProperties 为第三方 bean 绑定属性

@EnableConfigurationProperties注解可以将使用@ConfigurationProperties注解对应的类加入Spring容器

 

注意事项

  • @EnableConfigurationProperties.与@Component不能同时使用 

解除使用@ConfigurationProperties注释警告

6.松散绑定 

@ ConfigurationProperties 绑定属性支持属性名宽松绑定

注意事项

  • 宽松绑定不支持注解@Value引用单个属性的方式 

@ConfigurationProperties绑定属性支持属性名宽松绑定 

注意事项

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

7.常用计量单位应用

SpringBoot 支持 JDK8 提供的时间与空间计量单位

JDK8支持的时间与空间计量单位 

8.bean属性校验

数据校验

  • 开启数据校验有助于系统安全性,J2EE规范中7SR303规范定义了一组有关数据校验相关的API

添加JSR3日3规范坐标与Hibernate校验框架对应坐标

对Bean开启校验功能

设置校验规则

9.进制数据转换规则 

字面值表达方式

application.yml

servers:
  ipAddress: 192.168.0.1
  #  ipaddress: 192.168.0.1
  #  ip_address: 192.168.0.1
  #  ip-address: 192.168.0.1
  #  IPADDRESS: 192.168.0.1
  #  IP_ADD_R-E_SS: 192.168.0.1
  port: 4444
  timeout: -1
  serverTimeOut: 3
  dataSize: 10240

dataSource:
  driverClassName: com.mysql.jdbc.Driver456
  password: 0127

 ApplicationTests

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {
    @Value("${dataSource.password}")
    private String password;


    @Value("${servers.ipAddress}")
    private String msg;

    @Test
    void contextLoads() {
        System.out.println(msg);
        System.out.println(password);
    }

}

运行结果:(0127)转换成了8进制

10.加载测试专用属性

在启动测试环境时可以通过properties参数设置测试环境专用的属性

优势:比多环境开发中的测试环境影响范围更小,仅对当前测试类有效 

在启动测试环境时可以通过args参数设置测试环境专用的传入参数

Sprintboot14TestApplicationTests

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

//@SpringBootTest(properties = {"test.prop=testValue1"})
//@SpringBootTest(args = {"--test.prop=testValue2"})
@SpringBootTest(properties = {"test.prop=testValue1"}, args = {"--test.prop=testValue2"})
class Sprintboot14TestApplicationTests {

    @Value("${test.prop}")
    private String msg;

    @Test
    void contextLoads() {
        System.out.println(msg);
    }
}

 application.yml

test:
  prop: testValue

11.加载测试专用配置

使用@Import注解加载当前测试类专用的配置

MsgConfig.class

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MsgConfig {
    @Bean
    public String msg() {
        return "bean msg";
    }
}

ConfigurationTest.class

package com.example;

import com.example.config.MsgConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;

@SpringBootTest
@Import({MsgConfig.class})
public class ConfigurationTest {
    @Autowired
    private String msg;

    @Test
    void testConfiguration() {
        System.out.println(msg);
    }
}

运行结果:

12.测试类中启动web环境 

模拟端口

WebTest.class

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class WebTest {
    @Test
    void test() {

    }
}

 13.发送虚拟请求

 虚拟请求测试

BookController.class

package com.example.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/books")
public class BookController {
    @GetMapping
    public String getById() {
        System.out.println("getById is running...");
        return "sprintboot";
    }
}

WebTest.class

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void test() {

    }

    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }
}

运行结果:

14.匹配响应执行状态

虚拟请求状态匹配

WebTest.class

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();

        action.andExpect(ok);
    }
}

15.匹配响应体

虚拟请求响应体匹配 

WebTest.class

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();

        action.andExpect(ok);
    }

    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("springboot");

        action.andExpect(result);
    }
}

16.匹配响应体(json)

虚拟请求响应体(json)匹配

BookController.class

package com.example.controller;

import com.example.domain.Book;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/books")
public class BookController {
//    @GetMapping
//    public String getById() {
//        System.out.println("getById is running...");
//        return "springboot";
//    }

    @GetMapping
    public Book 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;
    }
}

WebTest.class

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();

        action.andExpect(ok);
    }

    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("springboot");

        action.andExpect(result);
    }

    @Test
    void testJson(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\"id\":1,\"name\":\"springboot\",\"type\":\"springboot\",\"description\":\"springboot\"}");

        action.andExpect(result);
    }
}

17.匹配响应头

虚拟请求响应头匹配

WebTest.class+ 

package com.example;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.HeaderResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }

    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();

        action.andExpect(ok);
    }

    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("springboot");

        action.andExpect(result);
    }

    @Test
    void testJson(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\"id\":1,\"name\":\"springboot\",\"type\":\"springboot\",\"description\":\"springboot\"}");

        action.andExpect(result);
    }

    @Test
    void testContentType(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        HeaderResultMatchers header = MockMvcResultMatchers.header();
        ResultMatcher contentType = header.string("Content-Type", "application/json");
        action.andExpect(contentType);
    }

    @Test
    void testGetById(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);

        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);

        HeaderResultMatchers header = MockMvcResultMatchers.header();
        ResultMatcher contentType = header.string("Content-Type", "application/json");
        action.andExpect(contentType);



        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\"id\":1,\"name\":\"springboot\",\"type\":\"springboot\",\"description\":\"springboot\"}");
        action.andExpect(result);
    }
}

18.业务层测试事务回滚

为测试用例添加事务,SpringBoot会对测试用例对应的事务提交操作进行回滚

如果想在测试用例中提交事务,可以通过@Rollback注解设置

19.测试用例设置随机数据 

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

  • ${random.int}表示随机整数
  • ${random.int(10)}表示10以内的随机数
  • ${random.int(10,20)}表示10到20的随机数
  • 其中()可以是任意字符,例如[],!!均可 

20.内置数据源 

现有数据层解决方案技术选型

  • 数据源:DruidDataSource
  • 持久化技术:MyBatis-Plus /MyBatis
  • 数据库:MySQL

格式一

格式二

SpringBoot提供了3种内嵌的数据源对象供开发者选择

  • HikariCP.
  • Tomcat提供DataSource.
  • Commons DBCP

 

通用配置无法设置具体的数据源配置信息,仅提供基本的连接相关配置,如需配置,在下一级配置中设置具体设定

21.JdbcTemplate

现有数据层解决方案技术选型

  • 数据源:DruidDataSource
  • 持久化技术: MyBatls-Plus / MyBatis
  • 数据库:MySQL

内置持久化解决方案——JdbcIemplate

JdbcTemplate配置

 

22.H2数据库

SpringBoot提供了3种内嵌数据库供开发者选择,提高开发测试效率

  • H2
  • HSQL
  • Derby

导入H2相关坐标 

设置当前项目为web工程,并配置H2管理控制台参数

访问用户名sa,默认密码123456 

操作数据库(创建表)

 

 设置访问数据源

H2数据库控制台仅用于开发阶段,线上项目请务必关闭控制台功能 

 

SpringBoot可以根据url地址自动识别数据库种类,在保障驱动类存在的情况下,可以省略配置

 

现有数据层解决方案技术选型 

 

 BookDao.interface

package com.example.springboot_15_sql.dao;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot_15_sql.domain.Book;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface BookDao extends BaseMapper<Book> {


}

Book.class 

package com.example.springboot_15_sql.domain;

import lombok.Data;

@Data
public class Book {
    private int id;
    private String name;
    private String type;
    private String description;
}

Sprintboot15SqlApplication.class

package com.example.springboot_15_sql;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Springboot15SqlApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springboot15SqlApplication.class, args);
    }

}

application.yml

#server:
#  port: 8080
#
#spring:
#  datasource:
#    url: jdbc:mysql://localhost:3308/test_db
#    hikari:
#      driver-class-name: com.mysql.cj.jdbc.Driver
#      username: root
#      password: 666666
#      maximum-pool-size: 50

#mybatis-plus:
#  global-config:
#    db-config:
#      table-prefix: tbl_
#      id-type: auto
#  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

server:
  port: 8080

spring:
  h2:
    console:
      enabled: true
      path: /h2

  datasource:
    url: jdbc:h2:~/test
    hikari:
      driver-class-name: org.h2.Driver
      username: sa
      password: 123456

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springboot_15_sql</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_15_sql</name>
    <description>springboot_15_sql</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <!--        <dependency>-->
        <!--            <groupId>com.mysql</groupId>-->
        <!--            <artifactId>mysql-connector-j</artifactId>-->
        <!--            <scope>runtime</scope>-->
        <!--        </dependency>-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--        <dependency>-->
        <!--            <groupId>com.baomidou</groupId>-->
        <!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
        <!--            <version>3.4.1</version>-->
        <!--        </dependency>-->
        <!--        <dependency>-->
        <!--            <groupId>com.alibaba</groupId>-->
        <!--            <artifactId>druid-spring-boot-starter</artifactId>-->
        <!--            <version>1.2.6</version>-->
        <!--        </dependency>-->

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

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

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

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>


        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Sprintboot15SqlApplicationTests.class

package com.example.springboot_15_sql;

import com.example.springboot_15_sql.dao.BookDao;
import com.example.springboot_15_sql.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@SpringBootTest
class Springboot15SqlApplicationTests {

    @Autowired
    private BookDao bookDao;

    @Test
    void test() {
        bookDao.selectById(1);
    }

    @Test
    void testJdbcTemplate(@Autowired JdbcTemplate jdbcTemplate) {
        String sql = "select * from tbl_book";
//        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
//        System.out.println(maps);
        RowMapper<Book> rm = 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.setType(rs.getString("type"));
                temp.setDescription(rs.getString("description"));
                return temp;
            }
        };
        List<Book> list = jdbcTemplate.query(sql, rm);
        System.out.println(list);
    }

//    @Test
//    void testJdbcTemplateSave(@Autowired JdbcTemplate jdbcTemplate) {
//        String sql = "insert into tbl_book values(null,'springboot','springboot','springboot')";
//        jdbcTemplate.update(sql);
//    }

    @Test
    void testJdbcTemplateSave(@Autowired JdbcTemplate jdbcTemplate) {
        String sql = "insert into tbl_book values(3,'springboot3','springboot3','springboot3')";
        jdbcTemplate.update(sql);
    }

}

23.redis下载安装与基本使用

市面上常见的NoSQL解决方案

  • Redis
  • Mongo
  • ES

Redis是一款key-value存储结构的内存级NoSQL数据库

  • 支持多种数据存储格式
  • 支持持久化
  • 支持集群

Redis下载(Windows版)

  • https://github.com/tporadowski/redis/releases

Redis安装与启动( Windows版)

  • Windows解压安装或一键式安装
  • 服务端启动命令

  • 客户端启动命令

 

24.SpringBoot整合Redis

导入SpringBoot整合Redis坐标

配置Redis(采用默认配置)

  • 主机: localhost(默认)
  • 端口:6379(默认)

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

 

 客户端:RedisTemplate

 

 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>sprintboot_16_redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sprintboot_16_redis</name>
    <description>sprintboot_16_redis</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml

spring:
  redis:
    host: localhost
    port: 6379

Springboot16RedisApplicationTests.class

package com.example.sprintboot_16_redis;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

@SpringBootTest
class Sprintboot16RedisApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    void set() {
        ValueOperations ops = redisTemplate.opsForValue();
        ops.set("age", "41");
    }

    @Test
    void get() {
        ValueOperations ops = redisTemplate.opsForValue();
        Object age = ops.get("age");
        System.out.println(age);
    }


    @Test
    void hset() {
        HashOperations ops = redisTemplate.opsForHash();
        ops.put("info", "a", "aa");
    }

    @Test
    void hget() {
        HashOperations ops = redisTemplate.opsForHash();
        Object val = ops.get("info", "a");
        System.out.println(val);
    }

}

25.Springboot读写Redis的客户端

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

客户端: StringRedisTemplate以字符串作为key和value,与Redis客户端操作等效 

 

StringRedisTemplateTest.class

package com.example.sprintboot_16_redis;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

@SpringBootTest
public class StringRedisTemplateTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    void get1() {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        String name = ops.get("name");
        System.out.println(name);
    }

    @Test
    void get2() {
        ValueOperations ops = redisTemplate.opsForValue();
        Object name = ops.get("name");
        System.out.println(name);
    }
}

26.Sprintboot操作Redis客户端实现技术切换(jedis)

客户端选择:jedis

配置客户端

配置客户端专用属性

 

lettcus与jedis区别

  • jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就大受影响。
  • lettcus基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnectian。StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettcus也支持多连接实例一起工作.

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1225763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息系统项目管理师 第四版 第1章 信息化发展

1.信息与信息化 信息是指音讯、消息、信息系统传输和处理的对象&#xff0c;泛指人类社会传播的一切内容。来自P1 信息化是指在国家宏观信息政策指导下&#xff0c;通过信息技术开发、信息产业的发展、信息人才的配置&#xff0c;最大限度地利用信息资源以满足全社会的信息需…

一种用于脑肿瘤和组织分割的具有体积特征对齐的三维跨模态特征交互网络

A 3D Cross-Modality Feature Interaction Network With Volumetric Feature Alignment for Brain Tumor and Tissue Segmentation 一种用于脑肿瘤和组织分割的具有体积特征对齐的三维跨模态特征交互网络背景贡献实验方法Cross-Modality Feature Interaction ModuleVolumetric …

UE 程序化网格 计算横截面 面积

首先在构造函数内加上程序化网格&#xff0c;然后复制网格体到程序化网格组件上&#xff0c;将Static Mesh&#xff08;类型StaticMeshActor&#xff09;的静态网格体组件给到程序化网格体上 然后把StaticMesh&#xff08;类型为StaticMeshActor&#xff09;Instance暴漏出去 …

Apache Hive源码阅读环境搭建

前置软件&#xff1a; JDK 1.8 Maven 3.3.9 1 下载源码 # 下载源码 git clone https://github.com/apache/hive.gitcd hive# 查看标签 git tag# 切换到要阅读的指定版本的tag git checkout rel/release-2.1.02 编译源码 mvn clean install -DskipTests执行报错 日志如下 E…

C#,数值计算——插值和外推,曲线插值(Curve_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Object for interpolating a curve specified by n points in dim dimensions. /// </summary> public class Curve_interp { private int dim { get; s…

消息积压了如何处理?

欢迎大家到我的博客阅读这篇文章。消息积压了如何处理&#xff1f; - 胤凯 (oyto.github.io)在系统中使用消息队列的时候&#xff0c;消息积压这个问题也经常遇到&#xff0c;并且这个问题还不太好解决。 消息积压的直接原因通常是&#xff0c;系统中的某个部分出现了性能问题…

初刷leetcode题目(2)——数据结构与算法

&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️…

YOLO目标检测——无人机检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;无人机识别数据集说明&#xff1a;无人机检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yolo(txt)三种格式标签…

【Web】PHP反序列化的一些trick

目录 ①__wakeup绕过 ②加号绕过正则匹配 ③引用绕过相等 ④16进制绕过关键词过滤 ⑤Exception绕过 ⑥字符串逃逸 要中期考试乐(悲) ①__wakeup绕过 反序列化字符串中表示属性数量的值 大于 大括号内实际属性的数量时&#xff0c;wakeup方法会被绕过 &#xff08;php5-p…

基于海洋捕食者算法优化概率神经网络PNN的分类预测 - 附代码

基于海洋捕食者算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于海洋捕食者算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于海洋捕食者优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针…

SQL零基础入门教程,贼拉详细!贼拉简单! 速通数据库期末考!(八)

FULL OUTER JOIN 除了前面讲到的 INNER JOIN&#xff08;内连接&#xff09;、LEFT JOIN&#xff08;左连接&#xff09;、RIGHT JOIN&#xff08;右连接&#xff09;&#xff0c;还有另外一种关联方式&#xff0c;即 FULL OUTER JOIN&#xff08;全外连接&#xff09; FULL O…

移动端路径传参以数字的形式,写死的情况

页面1 async getListTransferAndApprova() { //把mark值拼接到路径的后面&#xff0c;定义一个变量&#xff0c;使得切换穿的mark都不一样let mark ;if (this.tabsCurrent 0) {mark 2;} else if (this.tabsCurrent 1) {mark 3;}else if (this.tabsCurrent 2) {mark 4;}…

【AD封装】芯片IC-SOP,SOIC,SSOP,TSSOP,SOT(带3D)

包含了我们平时常用的芯片IC封装&#xff0c;包含SOP,SOIC,SSOP,TSSOP,SOT&#xff0c;总共171种封装及精美3D模型。完全能满足日常设计使用。每个封装都搭配了精美的3D模型哦。 ❖ TSSOP和SSOP 均为SOP衍生出来的封装。TSSOP的中文解释为&#xff1a;薄的缩小型 SOP封装。SSO…

WMS重力式货架库位对应方法

鉴于重力式货架的特殊结构和功能&#xff0c;货物由高的一端存入&#xff0c;滑至低端&#xff0c;从低端取出。所以重力式货架的每个货位在物理上都会有一个进货口和一个出货口。因此&#xff0c;在空间上&#xff0c;对同一个货位执行出入库操作需要处于不同的位置。 比如对…

Os-hackNos-1

Os-hackNos-1 一、主机发现和端口扫描 主机发现 arp-scan -l端口扫描 nmap -P 192.168.80.141二、信息收集 访问80端口&#xff0c;可知目标是ubuntu系统&#xff0c;中间件是Apache 目录扫描&#xff0c;发现两个路径 dirsearch -u http://192.168.80.141/ -e *index.html路…

FISCO BCOS 3.0【03】配置和使用pythonSDK

官方技术文档&#xff1a;https://fisco-bcos-doc.readthedocs.io/zh-cn/latest/index.html 我们在官方技术文档的基础上&#xff0c;进行&#xff0c;对文档中一些不清楚的地方进行修正 依赖软件 Ubuntu sudo apt install -y zlib1g-dev libffi6 libffi-dev wget git初始化…

STM32硬件调试器不一定准确,proteus不一定准确

我在做实验的过程中&#xff0c;发现里面的那个变量ii一直都不变搞了很久没有发现问题&#xff0c; 然后怀疑是不是软件出了问题&#xff0c;然后直接只用单片机的一个灯泡来检测是否正常&#xff0c;发现&#xff1a;单片机里面正常&#xff0c;但是硬件调试的时候&#xff0…

后端面经学习自测(三)

文章目录 1、ArrayList和Linkedlist区别&#xff1f;2、ArrayList扩容机制&#xff1f;3、ArrayList和Linkedlist分别能做什么场景&#xff1f;4、事务特性&#xff1f;MySQL事务Redis事务Spring事务5、在Spring中事务失效的场景&#xff1f;6、Java泛型&#xff1f;7、泛型擦除…

22 - 如何优化垃圾回收机制?

我们知道&#xff0c;在 Java 开发中&#xff0c;开发人员是无需过度关注对象的回收与释放的&#xff0c;JVM 的垃圾回收机制可以减轻不少工作量。但完全交由 JVM 回收对象&#xff0c;也会增加回收性能的不确定性。在一些特殊的业务场景下&#xff0c;不合适的垃圾回收算法以及…

VisualGDB 6.0 R2 Crack

轻松跨平台"VisualGDB 使 Visual Studio 的跨平台开发变得简单、舒适。它支持&#xff1a; 准系统嵌入式系统和物联网模块&#xff08;查看完整列表&#xff09; C/C Linux 应用程序 本机 Android 应用程序和库 Raspberry Pi 和其他Linux 板 Linux 内核模块&#xff08;单…