C3p0+QueryRunne快速入门

Java 专栏收录该内容
14 篇文章 0 订阅
C3P0 是一个开源的 JDBC 连接池 ,它实现了数据源和 JNDI 绑定,支持 JDBC3 规范和 JDBC2 的标准扩展。目前使用它的 开源项目 HibernateSpring 等。
   c3p0 - JDBC3.jar下载地址:http://www.java2s.com/Code/Jar/c/Downloadc3p00912jar.htm
 commons-dbutils-1.7.jar下载地址:http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi

使用步骤:
 1、将下载的c3p0-0.9.5.2.jar和commons-dbutils-1.7.jar及数据库驱动程序导入项目
        C3p0+QueryRunne快速入门 - 人生若只是初见 - 我们都是小菜鸟
 
 2、在scr下新建xml文件取名为c3p0-config.xml 并配置内容如下:
<? xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
    <default-config>
       <!--mysql数据库连接的各项参数-->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!--配置数据库连接池的最小链接数、最大连接数、初始连接数-->
        <property name="maxPoolSize">15</property>
        <property name="minPoolSize">5</property>
        <property name="initialSize">5</property>
    </default-config>
</c3p0-config>

3、在项目新建一个BaseUtils工具类类

/**
 * @描述: 工具类 提供数据库连接对象
 * @作者:刘运发
 * @创建时间:2018年4月3日 上午8:45:15
 * @版本:V1.0
 */
public class BaseUtil {
	private static DataSource dataSource = null;

	static {
		// 自动加载src目录下面的c3p0的配置文件,【c3p0-config.xml】
		dataSource = new ComboPooledDataSource();
	}

	public static QueryRunner getQueryRunner() {
		// 第一步:创建QueryRunner对象,传入连接池对象
		// 在创建QueryRunner对象的时候,如果传入数据对象dataSource,
		// 那么在使用QueryRunner对象的方法时候,就不需要传入连接对象
		QueryRunner query = new QueryRunner(dataSource);
		// 第二步:会自动从数据源中获取连接(不用关闭连接,连接池会自动关闭连接对象)
		return query;
	}

	/***
	 * 实现增删改的公共方法
	 * 
	 * @param sql
	 * @param arr
	 * @return
	 */
	public static boolean addUpdateDelete(String sql, Object[] arr) {
		QueryRunner qr = getQueryRunner();
		int count;
		try {
			count = qr.update(sql, arr);
			if (count > 0) {
				return true;
			} else {
				return false;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return false;
	}

}

4、创建好实体类
package org.bdqn.entity;

public class User {
	private int id;
	private String name;
	private String password;
	private String email;
	private String phone;

	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 String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	/**
	 *  重写toString方法  输出实体类的详细信息
	 */
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", password=" + password
				+ ", email=" + email + ", phone=" + phone + "]";
	}
}

5、dao层进行创建接口,再创建实现接口的类,当然实现c3p0和QueryRunner的关键代码就是dao层

package org.bdqn.dao;
import java.util.List;
import org.bdqn.entity.User;

public interface UserDao {
	/***
     * 查询所有用户信息
     * @param user
     * @return
     */
	public List<User> selectUser();
	
    /***
     * 根据条件查询用户信息
     * @param user
     * @return
     */
    public List<User> select(User user);
    
    /***
     * 添加用户信息
     * @param user
     * @return
     */
    public boolean insertUser(User user);
    
    /***
     * 修改用户的信息
     * @param user
     * @return
     */
    public boolean updateUser(User user);
    
    /***
     * 删除用户信息
     * @param id
     * @return
     */
    public boolean deleteUser(int id);
}

6、创建接口实现类去实现UserDao
package org.bdqn.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.bdqn.dao.UserDao;
import org.bdqn.entity.User;
import org.bdqn.util.BaseUtil;

public class UserDaoImpl implements UserDao {

