使用RedisTemplate

  1. 添加gradle依赖
dependencies {implementation 'org.springframework.boot:spring-boot-starter-jdbc'implementation 'org.springframework.boot:spring-boot-starter-data-redis'implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'implementation 'org.springframework.boot:spring-boot-starter-web'implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3'//lettuce依赖commons-pool2compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.6.2'runtimeOnly 'mysql:mysql-connector-java'compileOnly 'org.projectlombok:lombok'annotationProcessor 'org.projectlombok:lombok'testImplementation('org.springframework.boot:spring-boot-starter-test') {exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'}compile('org.springframework.boot:spring-boot-starter-cache')
}
  1. application.properties 添加redis连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456server.port=8945#redis数据库默认使用db0
spring.redis.database=2
spring.redis.password=
spring.redis.port=6379
spring.redis.host=127.0.0.1
# 连接超时时间
spring.redis.timeout=5s
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=8
# 连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
# 连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.lettuce.pool.max-wait=-1
#在关闭客户端连接之前等待任务处理完成的最长时间,在这之后,无论任务是否执行完成,都会被执行器关闭,默认100ms
spring.redis.lettuce.shutdown-timeout=100ms
#缓存保存时间(单位:秒)
spring.cache.redis.time-to-live=1800
#是否缓存空值
spring.cache.redis.cache-null-values=false
  1. 编写配置类
package org.example.base.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** @author l* @date Created in 2020/11/3 10:51*/
@Configuration
//@EnableCaching
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> restTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);//使用Jackson2JsonRedisSerializer替换默认的JdkSerializationRedisSerializer来序列化和反序列化redis的value值Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(mapper);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}
  1. 测试
@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Testpublic void test4() {//值类型操作User user = new User(231, "l", 12);ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();valueOperations.set(user.getId() + "", user, Duration.ofSeconds(1000));User user1 = (User) valueOperations.get(user.getId() + "");System.out.println(user1);//集合set类型操作SetOperations<String, Object> setOperations = redisTemplate.opsForSet();setOperations.add("keys","盖伦","卡特琳娜","崔丝塔娜","德莱厄斯");redisTemplate.expire("keys",Duration.ofSeconds(1000));Set<Object> members = setOperations.members("keys");System.out.println(members);System.out.println(redisTemplate.boundSetOps("keys").members());//集合zset类型操作ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();zSetOperations.add("zkeys","赵信",1.3);zSetOperations.add("zkeys","孙悟空",1.6);redisTemplate.expire("keys",Duration.ofSeconds(1000));System.out.println(zSetOperations.range("zkeys",0,-1));System.out.println(redisTemplate.boundZSetOps("zkeys").range(0,-1));//集合hash类型操作redisTemplate.boundHashOps("坦克").put("1","墨菲特");redisTemplate.boundHashOps("坦克").put("2","茂凯");redisTemplate.boundHashOps("坦克").put("3","奥恩");redisTemplate.expire("坦克",Duration.ofSeconds(1000));System.out.println(redisTemplate.boundHashOps("坦克").keys());System.out.println(redisTemplate.boundHashOps("坦克").values());//集合list类型操作redisTemplate.boundListOps("法师").rightPush("艾克");redisTemplate.boundListOps("法师").rightPush("奥莉安娜");redisTemplate.boundListOps("法师").leftPush("维迦");redisTemplate.boundListOps("法师").leftPush("维迦","卡萨丁");redisTemplate.boundListOps("法师").expire(Duration.ofSeconds(20L));System.out.println(redisTemplate.boundListOps("法师").range(0,100));}
  1. 结果


  1. RedisTemplate常用工具类
package com.example.util;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;@Component
public class RedisUtil {private final RedisTemplate<String, Object> redisTemplate;@Autowiredpublic RedisUtil(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}/*** 指定缓存失效时间** @param key  键* @param time 时间(秒)*/public void expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}} catch (Exception e) {e.printStackTrace();}}/*** 根据key 获取过期时间** @param key 键 不能为null* @return 时间(秒) 返回0代表为永久有效*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在** @param key 键* @return true 存在 false不存在*/public boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除缓存** @param key 可以传一个值 或多个*/@SuppressWarnings("unchecked")public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete(CollectionUtils.arrayToList(key));}}}//============================String=============================/*** 普通缓存获取** @param key 键* @return 值*/public Object get(String key) {return redisTemplate.opsForValue().get(key);}/*** 普通缓存放入** @param key   键* @param value 值* @return true成功 false失败*/public boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 普通缓存放入并设置时间** @param key   键* @param value 值* @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public boolean set(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 递增** @param key   键* @param delta 要增加几(大于0)* @return*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 递减** @param key   键* @param delta 要减少几(小于0)* @return*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}//================================Map=================================/*** HashGet** @param key  键 不能为null* @param item 项 不能为null* @return 值*/public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);}/*** 获取hashKey对应的所有键值** @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet** @param key 键* @param map 对应多个键值* @return true 成功 false 失败*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashSet 并设置时间** @param key  键* @param map  对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public boolean hmset(String key, Map<String, Object> map, long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @return true 成功 false失败*/public boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @param time  时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*/public boolean hset(String key, String item, Object value, long time) {try {redisTemplate.opsForHash().put(key, item, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除hash表中的值** @param key  键 不能为null* @param item 项 可以使多个 不能为null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值** @param key  键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回** @param key  键* @param item 项* @param by   要增加几(大于0)* @return*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key  键* @param item 项* @param by   要减少记(小于0)* @return*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}//============================set=============================/*** 根据key获取Set中的所有值** @param key 键* @return*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();return null;}}/*** 根据value从一个set中查询,是否存在** @param key   键* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {e.printStackTrace();return false;}}/*** 将数据放入set缓存** @param key    键* @param values 值 可以是多个* @return 成功个数*/public long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 将set数据放入缓存** @param key    键* @param time   时间(秒)* @param values 值 可以是多个* @return 成功个数*/public long sSetAndTime(String key, long time, Object... values) {try {Long count = redisTemplate.opsForSet().add(key, values);if (time > 0) {expire(key, time);}return count;} catch (Exception e) {e.printStackTrace();return 0;}}/*** 获取set缓存的长度** @param key 键* @return*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 移除值为value的** @param key    键* @param values 值 可以是多个* @return 移除的个数*/public long setRemove(String key, Object... values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {e.printStackTrace();return 0;}}//===============================list=================================/*** 获取list缓存的内容** @param key   键* @param start 开始* @param end   结束  0 到 -1代表所有值* @return*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取list缓存的长度** @param key 键* @return*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通过索引 获取list中的值** @param key   键* @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推* @return*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 将list放入缓存** @param key   键* @param value 值* @return*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, Object value, long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据索引修改list中的某条数据** @param key   键* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 移除N个值为value** @param key   键* @param count 移除多少个* @param value 值* @return 移除的个数*/public long lRemove(String key, long count, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}}}

