WEB-JDBC

来源:互联网 发布:淘宝买保险可靠吗 编辑:程序博客网 时间:2024/05/02 02:59

WEB- JDBC

1.1      案例一:使用JDBC完成CRUD的操作:

1.1.1    需求:

对分类管理使用JDBC进行CRUD的操作.

1.1.2    分析:

1.1.2.1  技术分析:

【JDBC的概述】

Ø  JDBC:Java DataBase Connectivity Java数据库的连接.

* 是SUN公司统一提供的一套接口规范(JDBC).各个数据库生产商提供实现.

Ø  驱动:两个硬件设备之间通信的桥梁.

【JDBC的开发步骤】

Ø  注册驱动:

Ø  获得连接:

Ø  获得执行SQL语句对象:

Ø  释放资源:

1.1.2.2  步骤分析:

【步骤一】:创建一个Java项目.

【步骤二】:引入mysql的驱动包.

【步骤三】:编写代码.

【步骤四】:完成CRUD的操作:

1.1.3    代码实现:

工具类的抽取:

public class JDBCUtils {

 

    /**

     * 注册驱动的方法

     */

    publicstatic void loadDriver(){

        try {

            Class.forName("com.mysql.jdbc.Driver");

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

    /**

     * 获得连接的方法

     */

    publicstatic Connection getConnection(){

       

        Connection conn = null;

        try {

            loadDriver();

            conn= DriverManager.getConnection("jdbc:mysql:///web_07","root", "123");

        } catch (SQLException e) {

            e.printStackTrace();

        }

        return conn;

    }

   

    /**

     * 释放资源的方法

     */

    publicstatic 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;

        }

    }

   

    publicstatic 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 {

    privatestatic final String driverClass;

    privatestatic final String url;

    privatestatic final String username;

    privatestatic final String password;

   

 

    static {

        Properties properties = null;

        // 读取属性文件:使用Java中Properties的对象.

        try{

            InputStreamis = 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");

    }

   

    /**

     * 注册驱动的方法

     */

    publicstatic void loadDriver(){

        try {

            Class.forName(driverClass);

        } catch (ClassNotFoundException e) {

            e.printStackTrace();

        }

    }

    /**

     * 获得连接的方法

     */

    publicstatic Connection getConnection(){

       

        Connection conn = null;

        try {

            loadDriver();

            conn= DriverManager.getConnection(url, username, password);

        } catch (SQLException e) {

            e.printStackTrace();

        }

        return conn;

    }

   

    /**

     * 释放资源的方法

     */

    publicstatic 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;

        }

    }

   

    publicstatic 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.1.4    总结:

1.1.4.1  JDBC的API:

【Connection】

Ø  创建执行SQL的对象:

Ø  进行事务管理:

【Statement】

Ø  执行SQL语句:

Ø  执行批处理:

【ResultSet】

Ø  获得结果集中的数据:

* getXXX(int idx);

     *select cname,cid from category;

* getXXX(String name); 

Ø  默认情况下:next();

* 正常的情况下结果集只能向下的.

1.2      案例二:使用连接池改造JDBC的工具类:

1.2.1    需求:

传统JDBC的操作,对连接的对象销毁不是特别好.每次创建和销毁连接都是需要花费时间.可以使用连接池优化的程序.

* 在程序开始的时候,可以创建几个连接,将连接放入到连接池中.用户使用连接的时候,可以从连接池中进行获取.用完之后,可以将连接归还连接池.

1.2.2    分析:

1.2.2.1  技术分析:

【自定义连接池】(了解)

* SUN公司提供了一个连接池的接口.(javax.sql.DataSource).

* 定义一个连接池:实现这个接口.

* 使用List集合存放多个连接的对象.

 

【自定义连接池的代码】

public class MyDataSource implements DataSource{

    // 创建一个List集合用于存放多个连接对象.

    privateList<Connection> list = new ArrayList<Connection>();

