知识点笔记(java / 数据库)

知识点,笔记,java,数据库 · 浏览次数 : 9

小编点评

1. **Redis备份恢复**:使用redis-cli连接server,如果有密码的话 auth 123(密码)授权bgsave:后台生成备份文件save:生成备份文件, 会阻塞其他指令生成的文件路径在redis.conf中的dir下关闭需要恢复的redis服务器上的redis服务(因为redis关闭时候会将内容的数据备份到路径下, 我们要覆盖他旧的备份文件)移动到需要备份redis服务器上的dir指向的路径(如果dir配置也是默认的, 可以选择配置一下, 或者执行以下save指令, 看生成的dump文件在哪里,就复制到哪里就行, 建议配置将日志和路径都修改到redis安装目录或者自定义的数据路径中, 防止出现默认./结果出现在根目录下的情况。 2. **文件路径配置**:默认的./,但是我生成的备份文件在根目录下, 反正根目录, 主目录, redis安装目录结合生成/修改时间检查一下。 3. **联表更新**:使用redisTemplate.opsForValue().set()方法设置多个值,每个值前缀以 : 作为目录名称,例如:cata:1:2:3:4,设置的值为:cata:1:2:3:4,值以:1,2,3,4,以:1,2,3,4,每个值的前面缀以 : 作为目录名称。 4. **命名空间**:使用redisTemplate.opsForValue().set()方法设置多个值,每个值前缀以 : 作为目录名称,例如:cata:1:2:3:4,设置的值为:cata:1:2:3:4,值以:1,2,3,4,以:1,2,3,4,每个值的前面缀以 : 作为目录名称,在使用上就当成一个整体使用即可。

正文

1. Java peek vs. map

两个函数的返回值都是一个新的Stream,但是接收类型 peek是Consumer,map是Function
使用场景:
对象数组的集合流, peek 为遍历数组, 对item进行处理; map为获取出某个属性或对整个item进行处理后返回

参考:
Java Stream peek vs. map
Java 8 Stream Api 中的 peek 操作


2. Java Map

HashMap、TreeMap和LinkedHashMap

  • LinkedHashMap按照访问顺序: Map<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);, 默认情况下LinkedHashMap的访问顺序是关闭的(即accessOrder为false), 开启后会通过map.get("a")使a到最后, 前提是a存在.

  • hutool中的Dict继承了LinkedHashMap, 但是没有给出accessOrder的设置(目前5.8.6是)

  • TreeMap: 默认比较器是键1.compareTo(键2), 也即键的自然顺序.

  • HashMap转TreeMap来排序:

    • hutool中的MapUtil.sort(map);
    • hutool中的原理:
      • 如果要手写通过值来判断顺序的话, 这个比较器中使用的map中的值(也即将map当作字典表去比较的), 也即当往sort中put的时候map中必须要有这个键, 不然.getCode()时候会有空异常, 也可以在比较器中给value一个默认值(如果可以让没有的在最前面, 如果默认指给得最大会遍历整个map来确定排在最后)
      • 如果sortMap已经创建出来了, 再次修改map中的一个键将值中的code修改得不一样, 再次sortMap.put()时候因为存在了那个键, 只会替换, 并不会按照map修改键对应值的新顺序来;
      • 相对应的, 如果构建出sortMap之后, 给map新增一个新的键值对, 再sortMap.put()时候, sortMap会按照map中的顺序插入.
      • 也就是排好序之后, 已经存在的键不会修改; 新进来的键会按照map中的比较器(是按照map的值得顺序, 也即新插入的键会有用, 传入map获取值, 插入的值没用)获取插入位置.
    Map<String, R<String>> map = new TreeMap<>();
    map.put("apple", R.ok());
    map.put("banana", R.param());
    map.put("orange", R.fail());
    
    TreeMap<String, R<String>> sortMap = new TreeMap<>(Comparator.comparing(p ->
    		Integer.parseInt(map.get(p).getCode())));
    sortMap.putAll(map);
    System.out.println("sortMap = " + JSONUtil.toJsonStr(sortMap));
    
  • 区别

    内部数据结构:
    HashMap:使用数组和链表(JDK 8之前)或者数组和红黑树(JDK 8及以后)的组合来存储键值对。
    TreeMap:使用红黑树作为内部数据结构,以保持键的有序性。
    LinkedHashMap:使用哈希表和双向链表的组合来存储键值对。双向链表维护了插入顺序或访问顺序,保证了迭代顺序与插入顺序或访问顺序一致。
    
    迭代顺序:
    HashMap:不关心插入顺序或访问顺序,迭代顺序无法保证。
    TreeMap:基于键的自然顺序或自定义比较器的顺序,迭代顺序为升序。
    LinkedHashMap:迭代顺序可以选择插入顺序或访问顺序(最近访问的元素放在最后),保证了迭代顺序与插入顺序或访问顺序一致。
    
    性能方面:
    HashMap:插入和查找操作的时间复杂度为O(1),但在哈希冲突较多的情况下,插入和查找操作可能会退化到O(n)。
    TreeMap:插入和查找操作的时间复杂度为O(log n),自带有排序功能。
    LinkedHashMap:插入和查找操作的时间复杂度为O(1),与HashMap类似,但比HashMap略慢。
    
    内存消耗:
    HashMap:内存消耗相对较低,不需要额外的空间来维护有序性。
    TreeMap:内存消耗较高,每个节点需要存储键、值以及额外的指针和颜色信息。
    LinkedHashMap:内存消耗略高于HashMap,因为需要额外的双向链表来维护顺序。
    
    综上所述,LinkedHashMap在功能上结合了HashMap和LinkedList的特点,既可以快速插入和查找,又可以保持插入顺序或访问顺序。然而与HashMap相比,LinkedHashMap在内存消耗方面稍高,并且略慢一些。在选择使用时,要根据具体的需求来进行权衡和选择。
    