使用Spring cache 注解

  1. 添加gradle依赖(同上)
  2. application.properties 添加redis连接信息(同上)
  3. 编写配置类
package org.example.base.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;/*** @author l* @date Created in 2020/11/3 10:51*/
@Configuration
@EnableCaching
public class RedisConfig {Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);@Beanpublic RedisTemplate<String, Object> restTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);//使用Jackson2JsonRedisSerializer替换默认的JdkSerializationRedisSerializer来序列化和反序列化redis的value值ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(mapper);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}@Bean("redisCacheManager")@Primarypublic CacheManager cacheManager(RedisConnectionFactory factory) {RedisSerializer<String> redisSerializer = new StringRedisSerializer();//解决查询缓存转换异常的问题ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(mapper);// 配置1 ,RedisCacheConfiguration config1 = RedisCacheConfiguration.defaultCacheConfig()//缓存失效时间.entryTtl(Duration.ofSeconds(36000))//key序列化方式.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))//value序列化方式.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))//不允许缓存null值.disableCachingNullValues();//配置2 ,RedisCacheConfiguration config2 = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(1000)).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).disableCachingNullValues();//设置一个初始化的缓存空间set集合Set<String> cacheNames = new HashSet<>();cacheNames.add("my-redis-cache1");cacheNames.add("my-redis-cache2");//对每个缓存空间应用不同的配置Map<String, RedisCacheConfiguration> configurationMap = new HashMap<>(3);configurationMap.put("my-redis-cache1", config1);configurationMap.put("my-redis-cache2", config2);return RedisCacheManager.builder(factory)//默认缓存配置.cacheDefaults(config1)//初始化缓存空间.initialCacheNames(cacheNames)//初始化缓存配置.withInitialCacheConfigurations(configurationMap).build();}}
  1. 编写service层
package org.example.base.service.impl;import org.example.base.bean.Animal;
import org.example.base.service.AnimalService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;/*** @author l* @date Created in 2020/11/4 17:33*/
@Service
@CacheConfig(cacheNames = "my-redis-cache1", cacheManager = "redisCacheManager")
public class AnimalServiceImpl implements AnimalService {@Override@Cacheable(key = "#id",sync = true)public Animal getAnimal(Integer id) {System.out.println("操作数据库,返回Animal");return new Animal(110, "cat", "fish");}/*** 使用@CachePut注解的方法,一定要有返回值,该注解声明的方法缓存的是方法的返回结果。* it always causes the* method to be invoked and its result to be stored in the associated cache**/@Override@CachePut(key = "#animal.getId()")public Animal setAnimal(Animal animal) {System.out.println("存入数据库");return animal;}@Override@CacheEvict(key = "#id")public void deleteAnimal(Integer id) {System.out.println("删除数据库中animal");}@Override@CachePut(key = "#animal.getId()")public Animal updateAnimal(Animal animal) {System.out.println("修改animal,并存入数据库");return animal;}}
  1. 测试
    @AutowiredAnimalService animalService;@Testpublic void test5() {Animal animal = new Animal(120, "dog", "bone");animalService.setAnimal(animal);System.out.println(animalService.getAnimal(120));animalService.updateAnimal(new Animal(120, "dog", "meat"));System.out.println(animalService.getAnimal(120));animalService.deleteAnimal(120);System.out.println(animalService.getAnimal(120));}
  1. 结果


