自定義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大功告成,可以使用其靈活的對數據庫進行增刪改查了

 

發佈了66 篇原創文章 · 獲贊 13 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章