3.mysql 列变行.

注意when后多个满足条件时, 会只取一个, 不会报错.
select max(case when then)


4.mysqlmybatis@var

必须在数据库配置文件的数据库地址url中加上一个属性allowMultiQueries=true
参考: MySQL设置变量以及如何在Mybatis中使用


5.mysql insert select *

mysql insert t1(v1, v2, v3) select v1, v2, v3 from t2
中间不要value 或 values


6.MySQL FIELD()

FIELD(str,str1,str2,str3,...)

  • 与order by 组合使用, 让字段按照后续字典表中的内容排序
    select * from demo order by field(review_status, 2, 3, 1), 其中review_status为字段名
    field()后可以跟descasc
    • asc(默认): 按照表顺序(231), 且不存在231中的数据排在前面, 231的数据在最后
    • desc: 按照表降序(132), 且不存在132中的数据排在后面, 132的数据在最前面
  • 单独使用, 求出第一个值在后列表中的位置(从1开始)
    • 第一个值是数字或字符串: select field(1, 1, 2, 3, 4, 5) res 结果是1
    • 第一个值是语句: select field((select id from (SELECT * FROM demo where id = 1) tt), 4, 1, 2, 1, 3) res 结果是2(后面多个1是取第一个的索引)
    • 后面存在语句select field(1, (select id from (SELECT * FROM demo where id in (1, 2, 3)) tt)) res 运行报错Subquery returns more than 1 row, 表示子查询返回多列, 如果其他地方遇到这种情况需要使用limit 1或关键词anysome等等
    • 补充: 当后面列表中不存在第一个值 或 第一个值为null时 返回0

7.mysql SUM(type = 1)

注意必须用sum才可以使用条件,count不可以, 如果count(*)=0时候type_1_percentage为null

SELECT COUNT(*) AS total_count, 
       SUM(type = 1) AS type_1_count, 
       (SUM(type = 1) / COUNT(*)) * 100 AS type_1_percentage
