常用技巧总结

JSONobject

readTree ObjectMapper //不建议用, 因为我 JSONNode.get数据时,有的结果带双引号,有的不带,一摸一样的数据就比如说get() 后有的得到的是“test”,有的得到是test,不知道是工具原因还是啥原因

JSON.parseObject //建议hutool的这个

定时运行某个方法

一般用于数据库更新,然后让后端数据重新读取
Timer timer =new Timer();
timer.shedule(new TImerTask(){ run(需要重复运行的方法)},(delay)5000,(period)5000)

JSON 变成键值对类型

set<Map.Entry<String,Object>> entry=jsonData.entrySet()

获取JSON中的所有key或者value

jsonData.keySet() jsonData.values

用逗号隔开列表中的数据

第一种

StringUtils.join(Set{1,2,2},“,”);
引入依赖

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>

第二种

list 去重
List collect = list.stream().distinct().collect(Collectors.toList());
user.setTags(Joiner.on(“,”).join(collect));

引入依赖

     <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>27.0.1-jre</version>
        </dependency>

把json对象转化为指定对象

OrderInfo orderInfo = JSON.parseObject(string, OrderInfo.class);

给某个对象的特定值赋值,而不用set

BeanUtils.setProperty(rowData,metaData.getColumnName(i),rs.getObject(i));
rowData : T rowData = clazz.newInstance();
meteData.getColumnName()要赋值的属性值
rs.getObject(i) 表示要赋值的值

让对象中的某个数值不序列化

加上@JSONIgnore

得到linux文件的行数

:set nu

jps看进程详情

jps -ml

flink向clinkhouse插入时间数据

entity里写String类型直接插

生成随机id

https://www.hutool.cn/docs/#/core/%E5%B7%A5%E5%85%B7%E7%B1%BB/%E5%94%AF%E4%B8%80ID%E5%B7%A5%E5%85%B7-IdUtil
hutool工具中有随机生成id

association 是mybaties 当两个表join时

请添加图片描述

驼峰命名转下划线

hutool

生成永不相同的主键

hutool

当实体对象属性特别多时,把object转换成hashmap

package com.hnradio.utils;

import cn.hutool.core.util.StrUtil;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author zhz
 * @date 2021/10/9
 */

public class ObjectToMap {


    public static HashMap<String, Object> convertToMap(Object obj) throws Exception {

        HashMap<String, Object> map = new HashMap<String, Object>();
        HashMap<String, Object> b = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int i = 0, len = fields.length; i < len; i++) {
            String varName = fields[i].getName();
            boolean accessFlag = fields[i].isAccessible();
            //必须加isAccessible 否则的话,当object中有属性是private时,运行报错
            fields[i].setAccessible(true);

            Object o = fields[i].get(obj);
            if (o != null) {
                map.put(varName, o.toString());
                fields[i].setAccessible(accessFlag);
            }
        }
        map.forEach((k,v) -> b.put(StrUtil.toUnderlineCase(k), v));
            return b;
    }
}

Mybatis 时间bug

不能写 =“” 否则报错
接受数据库的类时间也要用date(java.util) 别用localdatetime,否则解析错误

配置多数据源错误(一定要记住)

1配置不同数据库,如果,账户密码一样,只用写一个datasource
在这里插入图片描述
例如这个抖音快手B站 三个不同的数据库,但是账号密码一样,jdbc-url随便写一个就行,在mapper.xml写数据库也行
2如果是不同的账号密码 不仅要配置两个datasource,还要写两个@mapper ,我因为我两个数据库都是mysql,我把他写进一个mapper中,但读取第二个数据库时,总是用第一个账户密码,然后我浪费了3个小时解决这个问题

mybatis动态传入表名错误

在这里插入图片描述
delete from 表明,并不能使用#{} 要使用${} #{}传进来的是预编译的 ${}传进来就直接是个字符串

mybatis 传输数值为o问题

and T.status=#{work_status,jdbcType=INTEGER}

当work_status为0时,Mybatis会将0解析为了空字符串‘’,这样if判断就为false,如果想正确添加and后的查询条件,应该改成

and T.status=#{work_status,jdbcType=INTEGER}

参数校验

    <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <scope>provided</scope>
            <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <scope>provided</scope>
            <version>6.0.16.Final</version>
        </dependency>