    // 在程序开始的时候,初始化几个连接,将连接存放到list中.

    publicMyDataSource() {

        // 初始化3个连接:

        for(int i=1;i<=3;i++){

            Connectionconn = JDBCUtils.getConnection();

            list.add(conn);

        }

    }

   

    @Override

    // 获得连接的方法:

    publicConnection getConnection() throws SQLException {

        if(list.size() <= 0){

            for(inti=1;i<=3;i++){

                Connection conn = JDBCUtils.getConnection();

                list.add(conn);

            }  

        }

        Connection conn = list.remove(0);

        return conn;

    }

   

    // 归还连接的方法:

    publicvoid addBack(Connection conn){

        list.add(conn);

    }

...

}

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

Ø  问题?

1.如果使用自定义连接池,那么需要额外记住自定义连接池中的API.

2.能不能使用面向接口的编程方式.

Ø  解决:

不额外提供API方法,就可以解决上述两个问题!!!

能不能还调用Connection的close方法.能不能增强Connection的close方法,原有的销毁变为归还!!!

Ø  如何增强Connection的close方法:

* 增强一个Java类中的某个方法有几种方式???

    * 一种方式:继承的方式.

        * 能够控制这个类的构造的时候,才可以使用继承.

 

    * 二种方式:装饰者模式方式.

        * 包装对象和被包装的对象都要实现相同的接口.

        * 包装的对象中需要获得到被包装对象的引用.

        ***** 缺点:如果接口的方法比较多,增强其中的某个方法.其他的功能的方法需要原有调用.

 

    * 三种方式:动态代理的方式.

        * 被增强的对象实现接口就可以.

【继承和装饰者的案例】

/**

 * 继承的方式增强一个类中某个方法:

 */

class Man{

    publicvoid run(){

        System.out.println("跑....");

    }

}

 

class SuperMan extends Man{

    publicvoid run(){

        // super.run();

        System.out.println("飞....");

    }

}

 

/**

 * 使用装饰者的方式完成类的方法的增强

 */

interface Waiter{

    publicvoid server();

}

 

class Waiteress implements Waiter{

 

    @Override

    publicvoid server() {

        System.out.println("服务...");

    }

   

}

 

class WaiteressWrapper implements Waiter{

    privateWaiter waiter;

 

    publicWaiteressWrapper(Waiter waiter) {

    this.waiter = waiter;

    }

   

    @Override

    publicvoid server() {

        System.out.println("微笑...");

        // this.waiter.server();

       

    }

   

}

【使用装饰者模式增强Connection的close方法】

public class MyConnection implements Connection{

 

    privateConnection conn;

    privateList<Connection> list;

 

    publicMyConnection(Connection conn,List<Connection> list) {

        this.conn = conn;

        this.list = list;

    }

 

 

    @Override

    publicvoid close() throws SQLException {

        list.add(conn);

    }
     ...

}

 

连接池的getConnection方法:
    @Override

    // 获得连接的方法:

    publicConnection getConnection() throws SQLException {

        if(list.size() <= 0){

            for(inti=1;i<=3;i++){

                Connection conn = JDBCUtils.getConnection();

                list.add(conn);

            }  

        }

        Connection conn = list.remove(0);

        MyConnectionmyConn = new MyConnection(conn, list);

        return myConn;

    }

【常见的开源的数据库连接池】:

Ø  DBCP:

DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。

Ø  C3P0:

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。

Ø  Tomcat内置连接池:

【DBCP连接池的使用】

第一步:引入DBCP连接池的jar包.

第二步:编写DBCP代码:

    * 手动设置参数:

    * 配置文件设置参数:

【DBCP连接池的使用】

    @Test

    /**

     * 手动方式:

     */

