JDBC封装工具类代码(JDBCUtil+BaseDao)

1、新建数据库的配置文件(db.properties)

注: 这里使用mysql数据库。java

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=1234

2、建立JDBC工具类(JDBCUtil.java)

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

/** * 使用JDBC进行数据库链接与关闭的工具类 * * @author XIAOHU * @since 2018-04-08 */
public class JDBCUtil {

	private static String driver;
	private static String url;
	private static String username;
	private static String password;

	static {
		init();
		try {
			// 加载一次驱动
			Class.forName(driver);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/** * 初始化数据库链接数据 */
	public static void init() {
		Properties prop = new Properties();
		InputStream is = 
		     JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");
		try {
			prop.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		driver = prop.getProperty("jdbc.driver");
		url = prop.getProperty("jdbc.url");
		username = prop.getProperty("jdbc.username");
		password = prop.getProperty("jdbc.password");
	}

	/** * 获取数据库链接 * * @return */
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

	/** * 释放全部资源 * * @param rs * 结果集 * @param st * Statement对象 * @param conn * 数据库链接 */
	public static void closeAll(ResultSet rs, Statement st, Connection conn) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (st != null) {
			try {
				st.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}

3、建立字符串工具类(StringUtil.java)

/** * 字符串处理工具类 * * @author XIAOHU * @since 2018-04-11 */
public class StringUtil {
	
	/** * 将字符串首字母转为大写 * @param str 要转换的字符串 * @return 返回转换后的首字母大写的字符串 */
	public static String toUpper(String str){
		return str.substring(0, 1).toUpperCase() + str.substring(1);
	}
	
}

4、建立DAO层实现类的公共父类(BaseDao.java)

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.util.ArrayList;
import java.util.List;

import cn.xiyou.petshopsystem.utils.JDBCUtil;
import cn.xiyou.petshopsystem.utils.StringUtil;

/** * 封装JDBC的增删改查功能 * * @author XIAOHU * @since 2018-04-11 * */
public class BaseDao<T> {

	/** * 封装增、删、改功能 * * @param sql * 须要执行的sql语句 * @param args * 不定参数,是对sql语句中的占位符“?”传入的参数 * @return 返回操做所影响的行数 */
	public int executeUpdate(String sql, Object... args) {
		Connection conn = null;
		PreparedStatement pst = null;
		int rows = 0;
		try {
			conn = JDBCUtil.getConnection();
			pst = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				pst.setObject(i + 1, args[i]);
			}
			rows = pst.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeAll(null, pst, conn);
		}
		return rows;
	}

	/** * 查询一条记录 * * @param sql * 须要执行的sql语句 * @param cls * 由此 Class对象建模的类的类型。若是将被建模的类未知,则使用 Class<?>。 * 例如,String.class 的类型是Class<String>。 * @param args * 不定参数,是对sql语句中的占位符“?”传入的参数 * @return 返回操做所影响的行数 */
	public T selectOne(String sql, Class<T> cls, Object... args) {
		List<T> list = this.selectMany(sql, cls, args);
		return list.isEmpty() ? null : list.get(0);
	}

	/** * 查询全部记录 * * @param sql * 须要执行的sql语句 * @param cls * 由此 Class对象建模的类的类型。若是将被建模的类未知,则使用 Class<?>。 * 例如,String.class 的类型是Class<String>。 * @param args * 不定参数,是对sql语句中的占位符“?”传入的参数 * @return 返回操做所影响的行数 */
	public List<T> selectMany(String sql, Class<T> cls, Object... args) {
		Connection conn = null;
		PreparedStatement pst = null;
		ResultSet rs = null;
		List<T> list = new ArrayList<T>();
		try {
			conn = JDBCUtil.getConnection();
			pst = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				pst.setObject(i + 1, args[i]);
			}
			rs = pst.executeQuery();
			//从结果集中获取数据库表的相关信息
			ResultSetMetaData metaData = rs.getMetaData();
			while (rs.next()) {
				T obj = cls.newInstance();// 建立cls实例
				//metaData.getColumnCount():得到数据库表中列数(字段数)
				for (int i = 1; i <= metaData.getColumnCount(); i++) {
					String columnLabel = metaData.getColumnLabel(i);//获取字段名
					
					// 动态拼接成该属性对应实体中的setter方法的方法名(=set字符串拼接首字母大写
					// 的属性名)。如:setName(Stringname)的方法名为setName
					String name = "set" + StringUtil.toUpper(columnLabel);
					// 获取实体中全部声明(私有+公有)的属性
					Field field = cls.getDeclaredField(columnLabel);
					// 获取实体中全部声明(私有+公有)的形参为field.getType()类型,方法名为
					// name的方法
					Method method = cls.getDeclaredMethod(name, field.getType());
					// 经过结果集获取字段名为fieldName(与实体中的对应属性名彻底相同)的值
					Object realParam = rs.getObject(columnLabel);
					// 执行obj对象中的method方法,传入的实参为realParam
					method.invoke(obj, realParam);
				}
				list.add(obj);
			}
		} catch (SQLException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeAll(null, pst, conn);
		}
		return list;
	}

	/** * 查询总记录数 * * @param sql * 须要执行的sql语句 * @param args * 须要对sql语句中的占位符“?”传入的参数数组 * @return 返回操做所影响的行数 */
	public int selectCount(String sql, Object... args) {
		Connection conn = null;
		PreparedStatement pst = null;
		ResultSet rs = null;
		int count = 0;
		try {
			conn = JDBCUtil.getConnection();
			pst = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				pst.setObject(i + 1, args[i]);
			}
			rs = pst.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.closeAll(null, pst, conn);
		}
		return count;
	}

}

说明: 这里仅作了部分封装,更多的封装须要本身去实现。BaseDao.java中的封装代码为重点,相似于一些框架底层的实现,想要更深一步学习封装的,但愿本身去看一些框架源码和设计模式。mysql