package day4;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;
/*
* !!!!使用前提(也就是局限性):
* pojo包中类的字段名称必须和数据库中的字段一一对应
*
* 原因:因为是根据java反射机制编写的,所以在给对象赋值的时候,获取的是该类的
* 所有属性值个方法,所以为了赋值成功,类中成员变量字段必须和数据库中的字段相同
* */
public class JDBCUtil {
private static String url = null;
private static String className = null;
private static String root = null;
private static String password = null;
private static Connection con = null;
private static PreparedStatement ps = null;
private static ResultSet rs = null;
//静态代码块,进行初始化操作
static {
Properties properties = new Properties();
try {
Class clazz = JDBCUtil.class;
// 获取需要加载资源的流数据,加载的是在类路径下的文件,因为没有加/
InputStream inStream = clazz.getResourceAsStream("jdbc.properties");
// 加载数据
properties.load(inStream);
url = (String) properties.get("url");
root = (String) properties.get("user");
password = (String) properties.get("password");
className = (String) properties.get("driverClass");
// 1.加载驱动
Class.forName(className);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 数据库连接操作
* */
public static Connection getConnection() {
try {
// 2.建立数据库连接
con = DriverManager.getConnection(url, root, password);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}
/*
* 更新操作
* */
public static void myUpdate(String sql, Object[] obj) {
con = getConnection();
try {
ps = con.prepareStatement(sql);
if (obj != null) {
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
}
ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeAll(con, ps, rs);
}
}
/*
* 查询操作
*
* @Param sql 是sql语句
*
* @Param obj 是传递过来的sql中需要传值的数组
*
* @Param clazz 是需要返回的对象的类型
*/
public static ArrayList<Object> myQuery(String sql, Object[] obj, Class clazz) {
//获取数据库连接
con = getConnection();
//创建接收参数的集合
ArrayList<Object> list = new ArrayList<>();
try {
ps = con.prepareStatement(sql);
if (obj != null) {
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
}
rs = ps.executeQuery();
while (rs.next()) {
// 获取传入类的一个实例
Object newInstance = clazz.newInstance();
// 获取类的声明参数
Field[] declaredFields = clazz.getDeclaredFields();
Method[] declaredMethods = clazz.getDeclaredMethods();
// 找出类所有的方法,并且找到其中所有的set方法,并且找到对应的属性,进行赋值;
// 方式:外层嵌套方法循环
// 先判断第一个方法是否是set类型的方法,并且进去属性的嵌套循环,从而判断是否是该属性的set方法
// !!!前提:
// 对应属性必须有set方法!!!
// 且如数据库字段相同
for (int i = 0; i < declaredMethods.length; i++) {
for (int j = 0; j < declaredFields.length; j++) {
if (declaredMethods[i].getName().equals("set"
+ declaredFields[j].getName().substring(0, 1).toUpperCase()
+ declaredFields[j].getName().substring(1, declaredFields[j].getName().length()))) {
declaredMethods[i].invoke(newInstance, rs.getObject(declaredFields[j].getName()));
}
}
}
list.add(newInstance);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
closeAll(con, ps, rs);
}
return list;
}
/*
* 关闭操作
* */
private static void closeAll(Connection con, PreparedStatement ps, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
只是针对在刚学习jdbc操作阶段进行了封装。可以解决一部分代码重复,当然后面的学习就是用框架了,可以更加灵活和方便。
jdbc.properties在同一级包中
(如果有不足的地方还忘各位老铁们指出)