进阶4——对数据库和数据库表进行动态增删改查

不知道各位是否观察到,截止到现在的增删改查都建立在,在MYSQL数据库中建立好相应的数据库和数据表,写入相应的字段之后才开始使用JAVA对数据库的进行操作!我google了一下,没有发现在java中对数据库进行增删改查操作的,经由教程:https://www.yiibai.com/jdbc/jdbc_quick_guide.html启发,对数据库的操作分开了,但是重复代码很多,能不能像进阶2中一样结合在一起呢?

image.png
我自己动手调,写出了简单的框架,但是从外部传参到操作数据库之间自己也没有调出来,一个大佬耐心的帮我调了半天,终于把代码跑通,在此感谢大佬耐心的援助!
功能:在Java中实现,下述功能
image.png
其中3 创建表中嵌套了进阶2中对表的操作
image.png
插入后
image.png
查询
eclipse中
image.png
MYSQL中
image.png
可以看到对应的MYSQL中使用java对数据库和数据表的操作都已经更新在数据库中

完整代码

文件调用关系为:
Syn.java调用TestConnection.java和Test.java
Test.java调用Handle.java
Handle.java调用TestConnection.java

主文件

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

//此代码在JAVA中,连接数据库,对数据库进行操作,嵌套对表的操作
package database_20;

import java.sql.*;
import java.util.Scanner;

//步骤1:导入需要的包,java.sql是JDBC 4.0的主要包。它提供了与数据源进行交互的主要类。
public class Syn {

static final String JDBC_DRIVER = "com.mysql.jdbc.Driver"; //JDBC驱动名
static final String DB_URL = "jdbc:mysql://localhost/test?useSSL=false"; //数据库URL,test是在SQL中创建好的数据库,后面一句SSL要加上
static final String USER = "root"; //用户
static final String PASS ="12345678"; //密码
static String ch;
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection conn =null; //Connection 接口用于联系数据库
Statement stmt = null; //Statement:使用从此接口创建的对象将SQL语句提交到数据库。

int flag = 0;
try{
Class.forName(JDBC_DRIVER); //步骤2 :注册JDBC驱动
System.out.println("Connecting to database..."); //步骤3:打开一个连接
conn = DriverManager.getConnection(DB_URL, USER, PASS); //DriverManager:此类管理数据库驱动程序列表。 使用通信子协议将来自java应用程序的连接请求与适当的数据库驱动程序进行匹配。在JDBC下识别某个子协议的第一个驱动程序将用于建立数据库连接。

System.out.println("Creating statement..."); //步骤4:执行一个查询
stmt = conn.createStatement();
System.out.println("欢迎光临!");
do{
System.out.println("请输入您要进行的操作:0 显示数据库 1.建立数据库 2 选择数据库 3 创建表 4 删除表 5 删除数据库 6 关闭数据库:");
Scanner sc = new Scanner(System.in);
String str = sc.next();
int f=Integer.parseInt(str); //类型str转为int
switch (f){
case 0:
Statement stmte = conn.createStatement();
ResultSet resultSet = stmte.executeQuery("select * from information_schema.schemata"); //查询数据库名
while(resultSet.next()){
System.out.println(resultSet.getString(2)); //循环输出也可以写成getString("schema_name")

}
break;
case 1:
System.out.println("请输入建立的数据库名称:");
String na = sc.next(); //!!!只建立一个scanner也可以持续监听,注意next() nextline()的区别!!!
String sql ="CREATE DATABASE "+na; //获取外部输入的数据库na,是个变量
System.out.println(sql);
stmt.executeUpdate(sql);
System.out.println("数据库建立完成");
flag = f;
break;
case 2:
System.out.println("请输入选择的数据库名称:");
ch = sc.next(); //ch是外部输入选择使用的数据库名
String sql2 ="USE "+ch;
System.out.println(sql2);
stmt.executeUpdate(sql2);
System.out.println("数据库选择完成");
flag = f;
break;

case 3:
System.out.println("请输入需要建立的表的名字:");
String ta = sc.next(); //ta是外部输入得到的在ch库下面的表名
String sql3 = "CREATE TABLE "+ta+ //这里表名动态化了,但是字段类型还是在此固定了,以后是否可以进一步改进呢???
"(id INTEGER not NULL, " +
" name VARCHAR(255), " +
" salary INTEGER, " +
" dpId INTEGER, " +
" email VARCHAR(255), " +
" PRIMARY KEY ( id ))";
stmt.executeUpdate(sql3);
System.out.println("需要对表进行进一步操作么?1:是 2:否");
int j = sc.nextInt();
if(j==1){
TestConnection tc=new TestConnection(ch); //*****调用TestConnection并且将ch传递给数据库连接这个函数
Test.test(sc,tc,ta); //*****调用Test,并且将参数传递给test
}else
flag = f;
break;
case 4:
System.out.println("请输入需要删除的表名称:");
String deta = sc.next();
String sql4 ="DROP TABLE "+deta;
System.out.println(sql4);
stmt.executeUpdate(sql4);
System.out.println("表删除完成");
flag = f;
break;
case 5:
System.out.println("请输入需要删除的数据库名称:");
String de = sc.next();
String sql5 ="DROP DATABASE "+de;
System.out.println(sql5);
stmt.executeUpdate(sql5);
System.out.println("数据库删除完成");
flag = f;
break;
case 6:
System.out.println("程序退出!");
System.exit(0);
break;
}
}while(flag!=6);
//步骤6:清理环境
stmt.close();
conn.close();
}catch(SQLException se){ //SQLException:此类处理数据库应用程序中发生的任何错误。
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
System.out.println("Goodbye");
}
}//end main

