package jdbc;
import jdbc.POJO.Person;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
 * @program: tx_jdbc_demo
 * @description: ResultSet工具类
 * @author: czg
 * @create: 2019-09-29 14:38
 */
public class ResultSetUtil {
    /**
     * 获得Mysql数据库连接
     * @param url jdbc:mysql://127.0.0.1:3306/数据库名?serverTimezone=GMT%2B8
     * @param userName
     * @param psw
     * @return
     */
    public static Connection getMysqlConnetion(String url,String userName,String psw){
        Connection con=null;
        try {
            //使用发射机制加载mysql数据库的驱动 com.mysql.jdbc.Driver 已经被弃用了
            Class.forName("com.mysql.cj.jdbc.Driver");
            con = DriverManager.getConnection(url, userName, psw);
            return con;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获得Oracle数据库连接
     * @param url  jdbc:oracle:thin:@localhost:1521:数据库名
     * @param userName
     * @param psw
     * @return
     */
    public static Connection getOracleConnetion(String url,String userName,String psw){
        Connection con=null;
        try {
            //使用发射机制加载oracle数据库的驱动
            Class.forName("oracle.jdbc.driver.OracleDriver");
            con = DriverManager.getConnection(url, userName, psw);
            return con;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 通过忽略属性的访问权限进行赋值 (所转对象必须存在无参构造方法)
     * @param rs
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> List<T> parseResultSetByField(ResultSet rs, Class<T> cls) {
        List<T> list=new ArrayList<>();
        try {
            //将查询数据转换为对象
            while (rs.next()){
                //实例化对象
                T obj=cls.newInstance();
                //获取类中所有的属性
                Field[] arrf=cls.getDeclaredFields();
                //遍历属性
                for(Field f:arrf){
                    //判断返回结果集中是否存在该属性字段
                    if(isExistColumn(rs,f.getName())){
                        //设置忽略访问校验
                        f.setAccessible(true);
                        //如果该列存在为属性设置内容
                        f.set(obj, rs.getObject(f.getName()));
                    }
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    /**
     * 通过反射机制对set方法的执行,进行赋值(实体类属性必须有对应的set,get方法,存在无参构造方法)
     * @param rs
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> List<T> parseResultSetByMethod(ResultSet rs, Class<T> cls) {
        List<T> list=new ArrayList<>();
        try {
            //将查询数据转换为对象
            while (rs.next()){
                //实例化对象
                T obj=cls.newInstance();
                //获取类中所有的属性
                Field[] arrf=cls.getDeclaredFields();
                //遍历属性
                for(Field f:arrf){
                    //判断返回结果集中是否存在该属性字段
                    if(isExistColumn(rs,f.getName())){
                        //属性名字
                        String fieldName=f.getName();
                        //属性对应的set方法
                        StringBuilder methodName=new StringBuilder("set").append(fieldName.substring(0,1).toUpperCase())
                                .append(fieldName.substring(1));
                        //获得属性的类型
                        Class fieldType = f.getType();
                        //获得属性对应的set方法的对象
                        Method method = cls.getMethod(methodName.toString(), fieldType);
                        //执行set方法
                        method.invoke(obj,rs.getObject(fieldName));
                    }
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    /**
     * 判断查询结果集中是否存在某列
     * @param rs 查询结果集
     * @param columnName 列名
     * @return true 存在; false 不存在
     */
    public static boolean isExistColumn(ResultSet rs, String columnName) {
        try {
            if (rs.findColumn(columnName) > 0 ) {
                return true;
            }
        }
        catch (SQLException e) {
            return false;
        }
        return false;
    }
    /**
     * 便捷查询
     * @param con  数据库连接
     * @param sql  查询语句
     * @param cls  返回实体类的Class对象
     * @return
     */
    public static <T> List<T> queryBySql(Connection con,String sql,Class<T> cls){
        List<T> lists=null;
        try {
            PreparedStatement statement = con.prepareStatement(sql);
            ResultSet resultSet = statement.executeQuery();
            lists=parseResultSetByMethod(resultSet,cls);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return lists;
    }
}