JDBC的批量添加-大数据处理-结果集的元数据-Class反射-JDBC查询封装

一、使用JDBC批量添加

​ 知识点复习:

​ JDBC的六大步骤 (导入jar包, 加载驱动类,获取连接对象, 获取sql执行器、执行sql与并返回结果, 关闭数据库连接)

​ 封装了一个DBUtil 类, 通过读取属性文件的方式获取 基础连接信息。

​ 批量添加: 一次性可执行多个添加记录 ,将多个sql语句在当前这次连接中执行完毕。

    // 设置部门集合
        List<Dept> list = new ArrayList<>();
        list.add(new Dept(60,"市场部","武汉市"));
        list.add(new Dept(70,"研发部","武汉市"));
        list.add(new Dept(80,"教学部","武汉市"));

          //通过DBUtil获取数据库连接
        Connection conn = DBUtil.getConn();
        String sql="insert into dept(deptno,dname,loc) values (?,?,?)";
          //获取预编译sql执行器
        PreparedStatement ps = conn.prepareStatement(sql);
        //批量设置该条sql语句的 参数
        for(Dept dept : list){
            //设置参数
            ps.setInt(1,dept.getDeptno());
            ps.setString(2,dept.getDname());
            ps.setString(3,dept.getLoc());
            // 将设置好的参数 先放入批量添加的容器中
            ps.addBatch();
            //  对于完整的sql语句 可以用有参的
           // ps.addBatch(sql);
        }
        // 执行sql语句  返回每一行sql语句影响的行数  ,
        int [] counts = ps.executeBatch();
        System.out.println("结果长度:"+ counts.length);
        System.out.println("结果:"+ Arrays.toString(counts));
        //关闭sql语句
        DBUtil.closeAll(conn,ps,null);

补充知识点: Java使用Excel批量导入数据 到数据库中

1、先将Excel通过Java 的 POI框架 读取数据到内存中(List)

2、将List数据 批量添加到 数据库中。

package com.j2008.jdbc2;


import com.j2008.jdbc.Dept;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

import java.io.*;
import java.net.URLDecoder;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

//import javax.validation.ConstraintViolation;
//import javax.validation.Validation;
//import javax.validation.Validator;
//import javax.validation.ValidatorFactory;
//import org.springframework.expression.EvaluationException;

/**
 * ClassName: ExcelUtil
 * Description:
 * date: 2020/11/23 9:33
 *
 * @author wuyafeng
 * @version 1.0   softeem.com
 */
public class ExcelUtil {
   // Logger logger = Logger.getLogger(this.getClass());

