利用反射实现mysql数据库sql查询 返回List泛型(持久化)对象

  • Post author:
  • Post category:mysql

利用反射实现sql查询,得到持久化对象

标题想不出言简意赅的词汇,想找相关信息的朋友们,先来看看方法结构是否符合你的胃口。
public static <E> List<E> getObjectBySql(String sql,E e)
{   
    List<E> list = new ArrayList<E>();
    //...
    //.方法区域
    //...
    return list; 
}

正题


重温了一下hibernate中的hql,发现其中得到持久化对象很新奇,自己研究了会儿。
实现原理是利用 反射机制 通过 传入的Class对象(类似String.Class) 得到该对象的所有方法、变量名。
实现步骤如下:

import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * Created by HaoWeiTao on 2017/5/15.
 */
public class Eazy01 {
    private static DataSource ds ;//连接池

    static {
        Properties properties = new Properties();//得到一个properties对象
        try {
            properties.load(new FileInputStream("src\\main\\dbcp.properties"));//加载properties文件
            ds = BasicDataSourceFactory.createDataSource(properties);//通过连接池工厂加载数据
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static <E> List<E> getObjectBySql(String sql,E e)
    {
        Connection conn = null;     //连接
        Statement st = null;
        ResultSet rs = null;
        List<E> list = new ArrayList<E>();
        try {
            conn = ds.getConnection();  //得到一个连接
            st = conn.createStatement();
            rs = st.executeQuery(sql);
            ResultSetMetaData rsmd = rs.getMetaData();//得到结果集元数据对象,可以通过该对象得到列数,列名等信息
            int count = 0;
            while (rs.next())
            {
                Class<?> eClas = e.getClass();
                E eObj = (E) eClas.newInstance();
                int len = rsmd.getColumnCount();
                count++;
                for (int i=1;i<=len;i++)
                {
                    //得到列名
                    String columnName = rsmd.getColumnName(i);
                    //将列名首字母转大写
                    String columnNameUpCase = columnName.substring(0,1).toUpperCase()+columnName.substring(1);
                    //得到每一列在泛型对象中对应的set方法名
                    String columnSetMethod = "set"+columnNameUpCase;
                    Field filed = eClas.getDeclaredField(columnName);
                    Class<?> clazz = filed.getType();   //得到字段名对应的类型
                    //字段为int类型
                    if (clazz.isAssignableFrom(int.class)) {
                        //getMethod(),第一个参数为方法名,后边参数是方法中参数的类型,方法中有几个参数就写几个类型
                        Method method = eClas.getMethod(columnSetMethod, int.class);
                        //invoke()方法第一个参数是执行方法的对象,第二个是执行方法时的实参
                        method.invoke(eObj,rs.getInt(i));
                    }
                    //字段为字符串类型的
                    else if (clazz.isAssignableFrom(String.class)) {
                        Method method = eClas.getMethod(columnSetMethod,String.class);
                        method.invoke(eObj,rs.getString(i));
                    }
                    //字段为double类型
                    else if (clazz.isAssignableFrom(double.class)) {
                        Method method = eClas.getMethod(columnSetMethod,double.class);
                        method.invoke(eObj,rs.getDouble(i));
                    } //字段为float类型
                    else if (clazz.isAssignableFrom(float.class)) {
                        Method method = eClas.getMethod(columnSetMethod,float.class);
                        method.invoke(eObj,rs.getFloat(i));
                    }//字段为Integer类型
                    else if (clazz.isAssignableFrom(Integer.class)) {
                        Method method = eClas.getMethod(columnSetMethod,Integer.class);
                        method.invoke(eObj,rs.getInt(i));
                    }//字段为Float类型
                    else if (clazz.isAssignableFrom(Float.class)) {
                        Method method = eClas.getMethod(columnSetMethod,Float.class);
                        method.invoke(eObj,rs.getFloat(i));
                    }//字段为double类型
                    else if (clazz.isAssignableFrom(Double.class)) {
                        Method method = eClas.getMethod(columnSetMethod,Double.class);
                        method.invoke(eObj,rs.getDouble(i));
                    }//字段为Date类型
                    else if (clazz.isAssignableFrom(Date.class)) {
                        Method method = eClas.getMethod(columnSetMethod,Date.class);
                        method.invoke(eObj,rs.getDate(i));
                    }
                }
                list.add(eObj);
            }
        } catch (SQLException e0) {
            e0.printStackTrace();
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        } catch (InstantiationException e1) {
            e1.printStackTrace();
        } catch (NoSuchFieldException e1) {
            e1.printStackTrace();
        } catch (NoSuchMethodException e1) {
            e1.printStackTrace();
        } catch (InvocationTargetException e1) {
            e1.printStackTrace();
        }
        return list;
    }

    public static void main(String[] args) {
        String sql = "select * from title"; //查询sql
        List<Title> list = getObjectBySql(sql,new Title());
        for (Title title:list) {
            System.out.println(title);
        }
    }
}
}

Title实体类

/**
 * Created by HaoWeiTao on 2017/5/15.
 */
public class Title {
    private int id;
    private int titleId;
    private String titleName;
    private double beilv;
    private int isEffective;

    public Title() {
    }

    public Title(int id, int titleId, String titleName, double beilv, int isEffective) {
        this.id = id;
        this.titleId = titleId;
        this.titleName = titleName;
        this.beilv = beilv;
        this.isEffective = isEffective;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public int getTitleId() {
        return titleId;
    }

    public void setTitleId(int titleId) {
        this.titleId = titleId;
    }

    public String getTitleName() {
        return titleName;
    }

    public void setTitleName(String titleName) {
        this.titleName = titleName;
    }

    public double getBeilv() {
        return beilv;
    }

    public void setBeilv(double beilv) {
        this.beilv = beilv;
    }

    public int getIsEffective() {
        return isEffective;
    }

    public void setIsEffective(int isEffective) {
        this.isEffective = isEffective;
    }

    @Override
    public String toString() {
        return "Title{" +
                "id=" + id +
                ", titleId=" + titleId +
                ", titleName=" + titleName +
                ", beilv=" + beilv +
                ", isEffective=" + isEffective +
                '}';
    }
}

下面是数据库源数据

数据库字段`

下面是运行结果

这里写图片描述`

《对应jar包有mysql-connect和dbcp》


版权声明:本文为q6834850原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。