通过内省机制,将结果集自动映射到JavaBean中.
要求:
- JavaBean中的属性名和表的列名或列别名一一对应,大小写无所谓
- JavaBean代码
/**
* 实体类,成员变量名和数据库Users表的列名相同
*/
public class Users {
private int id;
private String loginId;
private String loginPwd;
private String realName;
private double score;
// getter/setter/toString等方法 略...
}
- 直接上测试类试一把
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
String sql = "select * from users";
Connection conn = DBUtils.getConn();
PreparedStatement pstat = conn.prepareStatement(sql);
ResultSet rs = pstat.executeQuery();
// 获取javaBean的描述信息
BeanInfo beanInfo = Introspector.getBeanInfo(Users.class);
// 获取属性描述器
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
// 获得结果集的元数据信息(包含列的数量,列的名称)
ResultSetMetaData rsmd = rs.getMetaData();
// 获得结果集中列的数量
int columnCount = rsmd.getColumnCount();
// 创建一个集合用于存储所有的别名,集合预设长度为结果集中列的数量
List<String> labelList = new ArrayList<String>(columnCount);
for(int i=0;i<columnCount;i++) {
// 将所有的列别名遍历出来,存入数组中
labelList.add(rsmd.getColumnLabel(i+1).toUpperCase());
}
List<Users> userList = new ArrayList<Users>();
while(rs.next()) {
// 创建对象
Object obj = Users.class.newInstance();
// 遍历属性描述器,
for (PropertyDescriptor pd : pds) {
String name = pd.getName();// 获得属性名
if(labelList.contains(name.toUpperCase())) { // 如果该属性存在于列名集合中
// 调用set方法,将列数据存入对象中
pd.getWriteMethod().invoke(obj, rs.getObject(name));
}
}
// 将对象存入集合
userList.add((Users)obj);
}
DBUtils.close(conn, pstat, rs);
System.out.println(userList);
}
}
- 把方法抽离,抽取成通用方法
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
public class JdbcRS {
public static <T> List<T> getList(ResultSet rs, Class<T> clazz) {
// 创建一个对象,通过内省执行方法的时候,调用该对象的方法
T obj = null;
// 创建一个集合,存储javaBean对象及返回数据
List<T> list = new ArrayList<T>();
try {
// 获取javaBean的描述信息
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
// 获取javaBean的属性描述器
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
// 获得结果集的元数据信息(包含列的数量,列的名称)
ResultSetMetaData rsmd = rs.getMetaData();
// 获得结果集中列的数量
int columnCount = rsmd.getColumnCount();
// 创建一个集合,存储所有的列别名
List<String> labelList = new ArrayList<String>(columnCount);
// 循环将列别名存入别名集合中
for(int i=0;i<columnCount;i++) {
labelList.add(rsmd.getColumnLabel(i+1).toUpperCase());
}
// 遍历查询结果集
while(rs.next()) {
// 创建对象
obj = clazz.newInstance();
// 遍历JavaBean属性描述器
for (PropertyDescriptor pd : pds) {
// 获取属性名
String name = pd.getName();
// 比对属性描述器中的属性是否在别名集合中存在
if(labelList.contains(name.toUpperCase())) {
// 筛选出存在的属性名,判断查询结果是否为空,避免将null值存入基本数据类型的错误
Object value = rs.getObject(name);
if(value!=null) {
// 获取查询结果,调用相对应的set方法存入对象属性中
pd.getWriteMethod().invoke(obj, value);
}
}
}
// 将对象存入集合
list.add(obj);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
- 最终的测试类
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
public class Demo {
public static void main(String[] args) throws Exception {
String sql = "select * from users";
Connection conn = DBUtils.getConn();
PreparedStatement pstat = conn.prepareStatement(sql);
ResultSet rs = pstat.executeQuery();
List<Users> list = JdbcRS.getList(rs, Users.class);
for (Users users : list) {
System.out.println(users);
}
DBUtils.close(conn, pstat, rs);
System.out.println(list);
}
}