    private String description = "";// 如果校验失败,将会给出详细提示信息
    private Sheet sheet;// execel 对象
    private List<String> fieldList;//从xml读取到的execel表格信息
    private int rowIndex = 0;//当前操作行
    private Object objectBean;//每一行数据封装
    private Cell cellStart;// 数据的开始单元格
    private Class clazz; //需要封装的类
//    private Validator validator; //hibernate 的校验器
    private String[] fieldVals ; //从execel读到的某一行的数据
    private int fieldSize = 0;  //有效数据的列数
    private DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); // 针对日期的默认转换形式
    private Expression exp ;//EL 解析器
    private ExpressionParser parser;

    private DecimalFormat df = new DecimalFormat("#");

    public String getDescription() {
        return description;
    }

    public Object getObjectBean() {
        return objectBean;
    }

    public ExcelUtil(InputStream execelIS,String xmlFilename,
                     Class clazz,String suffix) throws Exception{
        // 打开execel工作簿
        Workbook wb = null;
        try {
            if(suffix.equals(".xls")){
                wb = new HSSFWorkbook(execelIS);
            }else if(suffix.equals(".xlsx")){
                wb = new XSSFWorkbook(execelIS);
            }
            execelIS.close();
        } catch (IOException e) {
            throw new Exception("加载文件失败,请确保是否是Execel表格");
        }
        sheet = wb.getSheetAt(0);// 默认取第一个工作簿
        //读配置文件,获取所有的属性列描述
        fieldList = this.readFieldsFromXML(getAbsolutePath(xmlFilename));
        //个数
        fieldSize = fieldList.size();

        //找到有效数据的开始单元格
        cellStart = this.findStartCell();
        if(cellStart == null){
            throw new Exception(this.description);
        }

        //每次读取一行execel数据,rowIndex每次增1
        rowIndex = cellStart.getRowIndex()+1;

        //需要封装的对象类
        this.clazz = clazz;
        //初始化校验器
//        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
//        validator = factory.getValidator();
//        //初始化EL解析器
        parser = new SpelExpressionParser();
        exp = parser.parseExpression("values");
    }

    //是否还有数据
    public boolean hasNext(){
        Row row = sheet.getRow(rowIndex++);
        if(row == null)
            return false;
        fieldVals = this.getRowValues(row, cellStart.getColumnIndex());
        if(Arrays.asList(fieldVals).indexOf("") != -1){
            for(String s :fieldVals)//如果每个字段都是空的,则返回false 否则true
                if(!s.equals(""))
                    return true;
            return false;
        }
        return true;
    }
    //校验
    public boolean validate(){
        try {
            objectBean = Class.forName(clazz.getName()).newInstance();
        } catch (Exception e) {
           // logger.error(e);
            e.printStackTrace();
        }


        try{
           exp.setValue(objectBean, fieldVals);// 给objectBean的属性赋值

        }catch( Exception e){//由于所有的数据类型转换都有objectBean里面来处理,故可能有异常,需要进行相应的处理
            e.printStackTrace();
            return false;
        }

        return true;
    }

    private String[] getRowValues(Row row,int columnStartIndex){
        String[] values = new String[fieldSize];
        for(int j = columnStartIndex,t=0;t<fieldSize;j++,t++){
            Cell c = row.getCell(j);
            if(c==null){
                values[t] = "";
                continue;
            }
            switch(c.getCellType()){
                case Cell.CELL_TYPE_BLANK:
                    values[t] = "";
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    values[t] = String.valueOf(c.getBooleanCellValue());
                    break;
                case Cell.CELL_TYPE_NUMERIC:

                    if (HSSFDateUtil.isCellDateFormatted(c)) {
                        values[t] = format.format(c.getDateCellValue());
                    } else if(c.getCellStyle().getDataFormat() == 58) {
                        // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
                        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd");
                        double value = c.getNumericCellValue();
                        Date date = org.apache.poi.ss.usermodel.DateUtil
                                .getJavaDate(value);

                        values[t] = sdf.format(date);
                    }
                    else {
                        values[t] = new DecimalFormat("#").format(c.getNumericCellValue());
                    }
                    break;
                case Cell.CELL_TYPE_STRING:
                    values[t] = String.valueOf(c.getStringCellValue());
                    break;

                default:
                    values[t] = "";
                    break;
            }
        }
        return values;
    }
    // 根据某一个单元格,得到更人性化的显示,例如“A4”
    private String getCellRef(Cell cell) {
        return CellReference.convertNumToColString(cell.getColumnIndex()) + (cell.getRowIndex() + 1);
    }
    private  String getAbsolutePath(String file) throws Exception {
        try {
            file = this.getClass().getClassLoader().getResource(file).getFile();

        } catch (NullPointerException e) {
            throw new Exception("文件不存在");
        }
        try {
            // 解决当出现中文路径时不能解析的bug
            file = URLDecoder.decode(file, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new Exception( "解码失败");
        }
        return file;
    }
    private List<String> readFieldsFromXML(String xmlFilename)throws Exception{
        SAXReader reader = new SAXReader();
        Document document = null;

        try {
            document = reader.read(new File(xmlFilename));// 加载配置文件
        } catch (DocumentException e) {
            e.printStackTrace();
            this.description = "IO 异常,读取配置文件失败";
            throw new Exception("IO 异常,读取配置文件失败");
        }

        Element root = document.getRootElement();
        List<String> fields = new ArrayList<String>();
        for (Iterator iter = root.elementIterator("field"); iter.hasNext();) {
            Element field = (Element) iter.next();
            fields.add(field.getTextTrim());
        }

        return fields;
    }
    /**
     * 从execel表中找到数据开始的单元格
     * @return
     */
    private  Cell findStartCell(){
        String firstFieldDesc = this.fieldList.get(0);
        int endRow = sheet.getLastRowNum()>100?100:sheet.getLastRowNum();
        for(int i = 0;i<=endRow;i++){
            Row r = sheet.getRow(i);
            if (r == null)
                continue;
            for(int j = 0;j < r.getLastCellNum();j++){
                Cell c = r.getCell(j);
                if( c == null)
                    continue;
                if(c.getCellType() == Cell.CELL_TYPE_STRING){
                    if(c.getStringCellValue().trim().equals(firstFieldDesc)){//找到第一个符合要求的字段,接下来判断它相邻的字段是否都符合要求
                        if(fieldList.size()>r.getLastCellNum()-j){
                            this.description = "execel表格与所给配置描述不符,请下载模板文件";
                            return null;
                        }
                        for(int k=j+1,t=1;k<=j+fieldList.size()-1;k++,t++){
                            Cell c2 = r.getCell(k);
                            if(c2 == null){
                                this.description = "请确保单元格"+this.getCellRef(c2)+"内容是\""+fieldList.get(t)+"\"";
                                return null;
                            }
                            if(c2.getCellType() == Cell.CELL_TYPE_STRING){
                                if(c2.getStringCellValue().contains(fieldList.get(t)))
                                    continue;
                                else{
                                    this.description = "请确保单元格"+this.getCellRef(c2)+"内容是\""+fieldList.get(t)+"\"";
                                    return null;
                                }
                            }

                        }
                        return c;
                    }else
                        continue;
                }else
                    continue;
            }
        }
        this.description = "找不到\""+fieldList.get(0)+"\"这一列";
        return null;
    }

    public int getRowIndex() {
        return rowIndex;
    }

    public DateFormat getFormat() {
        return format;
    }


    public String createExcelIncludeFailReason(InputStream execelIS,String path,String newExcelName, HashMap<Integer,String> errHash) {
        FileOutputStream file;
        try {
            file = new FileOutputStream(path+"/"+newExcelName);
            Workbook workbook=this.getWorkbook(execelIS);
            Sheet s=workbook.getSheetAt(0);

            //int endRow = sheet.getLastRowNum()>100?100:sheet.getLastRowNum();
            int endRow = sheet.getLastRowNum();
            for(int i=1;i<=endRow;i++){
                if(errHash.get(i)!=null){
                    Row rowkk = s.getRow(i);
                    Cell error_cell = rowkk.createCell(fieldList.size());
                    error_cell.setCellValue(errHash.get(i));
                }
            }
            workbook.write(file);
            file.close();
        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        } catch (Exception e) {

            e.printStackTrace();
        }

        return newExcelName;
    }


    public String getFile(InputStream execelIS,String path,String appPath, List<Integer> listF, boolean b) {
        FileOutputStream file;
        try {
            file = new FileOutputStream(path+"/"+appPath);
            Workbook workbook=this.getWorkbook(execelIS);
            Sheet s=workbook.getSheetAt(0);
            Row row=null;
            //int endRow = sheet.getLastRowNum()>100?100:sheet.getLastRowNum();
            int endRow = sheet.getLastRowNum();
            for(int i=1;i<=endRow;i++){

                Row rowkk = s.getRow(i);
                Cell info_cell = rowkk.createCell(fieldList.size());
                info_cell.setCellValue("sss");

                //删除错误行
                if(b&& listF.contains(i)){
                    row=s.getRow(i);
                    if(row!=null)s.removeRow(row);
                }
                //删除正确行
                if(!b && !listF.contains(i)){
                    row=s.getRow(i);
                    if(row!=null)s.removeRow(row);
                }
            }
            workbook.write(file);
            file.close();
        } catch (FileNotFoundException e) {

            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return appPath;
    }
    public  Workbook  getWorkbook(InputStream execelIS) throws Exception{
        Workbook wb = null;
        try {
            wb = new HSSFWorkbook(execelIS);
        } catch (IOException e) {
            throw new Exception("加载文件失败,请确保是否是Execel表格");
        }
        return wb;
    }


    /**
     * 返回List集合
     * @param filePath
     * @param xmlName
     * @return
     * @throws Exception
     */
    public static List<Dept> getListByExcel(String filePath,String xmlName ) throws Exception {
        InputStream is = new FileInputStream(filePath);
        ExcelUtil eu = new ExcelUtil(is, xmlName, Dept.class,".xls");
        Dept cp = null;
        List<Dept> list = new ArrayList<>();
        while (eu.hasNext()) {
            if (eu.validate()) {
               // System.out.println( eu.getObjectBean());
                cp = (Dept) eu.getObjectBean();
              //  System.out.println(cp.getDeptno()+"/"+cp.getDname()+ "/"+cp.getLoc() );
                list.add(cp);
            }
        }
        return list;

    }

    

    /**
     *
     * @param args
     */
    public static void main(String[] args) throws Exception {

        /**
         *  使用Excel工具的前提
         *   1、定义一个实体类 , 并提供基本的get set方法 和 setValues方法
         *   2、提供一个 表头的 xml文件。  表头的名字和  xml中的   <field>部门编号</field>  一致
         *   3、 源数据: D:/dept.xls
         */

       List<Dept>  list =   getListByExcel("D:/dept.xls","importTitle.xml");
         for(Dept d : list){
             System.out.println(d);
         }
    }
}

二、JDBC处理大数据类型(Blob ,Text)

​ 将数据库中存储 类似图片,视频,音频,小说等这些大数据类型格式是,JDBC如何操作

分两种情况: 字节数据和字符数据

1、字节数据:

​ 原理: 存数据(添加记录):使用字节流先 读取到 内存中, 然后在保存数据中,

​ 取数据(根据id查询该结果记录): 先通过jdbc 从结果集中获取输入字节流,将字节流写出到磁盘中

添加数据:

  /**
     *  添加一个大数据类型
     * @throws Exception
     */
    public static void addImg() throws Exception {
        //获取连接
       Connection conn =  DBUtil.getConn();
       //获取预编译sql执行器
        String sql ="insert into mytest2 values(?,?,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);
        // 设置参数
        ps.setInt(1,1002);
        ps.setString(2,"李四");
        ps.setString(3,"男");
        ps.setString(4,"自我介绍说明");
        // 读取图片的源路径
        File file = new File("e:/12.jpg");
        FileInputStream fis = new FileInputStream(file);
        // 需要一个输入流
       // ps.setBlob(5,fis);
        ps.setBinaryStream(5,fis);
        //执行sql语句
       int count =   ps.executeUpdate();
       if(count>0){
           System.out.println("添加成功");
       }
       //关闭流
        DBUtil.closeAll(conn,ps,null);

    }

查询数据:

 /**
     *  根据id 获取 图片信息
     * @param id
     */
    public static String findById(int id) throws Exception {
            // 获取数据库连接
        Connection conn = DBUtil.getConn();
        //获取预编译sql执行器
        String sql = "select * from mytest2 where id = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1,id);
        ResultSet rs = ps.executeQuery();
        if(rs.next()){
            //获取记录
           String username =  rs.getString(2);
           //获取字节类型 blob
           Blob image = rs.getBlob("image");
           //获取字节流
           InputStream is =  image.getBinaryStream();
            FileOutputStream fos = new FileOutputStream("d:/my.jpg");
            // 文件读写
            byte [] b = new byte[1024];
            int len=0;
            while((len = is.read(b))!=-1){
                fos.write(b,0,len);
            }
            System.out.println("文件保存成功");
            fos.close();
            is.close();

            // 获取字符流 写出到文件中  text字段可直接通过String映射,也可以通过字符流
            Reader reader = rs.getCharacterStream("introduce");
            // 字符输出流 写出
            Writer writer = new FileWriter("d:/introduce.txt");
            char [] c = new char[1024];
            int len2 = 0;
            while( (len2 = reader.read(c)) !=-1){
                writer.write(c, 0 ,len2);
            }
            writer.close();
            reader.close();

            return username;

        }
        DBUtil.closeAll(conn,ps,rs);

        return null;

    }

三、JDBC元数据

​ 数据库的元数据表示数据库信息 和 结果集信息的 基础信息

1、 数据库元数据信息: DataBaseMetaData

​ 方法说明:

         //获取数据库连接
        Connection conn = DBUtil.getConn();
        DatabaseMetaData dbMetaData =  conn.getMetaData();
        System.out.println("数据库产品名称:"+ dbMetaData.getDatabaseProductName());
        System.out.println("数据库的主要版本"+dbMetaData.getDatabaseMajorVersion());
        System.out.println("数据库产品信息的版本"+dbMetaData.getDatabaseProductVersion());

        System.out.println("数据库的url:"+dbMetaData.getURL());
        System.out.println("驱动类:"+dbMetaData.getDriverName());
        System.out.println("用户名:"+dbMetaData.getUserName());

2、 结果集的元数据 ResultSetMetaData

用于获取结果集的基础信息(处理数据项以外的信息),例如字段名称,字段个数,字段的数据类型 ,字段值

用途: 可以通过字段信息 与Java实体类做映射关系 ,实现简易的ORM(Object Relation Mapping)框架

API :

getColumnCount

getColumnCount() : 获取字段的列个数

getColumnLabel(i) : 获取指定列的字段名

getColumnType(i):获取指定列的 类类型 : 常用类:

getColumnName() : 获取字段名 与getColumnLabel一样

1:char; 3:BigDecimal 4:int ;12 varchar 91 :Date

四、反射基础知识

1、为什么需要使用反射

​ 由于之前创建对象的过程 ,是已知这个类,然后对类进行编译,编译通过之后才可以创建对象, 现在可能出现 “未知的类” 只有“包名+类名” ,在运行期间才知道 该类是否存在,并动态创建该类的对象。 这时 创建对象的过程 可以通过反射的方式 完成。

​ 反射机制的定义: 对于任意一个类,都可以在运行期间,动态的创建该类的对象,能知晓该对象的属性和方法,并动态调用属性 和方法 ,这个过程就是Java的反射机制

​ 对于任意类 都存在一个该类的Class类型 ,如何获取类的Classs类型

方式一: Class cls = Class.forName("类的全类名")

方式二: Class cls = 类名.class;

方式三: Class cls = 类的对象名.getClass()

常用API

Construct:

​ cls.getConstructor(int.class , String.class); 根据参数类型和个数 获取cls 对应的 构造器对象

Field : 属性对应的类型

​ getDeclareFields () : 获取所有声明的属性 (包括 任何修饰符,不包括private修饰)

​ getFields(): 获取所有声明的public修饰的属性

getDeclareFiled(String name): 根据属性名获取属性对象

getField(String name):根据属性名获取属性对象 (必须是共有的 )

Method : 方法对应的类型

​ getDeclaredMethods() : 返回当前类的自己声明的方法

​ getMethods() :返回所有的方法(包括父类的)

​ invoke(obj,参数值) :调用该方法

​ getMethod(“方法名” ,参数值):根据方法名返回Method

            //获取所有的方法   返回当前类的自己声明的方法
            Method [] methods =  cls.getDeclaredMethods();
            System.out.println("当前类自己的方法========");
            for(Method  m : methods){
                //遍历每一个方法
                System.out.println(m.getName()+"------"+ m.getReturnType());
            }

            Method [] methods2 = cls.getMethods();
            System.out.println("它的所有方法=============");
            for(Method m : methods2){
                System.out.println(m.getName()+"---"+m);
            }

            // 调用属性 和 方法
            // 获取指定方法的方法
            Method m = cls.getMethod("sayHello", String.class);
            //调用方法 (参数1 : 方法所属的对象oibj  ,参数n : 方法的参数值)
            // retObj :方法调用的返回值
            Object retObj =  m.invoke(myObj,"商腾辉");
            System.out.println("方法返回值:"+retObj);


使用反射完成对象属性的拷贝功能

 /**
     * 对象的属性值拷贝
     * @param fromObj
     * @param toObj
     */
    public static void copy(Object fromObj ,Object toObj) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取这个对象的Class类型
        Class fromCls = fromObj.getClass();
        Class toCls = toObj.getClass();

        // 获取源对象的所有属性名
       Field[] fields = fromCls.getDeclaredFields();
       for(Field f : fields){
           //构建  getXxx的方法
           String methodName = "get"+ f.getName().substring(0,1).toUpperCase() +
                            f.getName().substring(1);
           //获取getXxx方法
           Method getMethod =  fromCls.getMethod(methodName,null);
           // 1 调用源对象的get方法,获取返回值, (如何获取get方法呢   id-》getId )
           Object value = getMethod.invoke(fromObj ,null);
           // 2 调用目标对象的set方法,设置值 ( set方法的参数类型 就是get方法的返回值类型,参数值就是get方法的返回值)
            String methodName2 ="set"+ f.getName().substring(0,1).toUpperCase() +
                    f.getName().substring(1);
           Method setMethod =   toCls.getMethod(methodName2,getMethod.getReturnType());
           //调用set方法
           setMethod.invoke(toObj ,value);
           System.out.println("属性赋值成功");
       }



      }

     Student stu1 = new Student(1001,"admin",22,"男");
        //目标对象
        Student stu2 = new Student();
        //复制对象的属性
        copy(stu1,stu2);
        System.out.println(stu1);
        System.out.println(stu2);

