SpringBoot整合NoSQL

309 阅读4分钟

1.简介

NoSQL的库其实有很多

1620263596167.png 这里我们讲解两种常见的NoSQL : Redis 和 MongoDB

这里需要有最基本的Docker、Redis 和 MongoDB的知识,如果没有,建议大家先自学Redis 和 MongoDB

2.整合Redis

启动redis

如果首次使用docker,密码为123,可以自己指定

1620263596167.png

如果之前有redis容器

1620264616254.png

idea创建springboot项目

1620264616254.png

application.properties添加3个基础配置

1620267546792.png

双击shift打开搜索面板搜索,进入 RedisAutoConfiguration 类

1620267546792.png

可以看见提供了两个模板类分别是 RedisTemplate 和 StringRedisTemplate

1620267546792.png

RedisTemplate 用来处理 key-value 是对象的数据(当然存入Redis后也会变成字符串)

StringRedisTemplate 用来处理 key-value 是字符串的数据

案例1:

准备User类,注意实现Serializable接口自动序列化

public class User implements Serializable {
    private String username;
    private String address;
    // 省略get,set,toString
}

在测试用例中分别测试运行查看结果

@SpringBootTest
class Redis01ApplicationTests {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    void contextLoads() {
        User user = new User();
        user.setUsername("southyin");
        user.setAddress("www.southyin.top");
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("u", user);
        User u = (User) valueOperations.get("u");
        System.out.println("u = " + u);
    }

    @Test
    void contextLoads1(){
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        valueOperations.set("southyin","www.southyin.top");
        String southyin = valueOperations.get("southyin");
        System.out.println(southyin);
    }

    @Test
    void contextLoads2() throws JsonProcessingException {
        User user = new User();
        user.setUsername("southyin");
        user.setAddress("www.southyin.top");
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        ObjectMapper om = new ObjectMapper();
        valueOperations.set("southyin",om.writeValueAsString(user));
        String southyin = valueOperations.get("southyin");
        User user1 = om.readValue(southyin, User.class);
        System.out.println(user1);
    }

}

注意:

redisTemplate 不管key-value是对象还是字符串都会进行序列化

stringRedisTemplate 不会对key-value进行序列化

3.session共享

在集群和分布式情况下,session共享很多时候是必要的先看如下架构:

集群

这样的架构会存在一些单服务应用不存在的问题,设想客户端发送一个请求到Nginx,被Nginx转发到Tomcat1上,Tomcat1在session中保存了写数据信息,然后客户端又发了一个请求,Nginx通过负载均衡将请求转发到了Tomcat2上,而Tomcat2上并没有之前保存的数据信息

解决这个问题比较简单,就是将各个服务中需要共享的数据保存在一个“公共场所”里,主流方案即Redis

redis

案例:

创建项目

1620269683774.png

配置文件

spring.redis.port=6379
spring.redis.password=123
spring.redis.host=192.168.189.101

HelloController

@RestController
public class HelloController {
    @Value("${server.port}")
    Integer port;

    @GetMapping("/set")
    public String set(HttpSession session) {
        session.setAttribute("southyin", "www.southyin.top");
        return String.valueOf(port);
    }

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

项目打包

1620270368440.png

1620270368440.png

上传linux后,开启两个项目

java -jar springboot-session-0.0.1-SNAPSHOT.jar --server.port=8080 >log1.log 2>&1 &
java -jar springboot-session-0.0.1-SNAPSHOT.jar --server.port=8081 >log2.log 2>&1 &

浏览器访问测试

1620270483081.png

1620270506555.png

1620270531953.png

测试发现我们并没有在8081端口下调用set存入数据,直接就能拿到8080端口下set的数据,说明session已经共享

4.Nginx实现负载均衡

上面的实例还不完美,实际操作中我们不可能人为指定的去访问8080或8081,所以采取Nginx来实现

启动nginx

1620270531953.png

进入容器,跳转目录

1620271921046.png

复制文件内容(ctrl+insert),exit退出编辑

创建文件vim default.conf,进入编辑模式后粘贴文件内容

1620271921046.png

保存后退出并粘贴进容器

docker cp ./default.conf mynginx:/etc/nginx/conf.d

再进入容器,跳转目录

1620271921046.png

查看文件

1620272448883.png

复制文件内容后,创建文件

1620272629036.png

粘贴进容器重启

1620272696280.png

启动浏览器测试查看负载均衡效果

1620272696280.png

1620272696280.png

1620290938430.png

5.接口幂特性

接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了两条,这就没有保证接口的幂等性

6.整合MongoDB

安装

准备mongo.yml

version: '3.1'

services:

  mongo:
    image: mongo
    ports:
      - 27017:27017
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: madmin
      MONGO_INITDB_ROOT_PASSWORD: m123

  mongo-express:
    links:
      - mongo
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_OPTIONS_EDITORTHEME: 3024-night
      ME_CONFIG_BASICAUTH_USERNAME: mongoexpress
      ME_CONFIG_BASICAUTH_PASSWORD: mongoexpress
      ME_CONFIG_MONGODB_ADMINUSERNAME: madmin
      ME_CONFIG_MONGODB_ADMINPASSWORD: m123

利用docker-compose启动两个容器(如果没有 docker-compose 按顺序执行如下代码安装)

cd /usr/local/bin
wget https://github.com/docker/compose/releases/download/1.14.0-rc2/docker-compose-Linux-x86_64
rename docker-compose-Linux-x86_64 docker-compose docker-compose-Linux-x86_64
chmod +x /usr/local/bin/docker-compose
docker-compose version

然后执行

docker-compose -f mongo.yml up -d

浏览器访问 ip:8081 登录,登录名和密码即为上面的 mongoexpress,刚开始默认有以下3个库

1620354987133.png

整合

创建项目

1620355246650.png

配置文件参数

spring.data.mongodb.port=27017
spring.data.mongodb.host=192.168.189.101
spring.data.mongodb.username=madmin
spring.data.mongodb.password=m123
# 采取test库,没有的话会创建test
spring.data.mongodb.database=test
# 用户密码信息基于 admin库 去认证
spring.data.mongodb.authentication-database=admin

测试用例测试,主要应用 MongoTemplate

@SpringBootTest
class SpringbootMongodbApplicationTests {
    @Autowired
    MongoTemplate mongoTemplate;
    @Test
    void contextLoads() {
        for (int i = 0; i < 10; i++) {
            User user = new User();
            user.setId((long) i);
            user.setUsername("southyin:" + i);
            user.setAddress("www.southyin.top:" + i);
            mongoTemplate.insert(user);
        }
    }

    @Test
    void contextLoads1() {
        List<User> users = mongoTemplate.findAll(User.class);
        for (User user : users) {
            System.out.println(user);
        }
    }

    @Test
    void contextLoads2() {
        User user = new User();
        user.setId(1L);
        mongoTemplate.remove(user);
    }

}

测试运行后访问 ip:8081 即 mongoexpress 查看