Java代码增加数据库表字段_如何较⽅便给上百张数据库表添
加表字段
前⾔
年前和业务部门的研发⼩伙伴聊天,他说由于之前表设计考虑不周全,导致业务表缺少了⼀些字段,他⽼⼤就把这个加表字段的任务给他,咋⼀听挺简单的,不就加些字段,但⼩伙伴烦恼的地⽅在于需要加这些字段的表⼤概有100多张,如果单靠⼿动添加,那效率太低了。于是他问我有没有啥⽅法,能⽐较⽅便的实现这个需求,今天就来⽔⼀下这个话题
需求分析
⼩伙伴的诉求在于⽅便的实现,那怎么实现⽅便这个诉求。答案的本质就是这个实现不要让他⾃⼰做,让别⼈或者其他东西实现他诉求
⽅案思路⽅案⼀: 把这个需求安排给其他⼈做,哈哈
⽅案⼆:写存储过程或者函数
⽅案三:通过写sql脚本执⾏
本⽂重点讲解⽅案三写sql脚本执⾏
如何实现这个sql脚本
实现这个sql脚本的⽅式有很多种,本⽂就讲下利⽤java程序⽣成这个sql脚本。⽣成这个sql脚本的关键在于DatabaseMetaData这个类,这个类是啥?它是java.sql包中的类,利⽤它可以获取我们连接到的数据库的结构、存储等很多信息
其更多详细介绍可以查看如下链接
核⼼代码实现1、获取数据库下的所有数据库表名/**
* 获取数据库下的所有数据库表名
*
* @return Map> key为数据库名称,value为该数据库下的所有表名
*/
public Map> getDbTablesNamesMap(){
Map> dbTableNamesMap = new HashMap<>();
try {
//获取数据库的元数据
DatabaseMetaData dbMetaData = getConnection().getMetaData();
//从元数据中获取到所有的表名
ResultSet rs = Tables(null, null, null,new String[] { "TABLE" });
List tableNames;
()) {
String tableName = rs.getString("TABLE_NAME");
String curTableDbName = rs.getString("TABLE_CAT");
String tableNameType = rs.getString("TABLE_TYPE");
/
/表模式(可能为空),在oracle中获取的是命名空间
String tableNameSchema = rs.getString("TABLE_SCHEM");
String tableNameRemark = rs.getString("REMARKS");
System.out.println("表名: " + tableName + ",表所属数据库: " + curTableDbName + ",表类型: " + tableNameType + ",表模式: " + tableNameSchema + ",表备注: " + tableNameRemark);
//跳过mysql⾃带的系统库
if("sys".equalsIgnoreCase(curTableDbName)){
continue;
}
ainsKey(curTableDbName)){
tableNames = (curTableDbName);
}else{
tableNames = new ArrayList<>();
}
tableNames.add(tableName);
dbTableNamesMap.put(curTableDbName,tableNames);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
close();
return dbTableNamesMap;
}2、拼凑要执⾏的sql语句public static List prepareSqlStatementWithStringFormat(boolean isForFiles) {
String sql = "alter table %s ADD COLUMN create_time DATETIME COMMENT '创建时间',ADD COLUMN created_by_id BIGINT(20) DEFAULT NULL COMMENT '创建⼈id', ADD COLUMN update_time DATETIME COMMENT '修改时间', ADD COLUMN last_updated_by_id BIGINT(20) DEFAULT NULL COMMENT '修改⼈id'";
List sqlStatements = new ArrayList<>();
Map> dbTableNamesMap = DbTablesNamesMap();
增加字段的sql语句
dbTableNamesMap.forEach((dbName,tableNames) -> {
for (String tableName : tableNames) {
String record = dbName + "." + tableName;
String sqlStatement = String.format(sql, record);
//如果是要写⼊⽂件,则每条⽣成的sql语句,需追加分号
if(isForFiles){
sqlStatement = sqlStatement + ";";
}
System.out.println(sqlStatement);
sqlStatements.add(sqlStatement);
}
});
return sqlStatements;
}3、将⽣成的sql语句写⼊⽂件public static void writeSqlStatement2File(List sqlStatements,String filePath){
try {
File file = new File(filePath);
if(!ists()){
}
FileUtil.writeUtf8Lines(sqlStatements,file);
System.out.println("数据库脚本写⼊"+filePath+"成功");
} catch (IOException e) {
e.printStackTrace();
System.out.println("数据库脚本写⼊"+filePath+"失败");
}
}
总结
⼩伙伴并没有采⽤⽅案三的实现⽅法,⽽是采取了⽅案⼀,通过⼀顿饭的代价,让我帮他实现了这个
需求。最后我帮他实现整体⽅案是以flyway+java程序实现的sql脚本的⽅式实现。说明下⼩伙伴遇到这种业务场景是发⽣在业务开发阶段,⽽⾮⽣产环境。像这种⼤批量修改表结构的场景,是属于架构上的严重失误,理论上是不应该犯的。如果确实发⽣这种现象,得由DBA做好审计才能推到⽣产环境
demo链接

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。