SpringBoot--中间件技术-2:整合redis,redis实战小案例,springboot cache,cache简化redis的实现,含代码
SpringBoot整合Redis
实现步骤
-
导pom文件坐标
<!--redis依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
yaml主配置文件,配置redis端口号
spring:redis:host: localhostport: 6379
-
测试类
字符串专用类:StringRedisTemplate stringRedisTemplate
@Autowired public RedisTemplate redisTemplate; @Test public void stringTest(){// 各种类型支持stringRedisTemplate.opsForValue();stringRedisTemplate.opsForList();stringRedisTemplate.opsForSet();stringRedisTemplate.opsForHash();stringRedisTemplate.opsForZSet();// 字符串stringRedisTemplate.opsForValue().set("teacher","刘老板");String teacher = stringRedisTemplate.opsForValue().get("teacher");System.out.println("stringRedisTemplate输出结果"+teacher);// 操作list列表stringRedisTemplate.opsForList().leftPush("tang","李白");stringRedisTemplate.opsForList().leftPush("tang","杜甫");stringRedisTemplate.opsForList().leftPushAll("songAll","欧阳修","苏轼","苏辙");List<String> songAll = stringRedisTemplate.opsForList().range("songAll", 0, 2);songAll.forEach(System.out::println);}
对象专用类:RedisTemplate redisTemplate
@Autowired(required = false) public RedisTemplate redisTemplate; @Test public void redisTemplate(){// 各种类型支持redisTemplate.opsForValue();redisTemplate.opsForList();redisTemplate.opsForSet();redisTemplate.opsForHash();redisTemplate.opsForZSet();ValueOperations valueOperations = redisTemplate.opsForValue();valueOperations.set("panda","花花");String panda = (String) valueOperations.get("panda");System.out.println(panda);Student student = new Student(1,"惠晨怡","女");redisTemplate.opsForValue().set("stu",student);Student student1 = (Student) redisTemplate.opsForValue().get("stu");System.out.println(student1);redisTemplate.opsForList().leftPushAll("animal","狗","猫","龙","鼠");List animal = redisTemplate.opsForList().range("animal", 0, 3);animal.forEach(System.out::println);}
在可视化页面中查看对象存入的键和值,看不明白,没有可读性,可以使用自定义类
自定义类实现步骤:
pom文件导入fastJson
<!--fastjson工具包 --> <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.3</version> </dependency><dependency><groupId>com.colobu</groupId><artifactId>fastjson-jaxrs-json-provider</artifactId><version>0.3.1</version> </dependency>
添加配置类RedisConfig
@Configuration public class RedisConfig {@Beanpublic RedisTemplate<Object,Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {// 创建自定义模板RedisTemplate<Object, Object> template = new RedisTemplate<>();//配置json类型的序列化工具template.setKeySerializer(new StringRedisSerializer());template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class)); template.setConnectionFactory(redisConnectionFactory);return template;} }
测试:装配的redis模板类需要和自定义的同名
@Autowired public RedisTemplate jsonRedisTemplate; @Test public void test03(){jsonRedisTemplate.opsForValue();jsonRedisTemplate.opsForList();jsonRedisTemplate.opsForSet();jsonRedisTemplate.opsForHash();jsonRedisTemplate.opsForZSet();Student student1 = new Student(2,"惠晨怡","男");Student student2 = new Student(3,"尚恒通","男");Student student3 = new Student(4,"李竟坡","男");ArrayList<Student> students = new ArrayList<>(Arrays.asList(student1,student2,student3));jsonRedisTemplate.opsForValue().set("stus",students);Object stus = jsonRedisTemplate.opsForValue().get("stus");String s = JSON.toJSONString(stus);List<Student> list = JSONObject.parseArray(s, Student.class);list.forEach(System.out::println); }
SpringBoot整合Redis实战案例
redis在项目中起到缓存作用,案例演示redis在项目中的实现
-
导入pom.xml文件
springboot版本2.7.14
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope> </dependency><!--mysql--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.29</version> </dependency><!--mybatis--> <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.1</version> </dependency><!--redis--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
yaml配置文件配置数据源和redis
# 配置数据源 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/spring?serverTimezone=GMTusername: rootpassword: 123456# 配置redisredis:host: localhostport: 6379mybatis:configuration:map-underscore-to-camel-case: true
用到了mybatis,所以配置了一个自动驼峰映射
-
Redis自定义模板配置类
@Component public class RedisConfig {@Beanpublic RedisTemplate<Object,Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setKeySerializer(new StringRedisSerializer());template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));template.setConnectionFactory(redisConnectionFactory);return template;} }
-
导入redisUtil工具类,工具栏中封装了大量redis操作代码,一般真实开发环境中都可以看到一个公司自己封装的RedisUtil
@Component public class RedisUtil {@Autowired(required = false)private RedisTemplate jsonRedisTemplate;// =========================================================/*** 指定缓存失效时间* @param key 键* @param time 时间(秒)*/public boolean expire(String key, long time) {try {if (time > 0) {jsonRedisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据key 获取过期时间* @param key 键 不能为null* @return 时间(秒) 返回0代表为永久有效*/public long getExpire(String key) {return jsonRedisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在* @param key 键* @return true 存在 false不存在*/public boolean hasKey(String key) {try {return jsonRedisTemplate.hasKey(key);} catch (Exception e) {return false;}}/*** 删除缓存* @param key 可以传一个值 或多个*/@SuppressWarnings("unchecked")public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {jsonRedisTemplate.delete(key[0]);} else {jsonRedisTemplate.delete(CollectionUtils.arrayToList(key));}}}// ============================String=============================/*** 普通缓存获取* @param key 键* @return 值*/public Object get(String key) {return key == null ? null : jsonRedisTemplate.opsForValue().get(key);}/*** 普通缓存放入* @param key 键* @param value 值* @return true成功 false失败*/public boolean set(String key, Object value) {try {jsonRedisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {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) {jsonRedisTemplate.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)*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return jsonRedisTemplate.opsForValue().increment(key, delta);}/*** 递减* @param key 键* @param delta 要减少几(小于0)*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return jsonRedisTemplate.opsForValue().increment(key, -delta);}// ================================Map=================================/*** HashGet* @param key 键 不能为null* @param item 项 不能为null*/public Object hget(String key, String item) {return jsonRedisTemplate.opsForHash().get(key, item);}/*** 获取hashKey对应的所有键值* @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return jsonRedisTemplate.opsForHash().entries(key);}/*** HashSet* @param key 键* @param map 对应多个键值*/public boolean hmset(String key, Map<String, Object> map) {try {jsonRedisTemplate.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 {jsonRedisTemplate.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 {jsonRedisTemplate.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 {jsonRedisTemplate.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) {jsonRedisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值** @param key 键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return jsonRedisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回** @param key 键* @param item 项* @param by 要增加几(大于0)*/public double hincr(String key, String item, double by) {return jsonRedisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key 键* @param item 项* @param by 要减少记(小于0)*/public double hdecr(String key, String item, double by) {return jsonRedisTemplate.opsForHash().increment(key, item, -by);}// ============================set=============================/*** 根据key获取Set中的所有值* @param key 键*/public Set<Object> sGet(String key) {try {return jsonRedisTemplate.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 jsonRedisTemplate.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 jsonRedisTemplate.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 = jsonRedisTemplate.opsForSet().add(key, values);if (time > 0)expire(key, time);return count;} catch (Exception e) {e.printStackTrace();return 0;}}/*** 获取set缓存的长度** @param key 键*/public long sGetSetSize(String key) {try {return jsonRedisTemplate.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 = jsonRedisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {e.printStackTrace();return 0;}}// ===============================list=================================/*** 获取list缓存的内容** @param key 键* @param start 开始* @param end 结束 0 到 -1代表所有值*/public List<Object> lGet(String key, long start, long end) {try {return jsonRedisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取list缓存的长度** @param key 键*/public long lGetListSize(String key) {try {return jsonRedisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通过索引 获取list中的值** @param key 键* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推*/public Object lGetIndex(String key, long index) {try {return jsonRedisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 将list放入缓存** @param key 键* @param value 值*/public boolean lSet(String key, Object value) {try {jsonRedisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存* @param key 键* @param value 值* @param time 时间(秒)*/public boolean lSet(String key, Object value, long time) {try {jsonRedisTemplate.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 {jsonRedisTemplate.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 {jsonRedisTemplate.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 {jsonRedisTemplate.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 = jsonRedisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {e.printStackTrace();return 0;}}}
-
实体类POJO
public class Student {private int stuId;private String stuName;private String stuSex;// get,set,构造,toString等 }
-
Dao层:Mapper
@Mapper public interface StudentMapper {@Delete("delete from student where stu_id = #{id}")public int delete(Integer id);@Select("select * from student where stu_id = #{id}")public Student find(Integer id); }
-
业务层:
接口
public interface IStudentService {public void delete(int id);public Student find(int id);}
实现类
@Service public class StudentServiceImp implements IStudentService {@Autowired(required = false)private StudentMapper mapper;@Autowiredprivate RedisUtil redisUtil;// 删除用户策略:删除数据表中数据,然后删除缓存@Overridepublic void delete(int id) {// 删除数据库int res = mapper.delete(id);String key = "student:id:"+id;// 判断数据库是否删除成功if(res != 0){boolean hasKey = redisUtil.hasKey(key);if(hasKey){redisUtil.del(key);System.out.println("删除了缓存中的key:" + key);}}}// 获取用户策略:先从缓存中获取用户,没有则取数据表中数据,再将数据写入缓存@Overridepublic Student find(int id) {String key = "student:id:" + id;//1.1判断key在redis中是否存在boolean hasKey = redisUtil.hasKey(key);if (hasKey) {//1.2存在缓存则直接获取Object stu = redisUtil.get(key);ObjectMapper change = new ObjectMapper();Student student = change.convertValue(stu,Student.class);System.out.println("==========从缓存中获得数据=========");System.out.println(student.getStuName());System.out.println("==============================");return student;} else {//1.3不存在缓存,先从数据库中获取,在保存至redis,最后返回用户Student student = mapper.find(id);System.out.println("==========从数据表中获得数据=========");System.out.println(student.getStuName());System.out.println("==============================");if (student != null){redisUtil.set(key, student);//写入缓存}return student;}} }
-
控制器
@RestController public class StudentController {@AutowiredIStudentService service;@RequestMapping("/delete/{id}")public Integer delete(@PathVariable("id") int id){service.delete(id);return id;}@RequestMapping("/find/{id}")public Student find(@PathVariable("id") int id){Student student = service.find(id);return student;}}
-
启动服务,地址栏中测试查看控制台打印结果,(测试时一定要保证redis服务正在运行,否则存不进redis)
第一次访问localhost:8080/find/1显示从数据表中获得的数据,第二次访问显示缓存中获取的数据
SpringBoot Cache
SpringBoot Cache介绍
Spring Cache是一个框架, 实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。
Spring Cache提供了一层抽象,底层可以切换不同的cache实现。具体就是通过CacheManager接口来统一不同的缓存技术。
CacheManager缓存管理器是Spring提供的各种缓存技术抽象接口
针对不同的缓存技术需要实现不同的CacheManager:
CacheManager | 描述 |
---|---|
EhCacheCacheManager | 使用EhCache作为缓存技术(Spring Cache框架操作的默认缓存) |
GuavaCacheManager | 使用Google的GuavaCache作为缓存技术 |
RedisCacheManager | 使用Redis作为缓存技术 |
SpringBoot Cache常用注解
注解 | 说明 |
---|---|
@EnableCaching | 开启缓存注解功能 |
@Cacheable | 在方法执行前spring先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中 |
@CachePut | 将方法的返回值放到缓存中 |
@CacheEvict | 将一条或多条数据从缓存中删除 |
使用步骤:
-
引入缓存启动器:spring-boot-starter-cache,spring-boot-starter-data-redis
-
@EnableCaching:在启动类上,开启基于注解的缓存
-
@Cacheable : 标在方法上,返回的结果会进行缓存
属性: value/cacheNames缓存的名字
key : 作为缓存中的Key值,可自已使用 SpEL表达式指定(不指定就是参数值), 缓存结果是
方法返回值
名字 | 描述 | 示例 |
---|---|---|
methodName | 当前被调用的方法名 | #root.methodName |
target | 当前被调用的目标对象 | #root.target |
targetClass | 当前被调用的目标对象类 | #root.targetClass |
args | 当前被调用的方法的参数列表 | #root.args[0] |
caches | 当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”,“cache2”})),则有两个cache | #root.caches[0].name |
argument name | 方法参数的名字. 可以直接 #参数名 ,也可以使用 #p0或#a0 的形式,0代表参数的索引; | #iban 、 #a0 、 #p0 |
result | 方法执行后的返回值(仅当方法执行之后的判断有效,在@CachePut 使用于更新数据后可用) | #result |
SpringBoot Cache案例简化Redis
代码实现演示:
-
pom文件导坐标
<!--redis依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.1</version> </dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope> </dependency>
-
yaml或properties主配置文件
spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=GMT%2B8#开启日志管理,可以查看sql语句 logging.level.com.apesource.springboot_redis03.mapper=debug debug=true#配置要连接redis的地址 spring.redis.host=localhost spring.redis.port=6379
-
POJO实体类
根据要操作的表写,演示为student
public class Student implements Serializable{private Integer stuId;private String stuName;private String stuSex;// get、set、toString、有参、无参构造 }
-
Dao层StudentMapper
public interface StudentMapper {@Select("select * from Student where stu_id = #{id}")public Student getStudentById(Integer id);@Delete("delete from student where stu_id = #{id}")public int deleteStudentById(Integer id);@Update("update student set stu_name=#{stuName},stu_sex=#{stuSex} where stu_id = #{stuId}")public int updateById(Student student);}
-
Service层
演示Cache简化redis实现,业务直接写实现类,没写接口
@Service public class StudentService {@Autowired(required = false)StudentMapper mapper;//根据@Cacheable注解中的cacheNames+key拼接后的值为key@Cacheable(cacheNames = "students",key = "#id")public Student findById(Integer id){return mapper.getStudentById(id);}@CacheEvict(cacheNames = "students",key = "#id")public void deleteStudentById(Integer id){mapper.deleteStudentById(id);}@CachePut(cacheNames = "students",key = "#result.stuId")public Student updateById(Student student){mapper.updateById(student);return student;}}
在业务层的方法中,加SpringBoot Cache的注解:
cacheNames会在缓存中开辟一块儿叫"students"的空间,以键值对的形式存放数据,键是cacheNames+key拼接组成,value就是被标注注解的方法返回值
-
控制器StudentController
@RestController public class UserController {@AutowiredStudentService userService;@GetMapping("/findById/{id}")public Student findById(@PathVariable("id") Integer id) {Student stu = userService.findById(id);return stu;}@GetMapping("/delete/{id}")public Integer delete(@PathVariable("id") Integer id) {userService.deleteStudentById(id);return id;}@GetMapping("/update/{id}/{name}/{hobby}")public Integer update(@PathVariable Integer id,@PathVariable String name,@PathVariable String sex) {userService.updateById(new Student(id,name,sex));return id;}}
-
启动类上添加注解
@SpringBootApplication @MapperScan("com.apesource.springboot_redis03") @EnableCaching public class SpringbootRedis03Application {public static void main(String[] args) {SpringApplication.run(SpringbootRedis03Application.class, args);}}
-
启动服务,浏览器访问localhost:8080/findById/1,访问之后刷新再次访问
注意启动程序服务之前,需要先把redis运行起来
第一次访问时,从数据库中获取的数据
第二次访问,没有SQL语句,但是也得到了数据,证明cache实现了缓存的作用
相关文章:

SpringBoot--中间件技术-2:整合redis,redis实战小案例,springboot cache,cache简化redis的实现,含代码
SpringBoot整合Redis 实现步骤 导pom文件坐标 <!--redis依赖--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>yaml主配置文件,配置…...
linux rsyslog配置文件详解
1.rsyslog配置文件简介 linux rsyslog配置文件/etc/rsyslog.conf分为三部分:MODULES、GLOBAL DIRECTIVES、RULES ryslog模块说明 模块说明MODULES指定接收日志的协议和端口。若要配置日志服务器,则需要将相应的配置项注释去掉。GLOBAL DIRECTIVES主要用来配置日志模版。指定…...

wordpress是什么?快速搭网站经验分享
作者主页 📚lovewold少个r博客主页 ⚠️本文重点:c入门第一个程序和基本知识讲解 👉【C-C入门系列专栏】:博客文章专栏传送门 😄每日一言:宁静是一片强大而治愈的神奇海洋! 目录 前言 wordp…...

排序 算法(第4版)
本博客参考算法(第4版):算法(第4版) - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 本文用Java实现相关算法。 我们关注的主要对象是重新排列数组元素的算法,其中每个元素…...

asp.net 在线音乐网站系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
一、源码特点 asp.net 在线音乐网站系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net 在线音乐网站系统1 应用…...
ElastaticSearch -- es之Filters aggregation 先过滤再聚合
使用场景 使用es时,有时我们需要先过滤后再聚合,但如果直接在query的filter中过滤,不止会影响到一个聚合,还会影响到其他的聚合结果。 比如,我们想要统计深圳市某个品牌的总销售额,以及该品牌的女款衣服的…...
如何把一个接口设计好?
如何把一个接口设计好? 如何设计一个接口?是在我们日常开发或者面试时经常问及的一个话题。很多人觉得这不就是CRUD,能实现不就行了。单纯实现来说,并非难事,但要做到易用、易扩展、易维护并不是一件简单的事。这里并…...

mini-vue 的设计
mini-vue 的设计 mini-vue 使用流程与结果预览: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name&qu…...
React整理杂记(一)
1.React三项依赖 1.react.js -> 核心代码 2.react-dom.js -> 渲染成dom 3.babel.js->非必须,将jsx转为js 类组件中直接定义的方法,都属于严格模式下 this的绑定可以放到constructor(){}中 2. JSX语法 1.可以直接插入的元素: num…...
[100天算法】-统计封闭岛屿的数目(day 74)
题目描述 有一个二维矩阵 grid ,每个位置要么是陆地(记号为 0 )要么是水域(记号为 1 )。我们从一块陆地出发,每次可以往上下左右 4 个方向相邻区域走,能走到的所有陆地区域,我们将其…...
esp32-rust-std-examples-blinky
以下为在 ESP-IDF (FreeRTOS) 上运行的 blinky 示例: https://github.com/esp-rs/esp-idf-hal/blob/master/examples/blinky.rs //! Blinks an LED //! //! This assumes that a LED is connected to GPIO4. //! Depending on your target and the board you are …...
【docker容器技术与K8s】
【docker容器技术与K8s】 一、Docker容器技术 1、Docker的学习路线 (1)学习Docker基本命令(容器管理和镜像管理) (2)学习使用Docker搭建常用软件 (3)学习Docker网络模式 启动容器的…...

RT-DTER 引入用于低分辨率图像和小物体的新 CNN 模块 SPD-Conv
论文地址:https://arxiv.org/pdf/2208.03641v1.pdf 代码地址:https://github.com/labsaint/spd-conv 卷积神经网络(CNN)在图像分类、目标检测等计算机视觉任务中取得了巨大的成功。然而,在图像分辨率较低或对象较小的更困难的任务中,它们的性能会迅速下降。 这源于现有CNN…...
Folw + Room 实现自动观察数据库的刷新
1、Room :定义数据结构、创建数据库 // 定义实体 Entity data class TestModel ()// 定义数据库 Dao interface TestDao { Query("SELECT * FROM TestTable") fun getAll(): List<TestModel> }// 获取数据库 abstract class TestDatabase: RoomDat…...

黑马程序员微服务Docker实用篇
Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…...

虚拟化服务器+华为防火墙+kiwi_syslog访问留痕
一、适用场景 1、大中型企业需要对接入用户的访问进行记录时,以前用3CDaemon时,只能用于小型网络当中,记录的数据量太大时,本例采用破解版的kiwi_syslog。 2、当网监、公安查到有非法访问时,可提供基于五元组的外网访…...

FlinkSQL聚合函数(Aggregate Function)详解
使用场景: 聚合函数即 UDAF,常⽤于进多条数据,出⼀条数据的场景。 上图展示了⼀个 聚合函数的例⼦ 以及 聚合函数包含的重要⽅法。 案例场景: 关于饮料的表,有三个字段,分别是 id、name、price࿰…...

TensorFlow学习笔记--(3)张量的常用运算函数
损失函数及求偏导 通过 tf.GradientTape 函数来指定损失函数的变量以及表达式 最后通过 gradient(%损失函数%,%偏导对象%) 来获取求偏导的结果 独热编码 给出一组特征值 来对图像进行分类 可以用独热编码 0的概率是第0种 1的概率是第1种 0的概率是第二种 tf.one_hot(%某标签…...

RT-Thread:嵌入式实时操作系统的设计与应用
RT-Thread(Real-Time Thread)是一个开源的嵌入式实时操作系统,其设计和应用在嵌入式领域具有重要意义。本文将从RT-Thread的设计理念、核心特性,以及在嵌入式系统中的应用等方面进行探讨,对其进行全面的介绍。 首先&a…...
SpringBoot学习笔记-创建菜单与游戏页面(下)
笔记内容转载自 AcWing 的 SpringBoot 框架课讲义,课程链接:AcWing SpringBoot 框架课。 CONTENTS 1. 地图优化改进2. 绘制玩家的起始位置3. 实现玩家移动4. 优化蛇的身体效果5. 碰撞检测实现 本节实现两名玩家即两条蛇的绘制与人工操作移动功能。 1. 地…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...

ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...

英国云服务器上安装宝塔面板(BT Panel)
在英国云服务器上安装宝塔面板(BT Panel) 是完全可行的,尤其适合需要远程管理Linux服务器、快速部署网站、数据库、FTP、SSL证书等服务的用户。宝塔面板以其可视化操作界面和强大的功能广受国内用户欢迎,虽然官方主要面向中国大陆…...