博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第7章WEB07- JDBC篇
阅读量:6989 次
发布时间:2019-06-27

本文共 11007 字,大约阅读时间需要 36 分钟。

今日任务

Ø 使用JDBC完成对分类表的CRUD的操作(JDBC的回顾)
Ø 使用DBCP,C3P0连接池完成基本数据库的操作(抽取工具类)
Ø 使用元数据抽取一个JDBC的框架.
Ø 能够使用DBUtils完成CRUD的操作
教学导航
教学目标
掌握DBCP和C3P0连接池的使用并掌握连接池的原理.
掌握使用元数据抽取基本的JDBC通用方法的思想.
能够使用DBUtils完成基本的CRUD的操作
教学方法
案例驱动法
1.1 上次课内容回顾:
MYSQL:

  • 数据库的概述:指的是一个文件系统,这个文件系统通过SQL访问.
  • 关系型数据库:数据库中存放的是实体之间的关系.
  • 常见的关系型数据库:MYSQL,Oracle,DB2,SQLServer,SQLite,SyBase
    MYSQL的使用:
  • 安装和卸载:
  • 存储结构:
    • 一台电脑安装了MYSQL的服务器软件,那么这台电脑称为是MYSQL数据库服务器.一个软件创建一个数据库,有一个实体类创建一个表与之对应,实体的实例对象通常使用表中的记录与之对应.
      SQL:结构化查询语言:
  • SQL的分类:
    • DDL:数据定义语言.create,alter,drop...
    • DML:数据操纵语言.update,insert,delete
    • DCL:数据控制语言.grant,if,...
    • DQL:数据查询语言.select
  • SQL对数据库CRUD:
  • SQL对数据库中表CRUD的操作
  • SQL对数据库中表的记录的操作:
    • update,insert,delete
    • Select ... From ... Where ... Group by ... Having ... Order by ...;
  • SQL的多表设计:
    • 一对多:在多的一方创建外键执向一的一方的主键.
    • 多对多:创建中间表,至少两个字段作为外键执向多对多双方的主键.
    • 一对一:唯一外键对应,主键对应.
  • SQL的多表的查询:
    • 连接查询:
      • 交叉连接:
      • 内连接:
        • 显式内连接:inner join
        • 隐式内连接:
      • 外连接
        • 左外连接:left outer join
        • 右外连接:right outer join
    • 子查询:
      1.2 案例一:使用JDBC完成CRUD的操作:1.2.1 需求:
      对分类管理使用JDBC进行CRUD的操作.
      1.2.2 分析:
      1.2.2.1 技术分析:
      【JDBC的概述】
      Ø JDBC:Java DataBase Connectivity Java数据库的连接.
  • 是SUN公司统一提供的一套接口规范(JDBC).各个数据库生产商提供实现.
    Ø 驱动:两个硬件设备之间通信的桥梁.
    【JDBC的开发步骤】
    Ø 注册驱动:
    Ø 获得连接:
    Ø 获得执行SQL语句对象:
    Ø 释放资源:
    1.2.2.2 步骤分析:
    【步骤一】:创建一个Java项目.
    【步骤二】:引入mysql的驱动包.
    【步骤三】:编写代码.
    【步骤四】:完成CRUD的操作:
    1.2.3 代码实现:
工具类的抽取:public class JDBCUtils {/** * 注册驱动的方法 */public static void loadDriver(){try {Class.forName("com.mysql.jdbc.Driver");} catch (ClassNotFoundException e) {e.printStackTrace();}}/** * 获得连接的方法 */public static Connection getConnection(){Connection conn = null;try {loadDriver();conn = DriverManager.getConnection("jdbc:mysql:///web_07", "root", "123");} catch (SQLException e) {e.printStackTrace();}return conn;}/** * 释放资源的方法 */public static void release(ResultSet rs,Statement stmt,Connection conn){if (rs != null) {        try {            rs.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        rs = null;    }if (stmt != null) {        try {                stmt.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        stmt = null;    }if (conn != null) {        try {                conn.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        conn = null;    }}public static void release(Statement stmt,Connection conn){if (stmt != null) {        try {                stmt.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        stmt = null;    }if (conn != null) {        try {                conn.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        conn = null;    }}}带有属性文件的工具类的抽取:定义了一个属性文件:public class JDBCUtils {private static final String driverClass;private static final String url;private static final String username;private static final String password;static {Properties properties = null;// 读取属性文件:使用Java中Properties的对象.try{InputStream is = new FileInputStream("src/jdbc.properties");properties = new Properties();properties.load(is);}catch(Exception e){e.printStackTrace();}driverClass = properties.getProperty("driverClass");url = properties.getProperty("url");username = properties.getProperty("username");password = properties.getProperty("password");}/** * 注册驱动的方法 */public static void loadDriver(){try {Class.forName(driverClass);} catch (ClassNotFoundException e) {e.printStackTrace();}}/** * 获得连接的方法 */public static Connection getConnection(){Connection conn = null;try {loadDriver();conn = DriverManager.getConnection(url, username, password);} catch (SQLException e) {e.printStackTrace();}return conn;}/** * 释放资源的方法 */public static void release(ResultSet rs,Statement stmt,Connection conn){if (rs != null) {        try {            rs.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        rs = null;    }if (stmt != null) {        try {                stmt.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        stmt = null;    }if (conn != null) {        try {                conn.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        conn = null;    }}public static void release(Statement stmt,Connection conn){if (stmt != null) {        try {                stmt.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        stmt = null;    }if (conn != null) {        try {                conn.close();        } catch (SQLException e) {                e.printStackTrace();        }        // 垃圾回收尽快回收对象.        conn = null;    }}}

参见JDBCDemo2类:

1.2.4 总结:
1.2.4.1 JDBC的API:
【Connection】
Ø 创建执行SQL的对象:
第7章WEB07- JDBC篇
第7章WEB07- JDBC篇
第7章WEB07- JDBC篇

Ø 进行事务管理:

第7章WEB07- JDBC篇
第7章WEB07- JDBC篇
第7章WEB07- JDBC篇

【Statement】

Ø 执行SQL语句:
第7章WEB07- JDBC篇
第7章WEB07- JDBC篇
第7章WEB07- JDBC篇

Ø 执行批处理:

第7章WEB07- JDBC篇
第7章WEB07- JDBC篇
第7章WEB07- JDBC篇

【ResultSet】

Ø 获得结果集中的数据:

  • getXXX(int idx);
    • select cname,cid from category;
  • getXXX(String name);
    Ø 默认情况下:next();
  • 正常的情况下结果集只能向下的.
    1.3 案例二:使用连接池改造JDBC的工具类:
    1.3.1 需求:
    传统JDBC的操作,对连接的对象销毁不是特别好.每次创建和销毁连接都是需要花费时间.可以使用连接池优化的程序.
  • 在程序开始的时候,可以创建几个连接,将连接放入到连接池中.用户使用连接的时候,可以从连接池中进行获取.用完之后,可以将连接归还连接池.
    1.3.2 分析:
    1.3.2.1 技术分析:
    【自定义连接池】(了解)
  • SUN公司提供了一个连接池的接口.(javax.sql.DataSource).
  • 定义一个连接池:实现这个接口.
  • 使用List集合存放多个连接的对象.
    【自定义连接池的代码】
public class MyDataSource implements DataSource{// 创建一个List集合用于存放多个连接对象.private List
list = new ArrayList
();// 在程序开始的时候,初始化几个连接,将连接存放到list中.public MyDataSource() {// 初始化3个连接:for(int i=1;i<=3;i++){Connection conn = JDBCUtils.getConnection();list.add(conn);}}@Override// 获得连接的方法:public Connection getConnection() throws SQLException {if(list.size() <= 0){for(int i=1;i<=3;i++){Connection conn = JDBCUtils.getConnection();list.add(conn);}}Connection conn = list.remove(0);return conn;}// 归还连接的方法:public void addBack(Connection conn){list.add(conn);}...}

【自定义连接池中问题及如何解决】

Ø 问题?
1.如果使用自定义连接池,那么需要额外记住自定义连接池中的API.
2.能不能使用面向接口的编程方式.
Ø 解决:
不额外提供API方法,就可以解决上述两个问题!!!
能不能还调用Connection的close方法.能不能增强Connection的close方法,原有的销毁变为归还!!!
Ø 如何增强Connection的close方法:

  • 增强一个Java类中的某个方法有几种方式???
    • 一种方式:继承的方式.
      • 能够控制这个类的构造的时候,才可以使用继承.
    • 二种方式:装饰者模式方式.
      • 包装对象和被包装的对象都要实现相同的接口.
      • 包装的对象中需要获得到被包装对象的引用.
        ***** 缺点:如果接口的方法比较多,增强其中的某个方法.其他的功能的方法需要原有调用.
    • 三种方式:动态代理的方式.
      • 被增强的对象实现接口就可以.
        【继承和装饰者的案例】
        /**
  • 继承的方式增强一个类中某个方法:
    */
    class Man{
    public void run(){
    System.out.println("跑....");
    }
    }
    class SuperMan extends Man{
    public void run(){
    // super.run();
    System.out.println("飞....");
    }
    }
    /**
  • 使用装饰者的方式完成类的方法的增强
    */
    interface Waiter{
    public void server();
    }
    class Waiteress implements Waiter{

}

class WaiteressWrapper implements Waiter{
private Waiter waiter;
public WaiteressWrapper(Waiter waiter) {
this.waiter = waiter;
}

@Override    public void server() {            System.out.println("微笑...");            // this.waiter.server();    }

}

【使用装饰者模式增强Connection的close方法】
public class MyConnection implements Connection{
private Connection conn;
private List<Connection> list;
public MyConnection(Connection conn,List<Connection> list) {
this.conn = conn;
this.list = list;

  • 手动设置参数:
  • 配置文件设置参数:

    • 手动方式:

      /
      public void demo1(){
      Connection conn = null;
      PreparedStatement stmt = null;
      ResultSet rs = null;
      BasicDataSource dataSource = new BasicDataSource();
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql:///web_07");
      dataSource.setUsername("root");
      dataSource.setPassword("123");
      try{
      // 获得连接:
      conn = dataSource.getConnection();
      // 编写SQL:
      String sql = "select
      from category";
      // 预编译SQL:
      stmt = conn.prepareStatement(sql);
      // 执行SQL:
      rs = stmt.executeQuery();
      while(rs.next()){
      System.out.println(rs.getInt("cid")+" "+rs.getString("cname"));
      }
      }catch(Exception e){
      e.printStackTrace();
      }finally{
      JDBCUtils.release(rs,stmt, conn);
      }
      }

      @Test

      /**

    • 配置文件方式:

      */
      public void demo2(){
      Connection conn = null;
      PreparedStatement stmt = null;
      ResultSet rs = null;
      Properties properties = new Properties();

      try{            properties.load(new FileInputStream("src/dbcpconfig.properties"));            DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);            // 获得连接:            conn = dataSource.getConnection();            // 编写SQL:            String sql = "select * from category";            // 预编译SQL:            stmt = conn.prepareStatement(sql);            // 执行SQL:            rs = stmt.executeQuery();            while(rs.next()){                    System.out.println(rs.getInt("cid")+"   "+rs.getString("cname"));            }    }catch(Exception e){            e.printStackTrace();    }finally{            JDBCUtils.release(rs,stmt, conn);    }

      }

      【C3P0连接池的使用】
      第一步:引入C3P0连接池的jar包.
      第二步:编写代码:

      • 手动设置参数:
      • 配置文件设置参数:
        【C3P0改造工具类】
        public class JDBCUtils2 {
        private static final ComboPooledDataSource DATA_SOURCE =new ComboPooledDataSource();
        /**
    • 获得连接的方法
      */
      public static Connection getConnection(){
      Connection conn = null;
      try {
      conn = DATA_SOURCE.getConnection();
      } catch (SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      return conn;
      }
      ...
      }
      1.4 案例三:手动抽取一个DBUtils的工具类:
      1.4.1 需求:
      每次进行JDBC的CURD的操作的时候,有很多的代码都是相似的.可以不可以抽取工具类.完成一些通用性的代码?
      1.4.2 分析:
      1.4.2.1 技术分析:
      【JDBC的元数据MataData】(了解)-- 编写通用性较高的代码.
      Ø DatabaseMetaData:获得数据库连接的信息,获得数据库的表的信息.
      • 获得数据库元数据:Connection中getMetaData();
        Ø ParameterMetaData:获得SQL中的参数的个数及类型.
      • 获得参数元数据:PreparedStatement中getParameterMetaData()
        Ø ResultSetMetaData:获得结果集中的列名及列的类型.
      • 获得结果集元数据:ResultSet中getMeta()
    • 数据库元数据

      */
      public void demo1(){
      Connection conn = null;
      conn = JDBCUtils2.getConnection();
      // 获得数据库元数据:
      try {
      DatabaseMetaData metaData = conn.getMetaData();
      System.out.println("获得驱动名称:"+metaData.getDriverName());
      System.out.println("获得驱动URL:"+metaData.getURL());
      System.out.println("获得用户名:"+metaData.getUserName());

      // 获得表中的主键:            ResultSet rs = metaData.getPrimaryKeys(null, null, "category");            if(rs.next()){                    String name = rs.getString("COLUMN_NAME");                    System.out.println(name);            }    } catch (SQLException e) {            e.printStackTrace();    }

      }

      @Test

      /**

    • 参数元数据:

      */
      public void demo2(){
      Connection conn = null;
      PreparedStatement stmt = null;
      try{
      conn = JDBCUtils2.getConnection();
      String sql = "update category set cname = ? where cid = ?";
      stmt = conn.prepareStatement(sql);
      ParameterMetaData metaData = stmt.getParameterMetaData();
      int count = metaData.getParameterCount();
      System.out.println(count);
      }catch(Exception e){

      }

      }

      @Test

      /**

    • 结果集元数据:

      /
      public void demo3(){
      Connection conn = null;
      PreparedStatement stmt = null;
      ResultSet rs = null;
      try{
      conn = JDBCUtils2.getConnection();
      String sql = "select
      from category";
      stmt = conn.prepareStatement(sql);
      rs = stmt.executeQuery();

      ResultSetMetaData metaData = rs.getMetaData();            int count = metaData.getColumnCount();            for(int i = 1;i<=count ;i++){                    String name = metaData.getColumnName(i);                    String type = metaData.getColumnTypeName(i);                    System.out.println(name+type);            }    }catch(Exception e){    }

      }

转载于:https://blog.51cto.com/13587708/2095173

你可能感兴趣的文章
Spring 下基于自定义注解拦截方法调用
查看>>
Eclipse常用快捷键
查看>>
fastdfs + nginx 搭建分布式文件系统(单机模式)
查看>>
PDF文件格式转换器下载免费版
查看>>
详解如何使git将项目上传到github
查看>>
sql多表连接,分组例子
查看>>
Rainbond v5.1.2发布,微服务架构应用便捷管理和交付
查看>>
新浪博客地址
查看>>
JAVA折腾微信公众平台(Token验证)
查看>>
疯狂Spring Cloud连载(28)开发消息微服务
查看>>
提高HTML5 canvas性能的几种方法!
查看>>
golang教程
查看>>
Redis 存储字符串和对象
查看>>
android样式开发遇到的小坑
查看>>
感知器算法
查看>>
课堂笔记-linux服务器架设
查看>>
解决OracleDBConsoleorcl不能启动
查看>>
如何设置exchange连接器传递限制
查看>>
域名转换IP
查看>>
linux系统学习之Linux系统日志及日志分析
查看>>