JDBC+反射封装工具类

JDBC+ 反射实现一个简易的工具类

首先构建一个反射工具类
主要有获取方法和获取字段两个方法
本来是准备再写个获取对应方法的参数名和参数类型的
如下 打印出来的参数名是 arg0>>class java.lang.Long
不是我们想要的 且在1.8后才能获取 所以在下面的getMethod方法使用一个
取巧的方式 且只针对javabean的set方法 显然很 low

		Method men = cls.getMethod("setId", Long.class);
		Parameter[] parameters = men.getParameters();
		for (Parameter parameter : parameters) {
			System.out.println(parameter.getName() + ">>" + parameter.getType());

		}
public class ReflectClassUtil {
	/**
	 * 获取类中所有字段和对应类型 将字段名做key 类型做value
	 * 
	 * @param cls
	 * @return Map
	 */
	public Map getField(Class cls) {
		HashMap<String, Class> map = new HashMap();
		Field[] fields = cls.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Field fiel = fields[i];
			fiel.setAccessible(false);
			map.put(fiel.getName(), fiel.getType());
		}
		return map;
	}

	/**
	 * 通过字节码文件对象获取改类的所有方法 用参数名做key值 method做值
	 * 
	 * @param 
	 * @param cls
	 * @return Map
	 */
	public Map getMethods(Class cls) {
		Method[] methods = cls.getDeclaredMethods();
		Map<String, Method> map = new HashMap<>();
		for (Method method : methods) {
			method.setAccessible(false);
			if (method.getName().startsWith("set")) {
				//将方法名截取set 获得后面的字符串  再将首字母大写转为小写即可获得参数名
				//显然很low 且大大降低了复用性
				char[] ns = method.getName().substring(3).toCharArray();
				ns[0] = Character.toLowerCase(ns[0]);
				String name = new String(ns);
				// System.out.println(name);
				map.put(name, method);
			}
		}
		return map;
	}
}

在结合jdbc 将查询方法的代码复用性提高
下面类中提供了statement方法 和PreparedStatement方法
查询代码大同小异 其他诸如增加 删除 修改只需简单封装成方法即可调用

import java.io.IOException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
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.List;
import java.util.Map;
import java.util.Properties;

public class JDBCUtill {
	private static JDBCUtill instance;
	private static Properties prop = new Properties();
	private String url;
	private String username;
	private String password;
	static {
		try {
			prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties"));
			Class.forName(prop.getProperty("driverClassName"));
			instance = new JDBCUtill();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 一个简易的封装查询方法
	 * 
	 * @param cls
	 * @param sql
	 * @return
	 */
	public <T> List<T> qeuryAll(T t, String sql) {
		Connection conn = getConnection();
		Statement statement = getStatement(conn);
		ResultSet rs = getResultSet(statement, sql);
		ReflectClassUtil util = new ReflectClassUtil();
		Class cls = t.getClass();
		ResultSetMetaData metaData = null;
		Map methodsmap = util.getMethods(cls);
		List<T> list = new ArrayList<>();
		try {
			Object o = cls.newInstance();
			metaData = getResultSetMetaData(rs);
			int count = metaData.getColumnCount();
			while (rs.next()) {
				for (int i = 1; i <= count; i++) {
					String name = metaData.getColumnName(i);
					Object os = rs.getObject(name);
					Method method = (Method) methodsmap.get(name);
					method.invoke(o, os);
				}
				list.add((T) o);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;

	}

	/**
	 * 获取连接对象
	 * 
	 * @return Connection
	 */
	public Connection getConnection() {
		url = prop.getProperty("url");
		username = prop.getProperty("username");
		password = prop.getProperty("password");
		Connection conn = null;
		try {

			conn = DriverManager.getConnection(url, username, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}

	/**
	 * 
	 * @param conn
	 *            连接对象
	 * @return Statement
	 */
	public Statement getStatement(Connection conn) {
		Statement ps = null;
		try {
			ps = conn.createStatement();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ps;
	}

	/**
	 * 
	 * @param sql
	 *            预编译语句
	 * @param conn
	 * @param params
	 *            params中的数据要和预编译中插入的数据顺序一致
	 * @return PreparedStatement
	 */
	public PreparedStatement getPreparedStatement(String sql, Connection conn, Object[] params) {
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 1; i <= params.length; i++) {
				ps.setObject(1, params[i - 1]);

			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return ps;

	}

	/**
	 * 
	 * @param statement
	 * @param sql
	 *            执行语句
	 * @return ResultSet
	 */
	public ResultSet getResultSet(Statement statement, String sql) {
		ResultSet rs = null;
		try {
			rs = statement.executeQuery(sql);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return rs;
	}

	/**
	 * 
	 * @param rs
	 *            ResultSet
	 * @return ResultSetMetaData
	 */
	public ResultSetMetaData getResultSetMetaData(ResultSet rs) {
		ResultSetMetaData metaDate = null;
		try {
			rs.getMetaData();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return metaDate;

	}

	public static JDBCUtill getInstance() {
		return instance;
	}

	private JDBCUtill() {

	}

}

补充:在经过查询之后 发现下面这篇文章解决了java1.8获取参数名为arg0的问题
原文链接:https://www.cnblogs.com/zhangshiwen/p/6022794.html

总结:总的来说 本代码的改进之处还有很多 受限之处颇多
如果以mybatis框架为准的话 可以将sql和javaBean类信息写在XML文件中
然后利用Dom4j解析xml文件获取对应的sql语句
且数据库连接对象Connection可以利用JDBC写一个原生的数据库连接池.

结语:编程路漫漫 永无止境

你可能感兴趣的:(JDBC,反射)