一次执行多条SQL的技术要点如下:
-
DatabaseMetaData接口是描述有关数据库的整体综合信息,由于DatabaseMetaData是接口,所以没有构造方法,故不能使用new来创建DatabaseMetaData对象,但是可以通过Connection的getMetaData()方法创建。例如:DatabaseMetaData md=con.getMetaData()。
-
DatabaseMetaData类的supportsBatchUpdates方法用于判断此数据库是否支持批量更新。其返回值类型为boolean,如果此数据库支持批量更新,则返回true;否则返回false。
-
Statement的addBatch(String sql)方法将给定的SQL命令添加到此Statement对象的当前命令列表中,此方法可多次调用。
-
Statement的executeBatch()方法的作用是将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。
1.java处理事务的程序
在与数据库操作时,如果执行多条更新的SQL语句(如:update或insert语句),在执行第一条后如果出现异常或电脑断电, 则后面的SQL语句执行不了,这时候设定我们自己提交SQL语句,不让JDBC自动提交,格式为:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
conn.setAutoCommit(false);stmt.addBatch("insert
into people values(078,'ding','duo')");stmt.addBatch("insert
into people values(30,'nokia','ddd')");stmt.executeBatch();执行多条SQL语句;conn.commit(); //事务提交//恢复自动提交模式conn.setAutoCommit(true);....if (con
!= null)
{con.rollback();con.setAutoCommit(true);} //如果发现异常,则采取回滚 |
如果多条语句重复,只是参数不变的话可以这样
特殊情况:如果是只是参数不变,如下也是一样的
|
1
2
3
4
5
6
|
PreparedStatement
ps=conn.prepareStatement("insert
into temp values(?)");ps.setInt(1, 100);ps.addBatch();ps.setInt(1, 200);ps.addBatch();ps.executeBatch(); |
|
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
|
package
net.xsoftlab.dict; import
java.sql.Connection;import
java.sql.DatabaseMetaData;import
java.sql.DriverManager;import
java.sql.ResultSet;import
java.sql.SQLException;import
java.sql.Statement; public class
Batch { /**
判断数据库是否支持批处理 */ public static boolean
supportBatch(Connection con)
{ try
{ //
得到数据库的元数据 DatabaseMetaData
md = con.getMetaData(); return md.supportsBatchUpdates(); }
catch (SQLException e) { e.printStackTrace(); } return false; } /**
执行一批SQL语句 */ public static int[]
goBatch(Connection con,
String[] sqls) throws Exception { if
(sqls == null)
{ return null; } Statement
sm = null; try
{ sm
= con.createStatement(); for (int i
= 0; i < sqls.length; i++) { sm.addBatch(sqls[i]);//
将所有的SQL语句添加到Statement中 } //
一次执行多条SQL语句 return sm.executeBatch(); }
catch (SQLException e) { e.printStackTrace(); }
finally { sm.close(); } return null; } public static void
main(String[] args) throws Exception { System.out.println("没有执行批处理时的数据为:"); query(); String[]
sqls = new String[3]; sqls[0]
= "UPDATE
staff SET depart='Personnel' where name='mali'"; sqls[1]
= "INSERT
INTO staff (name, age, sex,address, depart, worklen,wage) VALUES ('mali ', 27, 'w', 'china','Technology','2','2300')"; sqls[2]
= "DELETE
FROM staff where name='marry'"; Connection con
= null; try
{ con
= getConnection();// 获得数据库连接 boolean
supportBatch = supportBatch(con); // 判断是否支持批处理 System.out.println("支持批处理?
" +
supportBatch); if
(supportBatch) { int[]
results = goBatch(con, sqls);// 执行一批SQL语句 //
分析执行的结果 for (int i
= 0; i < sqls.length; i++) { if
(results[i] >= 0) { System.out.println("语句:
" +
sqls[i] + "
执行成功,影响了" +
results[i] + "行数据"); } else if
(results[i] == Statement.SUCCESS_NO_INFO) { System.out.println("语句:
" +
sqls[i] + "
执行成功,影响的行数未知"); } else if
(results[i] == Statement.EXECUTE_FAILED) { System.out.println("语句:
" +
sqls[i] + "
执行失败"); } } } }
catch (ClassNotFoundException e1) { throw
e1; }
catch (SQLException e2) { throw
e2; }
finally { con.close();//
关闭数据库连接 } System.out.println("执行批处理后的数据为:"); query(); } public static Connection getConnection()
{// 数据库连接 Connection con
= null; try
{ Class.forName("com.mysql.jdbc.Driver");//
加载Mysql数据驱动 con
= DriverManager.getConnection( "jdbc:mysql://localhost:3306/myuser", "root", "123456");//
创建数据连接 }
catch (Exception e) { System.out.println("数据库连接失败"); } return con; } public static void
query() throws Exception {// 查询所有的数据 Connection con
= getConnection(); Statement
st = con.createStatement(); ResultSet
rs = st.executeQuery("select
* from staff"); while
(rs.next())
{ String name =
rs.getString("name"); int age
= rs.getInt("age"); String
sex = rs.getString("sex"); String
address = rs.getString("address"); String
depart = rs.getString("depart"); String
worklen = rs.getString("worklen"); String
wage = rs.getString("wage"); System.out.println(name + "
" +
age + "
" +
sex + "
" +
address + "
" +
depart + "
" +
worklen + "
" +
wage); } } } |
程序解读:
-
support_Batch()方法判断数据库是否支持SQL语句的批处理。通过Connection的getMetaData方法获得数据库的元数据对象DatabaseMetaData,再调用DatabaseMetaData supportsBatchUpdates方法判断数据库是否支持批处理。
-
startBatch()方法执行一组SQL语句。首先创建执行SQL语句的Statement对象,通过Statement类的addBatch方法将待执行SQL语句添加到执行缓冲区中,再调用executeBatch方法将执行缓冲区中的SQL语句全部执行,返回一个整型数组,如果数组元素的值大于等于0,则表示该语句执行成功,该值表示了执行该SQL语句修改的记录的行数;如果数组元素的值等于Statement.SUCCESS_NO_INFO常量,表示该语句也执行成功,但不知道具体修改了多少条记录;如果数组元素的值等于Statement.EXECUTE_FAILED常量,表示该语句执行失败。
-
getConnection()方法封装了数据库的连接方式。如果在程序中需要使用数据库,直接调用此方法即可。
-
query()方法的作用是查询数据库,传入执行查询语句的Statement对象和待执行的SQL语句,通过Statement的executeQuery方法执行SQL语句,返回一个ResultSet对象。再调用ResultSet的next()方法,根据字段名将数据取出,并打印在控制台上。
本文介绍了一次执行多条SQL语句的技术要点,包括如何利用Java的Statement对象进行批量更新,判断数据库是否支持批量更新,以及如何处理事务确保数据一致性。
652

被折叠的 条评论
为什么被折叠?



