JAVA开发(对大表数据逐条进行处理踩的坑记录一下)

news2024/12/23 13:48:19

 

一、编程语言介绍

所使用的编程语言为JAVA。纯后端开发。

二、炫技代码分享

 现在我编写代码一般通过逆向工程生成,只需要设计好数据库表就可以逆向生成后端的接口模块。

三、案例分享

逆向工程。逆向工程涉及到的输出模块。具体运用需要关注和联系博主分享使用。

## 该工程的意义
- 该工程的主要好处是解决开发人员编写重复的代码, 
- 强制开发人员使用规范的编程模式和代码注解,  
- 提高代码的可维护性和阅读性,
- 降低了代码的不规范性和因个人编程缺陷引起的不必要风险,  
- 提高代码质量和开发效率。  

## 使用说明
- 1、修改dbConfig.xml文件配置数据源信息。  
- 2、修改project.xml文件配置微服务信息。  
    2.0、修改name为对应数据库,支持mysql、oracle、postgresql  
    2.1、修改schema为据库名称  
    2.2、修改table为表名,多个表以逗号分隔  
    2.3、修改version版本号  
    2.4、修改author为自己的OA名称  
    2.5、修改service为服务名称  
    2.6、修改module为模块名称  
    2.7、修改rootPackage为根包名称  
    2.8、修改application为启动类名称  
    2.9、其他内容无需修改  
- 3、运行Run.java,生成代码,路径为out目录下 。  

