(java)数据库(四)DBUtils工具、DBCP连接池

【DBUtils工具概述】

        为了简化JDBC开发,使用apache  commons  组件一个成员:DBUtils。

        DBUtils 是java编程中的数据库操作实用工具,小巧简单实用。

        Dbutils三个核心功能介绍:
                    (1) QueryRunner   中提供对sql语句操作的API

                                a.  方法update()  实现对数据库的 insert 、delete、update

                                b.  方法query()    实现对数据库的查询 select   返回值是T泛型

                    (2) ResultSetHandler接口    用于定义select操作后,怎样封装结果集

                                a.  接口实现类  ArrayHandler -- 将结果集的第一行存储到对象数组中  Object[]

                                b.  接口实现类  ArrayListHandler -- 结果集的每一行都存储在对象数组中,再将这些数组存储在List集合中

                                c.  接口实现类  BeanHandler -- 将结果集的第一行数据,封装成javaBean对象

                                d.  接口实现类  BeanListHandler -- 结果集每一行数据,都装成javaBean对象,将这些对象存储List集合中

                                e.  接口实现类  ColumnListHandler -- 将结果集指定列存储到List<Object>集合中

                                f.   接口实现类   ScalarHandler --  查询后结果集中只有1个结果  类型为long

                                g.  接口实现类  MapHandler --  将结果集的第1行数据封装到Map集合中去 Map<列名, 列数据>

                    (3) DbUtils类   是一个工具类,定义了关闭资源与事务处理的方法

【连接池】

          用池来管理Connection ,这样就可以重复使用Connection了。可以通过池来获取Connection对象,使用完后再归还给池。java为数据库连接池提供的公共接口:javax.sql.DataSource 。常见的连接池DBCP  C3P0。

        【DBCP连接池】

          作用:自身维护了多个Connection对象

          DataSource 接口   它是java与每种数据库连接池  连接的标准规范

          BasicDataSource类  它是DataSource接口的实现类

    【DBCP连接池常见配置

必须项

driverClassName

数据库驱动名称

url

数据库的地址

username

用户名

password

密码

基本项

maxActive

最大连接数量

initialSize

连接池中初始化多少个Connection连接对象

扩展项

maxWait

超时等待时间以毫秒为单位 1000等于1秒

 

【1. QueryRunner 方法update】

import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import usst.javacode.JDBCutils.JDBCutils;

/*
 *  使用QueryRunner类,实现对数据表的  增insert   删 delete   改 update
 *  1.方法    update(Connection con, String sql, Object...params)
 *               Object...params  Object类型   可变参数,SQL语句出现?占位符
 *               使用自己定义的工具类  创建数据库连接对象  JDBCutils.getConnection()
 */
public class QueryRunnerDemo1 {
	private static Connection con = JDBCutils.getConnection();
	public static void main(String[] args) throws SQLException {
		//insert();
		//update();
		delete();
	}
	
	// 1. 使用QueryRunner类  向数据库中添加数据
	public static void insert() throws SQLException{
		// 创建QueryRunner类对象
		QueryRunner qr = new QueryRunner();
		String sql = "INSERT INTO sort1 (sname,sprice,sdesc) VALUES (?,?,?)";
		// 调用qr对象的方法  update 执行SQL语句
		Object[] params = {"鼠标",99,"雷蛇"};   // 将三个实际占位符的参数写在数组中
		int row = qr.update(con, sql, params);
		System.out.println(row);
		DbUtils.closeQuietly(con);
	}
	
	// 2. 使用QueryRunner类   修改数据库中的数据
	public static void update() throws SQLException{
		// 创建QueryRunner类对象
		QueryRunner qr = new QueryRunner();
		String sql = "UPDATE sort1 SET sname = ?,sprice = ?, sdesc = ? WHERE sid = ?";
		// 定义Object数组,存储?中的参数
		Object[] params = {"记录本",49,"精装",13};
		int row = qr.update(con, sql, params);
		System.out.println(row);
		DbUtils.closeQuietly(con);
	}
	
