Java代码中实现创建数据库表
近期闲来无事,就想起来使用代码去实现创建数据库表,废话不多说,直接上代码
/**
* @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";
}
};
}