<?xml version="1.0" encoding="GBK"?>
<project>
	<import resource="dbConfig.xml" />
	<configuration>
		<prop key="defaultEncoding">UTF-8</prop>
		<prop key="outputEncoding">UTF-8</prop>
		<!-- 可通过设置不同的模板路径,生成对应的不同模板代码-->
		<prop key="templateDir">{root}/template</prop>
		
	</configuration>

	<templates>
		<template name="application">mhyr/application.ftl</template>
		<template name="baseApplication">mhyr/base-application.ftl</template>
		<template name="bootstrap">mhyr/bootstrap.ftl</template>
		<template name="app">mhyr/app.ftl</template>
		<template name="entity">mhyr/entity.ftl</template>
		<template name="dto">mhyr/dto.ftl</template>
		<template name="client">mhyr/client.ftl</template>
		<template name="constant">mhyr/constant.ftl</template>
		<template name="controller">mhyr/controller.ftl</template>
		<template name="service">mhyr/service.ftl</template>
		<template name="dao">mhyr/dao.ftl</template>
		<template name="cache">mhyr/cache.ftl</template>
		<template name="parentPom">mhyr/parent-pom.ftl</template>
		<template name="modulePom">mhyr/module-pom.ftl</template>
		<template name="target">mhyr/target.ftl</template>
	</templates>
	<rules>
		<rule name="tableName" type="JavaScript">
			<![CDATA[
            function convertTableName(tableName) {
                var a = tableName.split('_');
                if (a.length > 1) {
                    //a.shift();
                }
                var tempStr;
                for (var i = 0, len = a.length; i < len; i++) {
                    tempStr = a[i];
                    a[i] = tempStr.charAt(0).toUpperCase() + tempStr.substring(1).toLowerCase();
                }
                return a.join('');
            }
            ]]>
		</rule>
		<rule name="columnName" type="JavaScript">
			<![CDATA[
            function convertColumnName(columnName) {
                var a = columnName.split('_');
                if (a.length > 1) {
                    //a.shift();
                }
                var tempStr;
                for (var i = 0, len = a.length; i < len; i++) {
                    tempStr = a[i];
                    if (i == 0) {
                        a[i] = tempStr.toLowerCase();
                    } else {
                        a[i] = tempStr.charAt(0).toUpperCase() + tempStr.substring(1).toLowerCase();
                    }
                }
                return a.join('');
            }
            ]]>
		</rule>
	</rules>
	<inputs>
		<input>
			<source type="db">
				<!-- 支持mysql、oracle、postgresql -->
				<db name="postgressql">
					<!-- oracle为用户名(大写); mysql,postgresql为库名 -->
					<prop key="schema">public</prop>
					<!-- oracle要大写; 多个表中间用','隔开 -->
					<prop key="table">m_token_user</prop>
				</db>
			</source>
			<custom>
				<!--版本-->
				<prop key="version">1.0</prop>
				<!--作者-->
				<prop key="author">茅河野人</prop>
				<!--系统名称-->
				<prop key="system">maoheyeren-plat</prop>
				<!--服务名称-->
				<prop key="service">member-business</prop>
				<!--启动类名-->
				<prop key="application">Token</prop>
				<!--根包名称-->
				<prop key="rootPackage">cn.mhyr.member</prop>
				<!--client包名称-->
				<prop key="clientPackage">{rootPackage}.client</prop>
				<!--constant包名称-->
				<prop key="constantPackage">{rootPackage}.constant</prop>
				<!--controller包名称-->
				<prop key="controllerPackage">{rootPackage}.controller</prop>
				<!--dao包名称-->
				<prop key="daoPackage">{rootPackage}.dao</prop>
				<!--dto包名称-->
				<prop key="dtoPackage">{rootPackage}.dto</prop>
				<!--entity包名称-->
				<prop key="entityPackage">{rootPackage}.entity</prop>
				<!--dto包名称-->
				<prop key="dtoPackage">{rootPackage}.dto</prop>
				<!--service包名称-->
				<prop key="servicePackage">{rootPackage}.service</prop>
				<!--application包名称-->
				<prop key="applicationPackage">{rootPackage}/{application}</prop>
				<!--缓存包名-->
				<prop key="cachePackage">{rootPackage}.cache</prop>
			</custom>

			<outputs outputDir="{root}/out">
				<!--生成服务包-->
				<output name="base" subOutputDir="{service}/{service}/src/main/java/" template="entity" package-name="{entityPackage}">
					<rule>
						<prop key="tableName">tableName</prop>
						<prop key="columnName">columnName</prop>
					</rule>
					<filePattern>{package-name}/{class-name}.java</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="dto" package-name="{dtoPackage}">
					<filePattern>{package-name}/{class-name}DTO.java</filePattern>
				</output>
				<!--
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="client" package-name="{clientPackage}">
					<filePattern>{package-name}/{class-name}Client.java</filePattern>
				</output>
		        -->
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="constant" package-name="{constantPackage}">
					<filePattern>{package-name}/{class-name}Constant.java</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="controller" package-name="{controllerPackage}">
					<filePattern>{package-name}/{class-name}Controller.java</filePattern>
				</output>

				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="service" package-name="{servicePackage}">
					<filePattern>{package-name}/{class-name}Service.java</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="dao" package-name="{daoPackage}">
					<filePattern>{package-name}/{class-name}Mapper.java</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="baseApplication" package-name="{applicationPackage}">
					<filePattern>{package-name}Application.java</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/" template="modulePom" package-name="">
					<filePattern>pom.xml</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/resources/" template="bootstrap" package-name="">
					<filePattern>bootstrap.yml</filePattern>
				</output>
				 
				<output extends="base" subOutputDir="{service}/{service}/src/main/resources/" template="application" package-name="">
					<filePattern>application.yml</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/resources/META-INF" template="app" package-name="">
					<filePattern>app.properties</filePattern>
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/target" template="target" package-name="">
					<filePattern>target-test.txt</filePattern> 
				</output>
				
				<output extends="base" subOutputDir="{service}/{service}/src/main/java/" template="cache" package-name="{cachePackage}">
							<filePattern>{package-name}/{class-name}Cache.java</filePattern>
				</output>
		 
			</outputs>
		</input>
	</inputs>
</project>

 

四、如何学习高级技术

高级的技术总是让人感觉简洁。

 

五、介绍对大表数据逐条处理遇到的坑

背景:

有一批数据需要解密,数据量500W,需要导到pg数据库中。

处理方式:

通过Java代码,逐条读取数据进行处理,将处理结果更新。

编写代码:

使用 ApplicationRunner 线程