	// 3. 使用QueryRunner类   删除数据库中的数据
	public static void delete() throws SQLException{
		// 创建QueryRunner类对象
		QueryRunner qr = new QueryRunner();
		String sql = "DELETE FROM sort1 WHERE sid = ?";
		int row = qr.update(con, sql, 12);
		System.out.println(row);
		DbUtils.closeQuietly(con);
	}

}

 

【javaBean】 

javaBean就是一个类,在开发中常用封装数据。具有以下特性:
       (1) 需要实现接口:java.io.Serializable,通常实现接口这个步骤省略,不会影响程序

       (2) 提供私有字段:private  类型   字段名

       (3) 提供getter/setter方法

       (4) 提供无参构造方法

 

【2. QueryRunner方法query()】

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

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import usst.javacode.JDBCutils.JDBCutils;
import usst.javacode.JDBCutils.Sort;

/*
 *   QueryRunner类数据查询操作:
          方法 query(Connection con,String sql,ResultSetHandler r,Object...params)
 *        ResultSetHandler r  结果集的处理方式          传递ResultSetHandler接口的实现类
 *        Object...params   SQL语句中?号占位符的参数
 *   注意:query方法返回的是 T  泛型,具体返回值类型,跟随结果集处理方式变化                     
 * 
 */
public class QueryRunnerDemo2 {
	private static Connection con = JDBCutils.getConnection();
	public static void main(String[] args) throws SQLException {
		//arrayHandler();
		//arrayListHandler();
		//beanHandler();
		//beanListHandler();
		//columnListHandler();
		//scalarHandler();
		//mapHandler();
		mapListHandler();
	}
	
