使用代码去实现创建数据库表



/** * @Author Li * @data 2022/1/6 14:50 * @description 创建数据库表工具类 */ @Slf4j @Component public class CreateTable { @Autowired private ISysMeterService sysMeterService; private static CreateTable createTable; /** * 初始化注入的 service */ @PostConstruct public void init() { createTable= this; createTable.sysMeterService = this.sysMeterService; } private static String driverClassName; private static String url; private static String username; private static String password; /** * */ @Value("${spring.datasource.driverClassName}") public void setDriverClassName(String driverClassName) { CreateTable.driverClassName = driverClassName; } @Value("${spring.datasource.druid.master.url}") public void setUrl(String url) { CreateTable.url = url; } @Value("${spring.datasource.druid.master.username}") public void setUsername(String username) { CreateTable.username = username; } @Value("${spring.datasource.druid.master.password}") public void setPassword(String password) { CreateTable.password = password; } /*String*/ public static final String TYPE_STRING = "String"; /*Integer*/ public static final String TYPE_INTEGER = "Integer"; /*Double*/ public static final String TYPE_DOUBLE = "Double"; /*Date*/ public static final String TYPE_Date = "Date"; /*BigDecimal*/ public static final String TYPE_BigDecimal = "BigDecimal"; /*text*/ public static final String TYPE_text = "text"; /** * 连接MySQL数据库 */ public static Map<String, Object> connectMySQL(){ Connection connection = null; Statement statement = null; Map<String, Object> map = new HashMap<>(); try { // 连接数据库 Class.forName(driverClassName); // 获取数据库连接 connection = DriverManager.getConnection(url, username, password); // 根据连接获取可执行Statement statement = connection.createStatement(); map.put("connection",connection); map.put("statement",statement); return map; }catch (Exception e){ e.printStackTrace(); log.error("CreateTable 类中,连接数据库错误!"); } return null; } /** * 执行SQL语句 * @param sysMeter * @return */ public static String executeSQL(SysMeter sysMeter) throws SQLException { Connection conn = null; Statement state = null; try { Map<String, Object> map = connectMySQL(); if (!StringUtils.isNotNull(map)){ return "获取数据库连接失败..."; } // 获取数据库连接 conn = (Connection)map.get("connection"); // 获取SQL执行环境 state = (Statement)map.get("statement"); // 获取数据库表名 ResultSet tables = conn.getMetaData().getTables(null, null, sysMeter.getMeterName(), null); // 是否存在表 if (tables.next()){ // 存在不创建-存在删除表(强制同步) String sqlDropTable = createSQLDropTable(sysMeter.getMeterName()); System.out.println("--------------删除表sql开始---------------"); System.out.println(sqlDropTable); System.out.println("--------------删除表sql结束---------------"); // 删除表 state.executeUpdate(sqlDropTable); } String sql = createSQL(sysMeter); System.out.println("--------------创建表sql开始---------------"); System.out.println(sql); System.out.println("--------------创建表sql结束---------------"); // 创建表 state.executeUpdate(sql); // 修改为已同步 SysMeter meter = new SysMeter(); meter.setId(sysMeter.getId()); meter.setSynState("1"); createTable.sysMeterService.updateById(meter); }catch (Exception e){ e.printStackTrace(); return "表"+ sysMeter.getMeterName() +"同步失败!"; }finally { // 释放资源 state.close(); conn.close(); } return "表"+ sysMeter.getMeterName() +"同步成功"; } /** * 数据库是否存在表名 * @param tableName * @return true 存在 & 错误 * @return false 不存在 */ public static boolean existsTable(String tableName) throws SQLException { Connection conn = null; Statement state = null; // 获取数据库连接和SQL执行环境 try { Map<String, Object> map = connectMySQL(); if (!StringUtils.isNotNull(map)){ return true; } // 获取数据库连接 conn = (Connection)map.get("connection"); // 获取SQL执行环境 state = (Statement)map.get("statement"); // 获取数据库表名 ResultSet tables = conn.getMetaData().getTables(null, null,tableName, null); if (tables.next()){ return true; } }catch (Exception e){ e.printStackTrace(); log.error("验证数据库表名是否能存在错误!"); return true; }finally { state.close(); conn.close(); } return false; } /** * 创建生成表的SQL * @param sysMeter * @return */ public static String createSQL(SysMeter sysMeter){ // 创建主键集合 List<String> priKeyList = new ArrayList<String>(); // 创建 StringBuffer 拼接sql StringBuffer sb = new StringBuffer(); sb.append("CREATE TABLE `"+ sysMeter.getMeterName() +"` (\n"); List<SysMeterAttached> meterInfo = sysMeter.getMeterInfo(); for (int i = 0; i < meterInfo.size(); i++) { // 当前条数据 SysMeterAttached sma = meterInfo.get(i); // 判断数据类型 String fieldType = judgeDataType(sma.getFieldType()); sb.append(""+ sma.getFieldName() +""); if ("double".equals(fieldType)){ // 特殊处理 `age` double(23,0) DEFAULT NULL COMMENT '年龄', // 追加列 sb.append(" "+fieldType+"("+sma.getFieldLength()+","+ sma.getDecimalPoint() +") "); }else if ("decimal".equals(fieldType)){ // 追加列 sb.append(" "+fieldType+"("+sma.getFieldLength()+","+ sma.getDecimalPoint() +") "); }else { // 追加列 sb.append(" "+fieldType+"("+sma.getFieldLength()+") "); } // 判断是否为主键 - 等于1是主键 if ("1".equals(sma.getPrimaryKey())){ // 字段名称放进去 priKeyList.add(sma.getFieldName()); // 判断是否允许为空 等于1是允许为空; 只有不为空的时候,需要设置 if (!"1".equals(sma.getIsNull())){ sb.append("NOT NULL COMMENT '"+sma.getFieldRemark()+"',\n"); } // 如果到了最后一条,并且只有一个主键时 if (i >= meterInfo.size()-1 && priKeyList.size() == 1){ sb.append("PRIMARY KEY (`"+ priKeyList.get(0) +"`)"); sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;"); }else if (i >= meterInfo.size() -1 && priKeyList.size() > 1){ // 最后一条,并且存在多个主键时 sb.append("PRIMARY KEY ("); // 遍历主键集合 for (int j = 0; j < priKeyList.size(); j++) { // 最后一个时 if (j == priKeyList.size() -1){ sb.append("`"+ priKeyList.get(j) +"`) USING BTREE \n"); }else { sb.append("`"+ priKeyList.get(j) +"`,"); } } sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;"); } // 非主键,直接判断是否允许为空 }else { // 存在主键,并且为最后一个了 if (priKeyList.size() > 0 && i >= meterInfo.size() -1 ){ // 判断是否为空 if是可以为空 if ("1".equals(sma.getIsNull())){ sb.append("DEFAULT NULL COMMENT '"+ sma.getFieldRemark() +"',\n"); }else { sb.append("NOT NULL COMMENT '"+ sma.getFieldRemark() +"',\n"); } // 表示只有一个主键 if (priKeyList.size() == 1){ sb.append("PRIMARY KEY (`"+ priKeyList.get(0) +"`)\n"); sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;"); }else { // 最后一条,并且存在多个主键时 sb.append("PRIMARY KEY ("); // 遍历主键集合 for (int j = 0; j < priKeyList.size(); j++) { // 最后一个时 if (j == priKeyList.size() -1){ sb.append("`"+ priKeyList.get(j) +"`) USING BTREE \n"); }else { sb.append("`"+ priKeyList.get(j) +"`,"); } } sb.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;"); } }else { // 没有就追加 判断是否为空 if ("1".equals(sma.getIsNull())){ sb.append("DEFAULT NULL COMMENT '"+ sma.getFieldRemark() +"',\n"); }else { sb.append("NOT NULL COMMENT '"+ sma.getFieldRemark() +"',\n"); } } } } return sb.toString(); } /** * 删除表SQL * @param tableName * @return */ public static String createSQLDropTable(String tableName){ return "DROP TABLE "+ tableName +""; } /** * 判断类型 * varchar * int * double * datetime * decimal * text * * @param type * @return */ private static String judgeDataType(String type){ switch (type){ case TYPE_STRING: return "varchar"; case TYPE_INTEGER: return "int"; case TYPE_DOUBLE: return "double"; case TYPE_Date: return "datetime"; case TYPE_BigDecimal: return "decimal"; case TYPE_text: return "text"; default : return "varchar"; } }; }