线程类:

 

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import cn.ctg.member.service.TmpMUserService;
 
import lombok.extern.slf4j.Slf4j;

/**
 * 线程服务类
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class ToolServiceThread implements ApplicationRunner {
    
//	@Autowired
//	private HongkongPhoneService hongkongPhoneService;
	//ExecutorService threadPool = Executors.newFixedThreadPool(2);
	
	@Autowired
	private GenerateUrllinkClient generateUrllinkClient;
	@Autowired
	private WeixinAppService weixinAppService;
	
	@Autowired
	private TmpMUserService tmpMUserService;

	@Override
	public void run(ApplicationArguments args) throws Exception {
		log.info("开启线程.....,");
		tmpMUserService.updateOne();
		
	}
 
}

解密数据服务类。 

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.ctg.common.encryption.SHAUtils;
import cn.ctg.common.encryption.SM4Util;
import cn.ctg.member.dao.TmpMUserMapper;
import cn.ctg.member.entity.MUserSf;
import cn.ctg.member.entity.TmpMUser;
import lombok.extern.slf4j.Slf4j;

 
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class TmpMUserService extends ServiceImpl<TmpMUserMapper, TmpMUser> {

	@Autowired
	private TmpMUserMapper tmpMUserMapper;

	private String keyString = "秘钥";
	private String pre = "86-s4:";

	public TmpMUser getOne() {
		return tmpMUserMapper.selectTmpMUser();
	}

	public void updateOne() {

		
		for (int i = 0; i < 5000000; i++) {
			TmpMUser tmpMUser = getOne();
			if (null != tmpMUser) {
				String yphone = tmpMUser.getPhone();
				log.info("原手机号:"+yphone);
				if(!StringUtils.isEmpty(yphone)) {
					yphone = yphone.replaceFirst(pre, "");
					String phone = SM4Util.sm4Decode(yphone, keyString);
					String origPhone = SHAUtils.getSHA("86-" + phone);
					log.info("解密出手机号:"+phone);	
					tmpMUser.setPhone(phone);
					tmpMUser.setOrigPhone(origPhone);
					//tmpMUserMapper.updateById(tmpMUser);
					tmpMUserMapper.updateTmpMUser(tmpMUser.getUserId(), phone, origPhone);
				 
				  
				}
			
			}
		 
			log.info("已解密数据条数:"+i);
			
		}
	

	}
}

关键代码:



import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import cn.ctg.member.entity.TmpMUser;

  
@Repository
public interface TmpMUserMapper extends BaseMapper<TmpMUser> {
	
    /**
     * 更新字段
     */
    @Update("<script>" +
            "update 数据表  SET phone = #{phone},orig_phone =#{origPhone}  WHERE user_id = #{userId} ; commit " +
            "</script>")
    public void updateTmpMUser(@Param("userId") String userId,@Param("phone") String phone,@Param("origPhone") String origPhone);
    
    /**
     * 查询
     */
    @Select("<script>" +
            "select  *  from 数据表 where orig_phone is null and  phone is not null limit 1 " +
            "</script>")
    public TmpMUser selectTmpMUser();
    
   
}

讲解:

select  *  from 数据表 where orig_phone is null and  phone is not null limit 1;

这个语句就能从数据表一条条读数据,通过代码不可能把500W条数据全部加载到内存中处理。所以这里需要 limit  1.

"update 数据表  SET phone = #{phone},orig_phone =#{origPhone}  WHERE user_id = #{userId} ; commit 

这个语句对表进行更新,并commit 。 这里记住一定要显式commit ,如果没commit,pg数据表数据是不会更新的。 这就是这一次踩的坑。 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/564058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day82【Leetcode】

文章目录 前言一、检查替换后的词是否有效&#xff08;力扣1003&#xff09;二、有效的括号&#xff08;力扣20&#xff09;【1003类似题目】每日一题&#xff1a;数青蛙&#xff08;力扣1419&#xff09; 前言 1、检查替换后的词是否有效 2、有效的括号 3、数青蛙 一、检查替…

操作系统第三章——内存管理(中)

