Redis

什么是Redis?Redis是一个基于内存的非关系型数据库,简单来说就是一个可持久化的高速缓存。

常用场景:

  1. 缓存(数据查询,端链接,新闻内容,商品内容等等)--使用最多
  2. 聊天室的在线好友列表
  3. 任务队列(秒杀,抢购,12306等等)
  4. 应用排行榜
  5. 网站访问统计
  6. 数据过期处理(可以精确到毫秒)
  7. 分布式集群架构中的session分离

高并发的三种优化思路:写入内存而不是写入硬盘、异步处理而不是同步处理、分布式处理

5种数据结构

Redis启动后自动创建16个数据库,默认选中ID为0的数据库,可以使用select id来选择数据库。

Redis是Key-Value类型的存储系统,其中key值是字符串类型,value值支持5种常用的数据类型:

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

String字符串类型

字符串类型是Redis中最为基础的数据存储类型,字符串类型的Value最多可以容纳的数据长度是512M,常用命令:

功能 命令 说明
设置(修改)值 set key value 该key存在则进行覆盖操作,该操作总是返回"OK"。
获取值 get key 获取该key关联的字符串value值。如果value值不是字符串
会报错,如果key不存在则返回nil。
删除数据 del key key2 key3... 根据指定的key删除对应的数据。可一次删除多个
批量设置值 mset key1 value1 key2 value2 同时设置多对键值对
批量取值 mget key1 key2 同时获取过个key值对应的value值
设置值(返回原来的值) getset key value 给指定的key设置value值,返回原来的值(如果原来没有值返回null)

Hash哈希类型

Redis中的Hash类型可以看成具有String Key和String Value的map容器。

功能 命令 说明
为指定的key设定field/value hset key field value 设置单个值(hset stu name zhangsan)
获取指定key的field对应的value值 hget key field 获取单个值 (hget stu name)
删除指定key的field对应的value值 hdel key field field2 ... 可以删除多个值(hdel stu name age)
为指定的key批量设置值 hmset key field value field2 value2 批量设置值
获取指定key的多个值 hmget key field field2 field3 ... 批量获取值
获取指定key的所有键值对 hgetall key 获取所有的键值对

List 队列

List类型是按照插入顺序排序的字符串链表,可保存重复数据。在插入时,如果该键不存在,Redis将为该键创建一个新的链表。如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。

功能 命令 说明
头部插入数据 lpush key value1 value2... 从list的头部开始插入数据
尾部插入数据 rpush key value1 value2... 从list的尾部开始插入数据
查看list中所有数据 lrange key 0 -1 索引0指的是列表中第一个元素,-1指列表中最后一个元素
查看list中指定索引区间的元素 lrange key start end start:开始索引,从0开始;end:结束索引;
查看指定索引的值 lindex key index index:值在list中的索引
从list的头部弹出一个值 lpop key 获取并移除list头部的第一个值
从list的尾部弹出一个值 rpop key 获取并移除list头部的最后一个值

Set 无序集合

和List类型不同的是,Set集合中不允许出现重复的元素。

功能 命令 说明
设置值 sadd key value value1 value2...
查看set中的所有值 smembers key
移除并返回集合中的任意一个元素 spop key
删除值【set集合中是元素删除完后set消失】 srem key members member1 member2...
获取集合中的成员数 scard key

SortedSet 有序集合

有序集合中,每个元素都带有score(权重),以此来对元素进行排序。它有三个元素:key、member和score。

功能 命令 说明
添加一个或多个成员 zadd key score1 member1 score2 member2 ...
获取有序集合的成员数 zcard key
通过索引区间返回有序集合成指定区间内的成员 zrange key start stop [withscores]
通过索引区间返回有序集合成指定区间内的成员【顺序排列】 zrange key start stop withscores
通过索引区间返回有序集合成指定区间内的成员【倒序排列】 zrevrange key start stop withscores
移除有序集合中的一个或多个成员 zrem key member member1 ...

通用命令

  • keys pattern获取与pattern匹配的key,*表示任意个字符,?表示一个字符
  • del key1 key2…删除key
  • exists key判断该key是否存在,1代表存在,0代表不存在
  • type key获取指定key的类型。该命令将以字符串的格式返回。 返回的字符串为string、list、set、hash,如果key不存在返回none

Redis的Java客户端Jedis

导入依赖(jedis.jar``common-pool2.jar),这个是maven坐标:

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

常用API:

方法 描述
new Jedis(host, port) 创建jedis对象,参数host是redis服务器地址,参数port是redis服务端口
set(key,value) 设置字符串类型的数据
get(key) 获得字符串类型的数据
hset(key,field,value) 设置哈希类型的数据
hget(key,field) 获得哈希类型的数据
lpush(key,values) 设置列表类型的数据
lpop(key) 列表左面弹栈
rpop(key) 列表右面弹栈
del(key) 删除指定的key

示例:

Jedis 示例
//1.创建redis核心对象:arg1-host      arg2-端口
Jedis jedis = new Jedis("localhost",6379);
//2.存值
jedis.set("name","Redis");
//3.取值
String name = jedis.get("name");
System.out.println(name);
//4.释放资源
jedis.close();

JedisPool

JedisPool有两个核心类:JedisPoolJedisPoolConfig,后者为连接池配置类。

示例:

JedisPool 示例
//1 获得连接池配置对象,设置配置项
JedisPoolConfig config = new JedisPoolConfig();
// 1.1 最大连接数
config.setMaxTotal(30);
// 1.2 最大空闲连接数
config.setMaxIdle(10);
//2 获得连接池
JedisPool jedisPool = new JedisPool(config, "localhost", 6379);
//3 获得核心对象
Jedis jedis = jedisPool.getResource(); //释放资源
if(jedis != null){
jedis.close();
}
if(jedisPool != null){
jedisPool.close();
}

Jedis简单工具类示例:

JedisUtil
package com.bilibili.query_students.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import java.util.ResourceBundle; public class JedisUtil {
private static JedisPool jedisPool;
private static int maxTotal;
private static int maxIdle;
private static String host;
private static int port; static {
//ResourceBundle类和Properties类相似,一般用于解决地域性问题
ResourceBundle jedisPorperties = ResourceBundle.getBundle("jedis");
maxTotal = Integer.parseInt(jedisPorperties.getString("maxTotal"));
maxIdle = Integer.parseInt(jedisPorperties.getString("maxIdle"));
host = jedisPorperties.getString("host");
port = Integer.parseInt(jedisPorperties.getString("port"));
} static {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(maxIdle);
config.setMaxTotal(maxTotal);
jedisPool = new JedisPool(config, host, port);
} public static Jedis getJedis(){
return jedisPool.getResource();
} public static void release(Jedis jedis){
if (jedis != null) {
jedis.close();
}
}
}

Redis与Mysql实战对比

需求:使用ajax请求将所有的学员信息加载到页面的table中。

准备数据库:

新建表
CREATE TABLE `stu_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_name` varchar(255) DEFAULT NULL,
`student_no` varchar(255) DEFAULT NULL,
`sex` int(11) DEFAULT NULL COMMENT '1-男 2-女',
`class_id` int(11) DEFAULT NULL,
`test_id` int(11) DEFAULT NULL,
`subject_no` int(11) DEFAULT NULL COMMENT '学科编号:1-java 2-php 3-python 4-UI 5-前端 6-其他',
`password` varchar(255) DEFAULT NULL,
`test_status` int(11) DEFAULT NULL COMMENT '考试状态:0-结束 1-未结束',
`test_type` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8;

随便准备一些数据(准备了2000条):

前端页面:

HTML代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come test in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="../css/bootstrap.css">
<title>Stu</title>
<style>
.stuTable{
width: 70%;
margin: 20px auto;
}
</style>
</head>
<body>
<div class="container">
<button onclick="" id="btn" class="btn btn-primary center-block">查询</button>
</div>
<table class="stuTable table table-bordered " id="stuTable" >
<caption class="text-center h2">学员列表</caption>
<tr>
<th>ID</th>
<th>姓名</th>
<th>学号</th>
<th>性别</th>
<th>班级</th>
<th>学科</th>
</tr>
</table>
</body>
<script src="../js/jquery.js"></script>
<script src="/js/myjs/students.js"></script>
</html>

页面引入的Js代码:

Js代码
$('#btn').click(function () {
$.get('/getStuListServlet', function (stuData) {
//注意这里需要把字符串转化为JSON对象,然后调用JQuery的each方法
$.each(JSON.parse(stuData), function (index, element) {
element.sex = element.sex === '1' ? '男' : '女';
element.class_id = '就业班';
element.subject_no = 'java';
$("<tr><td>" + element.id + "</td><td>" + element.student_name + "</td><td>" + element.student_no + "</td><td>" + element.sex + "</td><td>" + element.class_id + "</td><td>" + element.subject_no + "</td></tr>").appendTo($("#stuTable"));
})
});
});

导入的jar包(这个Demo没用Maven):

数据库连接池和Jedis的连接池配置文件:

配置文件
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 1. 数据库的连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/forservlet</property>
<property name="user">root</property>
<property name="password">1234</property> <!-- 2. 连接池参数 -->
<!--初始连接数-->
<property name="initialPoolSize">5</property>
<!--最大连接数-->
<property name="maxPoolSize">10</property>
<!--等待多久以后抛出异常-->
<property name="checkoutTimeout">2000</property>
</default-config> <!-- 命名配置 -->
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/how2sql</property>
<property name="user">root</property>
<property name="password">root</property> <!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
host=127.0.0.1
port=6379
maxTotal=50
maxIdle=10

接着是Java代码:

JavaBean:Student类

实体类Student
package com.bilibili.query_students.bean;

public class Student {
private Integer id;
private String student_name;
private String student_no;
private Integer sex;
private Integer class_id;
private Integer subject_no; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getStudent_name() {
return student_name;
} public void setStudent_name(String student_name) {
this.student_name = student_name;
} public String getStudent_no() {
return student_no;
} public void setStudent_no(String student_no) {
this.student_no = student_no;
} public Integer getSex() {
return sex;
} public void setSex(Integer sex) {
this.sex = sex;
} public Integer getClass_id() {
return class_id;
} public void setClass_id(Integer class_id) {
this.class_id = class_id;
} public Integer getSubject_no() {
return subject_no;
} public void setSubject_no(Integer subject_no) {
this.subject_no = subject_no;
}
}

数据库和Jedis工具类:

工具类

数据库工具类

package com.bilibili.query_students.util;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; public class DataSourceUtil {
private static DataSource dataSource = new ComboPooledDataSource(); public static DataSource getDataSource(){
return dataSource;
} public static JdbcTemplate getJdbcTemplate(){
return new JdbcTemplate(dataSource);
}
}

Jedis工具类:

package com.bilibili.query_students.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import java.util.ResourceBundle; public class JedisUtil {
private static JedisPool jedisPool;
private static int maxTotal;
private static int maxIdle;
private static String host;
private static int port; static {
ResourceBundle jedisPorperties = ResourceBundle.getBundle("jedis");
maxTotal = Integer.parseInt(jedisPorperties.getString("maxTotal"));
maxIdle = Integer.parseInt(jedisPorperties.getString("maxIdle"));
host = jedisPorperties.getString("host");
port = Integer.parseInt(jedisPorperties.getString("port"));
} static {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(maxIdle);
config.setMaxTotal(maxTotal);
jedisPool = new JedisPool(config, host, port);
} public static Jedis getJedis(){
return jedisPool.getResource();
} public static void release(Jedis jedis){
if (jedis != null) {
jedis.close();
}
}
}

然后是三层架构:

后端

控制层:

package com.bilibili.query_students.web;

import com.bilibili.query_students.service.StudentService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException; @WebServlet("/getStuListServlet")
public class StuListServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StudentService studentService = new StudentService();
String stuJsonData = studentService.queryAllStudent();
response.setContentType("text/plain;charset=utf-8");
response.getWriter().print(stuJsonData);
}
}

业务层:

package com.bilibili.query_students.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.bilibili.query_students.bean.Student;
import com.bilibili.query_students.dao.StudentDao;
import com.bilibili.query_students.util.JedisUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.Jedis; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List; @WebServlet(name = "StudentService")
public class StudentService extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } public String queryAllStudent() {
Jedis jedis = JedisUtil.getJedis();
long redisBegin = System.currentTimeMillis();
String stuData = jedis.get("stuData");
if (stuData != null) {
long redisEnd = System.currentTimeMillis();
System.out.println("redis : "+(redisEnd-redisBegin));
} //Redis中没查询到则到MySQL中查询,并将结果添加到Redis中
if (stuData == null) {
StudentDao studentDao = new StudentDao();
long start = System.currentTimeMillis();
List<Student> list = studentDao.queryAll();
long end = System.currentTimeMillis();
System.out.println("sql : "+(end - start));
try {
stuData = new ObjectMapper().writeValueAsString(list);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
jedis.set("stuData", stuData);
}
JedisUtil.release(jedis);
return stuData;
}
}

持久层:

package com.bilibili.query_students.dao;

import com.bilibili.query_students.bean.Student;
import com.bilibili.query_students.util.DataSourceUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate; import java.util.List; public class StudentDao {
public List<Student> queryAll(){
JdbcTemplate jdbcTemplate = DataSourceUtil.getJdbcTemplate();
String sql = "select * from stu_info";
List<Student> stus = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Student.class));
return stus;
}
}

查询时间对比:

第一次查询在SQL中查询,2000条花费74毫秒,后面的查询均在Redis中查,花费1毫秒。


小结:Redis非常适合作为高并发的缓存。

Redis持久化

redis 支持两种持久化方式,一种是 RDB(快照)也是默认方式,另一种是 Append-only file(缩写AOF)的方式。

RDB

快照是默认持久化方式,也就是将内存中的所有数据写入硬盘。该方式有三种保存方式:一种是直接在主进程使用save命令,此时会此命令阻塞主进程,Redis将不再接收请求,直到数据写入完毕。第二种是调用bgsave命令,此时会fork出一条子进程,主进程继续接受请求,子进程进行持久化操作,持久化完毕后自动退出,这种方式会消耗更多的内存,优点是不会阻塞主进程。还有一种是自动保存机制,可以设置在单位时间内若果达到多少条修改便会自动保存。

这是Redis持久化配置选项:

###快照持久化选项

# 在win上这三个初始设定不生效,不知道为什么,自己从新设置的却可以
save 900 1 #900 秒内如果超过 1 个 key 被修改,则发起快照保存
save 300 10 #300 秒内容如超过 10 个 key 被修改,则发起快照保存
save 60 10000 #60 秒内如果超过10000个key被修改,则发起快照保存
stop-write-on-bgsave-error ###创建快照失败后是否仍然继续执行写命令
rdbcompression yes ###是否对快照进行压缩
dbfilename dump。rdb ###快照命名 ###AOF持久化选项
appendonly no ###是否进行AOF持久化
appendfaync everysec ###自动AOF间隔时长
no-appendfaync-on-rewrite no ###压缩时能否进行同步操作
# 重写需要同时满足下面的两个条件
auto-aof-rewrite-percentage 100 ###(文件增长率)相比上一次重写之后体积大于一倍(100%)执行压缩操作
auto-aof-rewrite-min-size 64mb ###体积大于64mb时执行压缩操作 dir ./ ###快照文件和AOF文件保存位置

RDB优缺点:

优点:

  1. 文件实现的数据快照,全量备份,便于数据的传输.比如我们需要把A服务器上的备份文件传输到B服务器上面,直接将rdb文件拷贝即可.
  2. 文件采用压缩的二进制文件,当重启服务时加载数据文件,比aof方式更快.

缺点:

  1. rbd采用加密的二进制格式存储文件,由于Redis各个版本之间的兼容性问题也导致rdb由版本兼容问题导致无法再其他的Redis版本中使用.
  2. 时效性差,容易造成数据的不完整性.因为rdb并不是实时备份,当某个时间段Redis服务出现异常,内存数据丢失,这段时间的数据是无法恢复的,因此易导致数据的丢失.

AOF

AOF的原理是以日志形式记录客户端的写入过程,然后再次启动的时候按照记录进行操作。

AOF有三种记录策略:

  1. appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化
  2. appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中
  3. appendfsync no //完全依赖 os,性能最好,持久化没保证

以日志记录数据的方式缺点是多次写操作写入一个数据时AOF文件会记录每次操作而变得臃肿,并且最后一次操作之后前面的操作记录就失效了。因此Redis引入了重写机制,也就是将过期数据剔除,从而达到减小文件大小的作用。

AOF的优缺点

优点:

  1. 多种文件写入(fsync)策略.
  2. 数据实时保存,数据完整性强.即使丢失某些数据,制定好策略最多也是一秒内的数据丢失.
  3. 可读性强,由于使用的是文本协议格式来存储的数据,可有直接查看操作的命令,同时也可以手动改写命令.

缺点:

  • 文件体积过大,加载速度比rbd慢.由于aof记录的是redis操作的日志,一些无效的,可简化的操作也会被记录下来,造成aof文件过大.但该方式可以通过文件重写策略进行优化.

RDB与AOF两种方式对比:

对比 RDB AOF
启动优先级
体积
恢复速度
数据安全性 可能丢数据 根据策略决定
轻重
兼容性 二进制加密,不同版本可能会出现不兼容 兼容性好,以文本形式记录命令,可直接查看,甚至直接修改

RDB与AOF的选择:

  1. 针对不同的情况来选择,建议使用两种方式相结合.
  2. 针对数据安全性、完整性要求高的采用aof方式.
  3. 针对不太重要的数据可以使用rdb方式.
  4. 对于数据进行全量备份,便于数据备份的可以采用rdb方式.

主从复制

这东西还是贴个Redis系列的博客吧深入学习Redis

