package com.bjsxt.dao.impl;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import com.bjsxt.commons.JDBCUtil;
import com.bjsxt.dao.BaseDao;
/*
* 创建BaseDaoimpl类实现BaseDao的接口,实现接口中的抽象方法
* 将 对数据库操作的一整套流程 写成模板 以供使用
*/
public class BaseDaoimpl implements BaseDao {
public int excuteUpdate(String sql ,Object[] param) {
Connection conn =null;
PreparedStatement ps =null;
int rows=0;
try {
conn=JDBCUtil.getConnection();
conn.setAutoCommit(false);//设置手动提交事务
ps=conn.prepareStatement(sql);
ParameterMetaData pmd = ps.getParameterMetaData();//获取sql语句中需要的参数个数
//通过for循环绑定param数组中的参数到sql语句中
//因为无法判断需要的参数是什么类型的,就用setObject将参数作为对象
for(int i=0;i<pmd.getParameterCount();i++) {
ps.setObject(i+1,param[i] ); //(位置,参数)
}
rows=ps.executeUpdate();//启动更新
conn.commit();//手动开启事务提交
} catch (Exception e) {
e.printStackTrace();
JDBCUtil.rollback(conn);//设置事务回滚
}finally {
JDBCUtil.closeResoure(ps, conn);
}
return rows;
}
/*
* 完成通用查询的方法,利用泛型
*使用ORM映射:即将 Department d = new Department();
d.setDepartmentId(rs.getInt("department_id"));
d.setDepartmentName(rs.getString("department_name"));
d.setLocationId(rs.getInt("location_id"));
这一步封装到对象中去
关键点:需要将Dept类中,模型对象的属性名要和数据库中的列名相同
*/
@Override
//参数分别表示:输入的查询SQL语句、用来保存Dept中属性的数组、类对象(某张表)
public <T> List<T> find(String sql, Object[] param, Class<T> clazz) {
Connection conn=null;
PreparedStatement ps =null;
ResultSet rs= null;
List<T> list =new ArrayList<>();
try {
conn=JDBCUtil.getConnection();
ps=conn.prepareStatement(sql);
//调用特定方法得到sql语句中需要用的参数的个数
ParameterMetaData pmd=ps.getParameterMetaData();
//绑定参数
for(int i=0;i<pmd.getParameterCount();i++) {
ps.setObject(i+1, param[i]);
}
//处理结果集
rs=ps.executeQuery();
//获取结果集的信息,rs.getMetaData()返回是当前操作数据库的属性个数,即列数
ResultSetMetaData rsmd =rs.getMetaData();
while(rs.next()) {
//完成ORM处理,通过反射获取类模板,并且实例化
//因为具体用的是哪个类模板并不知道,所以用泛型T表示
T bean = clazz.newInstance();//这句话相当于Department dept =new Department();
for(int i=0;i<rsmd.getColumnCount();i++) {
//利用Apache工具包,完成获取clazz对象中的属性
//先获取数据库列名
String columnName =rsmd.getColumnName(i+1);//通过列的位置获取列名
Object value = rs.getObject(columnName);
//通过Apache工具包中的BeanUtil工具类,将值封装到对象中
BeanUtils.setProperty(bean, columnName, value);
list.add(bean);//将获取的对象保存到集合中
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtil.closeResoure(ps, conn);
JDBCUtil.closeResultSet(rs);
}
return list;
}
}

老师第一个红色圈中的ParameterMetaData这个类是怎么来的,它就是用来保存ps.getParameterMetaData获取的参数的个数的嘛,但是参数个数是整型,为什么不能用 int numbuer =ps.getParameterMetaData();表示呢
第二个圈中ResultSetMetaData也是一个特有的类嘛?同样的rsmd是用来保存属性个数的话为什么不可以用整型来保存?
黄色框中的rsmd.getColumnName(i+1)这方法,既然rsmd是参数个数的话,它怎么可以用 getColumnName(i+1)
Object类型的value表示的是什么?是获取列名所对应的Dept对象嘛?