1、单元员 23 使用 JDBC 查询数据库单元目标 掌握 JDBC 程序的结构及工作原理; 掌握 JDBC 纯 Java 驱动方式; 掌握如何使用 JDBC 获取数据库连接; 掌握运用 JDBC 对数据进行查询。学习任务1.任务描述在员工管理系统中,需要建立员工表 emp,字段有员工编号(empno) 、姓名(ename) 、工作(job) 、经理编号(mgr) 、雇佣日期(hiredate)、工资(sal)、提成(comm)、部门编号(deptno),如图 5-23 所示。现要求使用 JDBC 连接数据库,能够根据员工编号查询、添加、修改、删除员工记录。图 5-23 员工表 emp 数据示例2
2、.运行结果员工数据管理程序设计知识准备23.1 JDBC 查询数据库JDBCAPI 完成三件事, 通过 Connection 接口建立与数据库连接, Statement接口执行 SQL 语句,ResultSet 接口处理返回结果。23.1.1 准备环境要想连接不同数据库,需要下载相应驱动程序,然后添加到当前工程中。比如, 连接 SQL Server 2008 数据库, 需准备 JDBC 驱动程序包 sqljdbc4.jar。然后, 在 Eclipse 中, 选中当前项目, 单击右键, 在菜单中选择属性 (Properties) ,打开配置对话框,选择 Java Build Path,选中 Li
3、braries 标签,单击 Add Jars 按钮,选择添加 sqljdbc4.jar 文件,将驱动程序包引入工程中。如图 5-26 所示:图 5-26 修改项目属性引入 sqljdbc4.jar 文件23.1.2 加载并注册驱动用 Class.forName()方法显示装载驱动程序。格式如下:tryClass.forName(JDBC 驱动程序类驱动程序类);/ 注册注册 JDBC 驱动驱动 catch (ClassNotFoundException e) / 处理异常处理异常System.out.println(无法找到驱动类无法找到驱动类);注解:员工数据管理程序设计1Class 类的
4、forName()方法以完整的 Java 类名字符串为参数,装载此类。此时将自动创建一个驱动类的实例,并自动调用驱动器管理器 DriverManager类中的 RegisterDriver 方法来注册它。2驱动类有可能不存在,使用此 Class.forName()方法就可能会抛出ClassNotFoundException 异常,因此需要捕获这个异常。比 如 : SQL Server2008数 据 库JDBC 驱 动 程 序 类 名 为com.microsoft.sqlserver.jdbc.SQLServerDriver,则对应加载驱动的代码为:tryClass.forName(com.mi
5、crosoft.sqlserver.jdbc.SQLServerDriver);/ 注册驱动 catch (ClassNotFoundException e) / 处理异常System.out.println(无法找到驱动类);23.1.3 Connection 对象Connection 对象与特定数据库的连接(会话) 。在连接上下文中执行 SQL语句并返回结果。标准方法是调用 DriverManager.getConnection()方法。格式如下:try / 用用 JDBCJDBC URLURL 标识数据库,建立数据库连接标识数据库,建立数据库连接Connection con=Driver
6、Manager.getConnection(JDBC URL,数据库用数据库用户名户名, ,密码密码); catch (SQLException e) / 处理异常处理异常e.printStackTrace();注解:1JDBC URL 格式格式为:jdbc:子协议子协议:子名称子名称jdbc 表示协议,JDBC URL 中的协议总是 jdbc;子协议是驱动器名称;子名称是数据库的名称, 如果是位于远程服务器上的数据库, 则还应该包括网络地址。例如:连接本机 SQL Server2008 数据库服务器中 empmanage 数据库的 JDBCURL 书写为:jdbc:sqlserver:/lo
7、calhost:1433;DatabaseName=empmanage注解:jdbc表示协议,sqlserver是子协议,/localhost:1433;DatabaseName=empmanage 称为子名称。2 getConnection()方法第二个参数是访问数据库所需的用户名,第三个参数是用户密码。3 DriverManager.getConnection()方法在执行时可能会抛出 SQLException异常,因此需要捕获这个异常。23.1.4 Statement 对象Statement 对象用于执行静态 SQL 语句并返回所生成结果的对象。通过Connection 接口的 crea
8、teStatement()方法可创建向数据库发送 SQL 语句的Statement 对象。格式如下:try Statement stmt = con.createStatement(); / 发送发送 SQL 语句语句 catch (SQLException e) / 处理异常处理异常e.printStackTrace();为了通过 Statement 对象操作数据库,需要将 SQL 语句作为参数提供给Statement 的方法,例如:ResultSetrs=stmt.executeQuery(“select*fromempwhereempno=7369”);ResultSet rs = st
9、mt.executeQuery(select * from emp);Statement提供了三种执行语句的方法, 即executeQuery()、 executeUpdate()和 execute()。使用哪一种方法由 SQL 语句所产生的内容决定。executeQuery()方法:用于产生单个结果集的语句,例如 select 语句。例如:查询所有员工信息ResultSet rs = stmt.executeQuery(select * from emp);【注意】执行语句的所有方法都将关闭所调用的 Statement 对象当前打开的结果集 (如果存在) 。这意味着在重新执行 Stateme
10、nt 对象之前,需要完成对当前 ResultSet对象的处理。23.1.5 ResultSet 对象ResultSet 对象表示数据库结果集的数据表, 通常通过执行查询数据库的语句生成。查询结果作为结果集(ResultSet)对象返回后,可以从 ResultSet 对象中提取结果。1使用 next()方法ResultSet 对象中含有检索出来的行,其中有一个指示器,指向当前可操作的行,初始状态下指示器是指向第一行之前。方法 next()的功能是将指示器下移移行, 所以第一次调用 next()方法时便将指示器指向第一行, 以后每一次对 next()方法的成功调用都会将指示器移向下一行。2使用 g
11、etXXX()方法使用相应类型的 getXXX()方法可以从当前行指定列中提取不同类型的数据。例如ename列都是SQL类型varchar, 提取varchar类型数据时就要用getString()方法,而提取 float 类型数据的方法是 getFloat()方法。【例 1-1】例如,获取所有员工信息/省略类的定义和方法的定义/省略数据库和创建语句的操作/利用以下语句完成获取所有员工信息的结果try ResultSet rs = stmt.executeQuery(select * from emp);while (rs.next() / 处理结果集int eno = rs.getInt(e
12、mpno);String name = rs.getString(ename);/省略其他字段的读取float sal = rs.getFloat(sal); catch (SQLException e) / 处理异常e.printStackTrace();/省略 JDBC 相关对象的关闭操作JDBC 提供两种方法为 getXXX()指明要提取的列。一种方法是给出列名,就像上面例子中看到的那样;另一种方法是给出列的索引(列序号) ,1 代表首列,员工数据管理程序设计2 代表第 2 列,依次类推。下面是以列序号代替列名的语句:String s = rs.getString(2);/提取当前的第
13、2 列数据【注意】这里的列序号指的是结果集中的列序号,而不是原表中的列序号。23.1.6 关闭数据库连接对象计算机资源是宝贵的,如果打开的资源太多,会造成内存缺失。虽然 Java提供垃圾回收机制,但是当内存达到一定程度,即使有垃圾回收机制,程序的运行效率也是非常低的。因此,当对象使用完成后,要关闭相关对象,让其释放占用的内存空间。关闭打开的各对象,该顺序与打开的顺序相反。需要依次关闭结果集对象、语句对象和连接对象。关闭结果集对象,代码为:rs.close();关闭语句对象,代码为:stmt.close();关闭连接对象,代码为:con.close();这些语句操作过程中会抛出异常 SQLExc
14、eption,所以操作时需要进行异常处理。任务实施1.实现思路(1) 创建数据库以及数据表;(2) 编写实体类 Employee 实现员工数据的封装;(3) 编写 BaseDAO 类完成数据库连接、关闭等功能;(4) 编写 EmployeeDAO 类实现了员工表访问功能;(5) 编写 EmployeeBiz 模拟员工管理系统的业务操作。2.程序代码(1)创建数据库以及数据表本任务可采用不同数据库完成,我们在此以 SQL Server2008 为例。您可以使用 SQL Server 的默认用户 sa 登录, 先创建一个数据库 empmanage, 并使用以下 SQL 语句创建 emp 表并为其添
15、加几行测试数据。CREATE TABLE EMP员工数据管理程序设计(EMPNO INT CONSTRAINT PK_EMP PRIMARY KEY,-员工编号ENAME VARCHAR(10) NOT NULL,-姓名JOB VARCHAR(9),-工作MGR INT,-经理编号HIREDATE DATE,-雇佣日期SAL NUMERIC(7, 2),-工资COMM NUMERIC(7, 2),-提成DEPTNOINTCONSTRAINTFK_DEPTNOREFERENCESDEPT(DEPTNO)-部门编号)GOINSERT INTO EMP VALUES(7369,SMITH,CLERK
16、,7902,to_date(17-12-1980,dd-mm-yyyy),800,NULL,20);(2)编写实体类 Employee 实现员工数据的封装import java.util.Date;public class Employee private String ename; / 员工姓名private String job; / 员工工作private int manager_no; / 员工的经理编号private Date hiredate; / 员工参加工作的日期private double salary; / 员工的工资private double commision; /
17、员工的提成private int deptno; / 员工的部门编号private int empno; / 员工编号public Employee() 员工数据管理程序设计public Employee(int empno, String ename, String job, int manager_no,Date hiredate, double salary, double commision, int deptno) / 给成员变量赋值/省略成员变量的 get 方法、set 方法void show() System.out.println(empno + + ename + + job
18、 + +manager_no+ + hiredate + + salary + + + commision + + deptno);(3)编写 BaseDAO 类完成数据库连接、关闭等功能/省略相关类库的导入语句public class BaseDAO private static final String DRIVER_CLASS =com.microsoft.sqlserver.jdbc.SQLServerDriver;private static final String DADABASE_URL =jdbc:sqlserver:/127.0.0.1:1433;DatabaseName=
19、 empmanage;private static final String DADABASE_USER = sa;private static final String DADABASE_PASSWORD = system;public static Connection getConnection()Connection con = null;tryClass.forName(DRIVER_CLASS);catch(ClassNotFoundException ce)ce.printStackTrace();trycon =DriverManager.getConnection(DADAB
20、ASE_URL,DADABASE_USER,DADAB员工数据管理程序设计ASE_PASSWORD);catch(SQLException e)e.printStackTrace();return con;public static void closeConnection(Connection con)tryif(con != null | !con.isClosed()con.close();catch(Exception e)e.printStackTrace();public static void closeResultSet(ResultSet rs)try if(rs != nu
21、ll) rs.close(); catch(Exception e) e.printStackTrace();public static void closeStatement(Statement stmt)try if(stmt != null) stmt.close(); catch(Exception e) e.printStackTrace();(4)编写 EmployeeDAO 类实现了员工表访问功能public class EmployeeDAO /* 查询所有的员工信息*/public List getAllEmployees() List lEmployees = new Ar
22、rayList();Student stu = null;Connection con = null;Statement stmt = null;try /省略创建 Connection 对象和 Statement 对象String sqlStr = select * from emp;ResultSet rs = stmt.executeQuery(sqlStr);while (rs.next() Employee e = new Employee();e.setEmpno(rs.getInt(empno);/省略给员工其他成员变量赋值语句e.show();lEmployees.add(e)
23、;BaseDAO.closeResultSet(rs);BaseDAO.closeStatement(stmt); catch (Exception e) e.printStackTrace(); finally BaseDAO.closeConnection(con);return lEmployees;/省略查询指定员工编号的员工信息/*员工数据管理程序设计* 添加一个新的员工* param Employee 员工信息*/public int addEmployee(Employee emp) int num = 0;Connection con = null;PreparedStatem
24、ent pstmt = null;try con = BaseDAO.getConnection();String sqlStr = INSERT INTOemp(empno,ename,job,hiredate,sal,comm,deptno,mgr) VALUES(?,?,?,?,?,?,?,?);pstmt = con.prepareStatement(sqlStr);pstmt.setInt(1, emp.getEmpno();/省略给其他参数赋值num = pstmt.executeUpdate();BaseDAO.closeStatement(pstmt); catch (Exce
25、ption e) e.printStackTrace(); finally BaseDAO.closeConnection(con);return num;/省略删除指定员工编号的员工信息/省略更新制定员工的员工信息(5)编写 EmployeeBiz 模拟员工管理系统的业务操作public class EmployeeBiz public static void main(String args) EmployeeDAO dao = new EmployeeDAO();dao.getAllEmployees();员工数据管理程序设计Calendar d = Calendar.getInstan
26、ce();d.set(1973, 5, 29); / 设置日历为 1973 年 6 月 29 日Employee e = new Employee(1000, zxg, Manager, 7369,d.getTime(),2900, 300, 10);dao.addEmployee(e);e.setEname(zhuxg);dao.updateEmployee(e);dao.deleteEmployee(1000);任务拓展如果使用 Oracle 数据库并采用纯 Java 驱动程序连接数据库,方法和步骤同连接 SQL Server 数据库基本相同。首先,准备好 Oracle 数据库 JDBC
27、驱动程序包 ojdbc14_g.jar。可以通过互联网去下载,也可以到 Oracle 的安装目录下去找,例如 OracleXE10g 安装在C:oraclexe下,那么ojdbc14_g.jar文件可以在C:oraclexeapporacleproduct10.2.0serverjdbclib 文件夹下找到。然后, 在配置 Build Path 对话框中, 选中 Libraries 标签, 添加 ojdbc14_g.jar文件,将驱动程序包引入工程中。最后,按照 JDBC 程序模板编写代码,通过纯 Java 驱动方式与数据库建立连接。Oracle 数据库 JDBC 驱动程序类名为 oracle
28、.jdbc.driver.OracleDriver,数据库JDBC URL 为 jdbc:oracle:thin:127.0.0.1:1521:xe, 其中 127.0.0.1 是数据库服务器的 IP 地址,1521 是监听器服务监听的端口号,xe 是在 Oracle 安装目录中的 tnsnames.ora 文件中配置的数据库服务名,这些都可以根据自己的实际情况进行修改。程序代码为:URL=jdbc:oracle:thin:127.0.0.1:1521:xe ;Class.forName(oracle.jdbc.driver.OracleDriver);/加载、注册驱动程序Connection
29、 con = DriverManager.getConnection(URL,scott ,tiger);/建立数据库连接虽然不推荐使用 JDBC-ODBC 桥, 但是在开发小型系统与测试中, 仍然有人在用。例如,在用 Access 建立数据库表之后,先在控制面板进行 ODBC 数据源配置,获得数据源的名称 emp、用户名 sa 和密码 sasa。接着,编写代码,通过桥连方式与数据库建立连接。编写时,按照 JDBC 程序模板,设定 JDBC驱 动 程 序 类 和 JDBC URL 。 JDBC-ODBC 桥 驱 动 程 序 类 名 为sun.jdbc.odbc.JdbcOdbcDriver ,
30、 数 据 源 名 称 为 emp , JDBC URL 为jdbc:odbc:emp。程序代码为:Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);/加载、注册驱动程序/建立数据库连接Connection con =DriverManager.getConnection(jdbc:odbc:emp,sa,sasa);比较使用不同数据库和不同类型的驱动程序在编程上的差别,主要是 JDBC驱动程序类和数据库 JDBC URL 不同,其他代码几乎不要修改。任务实训1.实训目的 掌握JDBC的工作原理; 掌握JDBC纯Java驱动方式; 掌握如何使用JDBC获取数据库连接; 掌握运用JDBC对数据进行查询。2.实训内容编写一个用户维护的功能模块, 在该模块中包括查询所有用户名称并显示对应的列表。Users 数据表结构为:字段名数据类型是否允许为空备注idintnot null主键,标识列,表示用户 IDnamevarchar(50)not null用户名pwdvarchar(20)not null用户密码员工数据管理程序设计