package com.sf.jdbctest;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.util.JdbcUtils;
import org.apache.commons.dbutils.DbUtils;
import org.junit.Test;

import javax.sql.DataSource;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import static sun.plugin.javascript.navig.JSType.URL;

/**
 * 通过数据库的操作类
 * @param <T>
 */
public class BaseDao<T> {
    /**
     * 通过的增删改
     */
    public void update(Connection conn,String sql,Object...args) throws SQLException {
        PreparedStatement ps = conn.prepareStatement(sql);
        //赋值
        if(args != null && args.length>0){
            for (int i = 0;i<args.length;i++){
                ps.setObject(i+1,args[i]);
            }
        }
        ps.executeUpdate();
    }


    /**
     * 查询列表
     * 原生反射
     * @return
     */
    public List<T> getList(Connection connection , String sql ,Class<T> clazz ,Object...args)throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
        List<T> list = new ArrayList<>();
        T t = null;
        //获取PreparedStatement
        PreparedStatement ps = connection.prepareStatement(sql);
        //赋值
        if(args!=null && args.length>0) {
            for(int i=0;i<args.length;i++) {
                ps.setObject(i+1, args[i]);
            }
        }
        //执行
        ResultSet rs = ps.executeQuery();
        //获取数据库表的元数据信息
        ResultSetMetaData rsmd = rs.getMetaData();
        //获取数据库表的列总数
        int columnCount = rsmd.getColumnCount();
        while(rs.next()) {
            //实例化对象
            t=clazz.newInstance();
            //循环获取列名
            for(int i=0;i<columnCount;i++) {
                //通过列的下标获取列名
                String columnLabel = rsmd.getColumnLabel(i+1);
                //通过列标签获取列值
                Object columnValue = rs.getObject(columnLabel);
                //反射通过名称获取java对象中描述属性的对象
                Field field = clazz.getDeclaredField(columnLabel);//dept_id as deptId
                //取消私有权限
                field.setAccessible(true);
                //给属性对象赋值
                field.set(t, columnValue);
            }
            list.add(t);
        }
        return list;
    }

    /**
     * 通用查询(单个)
     * 原生反射
     */
    public T getT(Connection connection,String sql,Class<T> clazz,Object ...args) throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
        T t = null;
        //获取PreparedStatement
        PreparedStatement ps = connection.prepareStatement(sql);
        //赋值
        if(args!=null && args.length>0) {
            for(int i=0;i<args.length;i++) {
                ps.setObject(i+1, args[i]);
            }
        }
        //执行
        ResultSet rs = ps.executeQuery();
        //获取数据库表的元数据信息
        ResultSetMetaData rsmd = rs.getMetaData();
        //获取数据库表的列总数
        int columnCount = rsmd.getColumnCount();
        if(rs.next()) {
            //实例化对象
            t=clazz.newInstance();
            //循环获取列名
            for(int i=0;i<columnCount;i++) {
                //通过列的下标获取列名
                String columnLabel = rsmd.getColumnLabel(i+1);
                //通过列标签获取列值
                Object columnValue = rs.getObject(columnLabel);
                //反射通过名称获取java对象中描述属性的对象
                Field field = clazz.getDeclaredField(columnLabel);//dept_id as deptId
                //取消私有权限
                field.setAccessible(true);
                //给属性对象赋值
                field.set(t, columnValue);
            }
        }
        return t;
    }


//    /**
//     * 通用查询(单个)
//     * 使用下面工具进行反射赋值
//     * commons-beanutils-1.8.0.jar
//     * commons-logging-1.1.1.jar
//     */
//    public T getT_(Connection connection,String sql,Class<T> clazz,Object ...args) throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, InvocationTargetException, NoSuchMethodException {
//        T t = null;
//        //获取PreparedStatement
//        PreparedStatement ps = connection.prepareStatement(sql);
//        //赋值
//        if(args!=null && args.length>0) {
//            for(int i=0;i<args.length;i++) {
//                ps.setObject(i+1, args[i]);
//            }
//        }
//        //执行
//        ResultSet rs = ps.executeQuery();
//        //获取数据库表的元数据信息
//        ResultSetMetaData rsmd = rs.getMetaData();
//        //获取数据库表的列总数
//        int columnCount = rsmd.getColumnCount();
//        if(rs.next()) {
//            //实例化对象
//            t=clazz.newInstance();
//            //循环获取列名
//            for(int i=0;i<columnCount;i++) {
//                //通过列的下标获取列名
//                String columnLabel = rsmd.getColumnLabel(i+1);
//                //通过列标签获取列值
//                Object columnValue = rs.getObject(columnLabel);
//                //反射通过名称获取java对象中描述属性的对象
//                //Field field = clazz.getDeclaredField(columnLabel);//dept_id as deptId
//                //取消私有权限
//                //field.setAccessible(true);
//                //给属性对象赋值
//                //field.set(t, columnValue);
//                PropertyUtils.setProperty(t, columnLabel, columnValue);
//            }
//        }
//        return t;
//    }


    /**
     * 数据库连接池
     */
    @Test
    public void t11() throws SQLException {
        DruidDataSource ds = new DruidDataSource();
        //设置初始化参数
        ds.setUrl("jdbc:mysql://localhost:3306/jdbc?characterEncoding=utf-8");
        ds.setUsername("root");
        ds.setPassword("root");
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        Connection conn = ds.getConnection();
        String sql = "INSERT INTO user(user_name,price,create_time) VALUES(?,?,?)";
//        预编译
        PreparedStatement pre = conn.prepareStatement(sql);
        pre.setString(1,"admin");
        pre.setDouble(2,100.21);
        pre.setDate(3,new Date(new java.util.Date().getTime()));
//        执行进行绑定参数之后的sql语句
        int i = pre.executeUpdate();
        System.out.println(i);
    }


    /**
     * 连接池2
     */
    @Test
    public void t12() throws Exception {
//听过加载外部配置文件的方式
        Properties p = new Properties();
        p.load(JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties"));
//采用Druid提供的工厂类创建DruidDataSource对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(p);
        Connection conn = dataSource.getConnection();

        String sql = "INSERT INTO user(user_name,price,create_time) VALUES(?,?,?)";
//        预编译
        PreparedStatement pre = conn.prepareStatement(sql);
        pre.setString(1,"admin");
        pre.setDouble(2,100.21);
        pre.setDate(3,new Date(new java.util.Date().getTime()));
//        执行进行绑定参数之后的sql语句
        int i = pre.executeUpdate();
        System.out.println(i);
    }

}
