利用反射实现mysql数据库sql查询 返回List<E>泛型(持久化)对象
2017-05-15 17:01
901 查看
利用反射实现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》
相关文章推荐
- 解决 ”不允许在查询中显式构造实体类型“问题及使用其他方法实现返回 List<Model对象>或者IQueryable<Model对象>对象
- Java中使用hql,sql查询返回的list<Object> 转成需要的实体对象--方法讲解!
- Hibernate中用纯SQL查询,并通过hibernate分页返回List<对象>
- 利用反射实现DataTable 与 List<T> 转换
- 利用反射实现DataTable 与 List<T> 转换
- 泛型与反射机制处理ComBox绑定的数据源是List<实体对象>
- 使用Map把sql返回的list<Object>转成需要的实体对象
- SSM框架不用实体类,查询单个对象返回Map,多条记录返回list<Map>,及分页
- ibatis 返回list<String[]>----resultClass="hashMap" 可以实现
- JAVA 利用反射机制查询数据库返回相应对象
- List<ExpendoObject> 对象使用Linq 查询.
- HQL查询的LIST<object> 返回omgrid显示
- 将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据
- 对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口
- System.Collections.Generic.List<>是System.Collections.ArrayList的泛型实现
- 通过反射把list<T>转换成datatable,kill进程,事务传入一个Lst<String>多条sql语句
- 利用java反射机制实现List<Map<String, Object>>转化为List<JavaBean>
- JDBC 利用反射技术将查询结果封装为对象(简单ORM实现)
- C#读取数据库返回泛型集合 把DataSet类型转换为List<T>泛型集合
- C# List<T> 泛型的反射, 泛型 函数的反射