1、前言
总结一些用到的小工具、API,慢慢进行积累。
老杜笔记:
www.yuque.com/dujubin/jav… 《第1章 环境准备》
www.yuque.com/dujubin/jav… 《第2章 磁盘与文件管理》
www.yuque.com/dujubin/jav… 《第3章 系统命令》
www.yuque.com/dujubin/jav… 《第4章 文件内容查看》
www.yuque.com/dujubin/jav… 《第5章 Linux用户管理》
www.yuque.com/dujubin/jav… 《第6章 文件权限》
www.yuque.com/dujubin/jav… 《第7章 软件的安装与卸载》
www.yuque.com/dujubin/jav… 《第8章 web部署阿里云》
www.yuque.com/dujubin/jav… 《第9章 shell编程》
2、使用
2.1: 组合二元对象返回
在pom中查看了使用Tuple所需要的依赖
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jool-java-8</artifactId>
<version>0.9.14</version>
</dependency>
public static Tuple2<Map<String, Object>, List<Object>> tupleTest() {
Map<String, Object> map = new HashMap<>();
map.put("name","张三");
map.put("userName","zhangsan");
map.put("age","18");
List<Object> list = new ArrayList<>();
list.add("1111");
list.add("2222");
list.add("3333");
//使用tuple() 方法 返回一个二元组
Tuple2<Map<String, Object>, List<Object>> tuple = Tuple.tuple(map, list);
return tuple;
}
public static void main(String[] args) {
Tuple2<Map<String, Object>, List<Object>> test = tupleTest();
Map<String, Object> v1 = test.v1;
List<Object> v2 = test.v2;
Object name = v1.get("name");
Object o = v2.get(0);
System.out.println("map---》"+name);
System.out.println("list---》"+o);
}
2.2:拆分list为子list
将一个大的list按照一定数量拆分为多个子list
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
//将每50000个list拆分为子list
List<List<String>> partition = Lists.partition(list, BizConstant.SPLIT_LIST_SIZE);
2.3:上传文件是否图片格式
判断是否有宽高属性
/**
* 通过读取文件并获取其width及height的方式,来判断判断当前文件是否图片,这是一种非常简单的方式。
*
* @param imageFile
* @return
*/
public static boolean isImage(MultipartFile imageFile) throws IOException {
Image img = ImageIO.read(imageFile.getInputStream());
if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
return false;
}
return true;
}
2.4:下载网络文件
try {
String downLink="网络资源url";
URL url = new URL(downLink);
URLConnection conn = url.openConnection();
return conn.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
2.5: excel转csv
public static void main(String[] args) {
String excelFilePath = "C:/Users/xulongyu/Desktop/数据源导出 (6).xlsx";
String csvFilePath = "C:/Users/xulongyu/Desktop/NB.csv";
try (Workbook workbook = WorkbookFactory.create(new File(excelFilePath));
BufferedWriter writer = new BufferedWriter(new FileWriter(csvFilePath))) {
int numberOfSheets = workbook.getNumberOfSheets();
for (int i = 0; i <numberOfSheets; i++) {
Sheet sheet = workbook.getSheetAt(i);
for (Row row : sheet) {
for (Cell cell : row) {
String cellValue = "";
if (cell.getCellType() == CellType.STRING) {
cellValue = cell.getStringCellValue();
} else if (cell.getCellType() == CellType.NUMERIC) {
cellValue = String.valueOf(cell.getNumericCellValue());
} else if (cell.getCellType() == CellType.BOOLEAN) {
cellValue = String.valueOf(cell.getBooleanCellValue());
}
writer.write(cellValue + ",");
}
writer.newLine();
}
}
System.out.println("Excel file converted to CSV successfully!");
} catch (IOException e) {
e.printStackTrace();
}
}
2.6: 查询最新日期表MP拦截器
public class MonthTableNameHandler implements TableNameHandler {
/**
* 需要查询最新日期表集合
**/
private final List<String> tableNameList;
/**
* 构造函数赋值
**/
private CommonService commonService;
public MonthTableNameHandler(String[] tableNames) {
tableNameList = Arrays.asList(tableNames);
}
@Override
public String dynamicTableName(String sql, String tableName) {
// 为commonService赋值
this.getInstance();
if (tableNameList.contains(tableName)) {
return commonService.getLatestTableName(tableName);
}
return tableName;
}
/**
* 为commonService赋值
*
* @return CommonService
* @author xulongyu
* @date 2023/6/5 13:21
**/
public CommonService getInstance() {
if (null == commonService) {
commonService = SpringUtil.getBean(CommonService.class);
}
return commonService;
}
}
2.7、nignx小记
1、nginx基本配置-代理转发
server {
listen 80;
server_name 127.0.0.1;
underscores_in_headers on;
location / {
proxy_pass http://xxxx:xxx;
#root /usr/share/nginx/html;
#index index.html;
}
}
2、配置https证书
将证书文件放到nginx/cert目录下
server {
listen 80;
listen 443 ssl;
server_name 域名;
underscores_in_headers on;
ssl_certificate /etc/nginx/cert/xxx.pem; //放证书文件
ssl_certificate_key /etc/nginx/cert/xxx.key; //放证书
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
}
3、禁止访问nginx下某个目录
#禁止访问目录
location ^~ /test/ {
deny all;
}
4、nginx代理添加固定cookie
location /etl {
proxy_pass http://192.168.xxx.xxx:8108;
proxy_set_header Cookie 'token=xxx.eUFkbWluIiwidW5pdE5vIjoiMTAxIiwidXNlck5hbWUiOiLnrqHnkIblkZgiLCJleHAiOjE3MjAwOTY0ODAsInVzZXJObyI6ImFkbWluIn0.H
Pui36ftX4B1g9pB8B7VdRRh4Ey1GvcfyW21Gq9OYL0DH4I1ooMB2Tq0wLBNgXmgnzPQ952m0BK_wc79oI8zZQ';
2.8、mysql贪婪匹配
/**
* mysql贪婪匹配
*
* @param str 关键字
* @return String
* @author xulongyu
* @date 2023/12/15 10:03
**/
public static String specialStrKeyword(String str) {
if (str == null || str == "") {
return null;
}
StringBuffer stringBuffer = new StringBuffer(str);
int length = str.length();
for (int i = 0; i < length; i++) {
char chari = stringBuffer.charAt(i);
if (i == 0) {
if (chari == '%' || chari == '_' || chari == '\\') {
stringBuffer.insert(i, "\\");
i++;
length++;
}
} else {
if (chari == '%' || chari == '_' || chari == '\\') {
stringBuffer.insert(i, "%\\");
i += 2;
length += 2;
} else {
stringBuffer.insert(i, "%");
i++;
length++;
}
}
}
return stringBuffer.toString();
}
2.9、stream多次排序
data.stream()
// 将匹配元素排在前面
.sorted(Comparator.comparing((TodoApiVO x) -> {
String itemNo = x.getItemNo();
Long appId = x.getAppId();
String match = appId + "_" + itemNo + "_" + userNo;
//标记已读
boolean readFlag=readMarksStr.contains(match);
x.setRead(readFlag);
return readFlag; })
.reversed()
.thenComparing(TodoApiVO::getUpdate)
.reversed())
.collect(Collectors.toList());
2.10、对list进行分页
/**
* 对List 分页
*
* @param list list
* @param pageNum 第几页
* @param pageSize 每页多少条
* @return PageWrapper<?>
* @author xulongyu
* @date 2024/5/20 18:57
**/
public PageWrapper<T> pageHelper(List<T> list, Integer pageNum, Integer pageSize) {
PageWrapper<T> pageWrapper = new PageWrapper<>();
pageWrapper.setPageSize(pageSize);
pageWrapper.setPage(pageNum);
int total = list.size();
pageWrapper.setTotal(total);
pageWrapper.setPages(total%pageSize == 0 ? total / pageSize : total / pageSize + 1);
int startIndex = (pageNum - 1) * pageSize;
int endIndex = Math.min(startIndex + pageSize, total);
if (startIndex > endIndex) {
pageWrapper.setList(new ArrayList<>());
return pageWrapper;
} else {
pageWrapper.setList(list.subList(startIndex, endIndex));
return pageWrapper;
}
}
2.11、获取请求IP
/**
* 获取用户真实IP地址
*
* @param request request
* @return ip
*/
public static String getIpAddress(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip != null && ip.length() != 0 && !ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
if (ip.contains(StrPool.COMMA)) {
ip = ip.split(StrPool.COMMA)[0];
}
}
if (ip == null || ip.length() == 0 || ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || ContextConstants.UNKNOW.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
2.12 SQL批量执行
mybaits-plus批量执行
//注入sqlSessionFactory
@Autowire
private SqlSessionFactory sqlSessionFactory;
//使用批处理
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
ReadMarkMapper readMarkMapper = sqlSession.getMapper(ReadMarkMapper.class);
list.forEach(readMarkMapper::insert);
sqlSession.commit();
sqlSession.clearCache();
mybaits mapper.xml批量执行
插入语句mapper使用 foreach标签 循环拼接
public void batchInsertData(List<ClassStuSign> dataList, String stuSignTable) {
// 指定每批次插入的数据量
int batchSize = 1000;
for (int i = 0; i < dataList.size(); i += batchSize) {
int endIndex = Math.min(i + batchSize, dataList.size());
List<ClassStuSign> batchList = dataList.subList(i, endIndex);
scheduleMapper.initStuSignInfo(batchList, stuSignTable);
}
}
2.13、数据库自动备份
#!/bin/bash
# 设置备份目录
backupDir="/home/backup"
# 设置需要备份的数据库名称和用户名、密码
dbUser="root"
dbPass="123456"
dbName="database_name"
# 设置备份文件名,包括日期和时间
backupFile="$backupDir/${dbName}_$(date +%Y%m%d_%H%M%S).sql"
# 执行备份命令
mysqldump -u$dbUser -p$dbPass $dbName > $backupFile
# 压缩备份文件
gzip -f $backupFile
# 删除7天前的备份文件
find $backupDir -mtime +7 -type f -name "${dbName}*.sql.gz" -delete
将这个脚本保存到一个文件中,如backup_db.sh,并添加可执行权限:
chmod +x backup_db.sh
通过编辑crontab文件,可以将这个脚本设置为定期自动运行,比如每天执行一次备份。打开终端,输入:
crontab -e
在文件末尾添加下面的一行:
0 0 * * * /path/to/backup_db.sh
# 20 12 * * * /path/to/backup_db.sh 表示每天12:20会执行一次脚本。
保存并退出crontab文件,这样在每天午夜0点进行自动备份。如果需要调整自动备份的时间,也可以修改crontab文件中的时间字段。
2.14 docker
安装docker
yum install -y yum-utils device-mapper-persistent-data lvm2 && \
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo && yum makecache fast && \
yum -y install docker-ce && \
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://j6o4qczl.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl enable docker
systemctl restart docker
安装docker-compose
curl -L "https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose version
使用 docker-compose 启动一个容器
以下是 docker-compose.yml 的内容
version: '2.1'
services:
nginx:
image: nginx:latest
container_name: nginx_test
ports: - 8080:80
volumes: - /opt/nginx:/opt/nginx/html
参数:
compose 文件格式的版本,恒定为 2.1
services 标签下可以定义多个类似 nginx 这样的服务
container_name 服务定义, nginx_test 是容器的名称
image nginx容器所使用的镜像
ports 定义端口映射,本例将容器内的 80 端口映射到宿主机的 8080 端口
volumes 定义目录映射,本例将容器内的 /opt/nginx/html 目录映射到宿主机的 /opt/nginx 目录
docker镜像迁移
# 打包容器
docker save <容器ID> /data/software/xxxx.tar
# 打包镜像
docker save -o xxx.tar 镜像id
# 加载镜像
docker load < /data/software/xxx.tar
# 修改镜像标签
docker tag 999c20aee5da <镜像名称>:<版本号>
2.15 boot打包本地jar包
<dependency>
<groupId>com.sun.jna</groupId>
<artifactId>jna</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/lib/jna.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.jna.examples</groupId>
<artifactId>examples</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${pom.basedir}/lib/examples.jar</systemPath>
</dependency>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>