自定义dbutils

使用jdbc访问数据库,每次建立连接,连接完成进行相应的操作后就对其进行关闭操作。每次访问都需建立对数据库的连接,很耗资源。就像刚建好一栋房子,进去住了几天,就把它拆了重新建立,虽然可以建立,但耗很大资源。为了防止这样的事情发生,于是数据库连接池产生了。

建立数据库连接池是由第三方提供的jar包,C3P0或者DBCP的jar包都可以。

本人使用C3P0jar包自己做了一个C3P0Utils工具类,代码如下:

package com.itheima.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;


public class C3P0Utils {

	private static DataSource ds=new ComboPooledDataSource();
	
	/**
	 * 获取数据库连接
	 * @return 返回Connection
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException{
		return ds.getConnection();
	}
	/**
	 * 获取数据源
	 * @return
	 */
	public static DataSource getDataSource(){
		return ds;
	}
	
	/**
	 * 关闭数据库
	 */
	public static void close(ResultSet rs,Statement ps,Connection con){
		if(rs!=null){
			try {
				rs.close();
				rs=null;
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(ps!=null){
			try {
				ps.close();
				ps=null;
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if(con!=null){
			try {
				con.close();
				con=null;
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
}

有了C3P0Utls工具类,自定义自己的dbutils就方便多了。

首先,在对数据库进行操作时,主要有增删改查,其中,增删改用一个方法update封装就搞定,查询涉及到把数据封装到bean中,也可以用一个方法query搞定。

具体代码如下:


package com.itheima.utils;

import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.itheima.dao.ResultSetHandler;

public class DbUtils {

 private static DataSource ds=null;

 public DbUtils(DataSource ds) {
  super();
  this.ds = ds;
 }
 /**
  * 对数据库进行增删改操作
  * @param sql SQL语句
  * @param params 传入的问号对应的参数
  */
 public static void executeUpdate(String sql,Object...params){
  Connection con=null;
  PreparedStatement ps=null;
  try {
   con=ds.getConnection();
   ps=con.prepareStatement(sql);
   ParameterMetaData pmd=ps.getParameterMetaData();
   int count=pmd.getParameterCount();
   if(count>0){
    if(params==null||params.length==0){
     //参数为空或者为null,都不能匹配需要传入的问号个数,则抛出异常
     throw new IllegalArgumentException("参数不能为null或者空");
    }else if(params.length!=count){
     System.out.println(count+"=="+params.length);
     //参数的长度不匹配问号个数,也要抛出异常
     throw new IllegalArgumentException("参数不匹配");
    }
    for(int i=0;i<count;i++){
     //参数个数等于问号个数,则将问号设置为参数
     ps.setObject(i+1, params[i]);
    }
   }
   ps.executeUpdate();
   
  } catch (Exception e) {
   throw new RuntimeException("操作失败");
  }finally{
   C3P0Utils.close(null, ps, con);
  }
 }
 /**
  * 查询单条记录并封装成对象
  * @param sql 要执行的语句
  * @param rsh 要封装的BeanHeadler类,封装的对象为传入的类字节码
  * @param params 查询参数
  * @return
  */
 public static Object executeQuery(String sql,ResultSetHandler rsh,Object...params){
  Connection con=null;
  PreparedStatement ps=null;
  ResultSet rs=null;
  try {
   con=ds.getConnection();
   ps=con.prepareStatement(sql);
   ParameterMetaData pmd=ps.getParameterMetaData();
   int count=pmd.getParameterCount();
   if(count>0){
    if(params==null||params.length==0){
     //参数为空或者为null,都不能匹配需要传入的问号个数,则抛出异常
     throw new IllegalArgumentException("参数不能为null或者空");
    }else if(params.length!=count){
     System.out.println(count+"=="+params.length);
     //参数的长度不匹配问号个数,也要抛出异常
     throw new IllegalArgumentException("参数个数不匹配");
    }
    for(int i=0;i<count;i++){
     //参数个数等于问号个数,则将问号设置为参数
     ps.setObject(i+1, params[i]);
    }
   }
   rs=ps.executeQuery();
   return rsh.handler(rs);
  } catch (Exception e) {
   throw new RuntimeException("操作失败");
  }finally{
   C3P0Utils.close(rs, ps, con);
  }
 }
}


3.写一个接口

package com.itheima.dao;

import java.sql.ResultSet;

public interface ResultSetHandler {

	Object handler(ResultSet rs);
}


 

4.写几个实现类

1.

package com.itheima.dao.impl;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import com.itheima.dao.ResultSetHandler;
/**
 * 自定义封装数据库查询的结果集
 * @author Administrator
 *
 */
public class BeanHeadler implements ResultSetHandler {

	private Class clazz;
	public BeanHeadler(Class clazz){
		this.clazz=clazz;
	}
	public Object handler(ResultSet rs) {
		//定义Object对象
		Object obj=null;
		//分而治之,将rs中的结果集封装到obj对象中
		try {
			if(rs.next()){
				obj=clazz.newInstance();
				//获取结果集元数据
				ResultSetMetaData rsmd=rs.getMetaData();
				int count=rsmd.getColumnCount();
				for(int i=0;i<count;i++){
					//通过元数据获取到每列的名字
					String columnName=rsmd.getColumnName(i+1);
					//通过列名获取到列值
					Object columnValue=rs.getObject(columnName);
					//有了列名再通过反射获取到类obj的属性值
					Field f=clazz.getDeclaredField(columnName);
					f.setAccessible(true);
					f.set(obj, columnValue);
				}
				
			}
			return obj;
		} catch (Exception e) {
			throw new RuntimeException("查询失败");
		}
	}

}


2.

package com.itheima.dao.impl;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import com.itheima.dao.ResultSetHandler;

public class BeanListHeadler implements ResultSetHandler {

 private Class clazz;
 public BeanListHeadler(Class clazz){
  this.clazz=clazz;
 }
 @Override
 public Object handler(ResultSet rs) {
  List list=new ArrayList();
  try {
   ResultSetMetaData rsmd=rs.getMetaData();
   int count=rsmd.getColumnCount();
   while(rs.next()){
    Object obj=clazz.newInstance();
    //获取结果集元数据
    for(int i=0;i<count;i++){
     //通过元数据获取到每列的名字
     String columnName=rsmd.getColumnName(i+1);
     //通过列名获取到列值
     Object columnValue=rs.getObject(columnName);
     //有了列名再通过反射获取到类obj的属性值
     Field f=clazz.getDeclaredField(columnName);
     f.setAccessible(true);
     f.set(obj, columnValue);
    }
    list.add(obj);
   }
   return list;
  } catch (Exception e) {
   throw new RuntimeException("查询失败");
  }

 }

}


通过以上几个步骤,一个简单的mydbutils大功告成,可以使用其灵活的对数据库进行增删改查了

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值