10月6日后端学习笔记(数据库)

标签

mybatis

mysql

数据库

redis

缓存

发布时间:

本文字数:1,194 字 阅读完需:约 4 分钟

jackson maven 依赖

pom.xml

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.6</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.6</version>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.9.6</version>
    </dependency>

MappingJackson2HttpMessageConverter

MappingJackson2HttpMessageConverter的意义是使用jackson处理controller层的返回值,将返回对象自动转为json字符串

spring-mvc.xml

    <!--开启RequestMapping映射处理器和适配器-->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=utf-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

配置完MappingJackson2HttpMessageConverter消息转换器后,只需要将controller层返回值改为ajaxresult对象即可,如下所示

package com.zr.controller.sys;

import com.alibaba.fastjson.JSON;
import com.zr.service.sys.SysUserService;
import com.zr.utils.AjaxResult;
import com.zr.vo.sys.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    @PostMapping("/login.action")
    public AjaxResult login(@RequestBody SysUser sysUser){
        SysUser user = sysUserService.login(sysUser);
        AjaxResult ajaxResult = null;
        if(user != null) {
            ajaxResult = AjaxResult.success(200,"登录成功", user);
        }else{
            ajaxResult = AjaxResult.fail(200,"账号或密码错误", null);
        }
         return ajaxResult;
    }

}

jsonformat注解

加在vo层

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    public Date getCreateTime() {
        return createTime;
    }

redis 基础

Redis数据类型

  1. string(字符串)
  2. hash(哈希)
  3. list(列表)
  4. set(集合
  5. zset(sorted set:有序集合)

操作命令

  1. select index 选取数据库 index 0-15
  2. Keys * 查看所有的值
  3. Del key 删除指定的key
  4. PEXPIRE key milliseconds 设置key的过期时间 毫秒单位
  5. Pttl key 获取key的剩余过期时间
  6. PERSIST key 移除key的过期时间 将永久保存
  7. set key value 设置键值
  8. get key 获取键值

Hash类型

Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象GET key 获取指定key的value
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)

  1. HMSET key field value field value … 设置key及hash字段和值
  2. HGETALL key 获取在哈希表中指定 key 的所有字段和值
  3. HGET key field 获取存储在哈希表中指定字段的值
  4. HDEL key field1 [field2] 删除一个或多个哈希表字段

List类型

Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

  1. LPUSH key value 将一个值插入到已存在的列表头部
  2. LLEN key 获取列表长度
  3. LINDEX key index 通过索引获取列表中的元素
  4. LRANGE key start stop 获取列表指定范围内的元素

Set类型

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

  1. SADD key member1 [member2] 向集合添加一个或多个成员
  2. SCARD key 获取集合的成员数
  3. SMEMBERS key 返回集合中的所有成员
  4. SREM key member1 [member2] 移除集合中一个或多个成员

Sorted set类型

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序,有序集合的成员是唯一的,但分数(score)却可以重复。

  1. ZADD key score1 member1 [score2 member2]向有序集合添加一个或多个成员,或者更新已存在成员的分数
  2. ZCARD key获取有序集合的成员数
  3. ZRANGE key start stop [WITHSCORES]通过索引区间返回有序集合指定区间内的成员
  4. ZREM key member [member ...]移除有序集合中的一个或多个成员

redis java 连接

pom.xml

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

连接测试

    @Test
    public void testRedis(){
        Jedis jedis = new Jedis(new HostAndPort("127.0.0.1", 6379));
        System.out.println(jedis.ping());
        jedis.set("city", "长春");
        System.out.println(jedis.get("city"));
        jedis.close();
    }

transient 关键字表示该属性不会被序列化

User.java

package com.zr.vo;

import java.io.Serializable;

public class User implements Serializable {
    private String userId;
    private String userName;
//    transient 关键字表示该属性不会被序列化
    private transient String password;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    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;
    }
}

SerializableUtil.java

package com.zr.utils;

import java.io.*;

public class SerializableUtil {
    public static byte[] serializable(Object object) throws IOException {
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bao);
        oos.writeObject(object);
        oos.flush();
        return bao.toByteArray();
    }
    public static Object unSerializable(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteArrayInputStream bai = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bai);
        return ois.readObject();
    }
}

AppTest.java

package com.zr;

import static org.junit.Assert.assertTrue;

import com.zr.utils.SerializableUtil;
import com.zr.vo.User;
import org.junit.Test;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;

import java.io.IOException;

/**
 * Unit test for simple App.
 */
public class AppTest 
{
    @Test
    public void testRedis() throws IOException, ClassNotFoundException {
        Jedis jedis = new Jedis(new HostAndPort("127.0.0.1", 6379));
        System.out.println(jedis.ping());
        User user = new User();
//        user.setUserId("admin");
//        user.setUserName("管理员");
//        user.setPassword("1234");
//        jedis.set("yonghu".getBytes(), SerializableUtil.serializable(user));
        Object obj = SerializableUtil.unSerializable(jedis.get("yonghu".getBytes()));
        if(obj.getClass().getName().contains("User")){
            user = (User) obj;
        }
        System.out.println(user.getUserName());
        jedis.close();

    }
}

redis持久化

RDB方式

redis database

会丢失最后一次的更改

二进制文件保存 速度快 快照

# 900秒之内1次更改
save 900 1
save 300 10
save 60 10000

AOF方式

append only file

保存运行的命令,每次运行时重新执行一遍所有命令
速度慢

redis常见问题

  1. 缓存穿透
    查询多次数据库不存在的对象,会对数据库造成压力。
    解决方法:数据库返回空对象,存入缓存
  2. 缓存击穿
    大量请求查询同一个key,缓存过期后给数据库造成压力
  3. 缓存雪崩
    大量请求查询不同key