@Null 被注解的元素必须为null
@NotNull 被注解的元素必须不为null
@AssertTrue 被注解的元素必须为true
@AssertFalse 被注解的元素必须为false
@Min(value) 被注解的元素必须为数字,其值必须大于等于最小值
@Max(value) 被注解的元素必须为数字,其值必须小于等于最小值
@Size(max,min) 被注解的元素的大小必须在指定范围内
@Past 被注解的元素必须为过去的一个时间
@Future 被注解的元素必须为未来的一个时间
@Pattern 被注解的元素必须符合指定的正则表达式

在方法入参中添加
@NotNull(message = “公共入参不能为空”) CommonParam commonParam调用方法时即可验证
或者利用
@Valid
private CarrierInfoDTO carrierInfoDTO;
@Length(
max = 200,
message = “年龄不能超过200”
)
@Range(
min = 2L,
max = 4L,
message = “改址类型不合要求”
)
@NotNull(
message = “号码为空”
)
@Within(
values = {0L, 2L, 3L, 4L, 7L, 9L, 10L, 11L, 12L},
message = “类型(signType)不合法”
)

//@Validated 这个注解就是如果传入的参数不符合条件就会报message中的错误

@PostMapping("/save")
public Object testUser(@Validated @RequestBody User user) {
    return user.toString();
}

mysql合适建造分表

单表行数超过 500 万行或者单表容量超过 2GB
这个具体还要根据内存吧,内存要有存储所有表的所有索引

flink或者spark 存入数据到redis等 可以用hahir

官网 http://bahir.apache.org/

时间转换LocalDateTime、LocalDate、Long、Date、String 相互转换


LocalDateTimeLocalDateLongDateString 相互转换

DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");

LocalDateTime localDateTime = LocalDateTime.parse("2019-07-31 00:00:00",dateTimeFormatter1);
LocalDate localDate = LocalDate.parse("2019-07-31",dateTimeFormatter2);
Date date = Date.from(LocalDateTime.parse("2019-07-31 00:00:00",dateTimeFormatter1).atZone(ZoneId.systemDefault()).toInstant());


String strDateTime = "2019-07-31 00:00:00";
String strDate = "2019-07-31";
Long timestamp=1564502400000l;

/** LocalDateTime 转 LocalDate */
System.out.println("LocalDateTime 转 LocalDate: "+localDateTime.toLocalDate());
/** LocalDateTime 转 Long */
System.out.println("LocalDateTime 转 Long: "+localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
/** LocalDateTime 转 Date */
System.out.println("LocalDateTime 转 Date: "+Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()));
/** LocalDateTime 转 String */
System.out.println("LocalDateTime 转 String: "+localDateTime.format(dateTimeFormatter1));

System.out.println("-------------------------------");

/** LocalDate 转 LocalDateTime */
System.out.println("LocalDate 转 LocalDateTime: "+LocalDateTime.of(localDate,LocalTime.parse("00:00:00")));
/** LocalDate 转 Long */
System.out.println("LocalDate 转 Long: "+localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli());
/** LocalDate 转 Date */
System.out.println("LocalDate 转 Date: "+Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
/** LocalDate 转 String */
System.out.println("LocalDateTime 转 String: "+localDateTime.format(dateTimeFormatter2));

System.out.println("-------------------------------");

/** Date 转 LocalDateTime */
System.out.println("Date 转 LocalDateTime: "+LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
/** Date 转 Long */
System.out.println("Date 转 Long: "+date.getTime());
/** Date 转 LocalDate */
System.out.println("Date 转 LocalDateTime: "+LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).toLocalDate());
/** Date 转 String */
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
System.out.println("Date 转 String: "+sdf.format(date));

System.out.println("-------------------------------");

/** String 转 LocalDateTime */
System.out.println("String 转 LocalDateTime: "+LocalDateTime.parse(strDateTime,dateTimeFormatter1));
/** String 转 LocalDate */
System.out.println("String 转 LocalDate: "+LocalDateTime.parse(strDateTime,dateTimeFormatter1).toLocalDate());
System.out.println("String 转 LocalDate: "+LocalDate.parse(strDate,dateTimeFormatter2));
/** String 转 Date */
System.out.println("String 转 Date: "+Date.from(LocalDateTime.parse(strDateTime,dateTimeFormatter1).atZone(ZoneId.systemDefault()).toInstant()));

System.out.println("-------------------------------");

/** Long 转 LocalDateTime */
System.out.println("Long 转 LocalDateTime:"+LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()));
/** Long 转 LocalDate */
System.out.println("Long 转 LocalDate:"+LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()).toLocalDate());
日期比较       
 LocalDateTime now = LocalDateTime.now();//2020-09-11T09:41:01.547
        LocalDateTime DiscountStartTime = now.minusDays(3);//减法 2020-09-08T09:41:01.547
        LocalDateTime DiscountEndTime = now.plusDays(3);//加法 2020-09-14T09:41:01.547