九月重楼二两&#xff0c;冬至蝉蜕一钱&#xff0c;煎入隔年雪煮沸&#xff0c;可治人间相思苦疾&#xff0c; 可是&#xff0c;重楼七叶一花&#xff0c;冬日何来蝉蜕&#xff0c;原是相思无解 殊不知 夏枯即为九叶重楼&#xff0c;掘地三尺寒蝉现&#xff0c;除夕子时雪&…

2022级云曦实验室考试(一)pwn

讲真&#xff0c;俺都不知道pwn是啥&#xff0c;等俺搜搜&#xff01; pwn简介&#xff1a; CTF中的pwn指的是通过通过程序本身的漏洞&#xff0c;编写利用脚本破解程序拿到主机的权限&#xff0c;这就需要对程序进行分析&#xff0c;了解操作系统的特性和相关漏洞&#xff0…

[PyTorch][chapter 35][Batch Normalize]

前言&#xff1a; Batch Norm 是深度学习里面常用的技术之一&#xff0c;主要作用是 把指定维度参数约束到范围内,有效的解决了梯度弥散 现象 ,有助于加速模型的训练速度。 问题解释 特征缩放 Feature Scaling Batch Normalization Torch API 一 问题解释 如上图,输入范…

《开箱元宇宙》爱心熊通过 The Sandbox 与粉丝建立更紧密的联系

你们有没有想过 The Sandbox 如何融入世界上最具标志性的品牌和名人的战略&#xff1f;在本期《开箱元宇宙》系列中&#xff0c;我们与 Cloudco Entertainment 的数字内容顾问 Derek Roberto 聊天&#xff0c;了解为什么爱心熊决定在 The Sandbox 中试验 web3&#xff0c;以及他…

Grpc 整合 Nacos SpringBoot 日常使用(Java版本)包括 Jwt 认证

前言 最近感到有点子迷茫&#xff0c;天天写业务代码有点麻木&#xff0c;趁着有点空闲时间去了解了下 Grpc 这个框架&#xff0c;一方面是听说他很火&#xff0c;支持多种语言。另一方面也是为了将来可能需要用到他&#xff0c;未雨绸缪一下&#xff0c;当然了本文只是基于使用…

Python数据可视化入门教程

什么是数据可视化&#xff1f; 数据可视化是为了使得数据更高效地反应数据情况&#xff0c;便于让读者更高效阅读&#xff0c;通过数据可视化突出数据背后的规律&#xff0c;以此突出数据中的重要因素&#xff0c;如果使用Python做数据可视化&#xff0c;建议学好如下这四个Pyt…

数据可视化是什么?怎么做?看这篇文章就够了

数据可视化是什么 数据可视化主要旨在借助于图形化手段&#xff0c;清晰有效地传达与沟通信息。也就是说可视化的存在是为了帮助我们更好的去传递信息。 我们需要对我们现有的数据进行分析&#xff0c;得出自己的结论&#xff0c;明确要表达的信息和主题&#xff08;即你通过…

https 建立连接过程

从真实的抓包开始 根据抓包结果可以看到 从客户端发起https 请求开始&#xff0c;主要经过以下几个过程&#xff1a; 1、tcp 三次握手 2、浏览器发送 Client Hello 到服务器 3、服务器对Hello 进行响应 4、服务器发送Server Hello 、证书、证书状态、服务器密钥&#xff0c;到…

【Linux服务】web基础与HTTP协议

web基础与HTTP协议 一、域名概述1.1域名空间结构1.2域名注册 二、网页的概念三、HTML概述3.1HTML超文本标记语言 四、Web概述4.1Web1.0与Web2.04.2静态网页4.3动态网页 五、HTTP协议概述5.1HTTP协议版本5.2http请求方法5.3GET 和 POST 比较5.4HTTP状态码5.5HTTP请求流程 一、域…

无代码开发:让程序员更高效,让非编程人员也能参与

