以下面的代码为例:
package com.my; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** *JDBC *查询account表中的所有数据,将查询结果输出到控制台 */ public class Test_JDBC{ public static void main(String[] args) throws Exception{ //1.注册数据库驱动------可能会出现抛出异常, //所以直接在主方法里面抛出(添加)throws Exception Class.forName("com.mysql.jdbc.Driver"); //2.获取数据库连接 //导入包时要导入import'Connection'(java.sql) Connection conn= DriverManager.getConnection( "jdbc:mysql://localhost:3306/jt_db?characterEncoding=UTF-8", "root", "123456" ); //3.获取传输器 Statement stat = conn.createStatement(); //4.发送SQL到服务器执行并放回结果 String sql = "select * from account"; ResultSet rs = stat.executeQuery(sql); //5.处理结果 while(rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); double money = rs.getDouble("money"); System.out.println(id+":"+name+":"+money); } //6.释放资源,越早获取的越后关闭 rs.close(); stat.close(); conn.close(); System.out.println("执行完成!"); } }
1、注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
所谓的注册驱动,就是让JDBC程序加载MySQL驱动程序,并管理驱动。驱动程序实现了JDBC API定义的接口以及和数据库服务器交互的功能,加载驱动是为了方便使用这些功能。
2、获取连接----数据库URL
Connection conn=
DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=UTF-8","root", "123456"
);
(1)DriverManager.getConnection()用于获取数据库连接,返回Connection连接对象是JDBC程序连接数据库很重要的一个对象。
(2)参数2和参数3分别是所连接数据库的用户名和密码。
(3)参数1:"jdbc:mysql://localhost:3306/jt_db”是连接数据库的URL,用于指定访问哪一个位置上的数据库服务器及服务器中哪一个数据库,其写法为:
jdbc:mysql://localhost:3306/jt_db
协议名称 主机名(ip)和端口 连接的库
(4)当连接本地数据库,并且端口为3306,可以简写为如下形式:
jdbc:mysql:///jt_db;
3、Statement传输对象
Statement stat = conn.createStatement();
该方法用于向数据服务器发送sql语句的Statement传输对象,该对象上提供了发送sql的方法:
executeQuery(String sql)--用于向数据库发送查询类型的SQL语句,返回一个ResultSet对象中
executeUpdate(String sql)--用于向数据库发送更新(增加、删除、修改)类型的SQL语句,返回一个int值,表示影响的记录行数
4、ResultSet结果集对象
ResultSet对象用于封装sql语句查询的结果,也是一个非常重要的对象。该对象上提供了遍历数据及获取数据的方法。
(1)遍历数据行的方法
next() ----使指向数据行的箭头向下移动一行,如果返回true则表示箭头指向的行有数据(记录),如果返回false,则表示箭头指向的行没有数据(记录)
(2)获取数据的方法
getInt(int columnIndex)
getInt(String columnLable)
getString(int columnIndex)
getString(String columnLable)
getDouble( int columnIndex)
getDouble(String columnLable)
getObject(int columnIndex)
getObject(int columnLable)
..........
5、释放资源
//释放资源,越早获取的越后关闭
rs.close();
stat.close();
conn.close();
此处释放资源必须按照一定的顺序释放,越晚获取的越先关闭。所以先关闭rs对象,再关闭stat对象,最后关闭conn对象。
为了避免程序出现异常,释放资源的代码要放在finally块中。
try{
...
}catch(Exception e){}
6.为了使释放资源的更安全的运行,调整整体代码:
(1)首先,删除主方法上的throws Exception:
(2)删除之后会出现很多错误,如图:
解决办法(1):
(3)选中所有在主方法里面的代码:
(4)选中后鼠标右键,选择Surround With,再选择Try/Catch Block
(4)用一个Catch来抛出异常,删掉一个Catch
(5)删掉之后再保存,如图:
再试想一下,如果释放资源的代码放在这个位置就安全了么?答案肯定是不安全的。
比如:如果前面的代码出现异常,资源就不能释放
Connection conn=
DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=UTF-8", "root", "123456"
);
//3.获取传输器
Statement stat = conn.createStatement();
//4.发送SQL到服务器执行并放回结果
String sql = "select * from account";
ResultSet rs = stat.executeQuery(sql);---------出现异常
解决办法(2):
(6)将释放资源的代码放入到一个finaly块中:
但是会发现,释放资源的代码还会报错,出现错误的原因是因为,rs,stat,conn所声明的变量是在try里面,并不在finaly中,所有它们接收不到前面的信息。
解决办法(3)如下:
(7)将声明变量的方法放在main里面,try外面,这样就可以获取到:
(8)另外俩个也是同样的步骤:
再看一下释放资源的代码,还是报错.
解决办法(4):
(9)鼠标划到释放资源的其中一个上面,发现会有提示上来:选中提示的第二个:Surround with try/catch
(10)选中后的结果:
但是资源还是没有释放掉,
解决办法(5):
(11)在添加一个finaly,让它的值为空:
补充:rs.close()释放资源比较及时;rs=null释放资源比较慢;如果rs.close()已经把资源释放到,rs=null不执行也不影响程序执行;如果rs.close()没有把资源释放掉,就执行rs=null,只是释放资源比较慢。
其他俩个同理。
解决办法(6):
再设想,这样就安全了么?
假设,前面的代码出异常,如:
stat = conn.createStatement();
那么将会出现,下面俩个直接就被跳过,直接运行catch,再运行finaly。
会造成以下语句接收不到,会出现一个空指针异常:
String sql = "select * from account";
rs = stat.executeQuery(sql);
//5.处理结果
while(rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+":"+name+":"+money);
}
所以,为了避免空指针异常,要将释放资源的语句放入一个if()语句中。
其他俩个同样的方法,所以,完整又安全可以运行的代码如下:
package com.my;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
*JDBC
*查询account表中的所有数据,将查询结果输出到控制台
*/
public class Test_JDBC{
public static void main(String[] args){
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
//1.注册数据库驱动------可能会出现抛出异常,
//所以直接在主方法里面抛出(添加)throws Exception
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
//导入包时要导入import'Connection'(java.sql)
conn=
DriverManager.getConnection(
"jdbc:mysql://localhost:3306/jt_db?characterEncoding=UTF-8", "root","123456"
);
//3.获取传输器
stat = conn.createStatement();
//4.发送SQL到服务器执行并放回结果
String sql = "select * from account";
rs = stat.executeQuery(sql);
//5.处理结果
while(rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
double money = rs.getDouble("money");
System.out.println(id+":"+name+":"+money);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//6.释放资源,越早获取的越后关闭
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
rs = null;
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
stat = null;
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally {
conn = null;
}
}
}
System.out.println("执行完成!");
}
}