FROM your_table;

pgsql中虽然不支持这样, 但是可以sum(case when type = 1 then 1 else 0), 巧妙引入case when语句来解决


8.@Conditional

运行jar包时候可以指定: java -jar myapp.jar --spring.profiles.active=prod

  • ConditionalOnExpression
    • 只能用于方法、类或注解的声明上
    • 基于 Spring 表达式语言(SpEL)来定义条件的,可以使用 SpEL 中的各种运算符、函数和属性来组合条件;如@ConditionalOnExpression("'prod'.equals('${spring.profiles.active}')")@ConditionalOnExpression("${spring.profiles.active.equals('prod')}").
    • 常用的字符串函数:
      • startsWith(prefix):判断字符串是否以指定的前缀开头。
      • endsWith(suffix):判断字符串是否以指定的后缀结尾。
      • contains(substring):判断字符串是否包含指定的子串。
      • equals(str):判断字符串是否与指定的字符串相等。
      • matches(regex):判断字符串是否匹配指定的正则表达式。
      • substring(startIndex):获取从指定位置开始到字符串结尾的子串。
      • substring(startIndex, endIndex):获取指定位置范围内的子串。
      • toLowerCase():将字符串转换为小写字母。
      • toUpperCase():将字符串转换为大写字母。
    • 可用在定时任务上
      @Slf4j
      @Configuration
      @EnableScheduling
      @RequiredArgsConstructor
      @ConditionalOnExpression("'prod'.equals('${spring.profiles.active}')")
      public class MidJob {
      }
      
    • 在注入bean时候可以与@Bean放在一起
    • 在输入自己写的服务时候
      • 在写的setter或者构造函数上加上
      • 使用@RequiredArgsConstructoronConstructor参数, 如:@RequiredArgsConstructor(onConstructor_ = {@Autowired, @ConditionalOnExpression(...)})
  • Conditional
    使用方法与上面类似, 不过这个是需要实现org.springframework.context.annotation.Condition.matches()方法, 见下图:
    image

9.redis 备份恢复

  • 备份: 使用redis-cli连接server, 如果有密码的话 auth 123(密码)授权
    • bgsave: 后台生成备份文件
    • save: 生成备份文件, 会阻塞其他指令
      生成的文件路径在redis.conf中的dir
  • 关闭需要恢复的redis服务器上的redis服务(因为redis关闭时候会将内容的数据备份到路径下, 我们要覆盖他旧的备份文件)
  • 移动到需要备份redis服务器上的dir指向的路径(如果dir配置也是默认的, 可以选择配置一下, 或者执行以下save指令, 看生成的dump文件在哪里,就复制到哪里), 然后启动redis即可.
    关于dir配置的路径: 默认的./, 但是我生成的备份文件在根目录下, 反正根目录, 主目录, redis安装目录结合生成/修改时间检查一下. 恢复服务器那边不清楚的话, 可以执行save指令查看以下生成dump.rdb文件在哪里, 就复制到哪里就行, 建议配置将日志和路径都修改到redis安装目录或者自定义的数据路径中, 防止出现默认./结果出现在根目录下的情况.

10.联表更新

  • mysql
    UPDATE t1
    JOIN t2 ON t1.t2_id = t2.id
    SET t1.t2_name = t2.name;
    
  • pgsql
    UPDATE t1
    SET t2_name = t2.name
    FROM t2
    WHERE t1.t2_id = t2.id;
    

11.正在执行的sql

  • pgsql: SELECT pid, query FROM pg_stat_activity
  • mysql: 无法找到pid与正在执行sql的关系, 可人为通过show processlist来找(来源是表information_schema.processlist), 古也可通过SELECT * FROM information_schema.processlist实现

12.redis命名空间