Test.java

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
//此程序将被Syn调用,然后它调用handle
package database_20;

import java.util.Scanner;
/**
* 测试类
* @author Administrator
*
*/
public class Test {
private static Scanner sc;

public static void test(Scanner sc,TestConnection tc,String ta) {
int index = 0;
System.out.println("表操作:");
//输出选项
do{
System.out.println("1:查询 2:更新 3:插入 4:删除 5:退出");
System.out.println("你想干什么? 请选择:");
sc = new Scanner(System.in);
//实例化数据操作类Handle
Handle hd = new Handle(sc, tc,ta); //注意,这里在传递参数

int type = sc.nextInt();
/**
* 判断用户选择操作的项
*/
switch(type){
case 1:
//调用Handle查询方法
hd.query();
System.out.println("查询完成!");
index = type;
break;
case 2:
//更新
hd.update();
System.out.println("更新完成!");
index = type;
break;
case 3:
//插入
hd.insert();
System.out.println("插入完成!");
index = type;
break;
case 4:
//删除
hd.delete();
System.out.println("删除完成!");
index = type;
break;
case 5:
//退出
System.out.println("程序退出!");
System.exit(0);
break;
}

}while(index != 5);
}
}

Handle.java

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//test调用handle,handle调用testconnection

package database_20;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
/**
* 数据库操作类
* @author Administrator
*
*/
public class Handle {
public String ta;
public Scanner sc;
public TestConnection tc;

public Handle(Scanner sc,TestConnection tc,String ta) {
this.sc=sc;
this.tc=tc;
this.ta=ta;
// TODO Auto-generated constructor stub
}
/**
* 查询方法
*/
public void query() {
System.out.println("1:查询全部");
System.out.println("2:根据ID查询");
System.out.print("选择你要执行选项:");
// Scanner sc2 = new Scanner(System.in);
int type2 = sc.nextInt();
switch (type2) {

case 1:
String Sql1 = "select ID,Name,Salary,dpId,email from "+ta+" where 1=?"; //表名在这里,这里顺序要和数据库表一致
Object[] array1 = { 1 };
List list = tc.getData(Sql1, array1);
/**
* 取键值 并打印 即为输出的列名 排列
*/
Map map2 = (Map) list.get(0);
// 存键值
Set set2 = map2.keySet();
Iterator it2 = set2.iterator();
while (it2.hasNext()) {
System.out.print("\t" + it2.next());
}

System.out.println();
//循环取出 每个行的数据

for (Object object : list) {
// list里面是map对象
Map map = (Map) object;
// 存键值
Set set = map.keySet();
Iterator it = set.iterator();

while (it.hasNext()) {
// 取键值

Object key = it.next();

// 输出 map里的数据

System.out.print("\t " + map.get(key));

}
System.out.println();
}

break;
case 2:
/**
* 根据用户输入的员工id进行查询
*/
System.out.println("输入ID:");
Object object = sc.nextInt();
Object[] array = { object };
String Sql2 = "select id,name,salary,dpId,email from "+ta+" where ID =? "; //表名

List list2 = tc.getData(Sql2, array);
//输出列名
Map map3 = (Map) list2.get(0);
// 存键值
Set set3 = map3.keySet();
Iterator it3 = set3.iterator();

while (it3.hasNext()) {
System.out.print("\t" + it3.next());
}

System.out.println();
//循环输出数据
for (Object object2 : list2) {
// list里面是map对象
Map map4 = (Map) object2;
// 存键值
Set set4 = map4.keySet();
Iterator it4 = set4.iterator();

while (it4.hasNext()) {
// 取键值

Object key = it4.next();

// 输出 map里的数据

System.out.print("\t " + map4.get(key));
// System.out.print("\\t"+ map.get(key));

}
System.out.println();
}

break;
}
}

/**
* 更新方法
*/
public void update(){
System.out.print("请输入ID:");
Object id = sc.next();
System.out.print("请输入想更新的薪水值:");
Object salary = sc.next();
//根据用户输入的员工号来修改薪水值并判断是否执行成功
String sql = "update" +ta+ "set Salary = ? where ID = ? " ; //表名
Object [] array = { salary, id };
//使用TestConnection的update方法
int line = tc.update(sql, array);
if(line>0){
System.out.println("信息更新成功!");
}

}
/**
* 插入方法
*/
public void insert(){
System.out.print("请输入ID:");
int id = sc.nextInt();
System.out.print("请输入Name:");
String name = sc.next();
System.out.print("请输入email:");
String email = sc.next();
System.out.print("请输入Salary:");
int salary = sc.nextInt();
System.out.print("请输入dapartmentId:");
int dpId = sc.nextInt();
Object[] array = {id,name,salary,dpId,email};
//插入用户输入的数据 并判断是否执行成功
String sql = "insert into "+ta+" values(?,?,?,?,?)"; //表名
int line = tc.update(sql, array);
if(line>0){
System.out.println("插入成功!");
}
}

/**
* 删除方法
*/
public void delete(){
System.out.print("请输入想删除的员工号:");
Object id = sc.next();
Object [] array = {id};
//删除用户输入 的员工号的数据并判断是否执行成功
String sql = "delete from "+ta+" where ID = ? "; //表名
int line = tc.update(sql, array);
if(line>0){
System.out.println("删除成功!");
}
}

}

