Java程序猿搬砖笔记(七)

Java程序猿搬砖笔记(七),第1张

Java程序猿搬砖笔记(七) Java导入1W条数据耗时超过100秒

项目中导入一个含合并单元格的Excel,1W条数据耗时超过100秒。Excel模板如下:

数据库设计:
合并单元格部分(框红部分)存入主表,后面的部分存入详细表。
目前代码逻辑:

循环插入主表然后把主表返回的主键封装到详细表的所需数据,批量插入详细表

问题原因:
导入1W条数据(如果全部未合并单元格)会循环插入主表数据库1W次,然后循环插入从表数据库1W次,效率及其低。
解决方法

把数据库主键自增改为UUID,通过Java代码生成
UUID uuid = UUID.randomUUID();封装主表数据批量插入、封装详细表数据批量插入

修改完成后1.1W条数据第一次12秒,之后大概6秒左右就可以插入完。

Java正则表达式的几种实现方式

方法一

 Pattern.matches(regex, str);

方法二

str.matches(regex);

方法三

Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
boolean flag = m.matches();

Matcher中的find()方法可以获取匹配的具体信息

while(m.find()) {
		System.out.println(m.start());
		System.out.println(m.end());
		System.out.println(m.group());
	}
Linux查询进程杀进程命令
# 查询进程
ps -ef|grep xxx.jar
UID       PID       PPID      C     STIME    TTY       TIME         CMD

zzw      14124   13991      0     00:38      pts/0      00:00:00    grep --color=auto dae

# 杀进程命令
kill -9 进程号

# 启动jar包程序
nohup java -jar xxx.jar &
# 远程调试启动
nohup java -jar -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 kjcgkyg-0.0.1-SNAPSHOT.jar &

# 实时查看输出日志
tail -f nohup.out
# 查看最后1000行日志
tail -n 1000 nohup.out

参考链接1 参考链接2

spring 注解@primary解析

@primary的作用是在多个类同时实现一个接口时,优先选择Bean注入。可以直接在类上使用:

@Component
@Primary
public class OperaSinger implements Singer {
    @Override
    public String sing(String lyrics) {
        return "I am OperaSinger: "+lyrics;
    }
}

可以在配置类的方法中使用,这种方法会被@Qualifier(value = “operaSinger”)注解覆盖:

@Configuration
public class CustomerConfiguration {

    @Bean
    @Primary
    public Singer getSinger(){
        System.out.println("我是CustomerConfiguration.getSinger!!!");
        return new metalSinger();
    }
}

参考链接

@resource可以和@Qualifier有一样的作用

参考链接

MySQL根据多字段查询出重复记录
SELECt id FROM t_awards WHERe id IN (
 SELECt  id FROM t_awards GROUP BY id,award_year,award_product
 HAVINg COUNT(*) > 1
)
MySQL取整的函数
# 向上取整
SELECt CEIL(1/2);  // 1
# 向下取整
SELECT FLOOR(0.6);  // 0
# 四舍五入
SELECT ROUND(1.5);  // 2  
MySQL 8.0忘记密码怎么办

参考链接1、参考链接2

MySQL 8.0官网解压版安装详细教程

参考链接

exists和in的区别

in引导的子查询只能返回一个字段,exists子查询可以有多个字段exists使用循环的方式,由outer表的记录数决定循环的次数,对于exists的影响最大,所以,外表的记录越小,子查询结果集较大时适用于existsin 先执行子查询,子查询的结果返回去重之后,再执行主查询,所以,子查询的返回结果越少,越适合使用in关键字。 MySQL用一个表更新另一个表

参考链接

git回滚commit的近几次版本

方法一
回退最近几次提交
git reset --soft head~方法二
git log、git reset --soft commitId
注意这里是回退commitId之后的 *** 作,commitId不回退方法三
git log
然后用IDEA *** 作
注意这里是回退commitId之后的 *** 作,commitId不回退

参考链接1、参考链接2

MySQL根据年份和id排序后,取前后五条数据的SQL


思路:可以先通过连接工具观察,然后一步一步调试写出sql。例子中的2022和199作为参数传过来的前后五条sql如下所示:
前五条sql:

SELECT id,project_code,project_name
FROM t_project_base_info
WHERe delete_flag = 0 AND ((project_year = 2022 and id > 199) or project_year > 2022)
order by project_year asc,id asc
LIMIT 0,5

后五条sql:

SELECT id,project_code,project_name
FROM t_project_base_info
WHERe delete_flag = 0 AND ((project_year = 2022 and id < 199) or project_year < 2022)
order by project_year desc,id desc
LIMIT 0,5
MyBatis映射集合,参数传入多个

xml映射文件代码:



其中,id、project_year、cgk_company_code是当前表的字段,id、projectYear、cgkCompanyCode作为SQL查询参数传入id为selectNextList的SQL。




Springboot获取配置文件属性的几种方法

参考链接1、参考链接2

BeanMap不能进行put *** 作
BeanMap map = BeanMap.create(req);
// 不能进行put *** 作,没有效果
map.put("cgkCompanyCode",companyCode);
SpringBoot配置集合(数组)
// yml配置文件中
rolekey:
  interfaceAndRms: [13,18]
// Java代码中(:后面的表示若配置文件取不到用默认值)
@Value("${interfaceAndRms:13,18}")
private List interfaceAndRms;   	
IDEA 搜索Jar包中的类和方法