springboot2整合redis的两种使用方式相关推荐

  1. Springboot2整合kafka的两种使用方式

    Springboot2整合kafka kafka docker上安装环境 Springboot2引入kafka 基于注解 基于客户端 kafka是一个分布式消息队列.在项目中应用十分广泛,具有高性能. ...

  2. redis的两种持久化方式详解

    一.背景 在实际开发中,为了保证数据的完整性,防止数据丢失,我们除了在原有的传统数据库保存数据的同时,最好是再用redis持久化再保存一次数据.如果仅仅是使用redis而不进行持久化配置的话,当red ...

  3. Redis的两种持久化方式

    Redis的高性能是由于其将所有的数据都存储在了内存中,为了使Redis在重启之后仍然能保证数据不丢失,需要将数据存内存中同步到硬盘中,这一过程就是持久化.Redis支持两种方式的持久化,一种是RDB ...

  4. Redis的两种备份方式:RDB和AOF

    在 Redis 中存在两种方式的备份:一种是快照恢复(RDB),通过快照(snapshotting)实现的,它是备份当前瞬间 Redis 在内存中的数据记录. 另一种是只追加文件(Append-Onl ...

  5. 将java对象存储到redis数据库(两种实现方式)

    本文为转载内容,特此声明,如若侵权,请联系删除,原文地址:https://www.cnblogs.com/potentPrince/p/8668544.html redis主要存储类型最常用的五种数据 ...

  6. Windows下修改redis端口号的方法及修改后redis的两种启动方式

    1.win+R输入cmd,然后打开Redis所在的文件路径,并输入redis-server.exe启动Redis. 如图我们可以看到现在的端口号为6379,也就是redis的默认端口号.我们可以记住这 ...

  7. Redis的两种连接方式

    1.简单连接 import redis conn = redis.Redis(host='207.148.120.229', port=6379) conn.set('foo', 'Bar') pri ...

  8. 探究Redis两种持久化方式下的数据恢复

    对长期奋战在一线的后端开发人员来说,都知道redis有两种持久化方式RDB和AOF,虽说大家都知道这两种方式大概运作方式,但想必有实操的人不会太多. 这里是自己实操两种持久化方式的一点点记录. 先看以 ...

  9. git整合分支的两种方式 merge 和 rebase

    git merge 和 git rebase 是整合分支的两种不同方式. 两者最大的区别是整合后的提交记录 两者没有绝对的好坏,适用不同的场景 一般的开发使用merge即可.除非对提交记录有特别的要求 ...

最新文章

  1. 大话云计算——认识云——“瑞友杯”虚拟化征文
  2. java知识大全积累篇
  3. 新华计算机学校环境好吗,新华电脑校园环境好不好?(二)
  4. 计算机老师任课教师寄语,任课老师寄语大全
  5. java bufferedwriter会自动创建文件吗_Java中为什么会有包装类?自动拆装箱必要吗?关于Wrapping Class这是重点!...
  6. ICSharpCode.SharpZipLib 压缩、解压文件 附源码
  7. linux下图片加密原理,Linux中常见的加密技术介绍
  8. java override报红_Eclipse @override报错解决
  9. centos7.4批量自动化安装(pxe、cobbler、制作自动化iso镜像);pxe安装;cobbler安装;
  10. 状态位字段使用char(1)还是tinyint(1)?
  11. Transformer-XL、Vanilla Transformer
  12. 【动画消消乐 】一个小清新类型的全局网页过渡动画 075
  13. cesium接入天地图影像与注记(经纬度)(cesium篇.70)
  14. 左岸读书-语不惊人死不休(95)
  15. 查看已有的docker镜像latest的具体版本号
  16. 程序设计思维与实践 Month3 模拟
  17. WideBaselineFeatureMatcher_PAMI
  18. 安卓虚拟键盘_这是第一台安卓手机,当年谷歌和 HTC 靠它正面刚苹果
  19. java(十)【属性集,缓冲流、转换流、序列化流】
  20. ZBar条型码、二维码

热门文章

  1. MYSQL导出数据字典
  2. python中isin函数_Python numpy.isin函数方法的使用
  3. 腾讯开放平台——client id is illegal(100008)!错误解决
  4. 梦想CAD控件COM接口光栅图处理
  5. 穿越雷区(Java)
  6. 总结SLAM论文主要创新点和论文分类 —— 持续更新ing
  7. 品效协同,国货新秀colorkey珂拉琪的户外广告制胜秘籍
  8. java多线程 守护线程setDaemon
  9. iOS 获取步数等健康信息
  10. pcDuino入门指南+如何烧写系统(SD卡-卡刷)