	public List<User> selectUser() {
		// 创建QueryRunner
		// 记住查询是BeanListHandler BeanHandler
		QueryRunner qr = BaseUtil.getQueryRunner();
		try {
			String sql = "select * from user ";
			// 创建BeanListHandler对象
			return qr.query(sql, new BeanListHandler<User>(User.class));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public List<User> select(User user) {
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "select *  from  user where name =?  ";
		try {
			return qr.query(sql, new BeanListHandler<User>(User.class),
					user.getName());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	// 增删改 是使用 BeanListHandler
	@Override
	public boolean insertUser(User user) {
		// 注意主键ID是否有自增 注意数据库的类型 改写sql语句
		String sql = "insert  into  user values(?,?,?,?,?)";
		Object[] param = { user.getId(), user.getName(), user.getPassword(),
				user.getEmail(), user.getPhone() };
		return BaseUtil.addUpdateDelete(sql, param);
	}

	@Override
	public boolean updateUser(User user) {
		String sql = "update   user set  name=? ,password=?,email=?,phone=? where id=?";
		Object[] param = { user.getName(), user.getPassword(), user.getEmail(),
				user.getPhone() ,user.getId() };
		return BaseUtil.addUpdateDelete(sql, param);
	}

	@Override
	public boolean deleteUser(int id) {
		String sql = "delete from user where id=" + id;
		// 如果不需要传递参数 直接写null
		return BaseUtil.addUpdateDelete(sql, null);
	}

}
7、测试

public class QueryRunnerTest {

    private UserDao dao=new UserDaoImpl();
    private UserService service=new UserServiceImpl();
    
    //查询所有信息的测试
    @Test
    public void selectUser(){
        List<User> list=dao.selectUser();
        for(User u:list){
            System.out.println(u);
        }
    }
    
    //根绝id查询的信息
    @Test
    public void selectUserId(){
        User user=dao.selectUserId(1);
        System.out.println(user);
    }
    
    //根据条件查询信息
    @Test
    public void select(){
        User user=new User();
        user.setName("张三");
        List<User> list=service.select(user);
        for(User u:list){
            System.out.println(u);
        }
    }
    
    @Test
    public void insertUser(){
        User user=new User();
        user.setName("张三");
        user.setPassword("123456");
        user.setEmail("1748@qq.com");
        user.setPhone("11223");
        
        boolean mark=service.insertUser(user);
        if(mark){
            System.out.println("插入成功");
        }else{
            System.out.println("插入失败");
        }
    }
    
    
    @Test
    public void update(){
        User user=new User();
        user.setName("李四");
        user.setId(1);
        
        boolean mark=service.updateUser(user);
        if(mark){
            System.out.println("修改成功");
        }else{
            System.out.println("修改失败");
        }
    }
    
    @Test
    public void delete(){
        boolean mark=service.deleteUser(1);
        if(mark){
            System.out.println("用户信息删除成功");
        }else{
            System.out.println("用户信息删除失败");
        }
    }
    
}

附录:QueryRunner其他方法:

   1、  QueryRunner数据查询操作,结果集八种处理方法

  QueryRunner数据查询操作 
   调用QueryRunner类方法 query(Connection con,String sql,ResultSetHandler r,Object..params) 

         conn: 连接对象,如果在创建QueryRunner对象时给过dataSource对象则可以忽略

         ResultSetHandler r :结果集的封装处理方式,传递ResultSetHandler接口实现类 
          Object...params : sql语句的?占位符  可以是数组 也可以是一个或多个 Object 值 如果不需要传参 赋值null
 
注意:query方法返回值,返回的是T 泛型,具体返回值类型,跟随结果集处理方式变化 
public class QueryRunnerDemo1 {

	/*
	 *  结果集第八种处理方法,MapListHandler
	 *  将结果集每一行存储到Map集合,键:列名,值:数据
	 *  Map集合过多,存储到List集合
	 */
	public static void mapListHandler()throws SQLException{
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "SELECT  * FROM user";
		//调用方法query,传递结果集实现类MapListHandler
		//返回值List集合, 存储的是Map集合
		List<Map<String,Object>> list = qr.query(sql, new MapListHandler());
		//遍历集合list
		for( Map<String,Object> map : list ){
			for(String key : map.keySet()){
				System.out.print(key+"..."+map.get(key));
			}
			System.out.println();
		}
		
	}
	
	/*
	 *  结果集第七种处理方法,MapHandler
	 *  将结果集第一行数据,封装到Map集合中
	 *  Map<键,值> 键:列名  值:这列的数据
	 */
	public static void mapHandler()throws SQLException{
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "SELECT  * FROM user";
		//调用方法query,传递结果集实现类MapHandler
		//返回值: Map集合,Map接口实现类, 泛型
		Map<String,Object> map = qr.query( sql, new MapHandler());
		//遍历Map集合
		for(String key : map.keySet()){
			System.out.println(key+".."+map.get(key));
		}
	}
	
	
	/*
	 *  结果集第六种处理方法,ScalarHandler
	 *  对于查询后,只有1个结果
	 */
	public static void scalarHandler()throws SQLException{
		QueryRunner qr =BaseUtil.getQueryRunner();
		String sql = "SELECT COUNT(*) FROM user";
		//调用方法query,传递结果集处理实现类ScalarHandler
		long count = qr.query( sql, new ScalarHandler<Long>());
		System.out.println(count);
	}
	
	/*
	 *  结果集第五种处理方法,ColumnListHandler
	 *  结果集,指定列的数据,存储到List集合
	 *  List<Object> 每个列数据类型不同
	 */
	public static void columnListHandler()throws SQLException{
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "SELECT * FROM user";		
		//调用方法 query,传递结果集实现类ColumnListHandler
		//实现类构造方法中,使用字符串的列名
		List<Object> list = qr.query(sql, new ColumnListHandler<Object>("name"));
		for(Object obj : list){
			System.out.println(obj);
		}
	}
	
	/*
	 *  结果集第四种处理方法, BeanListHandler
	 *  结果集每一行数据,封装JavaBean对象
	 *  多个JavaBean对象,存储到List集合
	 */
	public static void beanListHander()throws SQLException{
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "SELECT * FROM user";
		//调用方法query,传递结果集处理实现类BeanListHandler
		List<User> list = qr.query( sql, new BeanListHandler<User>(User.class));
		for(User s : list){
			System.out.println(s);
		}
	}
	
	/*
	 *  结果集第三种处理方法,BeanHandler
	 *  将结果集的第一行数据,封装成JavaBean对象
	 *  注意: 被封装成数据到JavaBean对象, User类必须有空参数构造
	 */
	public static void beanHandler()throws SQLException{
		QueryRunner qr =BaseUtil.getQueryRunner();
		String sql = "SELECT * FROM user";
		//调用方法,传递结果集实现类BeanHandler
		//BeanHandler(Class<T> type) 
		User  user = qr.query( sql, new BeanHandler<User>(User.class));
		System.out.println(user);
	}
	
	/*
	 *  结果集第二种处理方法,ArrayListHandler
	 *  将结果集的每一行,封装到对象数组中, 出现很多对象数组
	 *  对象数组存储到List集合
	 */
	public static void arrayListHandler()throws SQLException{
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "SELECT * FROM user";		
		//调用query方法,结果集处理的参数上,传递实现类ArrayListHandler
		//方法返回值 每行是一个对象数组,存储到List
		List<Object[]> result=  qr.query( sql, new ArrayListHandler());
		
		//集合的遍历
		for( Object[] objs  : result){
			//遍历对象数组
			for(Object obj : objs){
				System.out.print(obj+"  ");
			}
			System.out.println();
		}
	}
	
	/*
	 *  结果集第一种处理方法, ArrayHandler
	 *  将结果集的第一行存储到对象数组中  Object[]
	 */
	public static void arrayHandler()throws SQLException{
		QueryRunner qr = BaseUtil.getQueryRunner();
		String sql = "SELECT * FROM user";
		//调用方法query执行查询,传递连接对象,SQL语句,结果集处理方式的实现类
		//返回对象数组
		Object[] result = qr.query( sql, new ArrayHandler());
		for(Object obj : result){
			System.out.print(obj);
		}
	}
		
}

附录2:c3p0-config.xml模板详解(了解)
   < c3p0-config >
    <default-config>    
    <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->    
    <property name="acquireIncrement">3</property>    
      
    <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->    
    <property name="acquireRetryAttempts">30</property>    
      
    <!--两次连接中间隔时间,单位毫秒。Default: 1000 -->    
    <property name="acquireRetryDelay">1000</property>    
      
    <!--连接关闭时默认将所有未提交的操作回滚。Default: false -->    
    <property name="autoCommitOnClose">false</property>    
      
    <!--c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么    
    属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试    
    使用。Default: null-->    
    <property name="automaticTestTable">Test</property>    
      
    <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效    
    保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试    
    获取连接失败后该数据源将申明已断开并永久关闭。Default: false-->    
    <property name="breakAfterAcquireFailure">false</property>    
      
    <!--当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出    
    SQLException,如设为0则无限期等待。单位毫秒。Default: 0 -->    
    <property name="checkoutTimeout">100</property>    
      
    <!--通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径。    
    Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester-->    
    <property name="connectionTesterClassName"></property>    
      
    <!--指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置,默认null即可    
    Default: null-->    
    <property name="factoryClassLocation">null</property>    
      
    <!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs.    
    (文档原文)作者强烈建议不使用的一个属性-->    
    <property name="forceIgnoreUnresolvedTransactions">false</property>    
      
    <!--每60秒检查所有连接池中的空闲连接。Default: 0 -->    
    <property name="idleConnectionTestPeriod">60</property>    
      
    <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->    
    <property name="initialPoolSize">3</property>    
      
    <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->    
    <property name="maxIdleTime">60</property>    
      
    <!--连接池中保留的最大连接数。Default: 15 -->    
    <property name="maxPoolSize">15</property>    
      
    <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements    
    属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。    
    如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0-->    
    <property name="maxStatements">100</property>    
      
    <!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->    
    <property name="maxStatementsPerConnection"></property>    
      
    <!--c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能    
    通过多线程实现多个操作同时被执行。Default: 3-->    
    <property name="numHelperThreads">3</property>    
      
    <!--当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0    
    的数据源时。Default: null-->    
    <property name="overrideDefaultUser">root</property>    
      
    <!--与overrideDefaultUser参数对应使用的一个参数。Default: null-->    
    <property name="overrideDefaultPassword">password</property>    
      
    <!--密码。Default: null-->    
    <property name="password"></property>    
      
    <!--定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:    
    测试的表必须在初始数据源的时候就存在。Default: null-->    
    <property name="preferredTestQuery">select id from test where id=1</property>    
      
    <!--用户修改系统配置参数执行前最多等待300秒。Default: 300 -->    
    <property name="propertyCycle">300</property>    
      
    <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的    
    时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable    
    等方法来提升连接测试的性能。Default: false -->    
    <property name="testConnectionOnCheckout">false</property>    
      
    <!--如果设为true那么在取得连接的同时将校验连接的有效性。Default: false -->    
    <property name="testConnectionOnCheckin">true</property>    
      
    <!--用户名。Default: null-->    
    <property name="user">root</property>    
      
    <!--早期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数    
    允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始    
    广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到    
    支持,但今后可能的版本可能不支持动态反射代理。Default: false-->    
    <property name="usesTraditionalReflectiveProxies">false</property>  
      
    <property name="automaticTestTable">con_test</property>    
    <property name="checkoutTimeout">30000</property>    
    <property name="idleConnectionTestPeriod">30</property>    
    <property name="initialPoolSize">10</property>    
    <property name="maxIdleTime">30</property>    
    <property name="maxPoolSize">25</property>    
    <property name="minPoolSize">10</property>    
    <property name="maxStatements">0</property>    
    <user-overrides user="swaldman">    
    </user-overrides>    
    </default-config>    
    <named-config name="dumbTestConfig">    
    <property name="maxStatements">200</property>    
    <user-overrides user="poop">    
    <property name="maxStatements">300</property>    
    </user-overrides>    
    </named-config>    
</c3p0-config> 


  • 1
    点赞
  • 1
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值