当前位置: 首页 > news >正文

晋城做网站网站怎么优化推荐

晋城做网站,网站怎么优化推荐,网站管理系统源码,网建天地户型图Redis 学习笔记 2:Java 客户端 常见的 Redis Java 客户端有三种: Jedis,优点是API 风格与 Redis 命令命名保持一致,容易上手,缺点是连接实例是线程不安全的,多线程场景需要用线程池来管理连接。Redisson&…

Redis 学习笔记 2:Java 客户端

常见的 Redis Java 客户端有三种:

  • Jedis,优点是API 风格与 Redis 命令命名保持一致,容易上手,缺点是连接实例是线程不安全的,多线程场景需要用线程池来管理连接。
  • Redisson,在Redis基础上实现了分布式的可伸缩的java数据结构,例如Map、Queue等,而且支持跨进程的同步机制:Lock、Semaphore等待,比较适合用来实现特殊的功能需求。
  • lettuce,基于 Netty 实现,支持同步/异步和响应式编程,并且是线程安全的。支持 Redis 的哨兵模式、集群模式和管道模式。

Spring 对 Jedis 和 lettuce 进行了封装,spring-data-redis 提供统一的 API 进行操作。

Jedis

单个连接

下面是一个简单的 Jedis 连接示例。

创建一个 mvn 工程,并添加 Jedis 和 Junit 依赖:

<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.10.0</version><scope>test</scope>
</dependency>
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.0.0</version>
</dependency>

编写一个单元测试:

public class AppTests {private Jedis jedis;@BeforeEachpublic void beforeEach() {jedis = new Jedis("192.168.0.88", 6379);jedis.auth("123321");jedis.select(0);}@Testpublic void testString() {String res = jedis.set("name", "Jack");System.out.println(res);res = jedis.get("name");System.out.println(res);}@Testpublic void testHash() {jedis.hset("user:1", "name", "Jack");jedis.hset("user:1", "age", "18");Map<String, String> map = jedis.hgetAll("user:1");System.out.println(map);}@AfterEachpublic void afterEach() {if (jedis != null) {jedis.close();}}
}

在这个单元测试中,展示了如何使用 Jedis 客户端连接 Redis,并用 API 操作 String 类型和 Hash 类型的数据。基本上,这些 API 的命名和使用方式与前文介绍的 Redis 命令是相似的。

连接池

创建一个 Jedis 连接池的工具类:

public class JedisConnectionFactory {// Jedis 连接池private static JedisPool jedisPool;// 初始化 Jedis 连接池static {// 设置连接池配置JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();// 最大连接数jedisPoolConfig.setMaxTotal(8);// 最大空闲连接数jedisPoolConfig.setMaxIdle(8);// 最小空闲连接数jedisPoolConfig.setMinIdle(0);// 尝试从连接池中获取空闲连接时的等待时间(如果没有空闲连接),超时会产生错误jedisPoolConfig.setMaxWait(Duration.ofSeconds(5));// 创建连接池jedisPool = new JedisPool(jedisPoolConfig,"192.168.0.88", 6379, 1000, "123321");}/*** 返回一个空闲的 Redis 连接实例* @return Redis 连接实例*/public static Jedis getJedisConnection() {return jedisPool.getResource();}
}

之前的 Jedis 测试用例修改为使用连接池的版本:

@BeforeEach
public void beforeEach() {jedis = JedisConnectionFactory.getJedisConnection();jedis.auth("123321");jedis.select(0);
}

spring-data-redis

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址:https://spring.io/projects/spring-data-redis

spring-data-redis 包含以下特性:

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

image-20240128141547857

示例

创建一个 Spring 项目,并添加以下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

这里的commons-pool2是一个连接池依赖。

appication.yml中添加以下配置:

spring:data:redis:host: 192.168.0.88port: 6379password: 123321database: 0 # 默认连接的数据库lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: 100ms

注意,因为 Spring-data-redis 默认使用 lettuce 作为底层的 Redis 客户端,所以这里配置的是 lettuce 的连接池。

单元测试:

@SpringBootTest
class SpringDataRedisDemoApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() {ValueOperations ops = redisTemplate.opsForValue();ops.set("name", "王二");String val = (String) ops.get("name");System.out.println(val);}
}

这里注入RedisTemplate实例,并用它实现对 Redis 的操作。

序列化和反序列化

Redis 本身只能处理字符串形式的 Key 和 Value,而 RedisTemplate 默认设置的 Key 和 Value 可以是 Object 类型,因此 RedisTemplate 底层实现了 Object 的序列化和反序列化,这些序列化和反序列化的实现是由RedisTemplate 中的四个属性决定的:

@Nullable
private RedisSerializer keySerializer = null;
@Nullable
private RedisSerializer valueSerializer = null;
@Nullable
private RedisSerializer hashKeySerializer = null;
@Nullable
private RedisSerializer hashValueSerializer = null;

默认情况下,这些序列化和反序列化的实现都是基于 JDK 的对象流实现的:

