关于JDBC的相关知识,可参考本人上文: 3、JDBC小疑惑
代码内容:利用JDBC返回数据库结果集,遍历结果集的数据后,利用反射将每个数据封装成一个实体对象,存入集合。
这段代码使用泛型可以让用户根据自身需要,反射不同的类对象,提升此代码的复用性,适用于想把数据库内容封装成实体对象的情况。前提是数据库属性名和实体对象中的属性名要一致,且实体对象类中各个属性有相应的setter方法。如果想直接在控制台打印出结果,还要在实体类中重写toString()方法。
数据库:mysql
public class ReflectTest {
/**
* @param t 类对象,利用类对象可以获取类的成员方法和成员变量(属性),以及创建类的实例
* @param <T> 泛型,可以根据需要使用不同的类
* @return 返回存放多个对象的集合
* @throws Exception
*/
public <T> ArrayList<T> findAll(Class<T> t) throws Exception {
//连接数据库,返回结果集
Class.forName("com.mysql.jdbc.Driver");
//databaseName为实际的数据库名称,username和password也以用户实际设置为准
String url = "jdbc:mysql://localhost:3306/databaseName";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, username, password);
//
String sql = "SELECT * FROM databaseName";
PreparedStatement pst = conn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
ArrayList<T> list = new ArrayList<>();
//获取类对象所有属性(getDeclaredFields():忽略访问权限,直接提取属性)
Field[] fields = t.getDeclaredFields();
while (rs.next()) {
//调用类对象的newInstance()静态方法来实例化对象
T obj = (T) t.newInstance();
//根据每个属性,获取相应setXxx方法,将结果集数据存入对象
for (Field field : fields) {
String name = field.getName();
//rs_obj:从结果集获取到的单个属性
Object rs_obj = rs.getObject(name);
//setXxx方法的第一个X要大写,这里要对字符串name进行第一个字母大写的处理
char[] chars = name.toCharArray();
chars[0] = (char) (chars[0] - 'a' + 'A');
String methodName = "set" + String.valueOf(chars);
//获取setXxx方法并执行,将单个属性封装到对象属性
//getMethod()参数:第一个为方法名,后面为该方法所需参数类型的类对象,根据实际可以写多个参数类型
Method method = t.getMethod(methodName,field.getType());
method.invoke(obj, rs_obj);
}
list.add(obj);
}
// 与上面方法对比:上者根据属性获取方法,下者根据方法获取属性,建议使用上者
// Method[] methods = t.getMethods();
// while (rs.next()) {
// T obj = (T) t.newInstance();
// for (Method method : methods) {
// String name = method.getName();
// if (name.contains("set")) {
// String field = name.substring(3, name.length()).toLowerCase();
// method.invoke(obj, rs.getObject(field));
// }
// }
// list.add(obj);
// }
return list;
}
//这里是本人的测试,里面的User应为用户想要封装的实体对象类名称。
//如果想在控制台成功打印对象,记得在实体对象类重写toString()方法,不然打印出来的会是一串串地址
@Test
public void mainTest() throws Exception {
ArrayList<User> list = findAll(User.class);
System.out.println(list);
}
}