命名空间在图形化工具rdm中看到的效果类似文件目录一样, 他将同样前缀(:前的, 大于等于两条数据)的数据以前缀为目录归并起来, 而在使用上就当成一个整体使用即可
(这里提供两个版本下载rdm2021.4, rdm2022.5, 老版本稳定, 新版本界面和功能多, 电脑性能不高可能会卡)
image

redisTemplate.opsForValue().set("cata:1", "1");
redisTemplate.opsForValue().set("cata:1:2", "2");

redisTemplate.opsForValue().set("cata:1:2:3", "3");
redisTemplate.opsForValue().set("cata:1:2:4", "4");

// 非逐级的
redisTemplate.opsForValue().set("cata:2:2:3:4", "5");
redisTemplate.opsForValue().set("cata:2:2:3:5", "6");

与知识点笔记(java / 数据库)相似的内容:

知识点笔记(java / 数据库)

1-java stream peek vs map;; 2-java各种map;; 3-mysql列变行;; 4-java @Conditional;; 5-redis命名空间;; 等等等等...

结合RocketMQ 源码,带你了解并发编程的三大神器

摘要:本文结合 RocketMQ 源码,分享并发编程三大神器的相关知识点。 本文分享自华为云社区《读 RocketMQ 源码,学习并发编程三大神器》,作者:勇哥java实战分享。 这篇文章,笔者结合 RocketMQ 源码,分享并发编程三大神器的相关知识点。 1 CountDownLatch 实现网

C++算法之旅、09 力扣篇 | 常见面试笔试题(上)算法小白专用

算法学习笔记,记录容易忘记的知识点和难题。详解时空复杂度、50道常见面试笔试题,包括数组、单链表、栈、队列、字符串、哈希表、二叉树、递归、迭代、分治类型题目,均带思路与C++题解

C++算法之旅、08 基础篇 | 质数、约数

算法学习笔记,记录容易忘记的知识点和难题。试除法、分解质因数、筛质数、约数个数、约数之和、最大公约数

Kubernetes亲和性学习笔记

学习kubernetes亲和性的关键知识点

计算机系统中的大端模式和小端模式

最近工作中有用到一个知识点,就是大小端,当然这是一个小的知识点,为什么写一个博文呢,我其实是想测试一下chatGPT,所以我开始将自己的想法告诉这个chatbot,让他给我一些写博文的建议,并且给我解答了一些疑惑,今天将自己的学习笔记整理出来展示给大家(by the way,一个有用的搜索引擎和ch

聊聊多任务学习

最近翻译的一篇分享中,主要讲解了多任务学习的各个方面,很多的专业术语与概念都不清楚,因此简单的整理了下相关的知识,做个笔记。 ### 概述 现在大多数机器学习任务都是单任务学习。对于复杂的问题,也可以分解为简单且相互独立的子问题来单独解决,然后再合并结果,得到最初复杂问题的结果。这样做看似合理,其实

算法学习笔记(20): AC自动机

# AC自动机 **前置知识**: - 字典树:可以参考我的另一篇文章 [算法学习笔记(15): Trie(字典树)](https://www.cnblogs.com/jeefy/p/17101290.html) - ~~KMP~~:可以参考 [KMP - Ricky2007](https://ww

算法学习笔记(8.0): 网络流前置知识

网络流基础 网络流合集链接:网络流 网络 $G = (V, E)$ 实际上是一张有向图 对于图中每一条有向边 $(x, y) \in E$ 都有一个给定的容量 $c(x, y)$ 特别的,若 $(x,y) \notin E$ , 则 $c(x, y) = 0$ 图中还有两个指定的特殊结点,$S, T

算法学习笔记(8.2): 上下界网络流

# 上下界网络流 [TOC] > 前置知识以及更多芝士参考下述链接 > 网络流合集链接:[网络流](https://www.cnblogs.com/jeefy/p/17050215.html) 上下界网络流是普通网络流的一种变体,对于网络流,我们不仅关注其流量的上界,下届同样有所体现。 题型大致有五