柒索

一个头脑聪明,五肢发达的男人。

0%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>cn.smallbun.screw</groupId>
<artifactId>screw-core</artifactId>
<version>1.0.2</version>
</dependency>
<!-- HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql driver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.util.ArrayList;


/**
* @author Yang
* @version 1.0
* @description: TODO
* @date 2022/3/20 22:12
*/
public class Screw {

public static void main(String[] args) {

HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
hikariConfig.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/sys?serverTimezone=GMT");
hikariConfig.setUsername("root");
hikariConfig.setPassword("root");

//设置可以获取tables remarks信息
hikariConfig.addDataSourceProperty("useInformationSchema", "true");
hikariConfig.setMinimumIdle(2);
hikariConfig.setMaximumPoolSize(5);

DataSource dataSource = new HikariDataSource(hikariConfig);
//生成配置
EngineConfig engineConfig = EngineConfig.builder()
//生成文件路径
.fileOutputDir("./out")
//打开目录
.openOutputDir(true)
//文件类型
.fileType(EngineFileType.HTML)
//生成模板实现
.produceType(EngineTemplateType.freemarker).build();

//忽略表
ArrayList<String> ignoreTableName = new ArrayList<>();
ignoreTableName.add("test_user");
ignoreTableName.add("test_group");

//忽略表前缀
ArrayList<String> ignorePrefix = new ArrayList<>();
ignorePrefix.add("test_");

//忽略表后缀
ArrayList<String> ignoreSuffix = new ArrayList<>();
ignoreSuffix.add("_test");
ProcessConfig processConfig = ProcessConfig.builder()
//忽略表名
.ignoreTableName(ignoreTableName)
//忽略表前缀
.ignoreTablePrefix(ignorePrefix)
//忽略表后缀
.ignoreTableSuffix(ignoreSuffix).build();

//配置
Configuration config = Configuration.builder()
//版本
.version("1.0.0")
//描述
.description("数据库设计文档生成")
//数据源
.dataSource(dataSource)
//生成配置
.engineConfig(engineConfig)
//生成配置
.produceConfig(processConfig).build();
//执行生成
new DocumentationExecute(config).execute();
}

}

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
@echo off
setlocal enabledelayedexpansion
set /p port=Input Port Number:
for /f "tokens=1-5" %%a in ('netstat -ano ^| find ":%port%"') do (
if "%%e%" == "" (
set pid=%%d
) else (
set pid=%%e
)
echo !pid!
taskkill /f /pid !pid!
)
pause

使用方式

脚本具体使用方式如下:

  1. 在电脑上新建一个空的bat脚本文件,将代码保存进去。
  2. 双击执行脚本,输入被占用的端口
  3. 按下回车键,脚本执行完成之后会自动关闭窗口

问题概述

这个问题是使用ETL进行数据导入而产生的,需要使用Informatica对数据进行采集从ODS库导入到项目库中,且需要读取项目库中的配置,Informatica不涉及代码开发,只能读取表或者视图来配置参数,而项目库中的配置表则是用户在页面进行录入的,此时需要对页面录入的数据进行拼接给工具使用IN来使用,众所周知数据库中IN所传入的参数长度是有限制的,所以使用SELECT GROUP_CONCAT(CODE) FROM COUNTRY;的这种方式并不可取,会产生性能问题,为了解决这个现象,于是有了如下实现代码

