A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 shjava 于 2017-9-24 19:01 编辑

【同步教程】第1天 JDBC入门




第一章 JDBC入门
作者:上海JavaEE教研部  V1.0

u JDBC介绍
u JDBC API常用类与接口
u JDBC入门案例
u JDBC API详解
u 释放资源
u JDBC CRUD操作
u JDBC工具(JdbcUtil)类抽取
u 全天总结

       本章针对JDBC的入门、API详解及CRUD(增、删、改、查)操作和工具类的抽取进行详细的介绍。


1.1 JDBC介绍



   JDBC(Java DataBaseConnectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。
SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。

  如果没有JDBC,各种数据库驱动与应用程序之间是直接相连的,如图1-1-1所示。这样的缺点是应用程序必须满足各种数据库厂商提供的协议,才能使用多种数据库,兼容性较差。

图1-1-1没有JDBC时的驱动
  有JDBC之后,各种数据库驱动与应用程序之间是通过JDBC相连,如图1-1所示。这样的优点是各种数据库驱动和应用程序只要满足JDBC协议,就可以实现连接。

图1-1有JDBC时的驱动


1.2 JDBC API常用类与接口

JDBC操作的相关API如下:
     DriverManger:数据区驱动类,不同的数据库有不同的数据库驱动,是各数据库厂商对sun公司接口规范的实现;
    Connection:数据库连接,建立一个操作数据库的连接;
    Statement:数据库操作,向数据库发送sql语句;
    ResultSet:结果集,Statement执行完sql返回的结果。
    四种方法简写格式:驱动==》连接==》操作==》结果。如图1-2是几个核心类的关系。
图1-2 JDBC核心类关系图

1.3 JDBC 入门案例

步骤一:
      连接mysql数据库,如图1-3。(这里用到Mysql数据库的可视化工具SQLyogEnt)


图1-3可视化工具连接图



步骤二:
     创建一个数据库,再创建一个表,之后插入三条数据。
【文件1-1】数据库准备
[Java] 纯文本查看 复制代码
 创建数据库:
   CREATE DATABASE jdbcDemo;
   创建数据库表:
   CREATE TABLE employee(
       id INT PRIMARY KEYAUTO_INCREMENT,
       name VARCHAR(20),
       age INT
   );
   插入数据:
  INSERT INTO employee VALUES(NULL,'貂蝉',18);
  INSERT INTO employee VALUES(NULL,'小乔',19);
  INSERT INTO employee VALUES(NULL,'大乔',20);



步骤三:
      创建工程,并在工程下创建lib目录,将数据库驱动包复制到lib目录下,再右键鼠标选中Build path选项,再选中Add to Build Path,如图1-4。
图1-4创建工程

步骤四:
      编写入门案例:创建包名,编写入门案例,如图1-5所示。
图1-5创建包名
【文件1-2】 Demo.java
[Java] 纯文本查看 复制代码
public class Demo {
     @Test
     public void query() throws Exception {
                  // 1.加载数据库驱动
          DriverManager.registerDriver(newDriver());//导包是java.sql的包
          // 2.建立数据库连接
          // jdbc:mysql:连接mysql数据库的固定写法,localhost:ip地址,3306:端口号,jdbcDemo:数据库名称
          String url ="jdbc:mysql://localhost:3306/jdbcDemo";
          // 第一个参数:连接mysql数据库,第二和第三个参数分别是数据库的用户名和密码
         Connection con =DriverManager.getConnection(url, "root", "root");
         // 3.获取statement对象
         Statement st =con.createStatement();
         // 4.执行sql语句,并且获取结果
         String sql ="select * from employee";
         ResultSet res = st.executeQuery(sql);
         // 5.处理结果
         while (res.next()) {
             System.out.println(res.getString("name"));
         }
         // 6.释放资源
         res.close();
         st.close();
         con.close();
    }
 }

友情提示:
图1-6所示是JDBC编程步骤,仅供参考。
图1-6 JDBC编程步骤




1.4 JDBC API详解

  说明:
    本章所使用的API均来自于《JDK6API中文参考【沈东良】》。
1.4.1 DriverManager介绍
  DriverManager驱动管理类API介绍,如图1-7所示。
图1-7DriverManager驱动管理类API
  说明:
    参数Driver,来自于需要连接的数据库(如果连接orcale数据库,则来自于oracle数据库驱动,如果要连接Mysql数据库,则来自于Mysql数据库驱动)。

查看【文件1-2】Demo.java中DriverManager.registerDriver(new Driver())的源代码发现数据库驱动注册了两次,如图1-8所示。
图1-8 展示数据库驱动重复注册

使用DriverManager来注册数据库驱动的不足:
    1、 对驱动api依赖性太高,数据库驱动硬编码到了代码中;
    2、 当更换数据的时候,需要重新编译代码,重新发布;
    3、 驱动会注册两次。(因为在mysql中的Driver中有静态代码块,已经注册了。)

代码优化:
    可以使用Class.forName(“com.mysql.jdbc.Driver”);来注册数据库驱动。Class.forName是一个静态方法,同样可以用来加载类。而在加载类的时候就会执行类中的static静态代码块,也就相当于实现了数据库驱动的注册。

原代码修改如下
【文件1-3】   Demo.java
[Java] 纯文本查看 复制代码
  public class Demo {
  @Test
      public void query() throws Exception {
          // 1.加载数据库驱动
          //DriverManager.registerDriver(new Driver());
          Class.forName("com.mysql.jdbc.Driver");
          // 2.建立数据库连接
          // jdbc:mysql:连接mysql数据库的固定写法,localhost:ip地址,3306:端口号,jdbcDemo:数据库名称
          String url ="jdbc:mysql://localhost:3306/jdbcDemo";
         // 第一个参数:连接mysql数据库,第二和第三个参数分别是数据库的用户名和密码
         Connection con =DriverManager.getConnection(url, "root", "root");
         // 3.获取statement对象
         Statement st =con.createStatement();
         // 4.执行sql语句,并且获取结果
         String sql ="select * from employee";
         ResultSet res =st.executeQuery(sql);
         // 5.处理结果
         while (res.next()) {
             System.out.println(res.getString("name"));
         }
         // 6.释放资源
         res.close();
         st.close();
         con.close();
     }
 }


1.4.2 Connection详解

1.4.2.1 URL介绍
    URL:统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。它最初是由蒂姆·伯纳斯·李发明用来作为万维网的地址。现在它已经被万维网联盟编制为互联网标准RFC1738了。在本章是指定一个具体的数据库。
本章的url详解如图1-9所示。
图1-9 URL详解
Oracle的URL:jdbc:oracle:thin:@localhost:3306:jdbcDemo
MySql的URL :jdbc:mysql://localhost:3306/jdbcDemo
MySql的URL简写方式:jdbc:mysql:///jdbcDemo(注意:简写方式必须是本地连接-localhost,并且需要端口是3306的)
常用属性:useUnicode=true&characterEncoding=UTF-8
解决问题:中文乱码异常
举例:jdbc:mysql://localhost:3306/day07?useUnicode=true&characterEncoding=utf8

1.4.2.2 Connection
    获取数据库连接Connction的方法是DriverManager.getConnection(url, user, password);
说明:
    url:连接到某一个具体的数据库
    user:数据库的用户名
    password:数据库用户名对应的密码。
注意:
    获取连接时导入的包是java.sql.Connection;
    虽然导入com.mysql.jdbc.Driver; 然后进行强转也可以使用,但是这样就与代码耦合了,不方便更换数据库,如图1-10所示。

图1-10

    JDBC程序中的Connection,它用于代表数据库的链接,Connection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法是createStatement(),
如图1-11所示。
图1-11 Connection的常见方法
说明:
    createStatement():创建向数据库发送sql的statement对象。


1.4.3 Statement 详解
    Statement:向数据库发送sql的对象,并且得到执行sql之后的结果。
    Jdbc程序中的Statement对象用于向数据库发送SQL语句, 本章Statement对象常用方法如下:


    1executeQuery查询数据并返回结果,如图1-12所示。
图1-12-1executeQuery的API解析
说明:
  相当于执行select查询语句,当然查询语句就是executeQuery(String sql)中的参数,查询语句可以自定义。将查询到的数据封装到ResultSet中并进行返回。

    2executeUpdate:增删改操作并返回操作的记录数量,如图1-13所示。
图1-13 executeUpdate的API解析
说明:
    相当于执行update,delete,insert等语句,具体的语句就是executeQuery(String sql)中的参数,语句可以自定义。
    返回值int:代表执行增删改的时候总共影响到了几条记录。
  例如:
    update employee setage=21;  
    如果不加条件会修改数据库所有数据,一共修改三条,因此返回值为3(之前已在数据库中添加三条数据)。
    如果添加 where id = 1 就会修改1行记录,此时返回值为1。

【示例】
需求:将数据库中所有人的年龄改成21岁 。

步骤一:编写代码
【文件1-4】   Update方法
[Java] 纯文本查看 复制代码
    @Test
     public void update() throws Exception {
          // 1.加载数据库驱动
          Class.forName("com.mysql.jdbc.Driver");
          // 2.建立数据库连接
          // jdbc:mysql:连接mysql数据库的固定写法,localhost:ip地址,3306:端口号,jdbcDemo:数据库名称
          String url ="jdbc:mysql://localhost:3306/jdbcDemo";
          // 第一个参数:连接mysql数据库,第二和第三个参数分别是数据库的用户名和密码
          Connection con =DriverManager.getConnection(url, "root", "root");
         // 3.获取statement对象
         Statement st =con.createStatement();
         // 4.执行sql语句。
         String sql ="update employee set age = 21";
         int count =st.executeUpdate(sql);
         System.out.println("您总共操作了..."+count+"...条记录");
         // 5.释放资源
         st.close();
         con.close();
     }

步骤二:执行测试,结果如图1-14所示。
图1-14 执行结果演示

3execute执行任意sql语句的操作,如图1-15所示。
图1-15 executeAPI解析
说明:
如果第一个结果为 ResultSet 对象,则返回 true;如果其为更新计数或者不存在任何结果,则返回 false,可以通过stmt.getResultSet(); 获取当前sql 执行之后得到的结果集,如图1-16所示。
图1-16 getResultSet() API 解析
【示例】
需求:使用execute方法,进行查询和更新的测试。
【文件1-5】   execute方法
[Java] 纯文本查看 复制代码
  @Test
      public void execute () throws Exception{
         //注册驱动
          Class.forName("com.mysql.jdbc.Driver");
          //后去连接
          Connection con =DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo"
          ,"root", "root");
          //定义sql
          //String sql ="select * from employee";
         //更新貂蝉的年龄为18岁
         String sql ="update employee set age= 18 where name = '貂蝉'";
         //创建sql操作对象
         Statement st =con.createStatement();
         //执行查询,并且返回boolean
         boolean flag = st.execute(sql);
         //判断flag是否为true来判断到底是不是查询语句
         if (flag) {
             //如果是true,就证明是一个查询语句,需要获取结果集
             ResultSet res = st.getResultSet();
             while(res.next()){
                 System.out.println(res.getInt("id")+"..."+res.getString("name")+"..."+
            res.getInt("age"));
             }
             res.close();
         }else{
             //如果是false,就证明不是查询语句
             System.out.println("sql语句执行成功!一共操作了"+st.getUpdateCount()+"条sql语句");
         }
         // 释放资源
         st.close();
         con.close();
     }