以后再看。。。(〃` 3′〃)

Web基础之Redis的更多相关文章

  1. 基础拾遗------redis详解

    基础拾遗 基础拾遗------特性详解 基础拾遗------webservice详解 基础拾遗------redis详解 基础拾遗------反射详解 基础拾遗------委托详解 基础拾遗----- ...

  2. Golang友团无闻Go语言Web基础视频教程

    教程内容:GO语言资料Golang友团无闻Go语言编程基础Golang友团无闻Go语言Web基础教程 Go语言Web基础教程列表:[Go Web基础]12Go Web 扩展学习.mp4[Go Web基 ...

  3. HT for Web基础动画介绍

    在上一篇<基于HT for Web矢量实现3D叶轮旋转>一文中,我略微提了下HT for Web基础动画的相关用法,但是讲得不深入,今天就来和大家分享下HT for Web基础动画的相关介 ...

  4. Web基础开发最核心要解决的问题

    Web基础开发要解决的问题,往往也就是那些框架出现的目的 - 要解决问题. 1. 便捷的Db操作: 2. 高效的表单处理: 3. 灵活的Url路由: 4. 合理的代码组织结构: 5. 架构延伸 缓存. ...

  5. web基础--html

    WebBasic 1.web应用体系 课程大纲 1.web基础:做网页     2.结构:         a.html             勾勒网页结构及内容         b.css     ...

  6. java web基础环境搭建

    java web基础环境包括:(1)servlet容器也即tomcat(2)jre即java程序运行环境 环境变量配置:分别下载jdk和tomcat安装包. jdk环境变量配置: 第一步:系统环境变量 ...

  7. Web基础知识和技术

    WEB是一个外延广泛的概念,不单单指网站,乌徒帮专注拥有WEB界面的网站开发,帮助初学者或已经进入开发的朋友们提供参考讨论平台,然而并不一定能将所有的WEB知识讲全讲透,只是能满足初涉者的建站需求,能 ...

  8. java web基础 --- URL重定向Filter

    java web基础 --- URL重定向Filter httpRequest.getRequestDispatcher("/helloWorld").forward(httpRe ...

  9. (0)写给Web初学者的教案-----Web基础

    0,Web基础 一.    What is the Web? Can It Eat? 很多同学可能都听说过一个名词叫做“Web”,这个词隐隐约约好像和我们上网相关.但是呢,又很难说的清楚.我们今天每位 ...

随机推荐

  1. ADV-298 和谐宿舍2 动态规划

    和谐宿舍2 问题描述 我的某室友学过素描,墙上有n张他的作品.这些作品都是宽度为1,高度不定的矩形,从左到右排成一排,且底边在同一水平线上. 宿舍评比就要来了,为了及格,我们决定买不多于m块的矩形木板 ...

  2. 「Luogu P2845 [USACO15DEC]Switching on the Lights 开关灯」

    USACO的又一道搜索题 前置芝士 BFS(DFS)遍历:用来搜索.(因为BFS好写,本文以BFS为准还不是因为作者懒) 链式前向星,本题的数据比较水,所以邻接表也可以写,但是链式前向星它不香吗. 具 ...

  3. [GoogleInterview]连续子序列问题

    Before the Beginning 本文为 Clouder 原创文章,原文链接为 https://www.codein.icu/gci-subarray/,转载时请将本段放在文章开头显眼处.如进 ...

  4. 104、Java中String类之使用indexOf()等功能查找

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  5. 嵊州普及Day5T4

    题意:两个1,每次可将一个*k,一个*K2,n个问题,问能否达成x,y? 思路:只有将x,y相乘为3次方时,才可能.并且相乘的三次方一定要是x,y的因子. 下面证明:3次方易证,因为对每个k,都会乘三 ...

  6. 1-4SpringBoot操作之Spring-Data-Jpa(一)

    Spring-Data-Jpa JPA(Java Persistence API)定义了一系列对象持久化的标准, 目前实现这一规范的产品有Hibernate.TopLink等. Spring Data ...

  7. 多门店4s管理系统

    下载 系统登录用户名与密码:manage/123456

  8. uni-app小程序滑动事件

    <view class="relative" @touchmove="handletouchmove" @touchstart="handlet ...

  9. CentOS configuration uses the SFTP server

    SFTP,即 SSH 文件传输协议( SSH File Transfer Protocol ),或者说是安全文件传输协议( Secure File Transfer Protocol ).SFTP 是 ...

  10. JS动态判断设备类型为PC或者移动端,然后根据设备加载相应的代码

    这里是通过JS判断设备之后加载相应的网站,如果是移动端加载m开头的网站域名,如果是PC端就加载 www.开头的正式域名 <script> (function () { var url = ...