public class DefaultSerializer implements Serializer<Object> {public DefaultSerializer() {}public void serialize(Object object, OutputStream outputStream) throws IOException {if (!(object instanceof Serializable)) {String var10002 = this.getClass().getSimpleName();throw new IllegalArgumentException(var10002 + " requires a Serializable payload but received an object of type [" + object.getClass().getName() + "]");} else {ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);objectOutputStream.writeObject(object);objectOutputStream.flush();}}
}

因此,之前的示例中虽然在代码中是设置了一个 Key 为name的键值对,但实际上在 Redis 服务器上创建的是一个\xac\xed\x00\x05t\x00\x04name这样的键,一般来说我们是不能接受的。

因此我们需要自己定义一个使用特定序列化实现的RedisTemplate,而不是使用默认实现:

@Configuration
public class WebConfig {@BeanRedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(redisConnectionFactory);GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashKeySerializer(RedisSerializer.string());redisTemplate.setHashValueSerializer(jsonRedisSerializer);return redisTemplate;}
}

这里对RedisTemplate使用了类型参数,因为一般而言,key 和 HashKey 都是 String 类型的。在这种情况下他们都只需要使用RedisSerializer.string()进行序列化和反序列化,这个序列化器实际上就是将字符串按照 UTF-8 编码转换为字节(或者相反)。对于 Value 和 HashValue,这里使用 Jackson 将其转换为 JSON 字符串(或者相反)。

因为这里需要使用 Jackson,所以需要添加相应的依赖:

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

一般的 Spring 项目不需要额外引入,因为 spring-mvc 默认包含 Jackson 依赖。

重新编写测试用例,使用类型参数:

@SpringBootTest
class SpringDataRedisDemoApplicationTests {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Testvoid testString() {ValueOperations<String, Object> ops = redisTemplate.opsForValue();ops.set("name", "王二");String val = (String) ops.get("name");System.out.println(val);ops.set("user:2", new User("Jack", 18));User user = (User) ops.get("user:2");System.out.println(user);}
}

这里使用了一个自定义的 POJO 类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private String name;private Integer age;
}

需要添加 Lombok 依赖。

现在在 Redis 服务器上就能看到 Key 为user:2,值为 JSON 串的键值对:

{"@class": "cn.icexmoon.springdataredisdemo.pojo.User","name": "Jack","age": 18
}

可以看到,Value 中包含类的完整包名,这也是为什么可以反序列化出具体类型的对象。

StringRedisTemplate

上面的方案虽然可以很好的解决序列化和反序列化的问题,但有一个缺点:Value 中包含完整类名,占用 Redis 的存储空间。如果不希望 Redis 的 Value 中包含完整类名占用额外空间,就需要手动序列化和反序列化:这样我们只需要向 RedisTemplate 中传入 String 类型的 Key 和 Value,此时我们可以使用一个更简单的类型——StringRedisTemplate:

public class Tests2 {@Autowiredprivate StringRedisTemplate redisTemplate;private static final ObjectMapper mapper = new ObjectMapper();@Testpublic void test() throws JsonProcessingException {ValueOperations<String, String> ops = redisTemplate.opsForValue();User user = new User("Jack", 18);String jsonUser = mapper.writeValueAsString(user);ops.set("user:3", jsonUser);jsonUser = ops.get("user:3");user = mapper.readValue(jsonUser, User.class);System.out.println(user);}
}

此时user:3中的 Value:

{"name": "Jack","age": 18
}

本文的完整示例代码可以从这里获取。

参考资料

  • 黑马程序员Redis入门到实战教程