1.4.4 ResultSet 详解
查询所有数据的时候,得到结果,如图1-17所示。
图1-17 查询数据的结果

思考:
  ● 如何去遍历结果集
  ● 如何从结果集取出数据


1、如何去遍历ResultSet。
  查看API,得到如【表格1-1】所示的五种方法。
【表格1-1】遍历ResultSet

  
boolean
  
next()  
       将光标从当前位置向前移一行。
boolean
absolute(int row)  
       将光标移动到此 ResultSet 对象的给定行编号。
void
afterLast()  
       将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
void
beforeFirst()  
       将光标移动到此 ResultSet 对象的开头,正好位于第一行之前。
boolean
previous()  
       将光标移动到此 ResultSet 对象的上一行。

2、 如何去取出数据。
    通过查找API,有以下三种方法获取数据。
   ● getXxx(StringcolumnLabel)
  说明:
    xxx表示的是具体的数据类型。数据库表中的每个列(字段),有自己的数据类型。从结果集中取出数据是从列中取出数据。xxx表示的数据类型。如果某一列的类型是varchar(字符串),用getString() 来获取该列的数据。获取数据库中数据的类型需要和getXxx(XXX)方法的类型需要一一对应。

  ● getXxx(String 列的名字)
  说明:
     这种方法最常用常用,如果从列的名字是name的取出数据,就用getString(“name”);