//        now>DiscountStartTime && DiscountEndTime>now
//        DiscountEndTime>now>DiscountStartTime
        if(now.isAfter(DiscountStartTime) && DiscountEndTime.isAfter(now)){
            true;//输出true
        }

向数据库插入date 或者dateTime 时,如果用mybatis的话,String 都能插
但是如果要用jdbc 的话 date 对应的就是date dateTime对应的就是Timestamp
在这里插入图片描述
第三种是错误的,不能强转

mysql数据库插入时存在就更新,不存在就插入on DUPLICATE key

insert into test_duplication(ID,name,idcard) VALUES (1,‘1’,‘1’) on DUPLICATE key update id=2,NAME=‘2’,idcard=‘2’;

clickhouse分布式表 分表索引只能用Replicated?

我用clickhouse同步mysql的数据,因为大概800多万条数据,且更改比较多,我用了以下两种方法。
1 使用mysql表引擎 失败,查不到数据,因为我想要join redis中的数据,所以也没仔细研究
2 binlog通过kafka存入clickhouse使用CollapsingMergeTree 引擎,但是带我那个哥说 分布式表只能用Replicated 引擎,但是官网上并没有说,所以我头铁就用,果然可以,但是当我cout()的时候,每次结果都不同,查了问题 https://cloud.tencent.com/developer/article/1748216 就是说如果副本数大于2,count()的数量有可能计算多个副本的数量,所以建议用Replicated。那么我用ReplicatedCollapsingMergeTree ,但是不同机器上的分区能合并吗

Phoenix配置多数据源

    phoenix:
      article:
        driverClassName: org.apache.phoenix.jdbc.PhoenixDriver
        jdbc-url: jdbc:phoenix:10.1.100.39:2181
        username: li
        password: li

导入依赖是最恶心的,又是依赖冲突又是啥的,多亏我有一个超级好的学长。

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>29.0-jre</version>
        </dependency>
             <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.2.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency> 
          <dependency>
            <groupId>org.apache.phoenix</groupId>
            <artifactId>phoenix-core</artifactId>
            <version>5.0.0-HBase-2.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-log4j12</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>javax.el</artifactId>
                    <groupId>org.glassfish</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>
           <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>2.5.0</version>
        </dependency>

在这里插入图片描述
这个报冲突的错是因为没有引入 hadoop common

mybaties property报红

在这里插入图片描述像这个一般是没get set方法,但是我明明用@Data注解了啊,为啥还是错呢
我仔细看了下源码,get set并没有注入进去,然后我把@Accessors删除了,把Data放在仅靠类的上面,就可以了。这两个注释有矛盾吧,反正我只要同时用两个就报错,无语了。
在这里插入图片描述

关于mysql插入数据报错

emoji 错误,插入的String中有表情。

create table third_platforms_video
(
    id            int auto_increment
        primary key,
    platform      varchar(32)  null comment '属于哪个平台',
    open_id       varchar(255) null comment '授权用户唯一标识',
    nickname      varchar(255) null comment '账户名字',
    createTime    date         null comment '视频创建时间',
    item_id       varchar(255) null comment '视频ID',
    title         varchar(255) null comment '视频名称',
    digg_count    bigint       null comment '点赞量',
    comment_count bigint       null comment '评论量',
    share_count   bigint       null comment '分享量',
    forward_count bigint       null comment '转发量',
    play_count    bigint       null comment '视频播放量',
    coin_count    bigint       null comment '投币量',
    collect_count bigint       null comment '收藏量',
    update_at     datetime     null comment '新媒体矩阵平台中的更新时间',
    create_at     datetime     null comment '新媒体矩阵平台中的创建时间'
)
    engine = InnoDB
    charset = utf8mb4;

修改编码格式就可以了。utf8mb4

用group by 分组,没有分组的字段随便取一条记录

例如:
id trueName userName score
1 张三 zs 80
2 张三 zs1 100
3 张三 zs2 90