    publicvoid demo1(){

        Connection conn = null;

        PreparedStatement stmt = null;

        ResultSet rs = null;

        BasicDataSource dataSource = newBasicDataSource();

        dataSource.setDriverClassName("com.mysql.jdbc.Driver");

        dataSource.setUrl("jdbc:mysql:///web_07");

        dataSource.setUsername("root");

        dataSource.setPassword("123");

        try{

            // 获得连接:

            conn= dataSource.getConnection();

            // 编写SQL:

            Stringsql = "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

    /**

     * 配置文件方式:

     */

    publicvoid demo2(){

        Connection conn = null;

        PreparedStatement stmt = null;

        ResultSet rs = null;

        Properties properties = new Properties();

       

        try{

            properties.load(newFileInputStream("src/dbcpconfig.properties"));

            DataSourcedataSource = BasicDataSourceFactory.createDataSource(properties);

            // 获得连接:

            conn= dataSource.getConnection();

            // 编写SQL:

            Stringsql = "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 {

    privatestatic final ComboPooledDataSource DATA_SOURCE =new ComboPooledDataSource();

    /**

     * 获得连接的方法

     */

    publicstatic Connection getConnection(){

        Connection conn = null;

        try {

            conn= DATA_SOURCE.getConnection();

        } catch (SQLException e) {

            //TODO Auto-generated catch block

            e.printStackTrace();

        }

        return conn;

    }

...
}

1.3      案例三:手动抽取一个DBUtils的工具类:

1.3.1    需求:

每次进行JDBC的CURD的操作的时候,有很多的代码都是相似的.可以不可以抽取工具类.完成一些通用性的代码?

1.3.2    分析:

1.3.2.1  技术分析:

【JDBC的元数据MataData】(了解)-- 编写通用性较高的代码.

Ø  DatabaseMetaData:获得数据库连接的信息,获得数据库的表的信息.

* 获得数据库元数据:Connection中getMetaData();

 

Ø  ParameterMetaData:获得SQL中的参数的个数及类型.

* 获得参数元数据:PreparedStatement中getParameterMetaData()

 

Ø  ResultSetMetaData:获得结果集中的列名及列的类型.

* 获得结果集元数据:ResultSet中getMeta()

【元数据的使用】

    @Test

    /**

     * 数据库元数据

     */

    publicvoid demo1(){

        Connection conn = null;

        conn = JDBCUtils2.getConnection();

        // 获得数据库元数据:

        try {

            DatabaseMetaDatametaData = conn.getMetaData();

            System.out.println("获得驱动名称:"+metaData.getDriverName());

            System.out.println("获得驱动URL:"+metaData.getURL());

            System.out.println("获得用户名:"+metaData.getUserName());

           

            // 获得表中的主键:

            ResultSetrs = metaData.getPrimaryKeys(null, null, "category");

            if(rs.next()){

                String name =rs.getString("COLUMN_NAME");

                System.out.println(name);

            }

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

   

    @Test

    /**

     * 参数元数据:

     */

    publicvoid demo2(){

        Connection conn = null;

        PreparedStatement stmt = null;

        try{

            conn= JDBCUtils2.getConnection();

            Stringsql = "update category set cname = ? where cid = ?";

            stmt= conn.prepareStatement(sql);

            ParameterMetaDatametaData = stmt.getParameterMetaData();

            intcount = metaData.getParameterCount();

            System.out.println(count);

        }catch(Exception e){

           

        }

    }

   

    @Test

    /**

     * 结果集元数据:

     */

    publicvoid demo3(){

        Connection conn = null;

        PreparedStatement stmt = null;

        ResultSet rs = null;

        try{

            conn= JDBCUtils2.getConnection();

            Stringsql = "select * from category";

            stmt= conn.prepareStatement(sql);

            rs= stmt.executeQuery();

           

            ResultSetMetaDatametaData = rs.getMetaData();

            intcount = metaData.getColumnCount();

            for(inti = 1;i<=count ;i++){

                String name = metaData.getColumnName(i);

               

                String type = metaData.getColumnTypeName(i);

                System.out.println(name+type);

            }

        }catch(Exception e){

           

        }

    }

 

 

0 0
原创粉丝点击