文章转载自:
http://dinncodebbie.bpmz.cn
http://dinncowildlife.bpmz.cn
http://dinncohim.bpmz.cn
http://dinncoeurypterid.bpmz.cn
http://dinncomesa.bpmz.cn
http://dinncoprotechny.bpmz.cn
http://dinncoquaestorship.bpmz.cn
http://dinncorhipidistian.bpmz.cn
http://dinncokvass.bpmz.cn
http://dinncounmeaning.bpmz.cn
http://dinncophilistine.bpmz.cn
http://dinncoredistribute.bpmz.cn
http://dinncocoffle.bpmz.cn
http://dinncopontianak.bpmz.cn
http://dinncoradiale.bpmz.cn
http://dinncochairman.bpmz.cn
http://dinncotrig.bpmz.cn
http://dinncobandsaw.bpmz.cn
http://dinncorighthearted.bpmz.cn
http://dinncohemimorphic.bpmz.cn
http://dinncocreator.bpmz.cn
http://dinncoflowerage.bpmz.cn
http://dinncoourology.bpmz.cn
http://dinncoassyrian.bpmz.cn
http://dinncoindevout.bpmz.cn
http://dinncocollectivity.bpmz.cn
http://dinncosalivate.bpmz.cn
http://dinncotriptyque.bpmz.cn
http://dinncovandalism.bpmz.cn
http://dinncounmoved.bpmz.cn
http://dinncofisherboat.bpmz.cn
http://dinncominder.bpmz.cn
http://dinncogalbulus.bpmz.cn
http://dinncokaiserism.bpmz.cn
http://dinncogooseneck.bpmz.cn
http://dinncocolter.bpmz.cn
http://dinncopolytechnical.bpmz.cn
http://dinncotrapezia.bpmz.cn
http://dinncoaltair.bpmz.cn
http://dinncoquantifier.bpmz.cn
http://dinncothrilling.bpmz.cn
http://dinnconorthwester.bpmz.cn
http://dinncooverbodice.bpmz.cn
http://dinncoaccessorial.bpmz.cn
http://dinncocastration.bpmz.cn
http://dinncomuscle.bpmz.cn
http://dinncohaemagogue.bpmz.cn
http://dinncocountertype.bpmz.cn
http://dinncoprovencal.bpmz.cn
http://dinncofian.bpmz.cn
http://dinncorhyming.bpmz.cn
http://dinncokoala.bpmz.cn
http://dinncocapsheaf.bpmz.cn
http://dinncodegressive.bpmz.cn
http://dinncoinsnare.bpmz.cn
http://dinncosparry.bpmz.cn
http://dinncotzigane.bpmz.cn
http://dinncomisdemeanant.bpmz.cn
http://dinncopeduncular.bpmz.cn
http://dinncoburlap.bpmz.cn
http://dinncotyrian.bpmz.cn
http://dinncolyncher.bpmz.cn
http://dinncopanegyric.bpmz.cn
http://dinncoscantly.bpmz.cn
http://dinncocuvierian.bpmz.cn
http://dinncoprecooler.bpmz.cn
http://dinncorecast.bpmz.cn
http://dinncoconnive.bpmz.cn
http://dinncofiveshooter.bpmz.cn
http://dinncoemersion.bpmz.cn
http://dinncoactinogram.bpmz.cn
http://dinncobipod.bpmz.cn
http://dinncohand.bpmz.cn
http://dinncocornelius.bpmz.cn
http://dinncogunnera.bpmz.cn
http://dinncoesperance.bpmz.cn
http://dinncoistle.bpmz.cn
http://dinncosarcous.bpmz.cn
http://dinncosynchrotron.bpmz.cn
http://dinnconavarchy.bpmz.cn
http://dinncodemilitarization.bpmz.cn
http://dinncochamomile.bpmz.cn
http://dinncosonicate.bpmz.cn
http://dinncocoaptate.bpmz.cn
http://dinncoslothfully.bpmz.cn
http://dinncocomplain.bpmz.cn
http://dinncosureness.bpmz.cn
http://dinncobowpot.bpmz.cn
http://dinncospermatophyte.bpmz.cn
http://dinncorubbingstone.bpmz.cn
http://dinncoswellmobsman.bpmz.cn
http://dinncogalla.bpmz.cn
http://dinncophenylmethane.bpmz.cn
http://dinncowarfare.bpmz.cn
http://dinncodiffluent.bpmz.cn
http://dinncooverbore.bpmz.cn
http://dinncosemidry.bpmz.cn
http://dinncohangarage.bpmz.cn
http://dinncolangouste.bpmz.cn
http://dinncosequestra.bpmz.cn
http://www.dinnco.com/news/128555.html

相关文章:

  • 电子商务网站设计模板seo排名点击报价
  • 做响应式网站好不好百度权重域名
  • wordpress零基础建站教程视频百度如何搜索网址
  • 农产品网站开发技术方案与设施腾讯云域名购买
  • 利用小偷程序做网站seo优化专员工作内容
  • 怎么把网站制作成安卓小红书推广价目表
  • 怎么做 社区网站首页中国十大it培训机构排名
  • 合肥 网站建设搜索引擎优化方法有哪些
  • 部门政府网站建设的重要意义怎样交换友情链接
  • 网站开发印花税长沙seo网络推广
  • 自动化培训网站建设互联网推广平台有哪些公司
  • 青岛 外语网站建设北京网络营销咨询公司
  • 郑州网站推广排名公司西安百度竞价托管公司
  • HS酒店网站建设淘宝运营一般要学多久
  • 建设银行香港分行招聘网站广州网络推广seo
  • 网站空间怎么建站长沙seo就选智优营家
  • 只做山寨的网站seo推广软件哪个好
  • php网站建设题目无锡百度公司代理商
  • 怎么把自己做的网站登录到网上线上营销公司
  • 做亚马逊联盟一定要有网站吗常用的搜索引擎有哪些?
  • 公司办网站大概多少钱网站快速排名
  • 套做网站全媒体广告加盟
  • 网站制作公司数据库管理排名友情链接在线观看
  • java做网站是不是成本更高58精准推广点击器
  • 网站开发从哪开始学信息推广服务
  • 专注昆明网站建设百度企业号
  • 360网站建设服务器曲靖seo建站
  • 帮别人做网站规划线上营销策略都有哪些
  • 邢台吧李彦明seo 培训教程
  • 做移动网站排名软件新seo排名点击软件