对JDBC进行简单的封装

  由于最近使用jdbc使用的比较频繁,在使用的过程做了一些简单的封装。
  在这里简单的记录一下,方便以后使用。迷路的大神请勿见笑。
  数据库使用的Oracle。
使用时用dao层类extends类BaseDaoImpl.java

  1. 获取数据库连接的类
    DBConn.java
package com.utils;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;

/**
 * @author yxln
 * @function 获取数据库连接
 * 		获取方式   DBConn.getInstance.getConn();
 */
public class DBConn {

	private DBConn() {
	}

	// 数据库连接
	private static DBConn instance = null ;
	// 数据库配置文件
	private static Properties props = null ;
	// 数据池
	private static BasicDataSource ds = null ;
	
	static {
		try {
			// 创建本类实例
			instance = new DBConn() ;
			props = new Properties() ;
			// 加载数据库配置文件
			props.load(DBConn.class.getResourceAsStream("/db.properties"));
			
			// 加载驱动类
			ds = new BasicDataSource() ;
			ds.setDriverClassName(props.getProperty("driver"));
			ds.setUsername(props.getProperty("username"));
			ds.setPassword(props.getProperty("password"));
			ds.setUrl(props.getProperty("url"));
			// 设置数据库最大活动数
			ds.setMaxActive(Integer.parseInt(props.getProperty("maxActive")));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取数据库连接
	 * @return
	 */
	public Connection getConn() {
		Connection conn = null ;
		try {
			// 数据库连接
			conn = ds.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn ;
	}
	
	/**
	 * @author yxln
	 * @function 关闭数据库操作先关的一些的
	 * @date 2018年9月29日
	 * @param conn 数据库连接Connection
	 * @param sm 执行sql的Statement
	 * @param rs 结果集REsultSet
	 */
	public static void closeConn(Connection conn, Statement sm,ResultSet rs ) {
			try {
				if(rs != null) {
					rs.close();
				}
			} catch (SQLException e1) {
				e1.printStackTrace();
			}finally {
				if(null != sm) {
					try {
						sm.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}finally {
						try {
							if(null != conn) {
								conn.close();
							}
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
				}
			}
	}
	
	/**
	 * @author yxln
	 * @function 关闭数据库操作先关的一些的
	 * @date 2018年9月29日
	 * @param conn 数据库连接Connection
	 * @param sm 执行sql的PreparedStatement
	 * @param rs 结果集REsultSet
	 */
	public static void closeConn(Connection conn, PreparedStatement ps,ResultSet rs ) {
		try {
			if(rs != null) {
				rs.close();
			}
		} catch (SQLException e1) {
			e1.printStackTrace();
		}finally {
			if(null != ps) {
				try {
					ps.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}finally {
					try {
						if(null != conn) {
							conn.close();
						}
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	public static DBConn getInstance() {
		return instance;
	}
}
  1. 数据库中查询的数据ResultSet映射到实体类
    ObjectMapping.java
package com.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 将数据库中查询的数据ResultSet映射到实体类 
 * @author YinXilin
 * @param <T> 要转换的实体类
 */
@SuppressWarnings("unchecked")
public class ObjectMapping<T> {
	
	CommonUtils<T> common = new CommonUtils<>() ;
	
	/**
	 * 将ResultSet类型的数据转换成实体类domain
	 * @param rs 从数据库中的查询到的结果集
	 * @param domain 结果数据的实体类
	 * @return
	 */
	public List<T> mapping(ResultSet rs,Class<?> domain) {
		List<T> list = null ;
		T t = null ;
		if(null != rs) {
			try {
				
				// 实体类中的属性
				Field[] fields = null ;
				// 利用反射执行实行实体类中的方法
				Method method = null ;
				// 从结果集中的获取的值
				String value = "" ;
				// 遍历结果集
				list = new ArrayList<T>() ;
				while(rs.next()) {
					// 实例化实体类
					t = (T) domain.newInstance() ;
					try {
						// 获取实体类中的所有属性
						fields = domain.getDeclaredFields() ;
						// 循环遍历实体类中的属性
						for(int i = 0 ; i < fields.length ; i++) {
							// 获得属性名
							String fieldName = fields[i].getName() ;
							// 如果属性名为 serialVersionUID , 不行执行操作,跳过此次循环
							if("serialVersionUID".equals(fieldName)) {
								continue ;
							}
							// 获取属性的类型
							Class<?> fieldType = fields[i].getType() ;
							// 获取实体类中的方法
							method = domain.getMethod(common.getMethodName(fieldName),fieldType) ;
							// 从结果集中获取实体类的属性对应的字段的值
							String str = common.attributeNameToFieldName(fieldName) ;
							value = rs.getString(str) ;
							if(value != null && value.length() > 0 && !"null".equals(value)) {
								// 实体类的对象t 利用反射调用实体类中的方法(将结果集中的值value映射到实体类中)
								// 如果这里报argument type mismatch异常,有可能是 convert方法没有对这种数据进行转换
								method.invoke(t, convert(fieldType, value)) ; 
							}
						}
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					} catch (NoSuchMethodException e) {
						e.printStackTrace();
					} catch (SecurityException e) {
						e.printStackTrace();
					}
					list.add(t) ;
				}
			} catch (SQLException e) {
				e.printStackTrace();
			} catch (InstantiationException e2) {
				e2.printStackTrace();
			} catch (IllegalAccessException e2) {
				e2.printStackTrace();
			}
		}
		return list ;
	}
	
	/**
	 * 将源数据转换成制定的类型
	 * @param fieldType 需要转换成的制定的类型
	 * @param origin 需要转换的源数据
	 * @return 转换成目标类型后的数据
	 */
	public Object convert(Class<?> targetType,String origin){
		// 转换的目标类型或元数据为空,则无法转换,直接返回源数据
		if(null == targetType || null == origin) {
			return origin ;
		}
		// 将源数据转换成Integer类型
		if(targetType.equals(Integer.class)) {
			return Integer.parseInt(origin) ;
		// 将源数据转换成Date类型
		}else if(targetType.equals(Date.class)) {
			Date date = null ;
			try {
				date = new SimpleDateFormat("yyyy-MM-dd").parse(origin) ;
			} catch (ParseException e) {
				e.printStackTrace();
			}
			return date ;
		}else if(targetType.equals(Double.class)) {
			return Double.parseDouble(origin) ;
		}
		return origin ;
	}
}
  1. CRUD基本操作接口
    IBaseDao.java
package com.dao;

import java.util.List;
import java.util.Map;

/**
 * @author yxln
 * @function 
 * @date 2018年10月18日
 */
public interface IBaseDao<T> {

	/*
	 * 插入单条数据 
	 */
	public int insert(String sql,Object... args);
	
	/*
	 * 通过po插入单条数据
	 */
	public int insertPo(T po);
	
	/*
	 * 查询单条数据
	 */
	public T query(String sql ,Object... paras) ;
	
	/*
	 * 分页查找数据
	 */
	public List<T> queryListByPage_Oralce(String sql ,Map<String,Object> map)  ;
	
	/*
	 * 多条件、单次数据删除
	 */
	public int delete(String sql , Object... args) ;
	
	/*
	 * 批量删除
	 */
	public void deleteBatches(String sql,Object[]... args) ;
	
	/*
	 * 修改数据
	 */
	public int update(String sql,Object... paras) ;
	
}
  1. CRUD实现类
    BaseDaoImpl.java
package com.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.dao.IBaseDao;
import com.utils.CommonUtils;
import com.utils.DBConn;
import com.utils.ObjectMapping;

/**
 * @author yxln
 * @param <T>
 * @function 
 * @date 2018年10月18日
 */
public class BaseDaoImpl<T> implements IBaseDao<T>{
	
	// 数据库连接
	Connection conn = null ;
	// sql预处理对象
	PreparedStatement ps = null ;
	// 结果集对象
	ResultSet rs = null ;

	// 工具类
	CommonUtils<T> common = null ;
	
	// 结果集映射对象
	ObjectMapping<T> objMapping = new ObjectMapping<T>() ;
	
	private Class clazz ;
	/**
	 * @author yxln
	 * @function 添加数据
	 * @date 2018年10月18日
	 * @param sql
	 * @return
	 */
	public int insert(String sql,Object... args) {
		
		// 获取数据库连接
		conn = DBConn.getInstance().getConn() ;
		int flag = 0 ;
		try {
			// 对sql语句进行预处理
			ps = conn.prepareStatement(sql) ;
			if(args != null) {
				int paramIndex = 1 ;
				for(Object obj:args) {
					// 当前的值如果为java时间(java.util.Date())类型,需要转换成java.sql.Date()
					if("java.util.Date".equals(obj.getClass().getName())) {
						ps.setObject(paramIndex++, new java.sql.Date(((java.util.Date) obj).getTime()));
					}else {
						ps.setObject(paramIndex++, obj);
					}
				}
			}
			flag = ps.executeUpdate() ;
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBConn.closeConn(conn, ps, null);
		}
		return flag;
	}

	/**
	 * @author yxln
	 * @function 将实体类中的数据插入到数据库中
	 * @date 2018年10月18日
	 * @param po 实体类对象(持久对象) 
	 * 			-- 实体类名一定要和数据库表明一样,
	 * 			-- 实体类中的属性和数据库字段对应,属性必须采用驼峰命名法,数据库中_后面的字母大写	
	 * @return
	 */
	public int insertPo(T po) {
		 common = new CommonUtils<>() ;
		// 取出实体类中的属性名与对应的值
		Map<String,Object> attrs = common.getObjectAttribute(po) ;
		// 获取实体类的类名
		String className = po.getClass().getSimpleName().toUpperCase() ;
		
		// 错做数据数据库结果
		int flag = 0 ;
		// 将实体类中的数据插入数据库的sql语句 的前半段
		StringBuffer sqlHalf1 = new StringBuffer("insert into "+ className + "(");
		// sql 语句的后半段
		StringBuffer sqlHalf2 = new StringBuffer("values(");
		// 根据实体类中的属性拼接sql语句
		for(String key:attrs.keySet()) {
			sqlHalf1.append(common.attributeNameToFieldName(key).toUpperCase() + ",") ;
			sqlHalf2.append("?,") ;
		}
		sqlHalf1.deleteCharAt(sqlHalf1.length()-1).append(") ") ;
		sqlHalf2.deleteCharAt(sqlHalf2.length()-1).append(") ") ;
		// 获取数据连接
		conn = DBConn.getInstance().getConn() ;
		try {
			// 对sql语句进行预处理
			ps = conn.prepareStatement(sqlHalf1.append(sqlHalf2).toString()) ;
			int paramIndex = 1 ;
			// 遍历attrs,将其中的值设置到预处理sql中对应的占位符上
			for(Object obj:attrs.values()) {
				// 当前的值如果为java时间(java.util.Date())类型,需要转换成java.sql.Date()
				if("java.util.Date".equals(obj.getClass().getName())) {
					ps.setObject(paramIndex++, new java.sql.Date(((java.util.Date) obj).getTime()));
				}else {
					ps.setObject(paramIndex++, obj);
				}
			}
			// 执行查询的sql语句
			flag = ps.executeUpdate() ;
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBConn.closeConn(conn, ps, null);
		}
		return flag;
	}
	
	/**
	 * @author yxln
	 * @function 查询单条数数据并将结果映射到实体类
	 * @param sql
	 * @param paras
	 * @return
	 * @date 2018年10月31日
	 */
	public T query(String sql ,Object... paras) {
		
		conn = DBConn.getInstance().getConn() ;
		ResultSet rs = null ;
		T t = null ;
		try {
			ps = conn.prepareStatement(sql) ;
			if(paras != null && paras.length > 0) {
				for(int i = 0 ; i < paras.length ; i++)
				ps.setObject(i + 1, paras[i]);
			}
			rs = ps.executeQuery() ;
			Type type = (ParameterizedType) this.getClass().getGenericSuperclass();
			if(type instanceof ParameterizedType) {
				this.clazz = (Class) ((ParameterizedType)type).getActualTypeArguments()[0];
			}else {
				System.out.println("【异常】没有给定泛型的类型");
			}
			t = (T) objMapping.mapping(rs, clazz).get(0) ;
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBConn.closeConn(conn, ps, rs);
		}
		return t ;
	}
	
	/**
	 * @author yxln
	 * @function  分页查找数据
	 * @param sql
	 * @param pageNo
	 * @param pageSize
	 * @return
	 * @date 2018年10月23日
	 */
	public List<T> queryListByPage_Oralce(String sql ,Map<String,Object> map) {
		
		// map、pageNo、pageSize 中任何一个为空,则不能完成分页查询,
		if(map == null || map.get("pageNo") == null || map.get("pageSize") == null) {
			System.out.println("map、pageNo、pageSize 中任何一个为空,则不能完成分页查询");
			return null;
		}
		conn = DBConn.getInstance().getConn() ;
		ResultSet rs = null ;
		List<T> list = null ;
		int pageNo = 1 ;
		int pageSize = 5 ;
		
		Type type = (ParameterizedType) this.getClass().getGenericSuperclass();
		if(type instanceof ParameterizedType) {
			this.clazz = (Class) ((ParameterizedType)type).getActualTypeArguments()[0];
		}else {
			System.out.println("【异常】没有给定泛型的类型");
		}
		
		if(map.get("pageNo") != null) {
			pageNo = Integer.parseInt(map.get("pageNo") + "") ;
			map.remove("pageNo") ;
		}
		if(map.get("pageSize") != null) {
			pageSize = Integer.parseInt(map.get("pageSize") + "") ;
			map.remove("pageSize") ;
		}
		sql = " select * from ( select all_data.*,rownum all_data_row  from ("+sql+
				") all_data where ROWNUM <= "+(pageNo * pageSize)+") where all_data_row > " +((pageNo - 1) * pageSize) ;
		try {
			ps = conn.prepareStatement(sql) ;
			if(map != null) {
				Set<String> keySet = map.keySet() ;
			}
			rs = ps.executeQuery() ;
			list = new ArrayList<T>() ;
			while(rs.next()) {
				list = objMapping.mapping(rs, this.clazz) ;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBConn.closeConn(conn, ps, rs);
		}
		return list ;
	}
	
	/**
	 * 
	 * @author yxln
	 * @function 多条件、单次数据删除(注意此方法传进多个参数并不是用于批量删除,批量删除使用本类中的方法deleteBatches())
	 * @param sql 删除的sql语句
	 * @param args 参数,与sql语句中占位符对应
	 * 		例子1:deleteBatches("delete from employee where id = ? and name = ?",new String[] {"6","yxln4"}) 
	 * 		例子1:deleteBatches("delete from employee where id = ? and name = ?","6","yxln4") 
	 * @return
	 * @date 2018年10月30日
	 */
	public int delete(String sql , Object... args) {
		//获取数据库连接
		conn = DBConn.getInstance().getConn() ;
		int flag = 0 ;
		try {
			// 获取sql预处理对象
			ps = conn.prepareStatement(sql) ;
			
			// 判断是否有参数
			if(args != null && args.length > 0) {
				for(int i = 0 ; i < args.length ; i++) {
					// 将参数设置到对应的占位符
					ps.setObject(i + 1, args[i]);
				}
			}
			flag = ps.executeUpdate() ;
			
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBConn.closeConn(conn, ps, rs);
		}
		return flag;
	}
	
	/**
	 * 
	 * @author yxln
	 * @function  批量删除 
	 * @param sql 执行批量删除的sql
	 * @param args 每一组参数(参数个数与占位符对应)
	 * 		例子1:deleteBatches("delete from employee where id = ? ",
	 * 						new String[] {"4","6"}) 
	 * 		例子2:deleteBatches("delete from employee where id = ? ","4","6") 
	 * 		例子3:deleteBatches("delete from employee where id = ? and name = ?",
	 * 						new String[] {"4","yxln3"},new String[] {"6","yxln4"}) 
	 * 		例子4:deleteBatches("delete from employee where id = ? and name = ?",
	 * 						new String[][] {new String[] {"23","yxln9"},new String[] {"24","yxln9"}}) 
	 * @date 2018年10月31日
	 */
	public void deleteBatches(String sql,Object[]... args) {
		
		conn = DBConn.getInstance().getConn() ;
		int[] flag = new int[] {};
		try {
			//不自动提交
			conn.setAutoCommit(false); 
			ps = conn.prepareStatement(sql) ;
			// 判断是否有参数
			if(args != null && args.length > 0) {
				// 判断参数中的对象是否为数组
				if(args[0].getClass().isArray() && ((Object[])args[0]).length > 0) {
					Object[] obj = null ;
					for(int i = 0 ; i < args.length ; i++) {
						obj = (Object[]) args[i] ;
						for(int j = 0 ; j < obj.length ; j++) {
							ps.setObject(j + 1, obj[j]);
						}
						ps.addBatch();
					}
					flag = ps.executeBatch() ;
					conn.commit(); 
				// 只想sql语句传入一个参数
				}else {
					for(int i = 0 ; i < args.length ; i++) {
						ps.setObject(1, args[i]);
						ps.addBatch();
					}
					flag = ps.executeBatch() ;
					conn.commit(); 
				}
			}
		} catch (SQLException e) {
			// 捕获到执行过程的中的异常,回滚
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally {
			try {
				conn.setAutoCommit(true);
			} catch (SQLException e) {
				e.printStackTrace();
			}finally {
				DBConn.closeConn(conn, ps, rs);
			}
		}
	}
	
	/**
	 * @author yxln
	 * @function 修改单条数据 
	 * @param sql 执行修改的sql语句
	 * @param paras 参数
	 * @return
	 * @date 2018年10月31日
	 */
	public int update(String sql,Object... paras) {
		
		conn = DBConn.getInstance().getConn() ;
		int flag = 0 ;
		try {
			ps = conn.prepareStatement(sql) ;
			
			if(paras != null && paras.length > 0) {
				for(int i = 0 ; i < paras.length ; i++) {
					ps.setObject(i +1, paras[i]);
				}
			}
			flag = ps.executeUpdate() ;
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBConn.closeConn(conn, ps, rs);
		}
		return flag ;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值