TestConnection.java

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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
package database_20;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestConnection {

/**
* 定义链接需要的字符串
*/
private String ch;
private static final String str1 = "com.mysql.jdbc.Driver";
private static final String user = "root";
private static final String password = "12345678";
Connection conn;
PreparedStatement st;
ResultSet rs;

/**
* 加载驱动类
*/
static {

try {
Class.forName(str1);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public TestConnection(String ch) {
this.ch=ch;
// TODO Auto-generated constructor stub
}

/**
* 建立链接的方法
*
* @return
*/
private Connection getConnection() {

try {
String url = "jdbc:mysql://localhost/"+ch+"?useSSL=false"; //这里是数据库名
conn = DriverManager.getConnection(url, user, password);

} catch (Exception e) {
// TODO: handle exception
}
return conn;

}

/**
* 使用prepareStatement来预编译查询语句 然后传参数的值来作为条件查询数据库 返回list
*
* @param id
* @return
*/
public List getData(String sql, Object[] array) {
// SQL语句
List list = new ArrayList();
conn = this.getConnection();
try {
// 预编译
st = conn.prepareStatement(sql);
// 利用方法传入参数
for (int i = 0; i < array.length; i++) {
st.setObject(i + 1, array[i]);
}
// 执行查询
rs = st.executeQuery();
while (rs.next()) {
Map map = new HashMap();

ResultSetMetaData rsmd = rs.getMetaData();
// 以列名为键 存储每一行数据进map
for (int i = 1; i <= rsmd.getColumnCount(); i++) {

map.put(rsmd.getColumnName(i), rs.getObject(i));

}
// 将每一个map加入list 这样list的到就是每一行
list.add(map);

}

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
// 关闭连接
this.close();
}
return list;

}

/**
* 更新数据的方法
*
* @param sql
* @param array
* @return
*/
public int update(String sql, Object[] array) {
conn = this.getConnection();
int line = 0;
try {

st = conn.prepareStatement(sql);
// 传参数
for (int i = 0; i < array.length; i++) {
st.setObject(i + 1, array[i]);
}

line = st.executeUpdate();
// 判断是否修改成功
if (line > 0) {
return line;

} else {

System.out.println("更新失败");
}

} catch (SQLException e) {

e.printStackTrace();
} finally {
// 关闭连接
this.close();
}
return 0;
}

/**
* 关闭连接
*/
private void close() {

try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {

try {
if (st != null) {
st.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {

try {
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

优化

上述代码调通之后还是能完成比较完整的数据库和数据库标的操作,但是还有几点需要优化
1.大佬说我程序写的太乱,这个,我可能写的太少,还不知道怎样写出清晰明了的代码,确实有点冗余
2.主文件中那个字段是自己定的,就像之前MYSQL里面要预先写好数据库和表一样,这个需要改进
3.不知道大佬们看到这里有没有发现没有显示表的操作,导致每次都要重新新建一个表,这个也需要改进

-------------���Ľ�����л�����Ķ�-------------