对jdbc中操作数据库的简单封装(含连接,关闭,增删改查等)

由于jdbc中操作数据库的几大步骤是可以通用的,针对所有的数据访问操作,都会产生大量重复代码,所以,我们在这里对j操作数据库的步骤进行简单的数据封装。

首先,为了不用修改java源代码,可以将连接数据库的常见字符串直接配置到properties文件中,下面是配置好的properties文件代码(用的mysql数据库,mssqlserver和oracle稍有差异):

#mysql connection config
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mydb
user=root
password=123456
maxActive=10
minIdle=1
maxWait=10000

接下来我们要做的就是按照jdbc操作数据库的步骤将其封装起来,这里我封装了以下功能:

  1. 获取连接
  2. 关闭连接以及连接池(这里用到了alibaba druid 数据连接池)
  3. 封装通用的增删改操作
  4. 封装通用的查询操作
  5. 事务(确保连接唯一性,只创建一个连接)
  6. 解析指定查询语句,并将获取的数据(列名,列值)以集合(map)的形式返回
  7. 此处用到了map集合,需要将map集合转换为javabean,因此创建一个parseMapToBean方法
  8. 封装通用的查询集合操作,对于任何形式的查询,都能返回一个对象集合 / 对象
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 自己封装的数据库工具类,包含一些操作数据库的简便方法
 * 1. 获取连接
 * 2. 关闭资源
 * 3..
 * @author Wxp
 */
public class DBUtils {

	private static String driverClass;
	private static String url;
	private static String user;
	private static String password;
	
	/**最大活动连接数*/
	private static int maxActive;
	/**最小闲置连接*/
	private static int minIdle;
	/**等待连接获取的最长时间*/
	private static long maxWait;
	
	/**druid数据源对象*/
	private static DruidDataSource dataSource;
	
	
	static{
		init();
	}
	
