一、编程语言介绍
所使用的编程语言为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数据表数据是不会更新的。 这就是这一次踩的坑。