一、连接池

  在实际的开发应用中,我们常常会对数据库进行大量的高并发的访问,而最原始的连接和操作方式并不能满足这种大量的访问
,程序员为了追求更方便、更快捷、更科学安全的开发。第三方的工具类和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() 安静的关闭资源。

JAVA基础-JDBC二(常用的开源工具)的更多相关文章

  1. JAVA基础(二)—— 常用的类与方法

    JAVA基础(二)-- 常用的类与方法 1 Math类 abs ceil floor 绝对值 大于等于该浮点数的最小整数 小于等于该浮点数的最大整数 max min round 两参数中较大的 两参数 ...

  2. Java基础-Eclipse第三方安装包管理工具之Maven

    Java基础-Eclipse第三方安装包管理工具之Maven 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 玩过Linux的小伙伴应该都知道yum吧,我们只要把搭建好的yum仓库配 ...

  3. ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库

    1.MySQL存储过程   1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if  while)等等 的sql语句   1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...

  4. java 基础知识二 基本类型与运算符

    java  基础知识二 基本类型与运算符 1.标识符 定义:为类.方法.变量起的名称 由大小写字母.数字.下划线(_)和美元符号($)组成,同时不能以数字开头 2.关键字 java语言保留特殊含义或者 ...

  5. java基础(二章)

    java基础(二章) 一,变量 1.变量是内存中的一个标识符号,用于存储数据 2.变量命名规则 l  必须以字母.下划线 _ .美元符号 $ 开头 l  变量中,可以包括数字 l  变量中,不能出现特 ...

  6. Java基础十二--多态是成员的特点

    Java基础十二--多态是成员的特点 一.特点 1,成员变量. 编译和运行都参考等号的左边. 覆盖只发生在函数上,和变量没关系. Fu f = new Zi();System.out.println( ...

  7. java基础-多线程二

    java基础-多线程二 继承thread和实现Runnable的多线程每次都需要经历创建和销毁的过程,频繁的创建和销毁大大影响效率,线程池的诞生就可以很好的解决这一个问题,线程池可以充分的利用线程进行 ...

  8. JAVA基础语法:常用功能符以及循环结构和分支结构(转载)

    3.JAVA基础语法:常用功能符以及循环结构和分支结构 1.常用功能符 注释 ("文字"是被注释的部分) //文字 单行注释 /文字/ 多行注释 算术运算符 + - * / / 整 ...

  9. Java实习生常规技术面试题每日十题Java基础(二)

    目录 1. JAVA 的反射机制的原理. 2.静态嵌套类(Static Nested Class)和内部类(Inner Class)的不同? 3.如何将String类型转化成Number类型. 4.什 ...

随机推荐

  1. ip完整验证详情

    不想跳坑就看一下 之前一直不太会写正则表达式,很多要用到正则表达式的都直接百度,像上次要用正则表达式验证是否是合法的ip地址,然后就上网找,结果就是没找到一个对的,今天就为大家贡献一下,写个对的,并做 ...

  2. 12.21-Android ServerSocket

    建立ServerSocket服务器 1.new ServerSocket对象servierSocket 2.接收客户端请求Socket client = servierSocket.accept(); ...

  3. MongoDB全文检索

    1. 全文检索概念: 全文检索是对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式.  (暂时不支持中文) ...

  4. java使用for循环做猜数字游戏

    package org.llh.test;import java.util.Random;import java.util.Scanner;/** * 猜数字游戏 *  * @author llh * ...

  5. hdu 3555 Bomb(不要49,数位DP)

    Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submi ...

  6. Mongodb联合查询

    Mongodb使用联合查询的重点需要添加@DBref  这样的话不会将整个文档保存,只会保存关联集合的id package com.java.web; import java.util.List; i ...

  7. display:none和visibility:hidden区别

    <!-- display:none和visible:hidden都能把网页上某个元素隐藏起来,但两者有区别: --> <!-- display:none 不为被隐藏的对象保留其物理空 ...

  8. HTML5 input事件检测输入框变化[转载]

    原文:http://www.linuxidc.com/Linux/2015-07/119984.htm 之前一直用change事件来监听输入框内容是否发生变化,只有当输入框失去焦点时才会触发,没想到h ...

  9. canvas绘制旋转图形

    将绘制到canvas上的要素进行旋转: 1.绘制时,通过操作画布的坐标轴状态:平移画布原点,旋转坐标轴等,达到旋转图形的目的 2.操作操作DOM元素,直接旋转canvas画布 操作画布的坐标轴状态: ...

  10. phpstorm php $post数据为空的原因

    今天拿PHPstoem 写了个PHP的表单插入数据,然后直接在里面一运行,就一直提示什么未定义,其实是因为$_PSOT[] 取不到值. 后面发现原来是直接用phpstorm 运行PHP的话,他会自带端 ...