	public static void init(){
		try {
			Properties prop = new Properties();
			//加载属性文件
			prop.load(new FileInputStream("src/jdbc.properties"));
			//获取属性信息(连接数据库的相关字符串)
			driverClass = prop.getProperty("driverClass");
			url = prop.getProperty("url");
			user = prop.getProperty("user");
			password = prop.getProperty("password");
			
			maxActive = Integer.parseInt(prop.getProperty("maxActive"));
			minIdle = Integer.parseInt(prop.getProperty("minIdle"));
			maxWait = Long.parseLong(prop.getProperty("maxWait"));
			
			//创建数据源并配置
			dataSource = new DruidDataSource();
			dataSource.setDriverClassName(driverClass);
			dataSource.setUrl(url);
			dataSource.setUsername(user);
			dataSource.setPassword(password);
			dataSource.setMaxActive(maxActive);
			dataSource.setMinIdle(minIdle);
			dataSource.setMaxWait(maxWait);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
	/**
	 * 2.获取连接
	 * @return
	 */
	public static synchronized Connection getConn(){
		if(dataSource == null || dataSource.isClosed()){
			init();
		}
		try {
			return dataSource.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 关闭连接池
	 */
	public static synchronized void closePool(){
		if(dataSource != null){
			dataSource.close();
		}
	}
	
	/**
	 * 6.关闭资源
	 * @param rs
	 * @param stat
	 * @param conn
	 */
	public static void close(ResultSet rs,Statement ps,Connection conn){
		try {
			if(rs != null){
				rs.close();
			}
			if(ps != null){
				ps.close();
			}
			if(conn != null){
				conn.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 封装通用的增、删、改操作(针对任何数据库表的更新操作(DML语句)都能通过该方法实现)
	 * @param sql
	 * @return
	 */
	public static int exeUpdate(String sql,Object... params){
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			//获取连接
			conn = getConn();
			//编译sql语句获取预处理对象
			ps = conn.prepareStatement(sql);
			if(Objects.nonNull(params)){				
				for(int i = 0;i List query(String sql,CallBack callback,Object... params){
		List list = null;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = getConn();
			ps = conn.prepareStatement(sql);
			if(Objects.nonNull(params)){
				for (int i = 0; i < params.length; i++) {
					ps.setObject(i + 1, params[i]); 
				}
			}
			//执行查询操作
			rs = ps.executeQuery();
			list = callback.call(rs);
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			close(rs, ps, conn); 
		}
		return list;
	}
	
	/**
	 * 内部接口,里面包含一个函数(回调函数)
	 * @author Wxp
	 */
	@FunctionalInterface
	public interface CallBack{
		List call(ResultSet rs) throws SQLException;
	}
	
	/**
	 * 解析指定查询语句,并将获取的数据(列名,列值)以集合的形式返回
	 * @param sql
	 * @param params
	 * @return
	 */
	private static List> getDataPair(String sql,Object... params){
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		List> list = new ArrayList<>();
		try {
			conn = getConn();
			ps = conn.prepareStatement(sql);
			if(Objects.nonNull(params)){
				for (int i = 0;i < params.length;i++){
					ps.setObject(i+1, params[i]);
				}
			}
			rs = ps.executeQuery();
			//获取结果集元数据
			ResultSetMetaData rsmd = rs.getMetaData();
			//获取列总数,获取列名称,获取标签名,获取列值,将相关数据存储到map集合
			//获取查询的总列数
			int count = rsmd.getColumnCount();
			
			while(rs.next()){
				//对结果集每遍历一次,获取一条数据()即一个map对象
				Map map = new HashMap<>();
				//遍历每一列
				for(int i = 1;i <= count;i++){
					//获取列名称
					String columnName = rsmd.getColumnName(i);
					//获取标签名(列别名)
//					String columnLable = rsmd.getColumnLabel(i);
					//获取列值
					Object value = rs.getObject(i);
					if(Objects.nonNull(value)){
					//将数据存入map
					map.put(columnName, value);
					}
				}
				//将map集合存入List
				list.add(map);
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			DBUtils.close(rs, ps, conn);
		}
		return list;
	}
	
	/**
	 * 将一个map集合转换为一个Javabean并返回
	 * @param map
	 * @param t
	 * @return
	 */
	private static  T parseMapToBean(Map map, Class t) {
		T obj = null;
		try {
			//创建一个空实例
			obj = t.newInstance();
			//获取map集合的键集(所有列名称)
			Set keys = map.keySet();
			for (String cname : keys) {
				//获取属性对象
				Field f = t.getDeclaredField(cname);
				//获取set方法的名称
				String setMethodName = "set" + cname.substring(0, 1).toUpperCase()+cname.substring(1);
				//获取set方法对象
				Method method = t.getMethod(setMethodName, f.getType());
				//执行方法
				method.invoke(obj, map.get(cname));
			}
			
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return obj;
	}
	
	/**
	 * 封装通用的查询集合操作,对于任何形式的查询,都能返回一个对象集合
	 * @param t  需要返回的数据类型(泛型)
	 * @param sql  目标查询语句
	 * @param params  执行查询所需的参数
	 * @return  返回包含指定对象的集合
	 */
	public static  List queryList(Class t,String sql,Object... params){
		//声明空集合
		List data = new ArrayList<>();
		//获取查询结果信息
		List> list = getDataPair(sql,params);
		if(list.isEmpty()){
			return data;
		}
		for (Map map : list) {
			T obj = parseMapToBean(map,t);
			data.add(obj);
		}
		return data;
	}

	/**
	 * 封装通用的查询对象操作,对于任何形式的查询,都能返回一个确定的对象
	 * @param t  需要返回的数据类型(泛型)
	 * @param sql  目标查询语句
	 * @param params  执行查询所需的参数
	 * @return  返回指定对象
	 */
	public static  T queryOne(Class t,String sql,Object... params){
		List> list = getDataPair(sql,params);
		if(list.size()>0){
			Map map = list.get(0);
			T obj = parseMapToBean(map,t);
			return obj;
		}
		return null;
	}

你可能感兴趣的:(对jdbc中操作数据库的简单封装(含连接,关闭,增删改查等))