如下需求:一个复杂的统战系统,用户信息字段总共有26个sheet,54张小表,没有什么复杂的业务逻辑,纯增删改查。字段目测在1000个以上。建表54张。领导交待了一句这周末完成,我???
此时就要学会偷懒了。
偷懒的思路:
1.将excel表读到java中。
2:用拼音命名字段,1000多个字典,光起字段名就足够消耗你N多时间了。而用拼音,则可根据表内的中文名称作生成。这点用工具类是可以做到的。
3:成生建表语句
代码如下:
public class CreateTableMain {
private static String CREATE_SQL = "CREATE TABLE %s (id varchar(60) primary key,%s) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='%s';";
private static String COLUMN_SQL = "%s varchar(100) COMMENT '%s'";
public static void main(String[] args) {
ExcelReader reader = ExcelUtil.getReader("D:\\ccc\\tongzhan.xlsx");
List<String> tables = new ArrayList<>();
tables.add(readTable(reader, 1, 1, 64));
tables.add(readTable(reader, 2, 1, 24));
tables.add(readTable(reader, 2, 26, 41));
tables.add(readTable(reader, 2, 43, 48));
tables.add(readTable(reader, 2, 50, 56));
tables.add(readTable(reader, 2, 58, 65));
tables.add(readTable(reader, 3, 1, 9));
tables.add(readTable(reader, 4, 1, 4));
tables.add(readTable(reader, 5, 1, 4));
tables.add(readTable(reader, 5, 6, 16));
tables.add(readTable(reader, 6, 1, 7));
tables.add(readTable(reader, 7, 1, 19));
tables.add(readTable(reader, 7, 23, 29));
tables.add(readTable(reader, 7, 31, 40));
tables.add(readTable(reader, 8, 1, 8));
tables.add(readTable(reader, 9, 1, 6));
tables.add(readTable(reader, 10, 1, 13));
tables.add(readTable(reader, 11, 1, 18));
tables.add(readTable(reader, 12, 1, 56));
tables.add(readTable(reader, 12, 58, 73));
tables.add(readTable(reader, 12, 75, 78));
tables.add(readTable(reader, 12, 80, 85));
tables.add(readTable(reader, 13, 1, 21));
tables.add(readTable(reader, 14, 1, 11));
tables.add(readTable(reader, 15, 1, 8));
tables.add(readTable(reader, 16, 1, 13));
tables.add(readTable(reader, 17, 1, 15));
tables.add(readTable(reader, 18, 1, 12));
tables.add(readTable(reader, 19, 1, 15));
tables.add(readTable(reader, 19, 17, 23));
tables.add(readTable(reader, 19, 25, 30));
tables.add(readTable(reader, 20, 1, 12));
tables.add(readTable(reader, 21, 1, 10));
tables.add(readTable(reader, 21, 12, 22));
tables.add(readTable(reader, 21, 24, 31));
tables.add(readTable(reader, 21, 33, 40));
tables.add(readTable(reader, 21, 42, 49));
tables.add(readTable(reader, 22, 1, 7));
tables.add(readTable(reader, 23, 1, 13));
tables.add(readTable(reader, 24, 1, 14));
tables.add(readTable(reader, 24, 16, 26));
tables.add(readTable(reader, 24, 28, 38));
tables.add(readTable(reader, 24, 40, 51));
tables.add(readTable(reader, 24, 53, 63));
tables.add(readTable(reader, 24, 65, 72));
tables.add(readTable(reader, 24, 74, 80));
tables.add(readTable(reader, 24, 91, 93));
tables.add(readTable(reader, 24, 95, 100));
tables.add(readTable(reader, 24, 102, 106));
tables.add(readTable(reader, 24, 108, 114));
tables.add(readTable(reader, 24, 116, 122));
tables.add(readTable(reader, 25, 1, 11));
tables.add(readTable(reader, 25, 13, 20));
tables.add(readTable(reader, 26, 1, 5));
System.out.println("合计表张数=" + tables.size());
ZYFileUtils.writeLines(tables, new File("D:\\ccc\\统战用户对象信息.sql"), "UTF-8");
}
private static String readTable(ExcelReader reader, int sheetIndex, int tableNameY, int endRow) {
return readTable(reader, sheetIndex, tableNameY, tableNameY + 1, tableNameY + 2, endRow);
}
/**
* @param reader excel读取器
* @param sheetIndex sheet的索引
* @param tableNameY 大标题所在的列(表名,表内第一行那个合并的标题)
* @param headerRow 表头所在的行(找中文名称)
* @param startRow 数据开始行
* @param endRow 数据结束行
* @return 建表语句
*/
private static String readTable(ExcelReader reader, int sheetIndex, int tableNameY, int headerRow, int startRow, int endRow) {
reader.setSheet(sheetIndex - 1);
Object o = reader.readCellValue(0, tableNameY - 1);
String tableComment = String.valueOf(o);
String tableName = ZYPinYinUtils.userName2PinYin(tableComment);
List<Map<String, Object>> read = reader.read(headerRow - 1, startRow - 1, endRow - 1);
List<String> columns = new ArrayList<>();
for (Map<String, Object> row : read) {
Object mc = row.get("中文名称");
Object sm = row.get("说明");
String comment = String.valueOf(mc);
String pinYin = ZYPinYinUtils.userName2PinYinFirst(comment);
if (columns.contains(pinYin)) {
pinYin = pinYin + 1;
if (columns.contains(pinYin)) {
pinYin = pinYin + 1;
}
}
String columnSql = String.format(COLUMN_SQL, pinYin, comment + (ZYStrUtils.isNotNull(sm) ? "(" + String.valueOf(sm) + ")" : ""));
columns.add(columnSql);
}
String columnSqlItem = ZYStrUtils.join(columns, ",");
return String.format(CREATE_SQL, tableName, columnSqlItem, tableComment);
}
}
生成的效果:
CREATE TABLE dangpairenzhi (
id VARCHAR (60) PRIMARY KEY,
zz / jgmc VARCHAR (100) COMMENT '组织/机构名称(该党内职务任职期间所处的组织、机构的名称。)',
rzjb VARCHAR (100) COMMENT '任职级别(此次党内职务的级别。)',
jc VARCHAR (100) COMMENT '届次(该党内职务任职期间所处的届次。)',
hycs VARCHAR (100) COMMENT '会议次数(该党内职务任职期间所处的会议序列。)',
zw VARCHAR (100) COMMENT '职务(所任职的职务名称。)',
qrrq VARCHAR (100) COMMENT '起任日期(开始任职的时间。)',
xrrq VARCHAR (100) COMMENT '卸任日期(结束任职的时间。)',
xryy VARCHAR (100) COMMENT '卸任原由(结束任职的原因。)',
sfxr VARCHAR (100) COMMENT '是否现任(该党内职务是不是正在任职的职务。)',
sfzz VARCHAR (100) COMMENT '是否专职(该党内职务是不是专职职务。)',
fgnr VARCHAR (100) COMMENT '分工内容(分工工作的内容。)',
bz VARCHAR (100) COMMENT '备注(其他需要说明的情况。)'
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '党派任职';
CREATE TABLE hailianhuirenzhi (
id VARCHAR (60) PRIMARY KEY,
jb VARCHAR (100) COMMENT '级别(此次任职职务的级别。)',
ssdo VARCHAR (100) COMMENT '所属地区(此次任职期间所在地区的详细地址。)',
jc VARCHAR (100) COMMENT '届次(本次任职处于哪一届会议期间。)',
swmc VARCHAR (100) COMMENT '单位名称(此人员当前所在的工作单位名称。)',
rzsj VARCHAR (100) COMMENT '任职时间(本次任职的时间。)',
zw VARCHAR (100) COMMENT '职务(本次工作过程中所处的岗位职务。)',
rzzt VARCHAR (100) COMMENT '任职状态(当前正在任职的状态。)',
zwh VARCHAR (100) COMMENT '专委会(本次任职所属的专委会的名称。)',
zwhzw VARCHAR (100) COMMENT '专委会职务(本次海联会任职所属的专委会职务名称。)'
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '海联会任职';
CREATE TABLE oumeitongxuehuirenzhi (
id VARCHAR (60) PRIMARY KEY,
jb VARCHAR (100) COMMENT '级别(此次任职职务的级别。)',
ssdo VARCHAR (100) COMMENT '所属地区(此次任职期间所在地区的详细地址。)',
jc VARCHAR (100) COMMENT '届次(本次任职处于哪一届会议期间)',
swmc VARCHAR (100) COMMENT '单位名称(此人员当前所在的工作单位名称。)',
rzsj VARCHAR (100) COMMENT '任职时间(本次任职的时间。)',
zw VARCHAR (100) COMMENT '职务(本次工作过程中所处的岗位职务。)',
zwh VARCHAR (100) COMMENT '专委会(本次任职所属的专委会的名称。)',
zwhzw VARCHAR (100) COMMENT '专委会职务(本次欧美同学会任职所属的专委会职务名称。)',
rzzt VARCHAR (100) COMMENT '任职状态(当前正在任职的情况。)'
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '欧美同学会任职';
CREATE TABLE xinlianhuirenzhi (
id VARCHAR (60) PRIMARY KEY,
jb VARCHAR (100) COMMENT '级别(此次任职职务的级别。)',
ssdo VARCHAR (100) COMMENT '所属地区(此次任职期间所在地区的详细地址。)',
jc VARCHAR (100) COMMENT '届次(本次任职处于哪一届会议期间)',
swmc VARCHAR (100) COMMENT '单位名称(此人员当前所在的工作单位名称。)',
rzsj VARCHAR (100) COMMENT '任职时间(本次任职的时间。)',
zw VARCHAR (100) COMMENT '职务(本次工作过程中所处的岗位职务。)',
zwh VARCHAR (100) COMMENT '专委会(本次任职所属的专委会的名称。)',
zwhzw VARCHAR (100) COMMENT '专委会职务(本次新联会任职所属的专委会职务名称。)',
rzzt VARCHAR (100) COMMENT '任职状态(当前正在任职的情况。)',
bz VARCHAR (100) COMMENT '备注(其他需要说明的情况。)'
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '新联会任职';
CREATE TABLE zhilianhuirenzhi (
id VARCHAR (60) PRIMARY KEY,
jb VARCHAR (100) COMMENT '级别(此次任职职务的级别。)',
ssdo VARCHAR (100) COMMENT '所属地区(此次任职期间所在地区的详细地址。)',
jc VARCHAR (100) COMMENT '届次(本次任职处于哪一届会议期间)',
swmc VARCHAR (100) COMMENT '单位名称(此人员当前所在的工作单位名称。)',
rzsj VARCHAR (100) COMMENT '任职时间(本次任职的时间。)',
zw VARCHAR (100) COMMENT '职务(本次工作过程中所处的岗位职务。)',
zwh VARCHAR (100) COMMENT '专委会(本次任职所属的专委会的名称。)',
zwhzw VARCHAR (100) COMMENT '专委会职务(本次政协任职所属的专委会职务名称。)',
rzzt VARCHAR (100) COMMENT '任职状态(当前正在任职的情况。)'
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '知联会任职';
CREATE TABLE gongshanglianrenzhi (
id VARCHAR (60) PRIMARY KEY,
jb VARCHAR (100) COMMENT '级别(此次任职职务的级别。)',
swmc VARCHAR (100) COMMENT '单位名称(此人员当前所在的工作单位名称。)',
jc VARCHAR (100) COMMENT '届次(本次任职处于哪一届会议期间)',
zw VARCHAR (100) COMMENT '职务(本次工作过程中所处的岗位职务。)',
rzsj VARCHAR (100) COMMENT '任职时间(本次任职的时间。)',
rzzt VARCHAR (100) COMMENT '任职状态(当前正在任职的情况。)'
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT = '工商联任职';
总结:
脚本生成后,只需做少量调整和添加少量外键即可。
数据库建表命名虽然需要见名知义。但面对上述纯体力劳动。本人认为采用反规范命名是没问题的,原因如下:
1 字段足够多。形成了一种整体的命名风格一致性。
2 能使用生成工具,生成表,建表,再拿表生成代码和文档,美美的节省大量时间。
3 前端调用方便。前端可直接用excel文档绑定数据。根据拼音命名规则可直接获取到字段key。
4 能多出很多摸鱼时间,这点是最重要的。谁没事去1000个多字段一个个查有道词典命名。那是初级小白才会做的事。是吧。哈哈
良心过不去。还是一个个命下名吧。顺便核对一下字段类型和长度,改脚本比建脚本还是轻松点,哈哈
美滋滋,一周的活一小时干完了,嘻嘻,卷死后端,干死前端,哈哈