五、JDBC的添加,查询封装 (反射知识点)

​ 目前我们只对JDBC的 获取连接,关闭进行封装,对于 数据库表的操作 添加,删除修改,查询,根据id查询 ,都需要单独写,这样太麻烦了, 需要将公有的代码 简化。

​ 1、对添加,删除,修改方法写成一个方法

/**
     * 对于 添加,删除,修改方法    不同点在于  sql语句不同
     *  参数不同
     * @param sql  sql语句   insert into dept values(?,?,?)
     * @param objs 任意个数任意类型的参数  与sql的?一一对应
     * @return
     */
    public static  int executeUpdate(String sql ,Object ... objs){
        // 获取连接
        Connection conn=null;
        PreparedStatement ps=null;
        // 获取预编译sql执行器
        try {
            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql);
            //设置参数
            if(objs!=null){
                for(int i=0;i<objs.length;i++){
                    // 参数从1开始,数组objs的下标从0开始
                    ps.setObject(i+1 ,objs[i]);
                }
            }
            //执行sql语句
           int count = ps.executeUpdate();
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭连接
            DBUtil.closeAll(conn,ps,null);
        }
        return 0;
    }

查询

  /**
     * 查询所有的公共方法, 可以自动将结果集映射到 实体类上
     * @param sql  sql语句
     * @param cls  实体类的类型
     * @param <T>  实体类的泛型
     * @return
     */
    public static<T> List<T> listAll(String sql ,Class cls ){
        // 存储结果集的集合list
        List<T> list = new ArrayList<T>();
        Connection conn=null;
        PreparedStatement ps = null;
        ResultSet rs=null;
        try {
            //获取连接
            conn = DBUtil.getConn();
            ps = conn.prepareStatement(sql);
            rs  = ps.executeQuery();
            while(rs.next()){
                // 创建这个类型的对象
                Object obj = cls.newInstance();
                // 获取这个类的所有字段个数  获取每一行的元数据
                ResultSetMetaData rsmd = rs.getMetaData();
                int clsCount =rsmd.getColumnCount();
                for(int i=1;i<=clsCount;i++){
                    String columnName = rsmd.getColumnLabel(i);
                    //构建set方法
                    String setMethod =  "set"+columnName.substring(0,1).toUpperCase() + columnName.substring(1);
                   // 调用get方法 获取返回值类型
                    String getMethod = "get"+columnName.substring(0,1).toUpperCase() + columnName.substring(1);
                    Method m1 = cls.getMethod(getMethod,null);

                    //调用方法  方法的参数类型  是 get方法的返回值类型
                    Method m = cls.getMethod(setMethod, m1.getReturnType());
                    // 调用set方法
                    m.invoke(obj,rs.getObject(columnName));

                }
                // 将obj放入 list中
                list.add((T)obj);

            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }  catch (NoSuchMethodException e) {
            e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeAll(conn,ps,rs);
        }

        return list;
    }
/**
     * 根据id查询一行记录
     * @param sql
     * @param cls
     * @param <T>
     * @return
     */
    public static<T> T getById(String sql ,Class cls){
       List<T> list =  listAll(sql,cls)  ;
       //查询一个集合,取第一行记录
       return list.size()>0 ? list.get(0) : null;
    }

posted @ 2020-11-28 18:17  落雨♡̶初晴  阅读(102)  评论(0编辑  收藏  举报