	// 1. 结果集第一种处理方法   ArrayHandler  将结果集的第一行存储到对象数组中  Object[]
	public static void arrayHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		// 调用query方法执行查询,(传递连接对象,SQL语句,结果集处理方式的实现类)
		// 返回对象数组
		Object[] result = qr.query(con,sql,new ArrayHandler());
		for(Object res:result){
			System.out.print(res+"\t");      // 打印sort1数据表中第一行
			//  1	家电	3000.0	厂家促销	
		}
	}
	
	// 2. 结果集第二种处理方法   ArrayListHandler  将结果集的每一行,封装到对象数组中Object[]  对象数组存储到List集合
	public static void arrayListHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		// 调用query方法 , 结果集处理的参数上,传递实现类ArrayListHandler
		// 返回值  每一行是一个对象数组,存储到List中
		List<Object[]> result = qr.query(con, sql,new ArrayListHandler());
		// 集合遍历
		for(Object[] objs:result){
			// 遍历对象数组
			for(Object obj:objs){
				System.out.print(obj+"\t");  // 打印sort1表中的所有内容
				//  1	家电	3000.0	厂家促销	......
			}
			System.out.println();
		}
	}
	
	// 3. 结果集第三种处理方法,BeanHandler   将结果集的第一行数据     封装成javaBean对象
	//    注意: 被封装成数据  到javaBean对象Sort类,必须有空参数的构造方法  
	public static void beanHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		// 调用方法query  传递结果集实现类BeanHandler
		// BeanHandler(Class<T> type)
		Sort s = qr.query(con, sql, new BeanHandler<Sort>(Sort.class));
		System.out.println(s);              // 打印sort1数据表中第一行
		//  Sort [sid=1, sname=家电, sprice=3000.0, sdesc=厂家促销]
	}
	
	// 4. 结果集第四种处理方法BeanListHandler    将数据结果集的每一行,封装成javaBean对象      多个javaBean对象封装到List集合中
	public static void beanListHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		// 调用方法query 传递结果集实现类beanListHandler
		// BeanListHandler(Class<T> type)
		List<Sort> result = qr.query(con,sql, new BeanListHandler<Sort>(Sort.class));
		// 遍历
		for(Sort res:result){
			System.out.println(res);       // 打印sort1表中的所有内容  
			// Sort [sid=1, sname=家电, sprice=3000.0, sdesc=厂家促销] ......
		}
	}
	
	// 5. 结果集第五种处理方法 ,ColumnListHandler  将结果集中指定列的数据,存储到List集合   List<Object> 每个类数据类型不同
	public static void columnListHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		//  调用方法query, 传递结果集实现ColumnListHandler   实现类构造方法中使用字符串的列名
		List<Object> result = qr.query(con, sql, new ColumnListHandler<Object>("sname"));
		System.out.println(result);
		// [家电, 家具, 儿童玩具, 生鲜, 服装, 洗发水, 新能源汽车, 羽绒服, 新能源汽车, 新能源汽车, 鼠标1, 记录本]
		
		for(Object res:result){
			System.out.println(res);
			// 家电  家具 ......
		}
	}
	
	// 6. 结果集第六种处理方法,ScalarHandler    用於单数据   查询后只有一个结果     
	public static void scalarHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT COUNT(*) FROM sort1";
		// 调用query方法,传递结果集实现类ScalarHandler
		long count = qr.query(con,sql,new ScalarHandler<Long>());
		System.out.println(count);     //  12
	}
	
	// 7. 结果集第七种处理方法,MapHandler,将结果集中的第一行封装到Map集合中         Map<键,值>  键:列名     值:这列的数据
	public static void mapHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		// 调用query方法,传递结果集实现类MapHandler
		//    返回值:Map集合,Map接口实现类,泛型
		Map<String,Object> map = qr.query(con, sql,new MapHandler());
		// 遍历Map集合
		for(String key:map.keySet()){
			System.out.println(key+"="+map.get(key));
		}
		/*
		 * 打印结果
		  sid=1
          sname=家电
          sprice=3000.0
          sdesc=厂家促销
		 */
	}
	
	// 8. 结果集第八种处理方法,MapListHandler  奖结果集的每一行存储到Map集合中,键:列名    值:这列的数据
	//       Map集合过多,存储到List集合中去
	public static void mapListHandler() throws SQLException{
		QueryRunner qr = new QueryRunner();
		String sql = "SELECT * FROM sort1";
		// 调用query方法,传递结果集实现类MapListHandler
		//    返回值是List集合,里面存储的是Map集合
		List<Map<String,Object>> list = qr.query(con,sql,new MapListHandler());
		// 遍历集合List
		for(Map<String,Object> map:list){
			for(String key:map.keySet()){
				System.out.print(key+"="+map.get(key)+"\t");
			}
			System.out.println();
		}
		/*
		 * sid=1	sname=家电	  sprice=3000.0	  sdesc=厂家促销	
           sid=2	sname=家具	  sprice=8900.0	  sdesc=家具价格上调	
           sid=3	sname=儿童玩具	  sprice=300.0	  sdesc=销量火爆	
           ...         ....       ...              ...
		 */
	}

}

 

【连接池工具类】 -- BasicDataSource

           实际开发中“获得连接”和“释放连接”是非常消耗系统资源的两个过程,为了解决此类问题我们采用连接池技术,来共享连接Connection。

import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;

/*
 *   使用DBCP实现数据库的连接池
 *   连接池配置:
 *       最基本四项配置  1. 数据库驱动名称:setDriverClassName   2. 数据库地址:setUrl
 *                 3. 用户名:setUsername               4. 密码:setPassword
 *       基本项(扩展) 1. 初始化的连接数量:setInitialSize      2. 最大连接数量:setMaxActive
 *                 3. 最大空闲数:setMaxIdle             4. 最小空闲数:setMinIdle
 */
public class JDBCutils {
	// 创建出BasicDataSource类对象
	private static BasicDataSource dataSource = new BasicDataSource();
	
