springboot整合NoSql

x33g5p2x  于2022-02-07 转载在 Spring  
字(21.0k)|赞(0)|评价(0)|浏览(178)

1.springboot整合redis

1.1 配置requirepass,开启redis服务

1.2 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.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yl</groupId>
    <artifactId>redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redis</name>
    <description>Demo project for Spring Boot</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-web</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>
            </plugin>
        </plugins>
    </build>

</project>

1.3 application.properties

# redis的配置
# 密码
spring.redis.password=root123
# 主机,我这里连的是虚拟机上跑着的redis服务器
spring.redis.host=192.168.244.132
# 端口
spring.redis.port=6379
# 超时时间
spring.redis.timeout=25000

1.4 实体类

package com.yl.redis.domain;

import java.io.Serializable;

public class Student implements Serializable {
    private String name;
    private String sno;
    private Integer grade;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSno() {
        return sno;
    }

    public void setSno(String sno) {
        this.sno = sno;
    }

    public Integer getGrade() {
        return grade;
    }

    public void setGrade(Integer grade) {
        this.grade = grade;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sno='" + sno + '\'' +
                ", grade=" + grade +
                '}';
    }
}

1.5 测试

package com.yl.redis;

import com.yl.redis.domain.Student;
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
class RedisApplicationTests {

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    void contextLoads() {
        Student student = new Student();
        student.setSno("2020001");
        student.setName("小明");
        student.setGrade(98);
        ValueOperations ops = redisTemplate.opsForValue();
        ops.set("s1",student);
        System.out.println(ops.get("s1"));
    }

    @Test
    void test1() {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        ops.set("k1","hellovue");
        System.out.println(ops.get("k1"));
    }

}

1.6 结果

2.springboot整合session

2.1 使用场景

1.对于单体应用而言,session共享是没必要的,但是对于分布式应用其存在是必要的

2.图解

2.2 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.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yl</groupId>
    <artifactId>sessionshare</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sessionshare</name>
    <description>Demo project for Spring Boot</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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-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>
            </plugin>
        </plugins>
    </build>

</project>

2.3 application.properties

# redis的配置
#主机
spring.redis.host=192.168.244.132
# 端口号
spring.redis.port=6379
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000

2.4 testController

  1. 注意:如下我们在往session里写或者读数据,其实都是在redis里写或者读数据!
package com.yl.sessionshare;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class TestController {

    @Value("${server.port}")
    Integer port;

    @GetMapping("/set")
    public String setAttr(HttpSession session) {
        session.setAttribute("name","小明");
        return String.valueOf(port) + "setAttribute Successfully";
    }

    @GetMapping("/get")
    public String getAttr(HttpSession session) {
        String name = (String)session.getAttribute("name");
        return name + ":" + port;
    }
}

2.4 打包项目

2.5 打开终端启动两个进程

1.启动一个8080

2.启动一个8081

2.6 testController

package com.yl.sessionshare;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class TestController {

    @Value("${server.port}")
    Integer port;

    @GetMapping("/set")
    public String setAttr(HttpSession session) {
        session.setAttribute("name","小明");
        return String.valueOf(port) + "setAttribute Successfully";
    }

    @GetMapping("/get")
    public String getAttr(HttpSession session) {
        String name = (String)session.getAttribute("name");
        return name + ":" + port;
    }
}

2.7 测试

1.访问8080端口的set和get方法

2.访问8081端口的get方法

3.Nginx实现springboot请求负载均衡

3.1 拉取nginx的最新版本镜像

3.2 启动nginx实例

3.3 进入到nginx容器里,并且查看nginx.conf文件的内容

3.4 还可以看到有一个default.conf文件

3.5 把default.conf文件里的内容全部复制一下,然后退出,新建一个文件用于修改原本的内容(因为docker里原本是不支持vi的,所以我这里是在外面改好配置后,再复制文件进来)

3.6 配置负载均衡

3.7 复制修改后的文件替换掉原来的default.conf文件

3.8 nginx.conf文件也要做修改,先复制内容出来

3.8 同样的,在根目录创建一个新的nginx.conf,把刚才复制的内容粘贴进来,做修改,配置上游服务器,ip地址设置为本地物理机的

3.9 复制根目录下的nginx.conf替换掉原来的,并且重启nginx另配置生效

3.10测试

1.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.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yl</groupId>
    <artifactId>sessionshare</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sessionshare</name>
    <description>Demo project for Spring Boot</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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-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>
            </plugin>
        </plugins>
    </build>

</project>

2.application.properties

# redis的配置
#主机
spring.redis.host=192.168.244.135
# 端口号
spring.redis.port=6379
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000

3.controller

package com.yl.sessionshare;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class TestController {

    @Value("${server.port}")
    Integer port;

    @GetMapping("/set")
    public String setAttr(HttpSession session) {
        session.setAttribute("name","小明");
        return String.valueOf(port) + "setAttribute Successfully";
    }

    @GetMapping("/get")
    public String getAttr(HttpSession session) {
        String name = (String)session.getAttribute("name");
        return name + ":" + port;
    }
}

4.将项目打包,然后启动两个java-jar命令启动两个程序,端口分别为8080和8081

5.先往redis里存一次值

6.然后不指定端口,多次调用get方法,测试nginx是否分配请求到不同的程序

第一次:

第二次:

7.至此nginx实现springboot负载均衡的例子已实现

4. redis处理springboot接口幂等性

4.1 接口幂等性概念?