说起无代码开发&#xff0c;可能大多数人的第一反应就是&#xff1a;“我不知道&#xff01;” 作为一种能快速实现复杂系统的软件开发模式&#xff0c;无代码开发目前还处于推广阶段。但在我们看来&#xff0c;无代码开发是一个很好的尝试&#xff0c;它能让程序员更高效&…

《汇编语言》- 读书笔记 - 第4章-第一个程序

《汇编语言》- 读书笔记 - 第4章-第一个程序 4.1 一个源程序从写出到执行的过程4.2 源程序程序 4.11. 伪指令1.1 segment ends 声明段1.2 end 结束标记1.3 assume 关联 2. 源程序中的“程序”3. 标号4. 程序的结构5. 程序返回6. 语法错误和逻辑错误 4.3 编辑源程序4.4 编译4.5 …

Electron 我与你,今天不谈技术谈感情!

目录 前言一、无知二、初见三、再见四、相遇五、行动总结 前言 今天不谈技术&#xff0c;谈谈我和 Electron 的缘分。可能有人觉得&#xff0c;或许有些人认为&#xff0c;和一个框架谈感情这不是疯了吗&#xff1f;但是&#xff0c;我相信每个开发者都会有同样的经历&#xf…

数字化浪潮下,运维绕不开的需求升级

伴随企业数据中心规模化、复杂度、设备多样性的发展&#xff0c;运维也迎来史无前例的巨大挑战&#xff0c;运维的重要性被推向高点&#xff0c;对运维平台而言无疑是最好的时代&#xff0c;充分利用大数据和人工智能技术融合来解决实际问题&#xff0c;建立数据要素全周期管理…

XSS基础环境及实验演示教程(适合新手)

目录 前言 环境说明&#xff1a; 1、轻量级 Web 服务器 PHP 2、易受XSS攻击的PHP程序 3、非持久性 XSS 攻击 4、窃取会话cookie 5 注入表单窃取密码 前言 花了一点时间&#xff0c;做了一个“XSS基础环境及实验演示教程”&#xff0c;当然教程很简单&#xff0c;适合刚接触和安…

Electron 如何创建模态窗口?

目录 前言一、模态窗口1.Web页面模态框2.Electron中的模态窗口3.区分父子窗口与模态窗口 二、实际案例使用总结 前言 模态框是一种常用的交互元素&#xff0c;无论是在 Web 网站、桌面应用还是移动 APP 中&#xff0c;都有其应用场景。模态框指的是一种弹出窗口&#xff0c;它…

leetcode 1383. Maximum Performance of a Team(团队的最大performance)

n个工程师&#xff0c;长度为n的speed数组和efficiency数组。 每次最多选k个工程师&#xff0c;取出k个对应的speed和efficiency数字。 performancesum(k个speed) ✖ min(k个efficiency) 可以理解为k个人一起干&#xff0c;效率按最慢的人算&#xff08;一个环节干不完其他人都…

Linux——IO之系统接口+文件描述符详解

IO 文件再次理解系统接口文件操作理解文件描述符 fd 文件再次理解 文件 文件内容 文件属性 其中文件属性也是数据–>即便你创建一个空文件&#xff0c;其也是要占据磁盘攻坚的。 文件操作 文件内容的操作 文件属性的操作 有可能在操作文件的过程中即改变文件的内容&…

Linux---echo命令、反引号`、tail命令、重定向符

1. echo命令 可以使用echo命令在命令行内输出指定内容 语法&#xff1a;echo 输出的内容 无需选项&#xff0c;只有一个参数&#xff0c;表示要输出的内容&#xff0c;复杂内容可以用 ”” 包围 带有空格或 \ 等特殊符号&#xff0c;建议使用双引号包围。 如果不使用双引号…

华为OD机试真题 Java 实现【统计匹配的二元组个数】【2023Q2 200分】

一、题目描述 给定两个数组A和B&#xff0c;若数组A的某个元素A[i]与数组B中的某个元素B[j]满足 A[i] B[j]&#xff0c;则寻找到一个值匹配的二元组(i, j)。 请统计在这两个数组A和B中&#xff0c;一共存在多少个这样的二元组。 二、输入描述 第一行输入数组A的长度M&…