package javaee.db;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

 


/**
 * 父类DAO
 * @author kidd
 *
 */
public class BaseDAO<T> {

 private Connection con;//数据库连接
 
 private Statement stmt;//发送数据库执行请求
 
 private ResultSet rs;//数据库返回
 
 private PreparedStatement pstmt;//注册参数发送数据库执行请求
 
 /**
  * 获取连接
  * @return
  */
 public Connection getConnection(){
  return ConnectionManager.getConnectionByTomcat();
 }
 
 /**
  * 查询
  * @return 集合
  */
 public List<T> query(Class type,String sql,Object...args){
  List<T> list=new ArrayList<T>();//返回的集合
  this.con=getConnection();//con赋值
  try {
   this.pstmt=con.prepareStatement(sql);//发送SQL请求
   for (int i = 0; i < args.length; i++) {//循环注册传进来的参数
    pstmt.setObject(i+1, args[i]);
   }
   rs=pstmt.executeQuery();//执行查询返回结果集
   while(rs.next()){
    T entity=(T) type.getConstructor().newInstance();//实例化T
    Method[] methods=type.getMethods();//获取实体的所有方法
    for (Method method : methods) {//循环出所有的方法
     String methodName=method.getName();//获取所有的方法名字
     ColMapping colMapping=method.getAnnotation(ColMapping.class);
     if(methodName.startsWith("set") ){//所有方法名字是SET的方法
      String colName="";
      if(colMapping==null){
       colName=methodName.substring(3);//如果没有注解就截取他的SET后面的名字
      }else{
       colName=colMapping.value();//有注释就获取注释的值
      }
      Object colValue=rs.getObject(colName);//将要执行的值转换层OBJECT类型
      if(colValue!=null){
       method.invoke(entity, colValue);//执行这个方法
      }
     }
    }
    list.add(entity);//添加到这个集合
   }
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return list;//返回这个集合
 }
 
 /**
  * 更新
  * @return
  */
 public int update(String sql,Object...agrs){
  this.con=getConnection();//获取连接
  try {
   this.pstmt=con.prepareStatement(sql);//发送执行SQL语句
   for (int i = 0; i < agrs.length; i++) {//注册参数
    pstmt.setObject(i+1, agrs[i]);
   }
   int result=pstmt.executeUpdate();//获取返回值
   return result;
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return 0;//出错返回0
 }
 /**
  * 关闭数据库
  * @param rs
  * @param pstmt
  * @param con
  */
 public static void  dbClose(ResultSet rs,PreparedStatement pstmt ,Connection con){
  try {
   if (rs != null)rs.close();
   if (pstmt != null)pstmt.close();
   if (con != null)con.close();
  } catch (Exception e2) {
   // TODO: handle exception
  }
 }
}