zoukankan      html  css  js  c++  java
  • JAVA基础JDBC二(常用的开源工具)


    一、连接池

      在实际的开发应用中,我们常常会对数据库进行大量的高并发的访问,而最原始的连接和操作方式并不能满足这种大量的访问
    ,程序员为了追求更方便、更快捷、更科学安全的开发。第三方的工具类和Dao层的框架就应运而生了。DBCP连接池、和C3P0连
    接池就是2个常见的开源数据库连接池。
      在与数据库进行交互的过程中,获得连接”和“释放资源”是非常消耗系统资源的两个过程,为了解决此类性能问题,通常情况
    我们采用连接池技术,来共享连接Connection。这样我们就不需要每次都创建连接、释放连接了,这些操作都交给了连接池。用的
    时候从连接池里拿出来,用完了在给他放回去,下次使用时还可以接着用。

      同数据库的链接规范(JDBC)一样,java为数据库连接池也提供了一套规范(接口)- javax.sql.DataSource,各个厂商需要
    让自己的连接池实现这个接口。这样就方便了应用程序的扩展和我们的使用。

    (一)DBCP连接池

      DBCP连接池他是一个开源的连接池,属于Apache家族的一员,为Tomcat的内置连接池(自己的土,自己的地...)
    1、导入炸包
      使用第三方工具类的第一件事就是导入jar包,然后Build Patch一下,为了方便jar包的管理(另一方面满足于强迫症患者的
    整理欲望)一般都在工程下新建一个lib文件夹用来存放炸包。
      需要导入的jar包:
      * commons-dbcp-1.4.jar
      * commons-pool-1.5.6.jar

    2、DBCP连接池的使用

      连接数据库的操作是一个频繁使用,代码重复的操作,可以将其抽取成一个工具类。
      Java为数据库连接池也提供了一套规范接口:DataSource,它是java中提供的连接池,作为 DriverManager 工具的替代项。
    而DBCP包则提供了DataSource接口的实现类 - BasicDataSource类。


      栗子:

    public class JdbcUtils {
    //定义一个连接池
    private static BasicDataSource bd = new BasicDataSource();
    //工具类,私有他的无参构造
    private JdbcUtils() {
    super();
    }
    //使用静态代码块进行连接池的属性配置 
    //静态代码块是随着类的加载而加载的且只加载一次(节省资源)
    static {
    /*
    * 必须设置的项
    */
    //设置mySQL的驱动
    bd.setDriverClassName("com.mysql.jdbc.Driver");
    //设置要连接数据库的URL
    bd.setUrl("jdbc:mysql://localhost:3306/mydb");
    //设置用户名
    bd.setUsername("root");
    //设置数据库密码
    bd.setPassword("root");
    /*
    * 选择设置的项,不设置的话会有默认值跟着
    */
    //初始化连接数
    bd.setInitialSize(10);
    //最大连接数
    bd.setMaxActive(15);
    //最大空闲连接数
    bd.setMaxIdle(6);
    //最小空闲连接数
    bd.setMinIdle(3);
    }
    /**
    * 获取连接池对象
    * @return bd 连接池
    */
    public static DataSource getDataSource() {
    return bd;
    }
    }

    (二)C3P0连接池

      C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有
    Hibernate,Spring等。(百度百科)
      C3P0连接池有自动回收空闲连接的功能,而DBCP没有自动回收空闲连接的功能。
    1、导入jar包
      同DBCP的使用步骤一样,第一步要导入相关的jar包:
      c3p0-0.9.1.2.jar
    2、C3P0连接池的使用
      通过查看帮助文档(doc目录下的index.html文件里边有个快速入门)发现C3P0可以通过手动或者配置文件的方式使用。


        * 通过手动进行配置

    public static void main(String[] args) throws Exception {
    // 获得C3P0连接池对象
    ComboPooledDataSource source = new ComboPooledDataSource();
    // 设置驱动
    source.setDriverClass("com.mysql.jdbc.Driver");
    // 设置连接库的路径
    source.setJdbcUrl("jdbc:mysql:///mydb");
    // 设置用户名
    source.setUser("root");
    // 设置密码
    source.setPassword("root");
    // 通过连接池创建一个QueryRunner对象
    QueryRunner runner = new QueryRunner(source);
    // 测试
    String sql = "SELECT * FROM users";
    List<Object[]> list = runner.query(sql, new ArrayListHandler());
    for (Object[] objects : list) {
    for (Object object : objects) {
    System.out.print(object + " ");
    }
    System.out.println();
    }
    }

       

      * 通过配置文件进行配置
      C3P0连接池支持.xml和属性文件.properties的文件配置,当然了他对其配置文件的名字和里边的文件也有一定的要求(搞一个别
    的名他就不认识了),XML配置文件的名字一定是c3p0-config.xml,属性配置文件的名字一定是c3p0.properties.默认情况下C3P0连接
    池就会找类加载路径下的c3p0-config.xml进行解析。c3p0-config.xml配置文件除了一些链接数据库的一些必要属性外也可以配置一些
    连接池其他的属性:最小池里的数量,最大池里的数量等。具体的属性配置可以百度或者阅读开发文档。


      栗子:
      * c3p0-config.xml配置文件

    <c3p0-config>
    <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql:///mydb</property>
    <property name="user">root</property>
    <property name="password">root</property>
    </default-config>
    </c3p0-config>


      * C3P0的工具类

    public class C3p0Utils {
    // 定义一个c3p0连接池
    private static ComboPooledDataSource source;
    // 定义一个连接对象
    private static Connection connection;
    
    private C3p0Utils() {
    super();
    }
    
    static {
    // 初始化连接池
    source = new ComboPooledDataSource();
    try {
    // 获得一个连接
    connection = source.getConnection();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    
    public static Connection getConnection() {
    return connection;
    }
    }

      通过代码演示可以看到通过配置文件的方式还是非常方便的,后期维护的话只要改相关的配置文件就可以了,xml作为配置文件便于
    我们的阅读,所以推荐使用c3p0-config.xml配置文件。

    二、DBUtils工具类

      使用原生的JDBC进行开发,你会发现代码冗余过多,使用麻烦,极度不爽。而工具类的出现就是为了简化我们的开发。DBUtils是
    apache commons组件一个成员,使用DBUtils工具类首先要导入相关的jar包 - commons-dbutils-1.6.jar。
      DBUtils封装并简化了JDBC操作,减少了相关代码的书写、它一共有3个核心的部分组成:
      * QueryRunner提供对sql语句操作的API。
      * ResultSetHandler接口提供了执行完sql语句后怎样封装结果集。
      * DbUtils工具类提供了关闭相关资源和处理事物的方法。
    1、QueryRunner核心类
      * new QueryRunner() ,无参构造,使用无参构造时,调用update,query方法时需要传入Connection对象
      * update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作。
      * query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作。
    ------------------------------------------------------------------------------------------------------------------------------------------------------------------
      * new QueryRunner(DataSource ds) ,带参构造,使用带参构造时调用update,query方法无需要传入Connection对象
      * update(String sql, Object... params) ,用来完成表数据的增加、删除、更新操作。
      * query(String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作。


      栗子:
      * 无参构造的update方法

    /**
    * 增加操作
    * @throws SQLException
    */
    private static void method01() throws SQLException {
    // 通过工具类获得连接
    Connection connection = JdbcUtilsConfig.getConnection();
    // 获得QueryRunner对象
    QueryRunner runner = new QueryRunner();
    // 编写sql语句
    String insert = "INSERT INTO sort(sname,sprice,sdesc) VALUES(?,?,?)";
    // 执行update方法,也可以将数据存到Object数组里然后传入数组,返回值为影响的行数
    int update = runner.update(connection, insert, "家具", 1000, "很好用");
    System.out.println(update);
    }
    
    /**
    * 更新操作
    * 
    * @throws SQLException
    */
    private static void method02() throws SQLException {
    // 通过工具类获得连接
    Connection connection = JdbcUtilsConfig.getConnection();
    // 获得QueryRunner对象
    QueryRunner runner = new QueryRunner();
    // 编写sql语句
    String s = "UPDATE sort SET sname=?,sprice=?,sdesc=? WHERE sid=4";
    // 执行update方法
    runner.update(connection, s, "花卉", 100, "买给你爱的人");
    //安静的关闭
    DbUtils.closeQuietly(connection);
    }
    
    /**
    * 删除操作
    * 
    * @throws SQLException
    */
    private static void method03() throws SQLException {
    // 通过工具类获得连接
    Connection connection = JdbcUtilsConfig.getConnection();
    // 创建一个QueryRunner对象,用来完成SQL语句的执行
    QueryRunner qr = new QueryRunner();
    // 执行SQL语句
    String sql = "DELETE FROM zhangwu WHERE name = ?";
    Object[] params = { "股票收入" };
    int line = qr.update(connection, sql, params);
    // 结果集的处理,影响的行数
    System.out.println("line=" + line);
    }

      * 有参构造的query方法

    public static void main(String[] args) throws Exception {
    // 通过工具类获得连接池对象
    DataSource dataSource = C3p0Utils.getDataSource();
    // 通过连接池创建一个QueryRunner对象
    QueryRunner runner = new QueryRunner(dataSource);
    // 编写sql语句
    String sql = "SELECT * FROM users";
    // 执行query方法传入ArrayListHandler返回集合
    List<Object[]> list = runner.query(sql, new ArrayListHandler());
    // 遍历集合
    for (Object[] objects : list) {
    for (Object object : objects) {
    System.out.print(object + " ");
    }
    System.out.println();
    }
    }

    2、ResultSetHandler结果集处理类
      * ArrayHandler 将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录的值。
      * ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。
      * BeanHandler 将结果集中第一条记录封装到一个指定的javaBean中。
      * BeanListHandler 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中。
      * ColumnListHandler 将结果集中指定的列的字段值,封装到一个List集合中。
      * ScalarHandler 它是用于单数据。例如sql中的聚合函数SUM(),Count()等。
      * MapHandler 将结果集第一行封装到Map集合中,Key 列名, Value 该列数据,可以配合工具类
    BeanUtils.populate(Bean bean, Map map);一起使用方便数据的封装。
      * MapListHandler 将结果集第一行封装到Map集合中,Key 列名, Value 该列数据,Map集合存储到List集合。

      常用Handler举例:
      *BeanHandler的栗子:

    /**
         * 商品详情查询
         * 
         * @param pid
         * @return product
         * @throws Exception
         */
        @Override
        public Product findByPid(String pid) throws Exception {
            //通过连接池创建QueryRunner对象
            QueryRunner queryRunner = new QueryRunner(C3p0Utils.getDataSourse());
            //根据传入的商品ID编写sql语句
            String sql = "SELECT * FROM product WHERE pid=?";
            //传入sql语句和BeanHandler结果集返回商品Bean
            Product product = queryRunner.query(sql, new BeanHandler<Product>(Product.class), pid);
            return product;
        }

      * ScalarHandler的栗子:

        /**
         * 商品总数查询
         * @return totalCount
         * @throws Exception
         */
        @Override
        public Integer findAdmintotalCount() throws Exception {
            QueryRunner queryRunner = new QueryRunner(C3p0Utils.getDataSourse());
            //pflag字段为是否下架
            String sql = "SELECT COUNT(*) FROM product WHERE pflag=?";
            Long totalCount = (Long) queryRunner.query(sql, new ScalarHandler(),Product.UN_FLAG);
            //将Long转换成Integer类型返回
            return totalCount.intValue();
        }

      * BeanListHandler的栗子:

    /**
         * 根据类别查询商品
         * 
         * @param cid 商品ID
         * @param beginPage 起始页
         * @param pageSize 每页显示的条数
         * @return list
         * @throws Exception
         */
        @Override
        public List<Product> findPageByCid(String cid, Integer beginPage, Integer pageSize) throws Exception {
            QueryRunner queryRunner = new QueryRunner(C3p0Utils.getDataSourse());
            //分页查询
            String sql = "SELECT * FROM product WHERE cid=? AND pflag=? LIMIT ?,?";
            //BeanListHandler里泛型要写你查询实体Bean类型,传入参数为Bean.class
            List<Product> list = queryRunner.query(sql, new BeanListHandler<Product>(Product.class), cid, Product.UN_FLAG,
                    beginPage, pageSize);
            //返回结合
            return list;
        }

    3、DbUtils工具类
      此类提供了关闭相关资源和处理事物的方法:
      * DbUtils.closeQuietly() 安静的关闭资源。

    我们在键盘上留下的余温,也将随时代传递到更远的将来~
  • 相关阅读:
    linux如何查看端口或服务被占用情况
    linux网络查看及配置相关命令
    linux查看程序运行相关命令
    shell脚本编写一个用真实用户去访问的vsftpd服务器
    shell脚本监控CPU和内存利用率
    小白的个人技能树(基于自动化软件测试开发实习和软件开发实习)
    MySQL 8.0.12 基于Windows 安装教程(超级详细)
    C语言 0x7fffffff是多少(也就是INT_MAX,首位是 0,其余都是1,f代表1111)
    数通知识点
    数据结构之算法基础
  • 原文地址:https://www.cnblogs.com/0813lichenyu/p/8007522.html
Copyright © 2011-2022 走看看