想要获得张三的总分(userName 随便去一个值即可):

张三 zs 270 或 张三 zs1 270 或 张三 zs1 270
我在整理埋点数据的时候遇到了这个问题,可以用max 或者min
select name,max(第二列),sum(分数) group by name

dataGrip时差问题

在这里插入图片描述我的dataGrip时差问题没配好,差8小时,然后我在查询的时候发现了一个奇怪的问题,既然时差没配好,差8个小时,那么只查年月的话月份结果是没差的。

yml注入问题

@postStruct() 这个注解就是构造方法完成后,执行这个命令。

mybaties批量插入问题

等于说如果list大于6000条的话,那就2000条一拆分,2000条插入一次
SqlServer 对语句的条数和参数的数量都有限制,分别是 1000 和 2100。
Mysql 对语句的长度有限制,默认是 4M。
Mybatis 对动态语句没有数量上的限制。
//拆分list代码
package com.hnradio.bdthirdplatform.utils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhz
 * @date 2021/11/29
 */
public class SplitList {
    /**允许使用的最大记录数量*/
    private static final int SELECT_MAX_COUNT = 1000;
    /**
     * 按照count拆分成多个list
     * @param lists  需要拆分的数据
     * @param num  以num为拆分数据
     * @return
     */
    public static <T> List<List<T>> splitList(List<T> lists, Integer num) {
        int maxCount;
        if (num == null || num == 0) {
            maxCount = SELECT_MAX_COUNT;
        } else {
            maxCount = num.intValue();
        }
        List<List<T>> result = new ArrayList<>();
        if (lists != null) {
            //记录数量
            int length = lists.size();
            int time = length / num;
            //计算拆分几条
            time = length % num > 0 ? time + 1 : time;
            int end;
            List<T> tmpList;
            for (int i = 1, start = 0; i <= time; i++) {
                if (i == time) {
                    end = length;
                } else {
                    end = i * maxCount;
                }
                tmpList = lists.subList(start, end);
                start = end;
                result.add(tmpList);
            }
        }
        return result;
    }

    /**
     * 按照count拆分成多个list
     * 默认拆分记录条数 1000
     * @param lists 需要拆分的数据
     * @return 返回拆分后 数据集合用于使用
     */
    public static <T> List<List<T>> splitList(List<T> lists){
        return splitList(lists,SELECT_MAX_COUNT);
    }

}


直接用下面这个一步到位
List<List> partition = Lists.partition(res, 1000);

创建一个List,但里边只有一个值

在这里插入图片描述

浮点数比较大小

在这里插入图片描述

建立索引的经验

如果表格中大量增删改,最好别用索引(为啥因为B+树)
复合索引(where后 and 左右两边两个关联比较大的时候.如果建的是两个单一索引,则只会用一个,因为用的是一个B+tree呀!)
单一索引(where后 or )

日期取代SimpleDateFormat

在这里插入图片描述

String 拼接节省空间

在这里插入图片描述

SQL函数

date_add(date,interval 1 day)
month(date)
date_sub(date,interval 1 day)
TIMESTAMPDIFF(second, start_time, end_time)计算出时间差。
round(,1)保存几位小数。即保存一位小数
Row_Number() 用法,以deptid为分区,根据ORDER BY进行分区,SELECT *, Row_Number() OVER (partition by deptid ORDER BY salary desc) rank FROM employee
rank() over(partition by id order by dt) rankover和row_number的区别是rankover排序后相同的排名相等,row_number就是按照序列排。

当要面对group by 内,条件是每个数值的最大值时,但又不求这个最大值,可以使用拼接的方法,然后Max(String)。可以这样求这种思想。

windows下删除vue的node_modules

安装rimraf
npm install -g rimraf
node_modules的父级目录,执行
rimraf node_modules

Java中List 数组 Set相互转换

new ArrayList(set) 注意list或者set必须是封装类(比如就不能是int 而必须用inteager,如果用int的话,那set会把整个int当成一个set[0]的位置)
new HashSet(list)
list.toArray
set.toArray
Arrays.asList()
数组转换set必须先转list,再转换为set

hive的group by报错

hive本身有bug
在 select from (select 1 from a join b) 别名 group by
注意必须要有别名,否则hive报错

join时候注意点问题

A表中join的字段类型是double
B表中join的字段类型String
当进行on的时候隐式转换会把stirng类型有可能转为null.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值