接口幂等性,简单来说就是同一个请求不断地发起,有时候我们需要这些请求的数据要保持一致性,也是只能发一次请求,不能让其发起多次重复的请求,结合redis来可以解决这种问题。

4.2 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.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yl</groupId>
    <artifactId>idempontent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>idempontent</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</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-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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>
            </plugin>
        </plugins>
    </build>

</project>

4.3 application.properties

# redis的配置
#主机
spring.redis.host=192.168.244.135
# 端口号
spring.redis.port=6379
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000

4.4 RedisService和TokenService

package com.yl.idempontent.token;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedisService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public boolean setEx(String key,String value,Long expire) {
        boolean flag = false;
        try {
            ValueOperations<String, String> ops = redisTemplate.opsForValue();
            ops.set(key,value);
            redisTemplate.expire(key,expire, TimeUnit.SECONDS);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    public boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }

    public boolean remove(String key) {
        if (exists(key)) {
            return redisTemplate.delete(key);
        }
        return false;
    }
}
package com.yl.idempontent.token;

import com.yl.idempontent.Exception.IdempontentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.UUID;

@Service
public class TokenService {

    @Autowired
    RedisService redisService;

    public String generateToken() {
        String uuid = UUID.randomUUID().toString();
        redisService.setEx(uuid,uuid,30000L);
        return uuid;
    }

    public boolean verifyToken(HttpServletRequest request) throws IdempontentException {
        String token = request.getHeader("token");
        if (token == null || "".equals(token)) {
            token = request.getParameter("token");
            if (token == null || "".equals(token)) {
                throw new IdempontentException("token 不存在");
            }
        }
        if (!redisService.exists(token)) {
            throw new IdempontentException("重复操作");
        }
        boolean b = redisService.remove(token);
        if (!b) {
            throw new IdempontentException("重复操作");
        }
        return true;
    }
}

4.5 自定义异常类

package com.yl.idempontent.Exception;

import com.yl.idempontent.interceptor.IdemPontentInterceptor;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalException {

    @ExceptionHandler(IdempontentException.class)
    public String idempontentException(IdempontentException e) {
        return e.getMessage();
    }
}
package com.yl.idempontent.Exception;

public class IdempontentException extends Exception {
    public IdempontentException(String message) {
        super(message);
    }
}

4.6 自定义注解

package com.yl.idempontent.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoIdempotent {
}

4.7 自定义拦截器

package com.yl.idempontent.interceptor;

import com.yl.idempontent.Exception.IdempontentException;
import com.yl.idempontent.anno.AutoIdempotent;
import com.yl.idempontent.token.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
public class IdemPontentInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //对于没加到@AutoIdempotent注解的方法直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        //对于加到@AutoIdempotent注解的方法进行拦截,校验token,只允许操作一次,不可重复操作
        Method method = ((HandlerMethod) handler).getMethod();
        AutoIdempotent annotation = method.getAnnotation(AutoIdempotent.class);
        if (annotation != null) {
            try {
                return tokenService.verifyToken(request);
            } catch (IdempontentException e) {
               throw e;
            }
        }
        return true;
    }
}

4.8 添加自定义拦截器到拦截器链中

package com.yl.idempontent.config;

import com.yl.idempontent.interceptor.IdemPontentInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMVCConfigure implements WebMvcConfigurer {

    @Autowired
    private IdemPontentInterceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns("/**");
    }
}

4.9 controller

package com.yl.idempontent.controller;

import com.yl.idempontent.anno.AutoIdempotent;
import com.yl.idempontent.token.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @Autowired
    TokenService tokenService;

    @GetMapping("/getToken")
    public String getToken() {
        return tokenService.generateToken();
    }

    @PostMapping("hello")
    @AutoIdempotent
    public String hello() {
        return "hello java";
    }

    @PostMapping("hello2")
    public String hello2() {
        return "hello2 vue";
    }
}

4.10 测试

对hello接口进行了拦截,每调用一次hello接口,都要拿一次token才行

对hello2接口没有拦截,随便访问

4.11 以上是用拦截器来实现的,我们还可以用切面来做,把以上拦截器注释掉,加入下面这个类即可

package com.yl.idempontent.aop;

import com.yl.idempontent.Exception.IdempontentException;
import com.yl.idempontent.token.TokenService;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

@Component
@Aspect
public class IdempontentAspect {

    @Autowired
    TokenService tokenService;

    @Pointcut("@annotation(com.yl.idempontent.anno.AutoIdempotent)")
    public void pc1() {

    }

    @Before("pc1()")
    public void before() throws IdempontentException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        try {
            tokenService.verifyToken(request);
        } catch (IdempontentException e) {
           throw e;
        }
    }
}

5. springboot整合mongodb

5.1 首先在docker上安装好mongodb,并且启动mongodb

5.2 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.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yl</groupId>
    <artifactId>mongodb</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mongodb</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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>
            </plugin>
        </plugins>
    </build>

</project>

5.3 application.properties

# mongodb端口号
spring.data.mongodb.port=27017
# 主机
spring.data.mongodb.host=192.168.244.135
spring.data.mongodb.username=admin
spring.data.mongodb.password=123456
# 新建一个数据库test用于保存数据
spring.data.mongodb.database=test
# 认证用户名和密码时使用admin数据库
spring.data.mongodb.authentication-database=admin

5.4 实体类

package com.yl.mongodb.model;

import java.io.Serializable;

public class User implements Serializable {
    private Integer id;
    private String userName;
    private String password;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

5.5 测试-插入数据

5.6 测试-查看数据

5.7 测试-删除数据

相关文章

微信公众号

最新文章

更多

目录