设计一个方法 处理任何一个表格的任何一个查询单条
参数 SQL SQL上面所需的那些值Object 因为用户要保证sql顺序,可读性不好,所以用class类代替,可以不用顺序
返回值利用泛型
设计这个方法
public
//1.先创建一个用来存储最终返回值的变量
List
try {
//2.解析SQL
SQLAndKey sqlAndKey = handler.parseSQL(sql);
//3.加载驱动
Class.forName(className);
//4.获取连接
Connection connection = DriverManager.getConnection(url, user, password);
//5.创建状态参数(sql)
PreparedStatement pstat = connection.prepareStatement(sqlAndKey.getSQL());
//6.将SQL和那些值拼接在一起
if(obj!=null){
handler.handleParameter(pstat,obj,sqlAndKey.getKeyList());
}
//7.执行
ResultSet rs = pstat.executeQuery();
while(rs.next()){
//8.将结果集中的数据取出—-存入一个新的容器类
list.add((T)handler.handleResult(rs,resultType));
}
//8.关闭
rs.close();
pstat.close();
connection.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
//返回最终的对象
return list;
}
在第六步拼接的时候需要有小弟去处理 ArrayList 按顺序存放解析出来的全部key
* String 用来存放还原回去的那个原来的__sql 在第三天已经写了
因为我们是读取值,所以在读取存入一个新的容器的时候需要处理结果集,因为类型不一样所以需要单独处理赋值的问题
设计一个方法 负责将rs结果集的值取出来 存入一个新的容器中 基础类型 domain map 参数 rs class
Object handleResult(ResultSet rs,Class resultType) throws SQLException {
Object result = null;
if(resultType==int.class || resultType==Integer.class){
result = rs.getInt(1);
}else if(resultType==float.class || resultType==Float.class){
result = rs.getFloat(1);
}else if(resultType==double.class || resultType==Double.class){
result = rs.getDouble(1);
}else if(resultType==String.class){
result = rs.getString(1);
}else{
//觉得 map domain,这两个并不能进行简单的赋值,所以需要单独的找小弟去完成
if(resultType==Map.class){//map
result = this.getMap(rs);
}else{//domain
result = this.getObject(rs,resultType);
}
}
return result;
}
一个小小弟 负责帮助下面那个handleResult方法将rs结果集的值取出来 组合成一个domain对象
private Object getObject(ResultSet rs,Class resultType) throws SQLException {
Object obj = null;
try {
//通过反射创建一个对象 domain类型
obj = resultType.newInstance();//调用了一个默认无参数的构造方法创建了一个对象 new
//rs取值 存入obj中
ResultSetMetaData rsmd = rs.getMetaData();
//遍历结果集
for(int i=1;i<=rsmd.getColumnCount();i++){
//获取结果集中的每一个列名字
String columnName = rsmd.getColumnName(i);
//获取列名对应的值
Object value = rs.getObject(columnName);
//根据columnName反射找到obj中的某一个属性 操作属性将value存入
Field field = resultType.getDeclaredField(columnName);
//修改属性权限
field.setAccessible(true);//其实应该找寻属性对应的set方法 invoke那个set方法
//直接操作私有属性 赋值
field.set(obj,value);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return obj;
}
一个小小弟 负责帮助下面那个handleResult方法将rs结果集的值取出来 组合成一个map对象
private Map getMap(ResultSet rs) throws SQLException {
//1.创建一个新的map对象
Map result = new HashMap
//2.将结果集的所有信息取出来注意这里 用的是新方法来进行取值的操作
ResultSetMetaData rsmd = rs.getMetaData();
//3.rsmd遍历
for(int i=1;i<=rsmd.getColumnCount();i++){
//获取结果集中查询到的列名
String columnName = rsmd.getColumnName(i);
//通过列名获取 列值
Object value = rs.getObject(columnName);
//存入map集合
result.put(columnName,value);
}
return result;
}
总结:
这节课运用的方法和上节课类似,运用了许多集合的知识,在进行domain实体对象赋值的时候需要用到反射的原理,通过这几节课的学习,发现集合,反射,以及参数的运用并不是很熟,需要多多复习。