10月6日后端学习笔记(数据库)
发布时间:
本文字数: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数据类型
- string(字符串)
- hash(哈希)
- list(列表)
- set(集合
- zset(sorted set:有序集合)
操作命令
select index
选取数据库 index 0-15Keys *
查看所有的值Del key
删除指定的keyPEXPIRE key milliseconds
设置key的过期时间 毫秒单位Pttl key
获取key的剩余过期时间PERSIST key
移除key的过期时间 将永久保存set key value
设置键值get key
获取键值
Hash类型
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象GET key 获取指定key的value
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)
HMSET key field value field value …
设置key及hash字段和值HGETALL key
获取在哈希表中指定 key 的所有字段和值HGET key field
获取存储在哈希表中指定字段的值HDEL key field1 [field2]
删除一个或多个哈希表字段
List类型
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
LPUSH key value
将一个值插入到已存在的列表头部LLEN key
获取列表长度LINDEX key index
通过索引获取列表中的元素LRANGE key start stop
获取列表指定范围内的元素
Set类型
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
SADD key member1 [member2]
向集合添加一个或多个成员SCARD key
获取集合的成员数SMEMBERS key
返回集合中的所有成员SREM key member1 [member2]
移除集合中一个或多个成员
Sorted set类型
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序,有序集合的成员是唯一的,但分数(score)却可以重复。
ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,或者更新已存在成员的分数ZCARD key
获取有序集合的成员数ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合指定区间内的成员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常见问题
- 缓存穿透
查询多次数据库不存在的对象,会对数据库造成压力。
解决方法:数据库返回空对象,存入缓存 - 缓存击穿
大量请求查询同一个key,缓存过期后给数据库造成压力 - 缓存雪崩
大量请求查询不同key