测试数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for country
-- ----------------------------
DROP TABLE IF EXISTS `country`;
CREATE TABLE `country` (
`Code` char(3) NOT NULL DEFAULT '',
`Name` char(52) NOT NULL DEFAULT '',
`Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
`Region` char(26) NOT NULL DEFAULT '',
`SurfaceArea` float(10,2) NOT NULL DEFAULT '0.00',
`IndepYear` smallint(6) DEFAULT NULL,
`Population` int(11) NOT NULL DEFAULT '0',
`LifeExpectancy` float(3,1) DEFAULT NULL,
`GNP` float(10,2) DEFAULT NULL,
`GNPOld` float(10,2) DEFAULT NULL,
`LocalName` char(45) NOT NULL DEFAULT '',
`GovernmentForm` char(45) NOT NULL DEFAULT '',
`HeadOfState` char(60) DEFAULT NULL,
`Capital` int(11) DEFAULT NULL,
`Code2` char(2) NOT NULL DEFAULT '',
PRIMARY KEY (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- ----------------------------
-- Records of country
-- ----------------------------
BEGIN;
INSERT INTO `country` VALUES ('ABW', 'Aruba', 'North America', 'Caribbean', 193.00, NULL, 103000, 78.4, 828.00, 793.00, 'Aruba', 'Nonmetropolitan Territory of The Netherlands', 'Beatrix', 129, 'AW');
INSERT INTO `country` VALUES ('AFG', 'Afghanistan', 'Asia', 'Southern and Central Asia', 652090.00, 1919, 22720000, 45.9, 5976.00, NULL, 'Afganistan/Afqanestan', 'Islamic Emirate', 'Mohammad Omar', 1, 'AF');
INSERT INTO `country` VALUES ('AGO', 'Angola', 'Africa', 'Central Africa', 1246700.00, 1975, 12878000, 38.3, 6648.00, 7984.00, 'Angola', 'Republic', 'José Eduardo dos Santos', 56, 'AO');
INSERT INTO `country` VALUES ('AIA', 'Anguilla', 'North America', 'Caribbean', 96.00, NULL, 8000, 76.1, 63.20, NULL, 'Anguilla', 'Dependent Territory of the UK', 'Elisabeth II', 62, 'AI');
INSERT INTO `country` VALUES ('ALB', 'Albania', 'Europe', 'Southern Europe', 28748.00, 1912, 3401200, 71.6, 3205.00, 2500.00, 'Shqipëria', 'Republic', 'Rexhep Mejdani', 34, 'AL');
INSERT INTO `country` VALUES ('AND', 'Andorra', 'Europe', 'Southern Europe', 468.00, 1278, 78000, 83.5, 1630.00, NULL, 'Andorra', 'Parliamentary Coprincipality', '', 55, 'AD');
INSERT INTO `country` VALUES ('ANT', 'Netherlands Antilles', 'North America', 'Caribbean', 800.00, NULL, 217000, 74.7, 1941.00, NULL, 'Nederlandse Antillen', 'Nonmetropolitan Territory of The Netherlands', 'Beatrix', 33, 'AN');
INSERT INTO `country` VALUES ('ARE', 'United Arab Emirates', 'Asia', 'Middle East', 83600.00, 1971, 2441000, 74.1, 37966.00, 36846.00, 'Al-Imarat al-´Arabiya al-Muttahida', 'Emirate Federation', 'Zayid bin Sultan al-Nahayan', 65, 'AE');
INSERT INTO `country` VALUES ('ARG', 'Argentina', 'South America', 'South America', 2780400.00, 1816, 37032000, 75.1, 340238.00, 323310.00, 'Argentina', 'Federal Republic', 'Fernando de la Rúa', 69, 'AR');
INSERT INTO `country` VALUES ('ARM', 'Armenia', 'Asia', 'Middle East', 29800.00, 1991, 3520000, 66.4, 1813.00, 1627.00, 'Hajastan', 'Republic', 'Robert Kotšarjan', 126, 'AM');
INSERT INTO `country` VALUES ('ASM', 'American Samoa', 'Oceania', 'Polynesia', 199.00, NULL, 68000, 75.1, 334.00, NULL, 'Amerika Samoa', 'US Territory', 'George W. Bush', 54, 'AS');
INSERT INTO `country` VALUES ('ATA', 'Antarctica', 'Antarctica', 'Antarctica', 13120000.00, NULL, 0, NULL, 0.00, NULL, '–', 'Co-administrated', '', NULL, 'AQ');
INSERT INTO `country` VALUES ('ATF', 'French Southern territories', 'Antarctica', 'Antarctica', 7780.00, NULL, 0, NULL, 0.00, NULL, 'Terres australes françaises', 'Nonmetropolitan Territory of France', 'Jacques Chirac', NULL, 'TF');
INSERT INTO `country` VALUES ('ATG', 'Antigua and Barbuda', 'North America', 'Caribbean', 442.00, 1981, 68000, 70.5, 612.00, 584.00, 'Antigua and Barbuda', 'Constitutional Monarchy', 'Elisabeth II', 63, 'AG');

COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

实现代码

20为每行配置的参数,可根据实际情况进行调整

1
2
3
4
5
6
7
SELECT T.ROW_ID, GROUP_CONCAT(COUNTRYCODE) COUNTRYCODE  FROM (
SELECT ROW_ID,COUNTRYCODE FROM (
SELECT FLOOR(@ROWNUM/20) +1 AS 'ROW_ID', @ROWNUM:=@ROWNUM + 1 AS 'ROW', A.COUNTRYCODE
FROM CITY A ,(SELECT @ROWNUM:=0) B
) A
GROUP BY A.ROW_ID,A.ROW,A.COUNTRYCODE
) T GROUP BY T.ROW_ID;

结果展示

1
2
3
4
5
6
7
8
9
10
11
12
AUS,AUT,ABW,AZE,AFG,BDI,AGO,BEL,AIA,BEN,ALB,AND,ANT,ARE,ARG,ARM,ASM,ATA,ATF,ATG
BRA,BRB,BRN,BTN,BVT,BWA,BFA,CAF,BGD,CAN,BGR,CCK,BHR,CHE,BHS,BIH,BLR,BLZ,BMU,BOL
COK,COL,COM,CPV,CRI,CUB,CXR,CYM,CYP,CZE,CHL,DEU,CHN,DJI,CIV,DMA,CMR,DNK,COD,COG
ECU,GHA,EGY,GIB,ERI,ESH,ESP,EST,ETH,FIN,FJI,FLK,FRA,FRO,FSM,GAB,DOM,GBR,DZA,GEO
HND,HRV,GIN,HTI,GLP,HUN,GMB,IDN,GNB,IND,GNQ,GRC,GRD,GRL,GTM,GUF,GUM,GUY,HKG,HMD
KAZ,KEN,KGZ,KHM,KIR,KNA,IOT,KOR,IRL,KWT,IRN,LAO,IRQ,LBN,ISL,ISR,ITA,JAM,JOR,JPN
LTU,LUX,LVA,MAC,MAR,MCO,MDA,MDG,MDV,MEX,LBR,MHL,LBY,MKD,LCA,MLI,LIE,MLT,LKA,LSO
MNP,NLD,MOZ,NOR,MRT,MSR,MTQ,MUS,MWI,MYS,MYT,NAM,NCL,NER,NFK,NGA,MMR,NIC,MNG,NIU
PRT,PRY,NPL,PSE,NRU,PYF,NZL,QAT,OMN,REU,PAK,PAN,PCN,PER,PHL,PLW,PNG,POL,PRI,PRK
SLB,SLE,SLV,SMR,SOM,SPM,ROM,STP,RUS,SUR,RWA,SVK,SAU,SVN,SDN,SEN,SGP,SGS,SHN,SJM
TGO,THA,TJK,TKL,TKM,TMP,TON,TTO,TUN,TUR,SWE,TUV,SWZ,TWN,SYC,TZA,SYR,UGA,TCA,TCD
URY,ZWE,USA,UZB,VAT,VCT,VEN,VGB,VIR,VNM,VUT,WLF,WSM,YEM,YUG,UKR,ZAF,UMI,ZMB

代码实现

1
2
3
4
5
6
7
8
9
10
11
thousandthFormat (cellValue) {
// 将输入的数字进行千分位展示 例如:78,321,879
if (cellValue) {
return Number(cellValue)
.toFixed(2)
.replace(/(\d)(?=(\d{3})+\.)/g, ($0, $1) => {
return $1 + ','
})
.replace(/\.$/, '')
}
}

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 moneyConvert (money) {
// 以万元为单位
money = money * 10000
//汉字的数字
var cnNums = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖");
var cnIntRadice = new Array("", "拾", "佰", "仟"); //基本单位
var cnIntUnits = new Array("", "万", "亿", "兆"); //对应整数部分扩展单位
var cnDecUnits = new Array("角", "分", "毫", "厘"); //对应小数部分单位
var cnInteger = "整"; //整数金额时后面跟的字符
var cnIntLast = "元"; //整型完以后的单位
var maxNum = 999999999999999.9999; //最大处理的数字
var IntegerNum; //金额整数部分
var DecimalNum; //金额小数部分
var ChineseStr = ""; //输出的中文金额字符串
var parts; //分离金额后用的数组,预定义
var Symbol="";//正负值标记
if (money == "") {
return "";
}

money = parseFloat(money);
if (money >= maxNum) {
alert('超出最大处理数字');
return "";
}
if (money == 0) {
ChineseStr = cnNums[0] + cnIntLast + cnInteger;
return ChineseStr;
}
if(money<0)
{
money=-money;
Symbol="负 ";
}
money = money.toString(); //转换为字符串
if (money.indexOf(".") == -1) {
IntegerNum = money;
DecimalNum = '';
} else {
parts = money.split(".");
IntegerNum = parts[0];
DecimalNum = parts[1].substr(0, 4);
}
if (parseInt(IntegerNum, 10) > 0) { //获取整型部分转换
var zeroCount = 0;
var IntLen = IntegerNum.length;
for (var i = 0; i < IntLen; i++) {
var n = IntegerNum.substr(i, 1);
var p = IntLen - i - 1;
var q = p / 4;
var m = p % 4;
if (n == "0") {
zeroCount++;
}
else {
if (zeroCount > 0) {
ChineseStr += cnNums[0];
}
zeroCount = 0; //归零
ChineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
}
if (m == 0 && zeroCount < 4) {
ChineseStr += cnIntUnits[q];
}
}
ChineseStr += cnIntLast;
//整型部分处理完毕
}
if (DecimalNum != '') { //小数部分
var decLen = DecimalNum.length;
for (var i = 0; i < decLen; i++) {
var n = DecimalNum.substr(i, 1);
if (n != '0') {
ChineseStr += cnNums[Number(n)] + cnDecUnits[i];
}
}
}
if (ChineseStr == '') {
ChineseStr += cnNums[0] + cnIntLast + cnInteger;
} else if (DecimalNum == '') {
ChineseStr += cnInteger;
}
ChineseStr = Symbol +ChineseStr;
return ChineseStr
}

在Oracle中,存储过程和存储函数的概念其实是差不多的,一般地,我们都可以混合使用。只不过有的时候有的情况使用过程好一些,有的情况时候函数的时候好一些。下面会讲解在什么时机使用过程还是函数的。

存储过程

语法

1
2
3
create [or replace] procedure 过程名[(参数列表)]  
as
PLSQL程序体;【begin…end;/】

存储函数

语法

1
2
3
create [or replace] procedure 过程名[(参数列表)]  
as
PLSQL程序体;【begin…end;/】

使用场景

我们发现过程与函数的区别其实是不大的,一般我们都可以用函数来实现的时候, 也可以使用过程来实现….

但是,总有些情况,使用函数比使用过程要好,使用过程比使用函数要好,那什么时候使用过程,什么时候使用函数呢

不难发现的是,函数是必定要有一个返回值的,当我们在调用的时候,接受返回值就直接获取就行了。

也就是说

  • 当返回值只有一个参数的时候,那么就使用存储函数!
  • 当返回值没有参数或者多于一个参数的时候,那么就使用过程!