一、概述
1.为什么要用JDBC
数据库是程序不可或缺的一部分,每一个网站和服务器的建设都需要数据库。对于大多数应用程序员(此处不包含数据库开发人员)来说,我们更多的不是在DBMS中对数据库进行操纵,而是在我们编写的程序中对数据库进行访问,Java程序中一般都是通过JDBC来连接服务器并进行增删改查操作的。下面,就来具体介绍一下JDBC编程。
2.SQL语言的分类
根据所进行操作种类的不同,结构化查询语言SQL分为三类,分别为:
(1)DQL:数据查询语言 例:select
(2)DML:数据操纵语言 例:insert、update、delete
(3)DDL:数据定义语言 例:create
二、JDBC编程所需要的准备
1.开发环境准备
首先需要配置集成开发环境,本例中使用的IDE为MyEclipse2014,数据库为MySQL数据库。在我们进行编程之前,首先还要引用MySQL官方提供的jar包,该包中提供了数据库驱动,数据库驱动的加载是JDBC编程必不可缺的步骤。
引用jar包的步骤(在MyEclipse中):
(1)在项目路径下建立lib文件夹
(2)下载获得jar包,并复制到lib文件夹下
(3)右键单击导入到lib文件夹中的jar包,选择Build Path,之后添加到Build Path,添加到引用列表
在配置好了集成开发环境并引入MySQL的jar包后,我们就可以开始我们的JDBC编程了。
2.数据库准备
我们建立了一个存储员工的WORKER表,建表语句如下:
1 create table WORKER ( 2 worker_num varchar(10), 3 worker_name varchar(20) not null, 4 worker_dept int(3), 5 worker_address varchar(50), 6 worker_sal int(5), 7 worker_level varchar(10), 8 constraint pk_worker_num primary key(worker_num), 9 );
三、开始编写第一个JDBC程序
1.JDBC程序编写流程:
(1)加载数据库驱动
数据库驱动,就是应用于特定数据库的一套实现了JDBC接口的类集。我们在准备的时候加载了mysql数据库对应的jar包,其中就有数据库驱动。只有加载了数据库驱动,才能够继续进行对数据库的操作。
1 //加载数据库驱动的代码如下 2 Class.forName("com.mysql.jdbc.Driver");
其中,forName方法的参数由不同的数据库决定,这里我们加载的是MySQL数据库的驱动。
(2)定义数据库的url(统一资源定位符)
url是获取连接的必须要素,其格式如下:协议、IP地址、端口号、数据库名
我们定义的url如下:
String url = “jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8”
其中,jdbc:mysql为协议部分;localhost为IP地址,此处是本机;3306为MySQL的默认端口号;mydb为数据库名;问号后面部分的作用是防止乱码。
(3)获得数据库连接(Connection对象)
要想进行对数据库的操作,首先需要获得数据库的连接对象,JDBC中我们使用DriverManager的静态方法进行连接对象的初始化。
1 //获得数据库连接对象的代码如下: 2 Connection conn = DriverManager.getConnection(url, userName, passWord);
其中getConnection方法有三个String类型的参数,分别为数据库连接的url,数据库登陆的用户名和数据库登陆的密码。
(4)创建Statement并初始化
Statement是用来执行语句的,我们利用Connection的内置方法对Statement进行初始化,之后通过Statement对象执行SQL语句。
//创建Statement对象的代码如下: Statement stmt = conn.createStatement();
其中,conn为已经获得的Connection对象
(5)执行SQL语句
(6)释放数据库资源
数据库资源是有限的,如果一直不释放连接对象,那么一旦达到上限,则之后的应用无法获取连接对象,也就无法继续程序的执行;同理,Statement对象会占用内存,一旦内存使用完毕,也会阻碍程序的执行。因此,我们要在每次使用完这些对象后进行关闭。
2.一个对数据库进行DQL操作的例子
1 //连接数据库,并进行查询 2 public class JdbcTest { 3 public static void main(String[] args) { 4 String url = "jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8"; 5 String user = "root"; 6 String psw = "root"; 7 String sql = "select * from WORKER"; 8 Connection conn = null; 9 Statement stmt = null; 10 ResultSet rs = null; 11 try { 12 Class.forName("com.mysql.jdbc.Driver"); 13 conn = DriverManager.getConnection(url, user, psw); 14 stmt = conn.createStatement(); 15 rs = stmt.executeQuery(sql); 16 while(rs.next()) { 17 String workerNumber = rs.getString("worker_num"); 18 System.out.println(workerNumber); 19 } 20 21 } catch (ClassNotFoundException e) { 22 e.printStackTrace(); 24 } catch (SQLException e) { 25 e.printStackTrace(); 26 }finally { 27 try { 28 stmt.close(); 29 conn.close(); 30 } catch (SQLException e) { 31 e.printStackTrace(); 32 } 33 } 36 } 37 }
其中,ResultSet是结果集对象,用来接收查询的结果,最后从结果集中获得查询到的数据,进行输出。
四、JDBC程序编写的改进
1.将配置文件与程序分离
工具类的抽象方法是将一段需要执行多次的代码抽象出来,形成工具方法。除却此改进外,JDBC程序还可以利用配置文件,来将配置信息与程序分隔开来(这种方法被称为软编码),这样能够避免在修改配置信息的时候修改程序,导致需要大量的对程序的重新测试。
常用的配置文件有两种类型,一种是.xml文件,另一种是.properties文件。在这里由于我们需要的配置都是一些二维的基本字符串,所以可以采用.properties文件进行配置。
配置文件如下:
1 #db.properties 2 driver = com.mysql.jdbc.Driver 3 url = jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf-8 4 username = root 5 password = root
2.对可复用代码的封装
仔细想一想JDBC程序的执行过程,会发现有很多操作是每次进行数据库连接都需要做的:如果我们有几个需要操作数据库的类需要连接相同的数据库并对其执行数据操作,那么我们就可以把获得Connection对象的功能抽象出来,形成一个单独的工具类。具体如下:
1 //工具类的编写 2 public class JDBCUtils { 3 private static String driverClass; 4 private static String url; 5 private static String userName; 6 private static String passWord; 7 static {
//对资源文件的读取 8 Properties p = new Properties(); 9 try { 10 p.load(JDBCUtils.class.getResourceAsStream("db.properties")); 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 driverClass = p.getProperty("driver"); 15 url = p.getProperty("url"); 16 userName = p.getProperty("username"); 17 passWord = p.getProperty("password"); 18 try { 19 Class.forName(driverClass); 20 } catch (ClassNotFoundException e) { 21 e.printStackTrace(); 22 } 23 } 24 public static Connection getConnection(){ 25 Connection conn = null; 26 try { 27 conn = DriverManager.getConnection(url, userName, passWord); 28 } catch (SQLException e) { 29 e.printStackTrace(); 30 } 31 return conn; 32 } 33 public static void closeAll(ResultSet result, Statement stmt, Connection conn) { 34 try { 35 result.close(); 36 } catch (SQLException e) { 37 e.printStackTrace(); 38 } 39 try { 40 stmt.close(); 41 } catch (SQLException e) { 42 e.printStackTrace(); 43 } 44 try { 45 conn.close(); 46 } catch (SQLException e) { 47 e.printStackTrace(); 48 } 49 } 50 public static void closeAll(PreparedStatement stmt, Connection conn) { 51 try { 52 stmt.close(); 53 } catch (SQLException e) { 54 e.printStackTrace(); 55 } 56 try { 57 conn.close(); 58 } catch (SQLException e) { 59 e.printStackTrace(); 60 } 61 } 62 }
工具类的编写中,我们用到了static块,此处static块中包含的部分是只需要在类加载的时候执行的类,同时们把工具方法设置成静态方法,方便调用。
3.改进后的JDBC程序
1 public class NewGetWorker { 2 public static void main(String[] args) { 3 Connection conn = null; 4 Statement stmt = null; 5 ResultSet result = null; 6 String sql = "select * from WORKER"; 7 conn = JDBCUtils.getConnection(); 8 try { 9 stmt = conn.createStatement(); 10 result = stmt.executeQuery(sql); 11 while(result.next()) { 12 String workerNum = result.getString("worker_num"); 13 String workerName = result.getString("worker_name"); 14 String workerAddress = result.getString("worker_address"); 15 String workerLevel = result.getString("worker_level"); 16 System.out.println(workerNum + " " + workerName + " " + workerAddress + " " + workerLevel); 17 } 18 } catch (SQLException e) { 19 e.printStackTrace(); 20 }finally { 21 JDBCUtils.closeAll(result, stmt, conn); 22 } 23 24 } 25 }
由改进后的程序中可以看到,我们可以直接调用工具类中的方法获取连接对象,同时在finally块中调用工具类的close方法对对象进行关闭,这样做有效的增加了代码的复用性。
五、总结
JDBC是Java提供的一套与数据库进行连接的API的集合。利用这些API,已经可以满足日常开发中Java程序连接数据库的需求。关于JDBC的内容远不止于这一篇博文的介绍,还有很多后续知识的介绍。相信看过了这篇博文,大家会对JDBC程序的编写已有了初步的了解,后续还会写更多文章进行介绍。
ps.博主也是正在学习路上的菜鸟,有想一起学习的小伙伴欢迎交流哈。