● getXxx(int 列的顺序)  
  说明:
     注意:列的顺序从1开始。如果想要获取name(表字段中第二个),就用getString(2);

  建议使用按照列名去获取数据。如果有别名,也可以按照别名去获取,如图1-18演示。
图1-18获取数据的方法
【示例】
需求:从数据库中查询所有数据,并将每一行记录封装到一个Employee对象中,并且遍历所有数据库中查询出来的人员信息。

步骤一:创建Employee对象,用于封装数据。
【文件1-6】   Employee .java
[Java] 纯文本查看 复制代码
     public class Employee {
      private int id;
      private String name;
      private int age;
      public int getId() {
          return id;
      }
      public void setId(int id) {
          this.id = id;
     }
     public String getName() {
         return name;
     }
     public void setName(String name) {
         this.name = name;
     }
     public int getAge() {
         return age;
     }
     public void setAge(int age) {
         this.age = age;
     }
     @Override
     public String toString() {
         return "Employee[id=" + id + ", name=" + name + ", age=" + age +"]";
     }
 }

步骤二:编程程序获取数据库数据并进行封装和遍历
【文件1-7】   测试类
[Java] 纯文本查看 复制代码
  //需求:从数据库中查询所有数据,并将每一行记录封装到一个Employee对象中,并且遍历所有数据库中查询出来的人员信息。
      @Test
      public void resultSet() throws Exception{
          //注册数据库驱动
          Class.forName("com.mysql.jdbc.Driver");
         //创建连接
          Connection con =DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo","root","root");
          //定义sql
          String sql ="select * from employee";
         //创建sql的操作对象
         Statement st =con.createStatement();
         //发送sql,获取结果集
         ResultSet res =st.executeQuery(sql);
         //创建一个集合用来存储对象
         List<Employee>list = new ArrayList<Employee>();
         //处理结果集
         while(res.next()){
             //将获取的数据封装的对象中
             Employee emp = new Employee();
             emp.setId(res.getInt("id"));
             emp.setName(res.getString("name"));
             emp.setAge(res.getInt("age"));
             list.add(emp);
            
         }
         System.out.println(list);
         //absolute:获取指定行的数据,数据库行数索引号的起始值从0开始
         boolean absolute = res.absolute(1);
         if (res.next()) {
          System.out.println(res.getInt("id")+"..."+res.getString("name")+res.getInt("age"));
         }
         //afterLast:将光标指向最后一行记录之下。
         res.afterLast();
         //previous:获取当前光标往上一行的数据
         res.previous();
      System.out.println(res.getInt("id")+"..."+res.getString("name")+res.getInt("age"));
         //beforeFirst:将光标执行第一行记录之上。
         res.beforeFirst();
         if (res.next()) {
          System.out.println(res.getInt("id")+"..."+res.getString("name")+res.getInt("age"));
         }
         res.close();
         st.close();
         con.close();
     }

