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

来源:互联网 发布:conor maynard知乎 编辑:程序博客网 时间:2024/06/05 05:02

利用反射实现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》

阅读全文
0 0
原创粉丝点击