约束条件:1.实体类中的属性名必须和查询的列名一致;
2.实体类中的属性类型必须和所查询列的类型对应
方法名及参数为:
public <T> List executeQuery(Class<T> cla, String sql, Object... params){
protected Connection conn = null;
protected PreparedStatement ps = null;
protected ResultSet rs = null;
}
//三个参数分别为所对应的实体类的class对象,SQL语句,可变参数。
第一步:连接数据库;
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动,字符串内容为驱动所在的引用。
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javaweb-db",
"root", "root");
// DriverManager.getConnection()中的三个参数分别为所调用的数据库的位置,
数据库的账号,数据库的密码。
第二步:创建预处理对象;
ps=conn.prepareStatement(sql);
第三步:设置?占位符的值。首先根据参数列表判断是否有?占位符;
if(params!=null&¶ms.length!=0){
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
}
第四步:执行查询结果,返回结果集;
rs=ps.executeQuery();
第五步:创建一个List集合用于接收返回的对象;
List<T> list=new ArrayList<>();
//<T>表示返回值泛型,意思就是你给我什么我就返回什么
第五步:获得数据库的元文件;
ResultSetMetaData rsmd=rs.getMetaData();
第六步:通过遍历rs集合,进行反射操作;
while(rs.next()){
//创建类对象
T t=cla.getDeclaredConstructor().newInstance();
//遍历rs集合
for(int i=0;i<rsmd.getColumnCount();i++){
//根据元文件获得对应的列名
String columnName=rsmd.getColumnName(i+1);
//根据列的编号获得每列数据
Object val=rs.getObject(i+1);
//获得属性值
Field fieldName=cla.getDeclaredField(columnName);
//拼接set方法名
String methodName="set"+columnName.substring(0,1).toUpperCase()
+columnName.substring(1);
//获取set方法
Method method=cla.getDeclaredMethod(methodName,fieldName.getType());
//调用set方法
method.invoke(t, ConvertUtils.convert(val,fieldName.getType()));
}
list.add(t);
}
return list;
总结:需要特别注意的是:并不是根据数据库的表的结构进行输出,不是说表中有多少列就输出多少列。而是通过灵活的通过sql语句,来得到输出的内容,进而确定需要操作哪些列。这里就用到了元文件,元文件中的内容主要就是表的结构(即就是我们在数据库中点击“设计表”出现的内容)。rs结果集通过ResultSetMetaData rsmd=rs.getMetaData();得到rsmd,即输出的元文件。进而通过rsmd.getColumnCount()得到一共输出了哪些列,通过rsmd.getColumnName(参数:列号)获得列的名字。然后进行反射操作。
完整代码:
public <T> List executeQuery(Class<T> cla, String sql, Object... params){
//连接数据库
Class.forName("com.mysql.cj.jdbc.Driver");
return conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javaweb-db?,
"root", "root");
//创建预处理对象
ps=conn.prepareStatement(sql);
//设置?占位符的值,根据parmas参数判断,sql语句是否含有?占位符
if(params!=null&¶ms.length!=0){
for(int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
}
//创建一个List对象
List<T> list=new ArrayList<>();
//执行查询结果,返回结果集
rs=ps.executeQuery();
//获得数据库的元文件
ResultSetMetaData rsmd=rs.getMetaData();
while(rs.next()){
//创建类对象
T t=cla.getDeclaredConstructor().newInstance();
//遍历rs集合
for(int i=0;i<rsmd.getColumnCount();i++){
//根据元文件获得对应的列名
String columnName=rsmd.getColumnName(i+1);
//根据列的编号获得每列数据
Object val=rs.getObject(i+1);
//获得属性值
Field fieldName=cla.getDeclaredField(columnName);
//拼接set方法名
String methodName="set"+columnName.substring(0,1).toUpperCase()
+columnName.substring(1);
//获取set方法
Method method=cla.getDeclaredMethod(methodName,fieldName.getType());
//调用set方法
method.invoke(t, ConvertUtils.convert(val,fieldName.getType()));
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
this.closeAll();
}
return null;
}