Double Shift就行了

MySQL替换指定字段中的字符串

MySQL有replace函数
语法:

replace (`field_name`,'from_str','to_str')

示例:

-- 把t_achievement表的company_name字段中的","的替换为"、"
UPDATe t_achievement
SET company_name = replace(company_name, ',', '、')
WHERe company_name LIKE '%,%'

参考链接

SpringBoot事务学习

1、确保在启动类中添加了@EnableTransactionManagement注解,在seivice中添加@Transactional 注解
Spring底层会设置数据库开启事务、不自动提交,所以加上上面两个注解就可以了。
2、事务回滚
Spring事务默认只在发生未被捕获的RuntimeExcetpion时才回滚。可以捕获到异常后抛出新的RuntimeExcetpion,推荐这种方法。

// 插入失败后抛出自定义异常(继承RuntimeExcetpion),事务才能回滚
   try {
                            achievementTagMapper.insertSelective(achievementTag);
                        } catch (Exception e) {
                            log.error("AchievementServiceImpl.importAchievement批量插入achievementTag表失败:", e.getMessage());
                            throw new CommonsException(MessageCode.Insert_Error, e);
                        }

也可以捕获异常后添加
TransactionAspectSupport.currentTransactionStatus().setRollbackonly();代码
手动回滚,这样上层就无需去处理异常,但是这样接口出错信息返回不到前端了。

service类中不加@Transactional注解,方法A调用方法B
1、注解加在方法A,方法B不加:
①方法A异常(抛出)
方法A中事务回滚,不走方法B
②方法B异常(抛出)
方法A,方法B事务都回滚

2、注解加在方法B,方法A不加:
①方法A异常(抛出)
方法A中事务不回滚,不走方法B
②方法B异常(抛出)
方法A事务不回滚,方法B回滚

service类中加@Transactional注解,相当于所有方法都加了注解

参考链接

查看MySQL事务开启

参考链接

Java替换最后一个字符
public static String replaceLast(String text, String currentStr, String targetStr) {
    return text.replaceFirst("(?s)" + currentStr + "(?!.*?" + currentStr + ")", targetStr);
}

例子:

 String str = "、1232、43424、、55、、";
// 输出:、1232、43424、、55、
System.out.println(replaceLast(str,"、",""));
Java替换第一个字符

用Java String自带的replaceFirst方法,第一个参数是正则表达式
例子:

String str = "、1232、43424、、55、、";
// 输出:1232、43424、、55、、
System.out.println(str.replaceFirst("、", "" ));
MySQL查询Text字段会非常慢(IO慢),高并发下会特别明显。

列表查询尽量不要查这个字段。可以改为blob数据类型,得代码转换。

bootstrap.yml配置

SpringBoot 项目中如果没有依赖spring-cloud-context的话不会读取到bootstrap.properties(yml)文件,bootstrap.yml配置是SpringCloud项目才会用到的。


    org.springframework.cloud
    spring-cloud-context
    2.0.1.RELEASE

bootstrap中的相同配置会被覆盖,bootstrap中的相同配置会被覆盖(亲自测试),所以application中不要配置bootstrap中已有的配置。applicaiton中的配置按优先级,以第一次读取的为准。一般服务名和配置中心信息在bootstrp文件中指定。 BeanMap存在很多问题,最好用反射转换对象为Java原生Map MySQL *** 作binlog相关命令

查询所有相关日志
SHOW MASTER logs;最新使用的日志
SHOW MASTER status;查询指定日志文件修改
SHOW BINLOG EVENTS IN ‘binlog.000014’;把指定时间开始的binlog导出为sql文件
mysqlbinlog --no-defaults --start-datetime=“2021-12-08 16:00:00” “D:Program Filesmysql-8.0.27-winx64Databinlog.000014” > D:exporttest1.sql IDEA有时候修改父项目pom.xml,子项目没有引用到父项目的jar包

解决方法:先看父项目中是否引用到,如果父项目有子项目没有,清理IDEA缓存重启一下(已经这样解决两次了)。

Linux查看端口占用情况

命令:lsof -i:端口号
例子:
查看服务器 8000 端口的占用情况:

lsof -i:8000

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nodejs 26993 root 10u IPv4 37999514 0t0 TCP *:8000 (LISTEN)
可以看到 8000 端口已经被轻 nodejs 服务占用。

Java8中list转map如果Key重复的解决方法

若不处理会抛异常
java.lang.IllegalStateException: Duplicate key 11
解决方法:用第二个key覆盖第一个key。
示例代码如下:

Map roleKeyMap = allRoleList.stream()
                .collect(Collectors.toMap(Role::getName, Role::getRoleKey, (key1, key2) -> key2));

参考链接

HttpClient的一些方法
// 发送请求
httpResponse = httpClient.execute(httpPost);
// 获取状态码
int statusCode=httpResponse.getStatusLine().getStatusCode();
// 从响应对象中获取响应内容并转为String
String result = EntityUtils.toString(httpResponse.getEntity());
// 把result转为HashMap
HashMap resultMap = new Gson().fromJson(result, HashMap.class);
MySQL模糊匹配表名拼接删表语句
# drop不支持删表
SELECT CONCAT( 'drop table ', TABLE_NAME, ';')
FROM information_schema.tables
WHERe table_name LIKE 'wb_role_%';

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5719024.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存