1.5 资源释放



  连接资源是珍贵的,是有数目限制的。如果只有打开没有关闭,那么当达到一个限定之后,其他人将无法继续连接数据库。所以需要关闭连接。因此,在使用完资源以后,就必须将资源释放掉,节省资源。
【示例】
需求:统计数据库记录行数,并且释放资源。
【文件1-8】   测试释放资源的方法
[Java] 纯文本查看 复制代码
      @Test
      public void close() {
         Connection con = null;
         Statement st = null;
         ResultSet res = null;
          try {
              // 加载数据库驱动
             Class.forName("com.mysql.jdbc.Driver");
              con =DriverManager.getConnection("jdbc:mysql:///jdbcDemo","root", "root");
             st = con.createStatement();
             // 执行查询
             res = st.executeQuery("select count(*) as num fromemployee");
             // 遍历数据
             if (res.next()) {
                 System.out.println(res.getInt("num"));
            }
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 if (res != null) {
                    res.close();
                }
             } catch (SQLException e1) {
                 e1.printStackTrace();
            }
             try {
                if (st != null) {
                    st.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
             try {
                 if (con != null) {
                     con.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
     }


1.6 JDBC CRUD 操作



  在项目开发过程中,最常用的就是基本的CRUD(增、删、改、查)操作。
  本节中,首先新建一个CRUD的测试类进行增、删、改、查的测试,如图 1-19所示。

图1-19新建CRUD测试类
1.6.1 insert(增)
  在CRUD类中编写插入逻辑
【示例】
在数据库中插入一条记录
【文件1-9】   测试insert的方法
[Java] 纯文本查看 复制代码
  @Test
      public void insert() {
          Connection con = null;
          Statement st = null;
          try {
              // 加载驱动
             Class.forName("com.mysql.jdbc.Driver");
              // 建立连接
              con =DriverManager.getConnection("jdbc:mysql:///jdbcDemo","root", "root");
             // 创建数据库操作对象
             st = con.createStatement();
             // 执行插入操作
             st.executeUpdate("insert into employee values(null,'洛神',21)");
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 if (con != null) {
                     con.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
            }
            try {
                 if (st != null) {
                     st.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
     }


1.6.2 update(改)
编写关于修改的逻辑
【示例】
将数据库中任意一个人的年龄修改为30岁
【文件1-10】 测试修改的方法
[Java] 纯文本查看 复制代码
      @Test
      public void update(){
         Connection con = null;
          Statement st = null;
          try {
              // 加载驱动
             Class.forName("com.mysql.jdbc.Driver");
              // 建立连接
             con =DriverManager.getConnection("jdbc:mysql:///jdbcDemo","root", "root");
             // 创建数据库操作对象
             st = con.createStatement();
             // 执行插入操作
             int count = st.executeUpdate("update employee set age = 22where id = 4");
             System.out.println("一共修改了"+count+"条记录");
            
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 if (con != null) {
                     con.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
             try {
                 if (st != null) {
                     st.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
     }
1.6.3 delete(删)
编写删除逻辑
【示例】
选择数据库中任意一条记录进行删除
【文件1-11】 测试删除的方法
[Java] 纯文本查看 复制代码
     @Test
     public void delete() {
          Connection con = null;
          Statement st = null;
          try {
              // 加载驱动
              Class.forName("com.mysql.jdbc.Driver");
              // 建立连接
              con =DriverManager.getConnection("jdbc:mysql:///jdbcDemo","root", "root");
             // 创建数据库操作对象
             st = con.createStatement();
             // 执行插入操作
             int count = st.executeUpdate("delete from employee where id= 4");
             System.out.println("您成功删除了" + count + "条记录");
  
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 if (con != null) {
                     con.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
             try {
                 if (st != null) {
                     st.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
     }
1.6.4 select(查)
编写查询逻辑
【示例】
查询数据库中id在1—4之间的所有的员工信息封装为一个个的employee对象,并且存储到一个集合中。
【文件1-12】 测试查询的方法
[Java] 纯文本查看 复制代码
  @Test
      public void select() {
          Connection con = null;
          Statement st = null;
          ResultSet res = null;
          try {
              // 加载驱动
              Class.forName("com.mysql.jdbc.Driver");
              // 建立连接
             con =DriverManager.getConnection("jdbc:mysql:///jdbcDemo","root","root");
             // 创建数据库操作对象
             st = con.createStatement();
             // 执行插入操作
             res = st.executeQuery("select * from employee where idbetween 1 and 4");
             // 定义集合,将数据存入到集合中
             List<Employee> list = new ArrayList<Employee>();
             // 遍历封装
             while (res.next()) {
                 System.out.println(res.getInt("id")+ "..." + res.getString("name") + "..." +res.getInt("age"));
                 // 封装到对象中
                Employee employee = newEmployee();
                 employee.setId(res.getInt("id"));
                 employee.setName(res.getString("name"));
                 employee.setAge(res.getInt("age"));
                 // 将数据存入集合
                 list.add(employee);
            }
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             try {
                 if (con != null) {
                    con.close();
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
             try {
                 if (st != null) {
                     st.close();
                }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
             try {
                if (res != null) {
                     res.close();
                 }
             } catch (SQLException e) {
                e.printStackTrace();
             }
         }
     }









1.7 JDBC 工具类抽取



  在上节的CRUD测试中发现,除了操作sql语句的过程不一致,其他大部分代码大致都一样。
  为了解决重复代码编写的问题,本节所要讲解的是可以抽取一个工具类来简化我们的程序开发过程。
1.7.1工具类抽取
步骤一:
    创建一个utils包并在该包下创建一个工具类,如图1-20所示。

1-20 创建一个JdbcUtils工具类

步骤二:抽取工具类
【文件1-13】JdbcUtils.java
[Java] 纯文本查看 复制代码
1.     public class JdbcUtils {
2.      // 数据库驱动只需要加载一次
3.      // static静态代码块在类加载的时候会执行,并且只执行一次
4.      static {
5.          try {
6.              Class.forName("com.mysql.jdbc.Driver");
7.          } catch(ClassNotFoundException e) {
8.              e.printStackTrace();
9.          }
10.     }
11.  
12.     // 对外提供获取连接的方法
13.     // 异常可以直接抛出,因为在调用该方法处还会执行try-catch.
14.     public static Connection getConnection() throws SQLException {
15.         String url ="jdbc:mysql:///jdbcDemo";
16.         String user ="root";
17.         String password ="root";
18.         Connection con =DriverManager.getConnection(url, user, password);
19.         return con;
20.     }
21.     
22.     //释放资源方法2
23.     //其他增删改释放资源
24.     public static void release(Connection con, Statement st) {
25.         try {
26.             if (st != null) {
27.                 st.close();
28.             }
29.         } catch (SQLException e){
30.             e.printStackTrace();
31.         }
32.         try {
33.             if (con != null) {
34.                 con.close();
35.             }
36.         } catch (SQLException e){
37.             e.printStackTrace();
38.         }
39.     }
40.     //释放资源方法1
41.     // 查询的时候释放资源
42.     public static void release(Connection con, Statement st,ResultSet res) {
43.         try {
44.             if (res != null) {
45.                 res.close();
46.             }
47.         } catch (SQLException e){
48.             e.printStackTrace();
49.         }
50.         try {
51.             if (st != null) {
52.                 st.close();
53.             }
54.         } catch (SQLException e){
55.             e.printStackTrace();
56.         }
57.         try {
58.             if (con != null) {
59.                 con.close();
60.             }
61.         } catch (SQLException e){
62.             e.printStackTrace();
63.         }
64.     }
注意:
    在释放资源的时候,如果没有使用到ResultSet结果集,那么也可以使用JdbcUtils.release(con, st,null);
    但是这样写不符合编程规范,并且如果在其他人调用该方法的时候,就会对于方法中为什么要传递一个null存在疑惑,因此可以编写一个重载的方法来进行区分。

1.7.2 工具类测试
使用自定义的工具类测试效果
【文件1-14】使用自定义工具类测试释放资源方法
[Java] 纯文本查看 复制代码
1.  @Test
2.      public void select2() {
3.          Connection con = null;
4.          Statement st = null;
5.          ResultSet res = null;
6.          try {
7.              con= JdbcUtil.getConnection();
8.              String sql = "select * from employee";
9.              st = con.createStatement();
10.             res = st.executeQuery(sql);
11.             List list = new ArrayList();
12.             // 处理结果集
13.             while (res.next()) {
14.                 Employee emp = newEmployee();
15.                 emp.setId(res.getInt(1));
16.                 emp.setName(res.getString(2));
17.                 ;
18.                 emp.setAge(res.getInt(3));
19.                 // 将对象存入集合
20.                 list.add(emp);
21.             }
22.             System.out.println(list);
23.         } catch (Exception e) {
24.             e.printStackTrace();
25.         } finally {
26.             JdbcUtil.release(con, st, res);
27.         }
28.     }



1.7.3 工具类优化
步骤一:创建jdbc.properties文件,如图1-21所示。

图1-21创建jdbc.properties文件

步骤二:编写内容
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///jdbcDemo
user=root
password=root
注意:每行代码之间以及代码的前后端都不要出现空格。

步骤三:修改工具类
【文件1-15】修改后的JdbcUtils.java
[Java] 纯文本查看 复制代码
1.  public class JdbcUtils {
2.      static String url;
3.      static String user;
4.      static String password;
5.      static String driverClass;
6.      // 数据库驱动只需要加载一次
7.      // static静态代码块在类加载的时候会执行,并且只执行一次
8.      static {
9.          try {
10.             Properties pro = new Properties();
11.             InputStream inputStream = newFileInputStream("src/jdbc.properties");
12.             //加载properties文件
13.             pro.load(inputStream);
14.             //读取properties文件中的数据
15.             driverClass = pro.getProperty("driverClass");
16.             url=pro.getProperty("url");
17.             user=pro.getProperty("user");
18.             password=pro.getProperty("password");
19.             Class.forName(driverClass);
20.         } catch (Exception e) {
21.             e.printStackTrace();
22.         }
23.     }
24.  
25.     // 对外提供获取连接的方法
26.     // 异常可以直接抛出,因为在调用该方法处还会执行try-catch.
27.     public static Connection getConnection() throws SQLException {
28.         Connection con =DriverManager.getConnection(url, user, password);
29.         return con;
30.     }
31.  
32.     //其他增删改释放资源
33.     public static void release (Connection con, Statement st){
34.         try {
35.             if (con != null) {
36.                 con.close();
37.             }
38.         } catch (SQLException e){
39.             e.printStackTrace();
40.         }
41.         try {
42.             if (st!=null) {
43.                 st.close();
44.             }
45.         } catch (SQLException e){
46.             e.printStackTrace();
47.         }
48.     }
49.     
50.     // 查询的时候释放资源
51.     public static void release(Connection con, Statement st,ResultSet res) {
52.         try {
53.             if (con != null) {
54.                 con.close();
55.             }
56.         } catch (SQLException e){
57.             e.printStackTrace();
58.         }
59.         try {
60.             if (st!=null) {
61.                 st.close();
62.             }
63.         } catch (SQLException e){
64.             e.printStackTrace();
65.         }
66.         try {
67.             if (res!=null) {
68.                 res.close();
69.             }
70.         } catch (SQLException e){
71.             e.printStackTrace();
72.         }
73.     }
74. }




1.8 全天总结



一、JDBC介绍:sun公司为了简化和统一数据库的操作,制定的一套操作数据库的规范,简称JDBC。
二、jdbc API常用类和接口:
1、DriverManager: 加载数据库驱动

2、Connection: 建立数据库连接
通过DriverManager.getConnection(url,user,password)获取

3、Statement:执行sql语句
通过connection.createStatement()获取

4、ResultSet:获取数据
通过statement.executeQuery(sql)获取

三、资源释放:数据库资源有限,需要适时释放。
四、工具类的抽取。




0 个回复

您需要登录后才可以回帖 登录 | 加入黑马