码迷,mamicode.com
首页 > 数据库 > 详细

封装jdbc让你轻松理解Java反射机制

时间:2017-06-03 15:18:40      阅读:400      评论:0      收藏:0      [点我收藏+]

标签:password   statement   目录结构   invoke   实例   技术分享   auto   ase   ret   

1.目录结构

  技术分享

 

2.BasicDao.java

  static{
    try {
      Class.forName("com.mysql.jdbc.Driver");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public Connection getConnection() throws SQLException{
    String url = "jdbc:mysql://127.0.0.1:3306/dbparam?autoReconnect=true&useUnicode=true&characterEncoding=UTF8";
    String user = "root";
    String password = "123456";
    return DriverManager.getConnection(url, user, password);
  }

  public void close(ResultSet rs, Statement st, Connection conn){
    if(rs!=null){
      try {rs.close();} catch (SQLException e) {e.printStackTrace();}
    }
    if(st!=null){
      try {st.close();} catch (SQLException e) {e.printStackTrace();}
    }
    if(conn!=null){
      try {conn.close();} catch (SQLException e) {e.printStackTrace();}
    }
  }

  public String getMethodName(String fieldName){
    byte[] buffer = fieldName.getBytes();
    buffer[0] = (byte)(buffer[0]-32);
    String name = new String(buffer);
    return "get"+name;
  }

  public String setMethodName(String fieldName){
    byte[] buffer = fieldName.getBytes();
    buffer[0] = (byte)(buffer[0]-32);
    String name = new String(buffer);
    return "set"+name;
  }

3.GetEntity.java

/**
* T为实体对象,可以是由属性和setter/getter组成的实体类,这里要求属性名和查询的数据库字段名相同(顺序可以不一致)
* @author zhzhair
* @param <T>
*/

public class GetEntity<T> extends BasicDao{
  /**
  * @todo 获取实体对象,T为实体类,sql为sql语句字符串,param为sql中传的参数
  * @return T
  */
  public T getEntity(Class<T> clazz, String sql, Object[] param) {
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
      Field[] fields = clazz.getDeclaredFields();//实体类(POJO)的属性数组(Declared表示按照顺序)
      conn = getConnection();
      ps = conn.prepareStatement(sql);
      for (int i = 0; i < param.length; i++) {
        ps.setObject(i+1, param[i]);
      }
      rs = ps.executeQuery();
      if (rs.next()) {
        T entity = clazz.newInstance();//创建实例(给实体类分配内存)
        ResultSetMetaData rsmd = rs.getMetaData();//获取数据库表的元数据信息
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
          String columnName = rsmd.getColumnName(i);//数据库表的字段名(按照顺序)
          for (Field f : fields) {
            if (columnName.equalsIgnoreCase(f.getName())) {
              Object columnValue = rs.getObject(columnName);//根据属性名获取值
              String methodName = setMethodName(f.getName());//实体的属性名首字母必须小写,获取get方法名
              Method method = clazz.getMethod(methodName,f.getType());//根据get方法名和属性的类型返回get方法
              method.invoke(entity, columnValue);//唤醒get方法(让get方法生效)
            }
          }
        }
        return entity;
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      close(rs, ps, conn);
    }
    return null;
  }
  /**
  * @todo 获取实体对象的列表,sql为sql语句字符串,param为sql中传的参数
  * @return List<T>
  */
  public List<T> getEntityList(Class<T> clazz, String sql, Object[] param) {
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    List<T> entities = new ArrayList<T>();
    try {
      Field[] fields = clazz.getDeclaredFields();//bean属性的数组(按照顺序)
      conn = getConnection();
      ps = conn.prepareStatement(sql);
      for (int i = 0; i < param.length; i++) {
        ps.setObject(i+1, param[i]);
      }
      rs = ps.executeQuery();
      while (rs.next()) {
        T entity = clazz.newInstance();
        ResultSetMetaData rsmd = rs.getMetaData();
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
          String columnName = rsmd.getColumnName(i);
          for (Field f : fields) {
            if (columnName.equalsIgnoreCase(f.getName())) {
              Object columnValue = rs.getObject(columnName);
              String methodName = setMethodName(f.getName());
              Method method = clazz.getMethod(methodName,f.getType());//根据get方法名和属性的类型返回get方法
              method.invoke(entity, columnValue);//唤醒get方法(让get方法生效)
            }
          }
        }
        entities.add(entity);
      }
      return entities;
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      close(rs, ps, conn);
    }
    return null;
  }
}

封装jdbc让你轻松理解Java反射机制

标签:password   statement   目录结构   invoke   实例   技术分享   auto   ase   ret   

原文地址:http://www.cnblogs.com/zhzhair-coding/p/6937099.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!