	// 静态代码块,进行配置
	static{
		// 连接数据库的4个基本信息,通过对象方法setXXX进行设置  (必须进行配置)
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/mybase1");
		dataSource.setUsername("root");
		dataSource.setPassword("123");
		
		// 对 dataSource连接池对象  的连接数量进行配置    (可选配置,有默认配置)
		dataSource.setInitialSize(10);   // 初始化的连接数量
		dataSource.setMaxActive(8);      // 最大连接数量
		dataSource.setMaxIdle(5);        // 最大空闲数
		dataSource.setMinIdle(1);        // 最小空闲数
	}
	// 定义静态方法,返回BasicDataSource类对象
	public static DataSource getDataSource(){
		return dataSource;
	}

     // 定义静态方法,返回Connection对象
     public static Connection getConnection(){
        return dataSource.getConnection;
     }

}

【测试连接池工具类】 

import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;

/*
 *   测试写好的工具类:JDBCutils   静态方法getDataSource()  返回值类型是DataSource
     QueryRunner 类构造方法,接受DataSource接口的实现类
 */
public class QueryRunnerDemo {
	// 定义2个方法,实现数据表的添加  、数据表的查询
	//    QueryRunner类对象写在成员变量位置
	private static QueryRunner qr =new  QueryRunner(JDBCutils.getDataSource());
	public static void main(String[] args) {
		//insert();
		select();
	}
		
	// 数据表添加数据
	public static void insert(){
		String sql = "INSERT INTO sort1 (sname,sprice,sdesc) VALUES(?,?,?)";
		Object[] params = {"核桃",29.9,"新疆干果"};
		try{
			int row  = qr.update(sql,params); // 无须传递Connection对象
			System.out.println(row);
		}catch(SQLException ex){
			throw new RuntimeException(ex+"数据库添加失败");
		}
	}
	
	// 数据表查询函数
	public static void select(){
		String sql = "SELECT * FROM sort1";
		try{
			List<Object[]> lists = qr.query(sql, new ArrayListHandler());
			for(Object[] list:lists){
				for(Object l:list){
					System.out.print(l+"\t");
				}
				System.out.println();
			}
		}catch(SQLException ex){
			throw new RuntimeException(ex+"数据库查询失败");
		}
		/* 打印结果
		 * 1	家电	3000.0	厂家促销	
           2	家具	8900.0	家具价格上调	
           3	儿童玩具	300.0	销量火爆	
                 ...          ...
		 */
	}

}

【连接池工具】-- 读取 .properties文件配置数据库

       db.properties文件 

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybase1
username=root
password=123

      DBCPUtils类 获取连接池 和 连接对象的静态方法

import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPUtils {
	// 声明DataSource类型成员变量
	private static DataSource dataSource;
	
	static {
		try {
			// 使用类的加载器读取数据库.properties配置文件(在src目录下)
			InputStream in = DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties");
			// 加载输入流
			Properties pros = new Properties();
			pros.load(in);
			// 使用工具类创建连接池(数据源)
			dataSource = BasicDataSourceFactory.createDataSource(pros);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	// 静态方法获得连接池
	public static DataSource getDataSource() {
		return dataSource;
	}
	
	// 静态方法获得连接
	public static Connection getConnection() {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

}

【c3p0连接池工具】

       c3p0-config.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

	<default-config>
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///mybase1</property>
		<property name="user">root</property>
		<property name="password">123</property>
		<property name="initialPoolSize">5</property>
		<property name="maxPoolSize">20</property>
	</default-config>

	<named-config name="namedConfig">
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql:///mybase1</property>
		<property name="user">root</property>
		<property name="password">123</property>
	</named-config>


</c3p0-config>
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
	// 使用默认配置 -- 自动读取c3p0-config.xml中的配置信息
	private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
	// 使用命名配置
	//private static ComboPooledDataSource dataSource = new ComboPooledDataSource("namedConfig");
	
	// 静态方法获得连接池
	public static DataSource getDataSource() {
		return dataSource;
	}
	
	// 静态方法获得连接
	public static Connection getConnection() {
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章