先贴代码:

1 package com.hongli.util;
  2 import java.lang.reflect.Field;
  3 import java.sql.Connection;
  4 import java.sql.DriverManager;
  5 import java.sql.PreparedStatement;
  6 import java.sql.ResultSet;
  7 import java.sql.ResultSetMetaData;
  8 import java.sql.SQLException;
  9 import java.util.ArrayList;
 10 import java.util.HashMap;
 11 import java.util.List;
 12 import java.util.Map;
 13 public class DBconn {
 14      
 15     public class JdbcUtils {
 16         //数据库用户名
 17         private static final String USERNAME = "root";
 18         //数据库密码
 19         private static final String PASSWORD = "yanzi";
 20         //驱动信息 
 21         private static final String DRIVER = "com.mysql.jdbc.Driver";
 22         //数据库地址
 23         private static final String URL = "jdbc:mysql://localhost:3306/mydb";
 24         private Connection connection;
 25         private PreparedStatement pstmt;
 26         private ResultSet resultSet;
 27         public JdbcUtils() {
 28             // TODO Auto-generated constructor stub
 29             try{
 30                 Class.forName(DRIVER);
 31                 System.out.println("数据库连接成功!");
 32      
 33             }catch(Exception e){
 34      
 35             }
 36         }
 37         
 38         /**
 39          * 获得数据库的连接
 40          * @return
 41          */
 42         public Connection getConnection(){
 43             try {
 44                 connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
 45             } catch (SQLException e) {
 46                 // TODO Auto-generated catch block
 47                 e.printStackTrace();
 48             }
 49             return connection;
 50         }
 51      
 52         
 53         /**
 54          * 增加、删除、改
 55          * @param sql
 56          * @param params
 57          * @return
 58          * @throws SQLException
 59          */
 60         public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException{
 61             boolean flag = false;
 62             int result = -1;
 63             pstmt = connection.prepareStatement(sql);
 64             int index = 1;
 65             if(params != null && !params.isEmpty()){
 66                 for(int i=0; i<params.size(); i++){
 67                     pstmt.setObject(index++, params.get(i));
 68                 }
 69             }
 70             result = pstmt.executeUpdate();
 71             flag = result > 0 ? true : false;
 72             return flag;
 73         }
 74      
 75         /**
 76          * 查询单条记录
 77          * @param sql
 78          * @param params
 79          * @return
 80          * @throws SQLException
 81          */
 82         public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException{
 83             Map<String, Object> map = new HashMap<String, Object>();
 84             int index  = 1;
 85             pstmt = connection.prepareStatement(sql);
 86             if(params != null && !params.isEmpty()){
 87                 for(int i=0; i<params.size(); i++){
 88                     pstmt.setObject(index++, params.get(i));
 89                 }
 90             }
 91             resultSet = pstmt.executeQuery();//返回查询结果
 92             ResultSetMetaData metaData = resultSet.getMetaData();
 93             int col_len = metaData.getColumnCount();
 94             while(resultSet.next()){
 95                 for(int i=0; i<col_len; i++ ){
 96                     String cols_name = metaData.getColumnName(i+1);
 97                     Object cols_value = resultSet.getObject(cols_name);
 98                     if(cols_value == null){
 99                         cols_value = "";
100                     }
101                     map.put(cols_name, cols_value);
102                 }
103             }
104             return map;
105         }
106      
107         /**查询多条记录
108          * @param sql
109          * @param params
110          * @return
111          * @throws SQLException
112          */
113         public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException{
114             List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
115             int index = 1;
116             pstmt = connection.prepareStatement(sql);
117             if(params != null && !params.isEmpty()){
118                 for(int i = 0; i<params.size(); i++){
119                     pstmt.setObject(index++, params.get(i));
120                 }
121             }
122             resultSet = pstmt.executeQuery();
123             ResultSetMetaData metaData = resultSet.getMetaData();
124             int cols_len = metaData.getColumnCount();
125             while(resultSet.next()){
126                 Map<String, Object> map = new HashMap<String, Object>();
127                 for(int i=0; i<cols_len; i++){
128                     String cols_name = metaData.getColumnName(i+1);
129                     Object cols_value = resultSet.getObject(cols_name);
130                     if(cols_value == null){
131                         cols_value = "";
132                     }
133                     map.put(cols_name, cols_value);
134                 }
135                 list.add(map);
136             }
137      
138             return list;
139         }
140      
141         /**通过反射机制查询单条记录
142          * @param sql
143          * @param params
144          * @param cls
145          * @return
146          * @throws Exception
147          */
148         public <T> T findSimpleRefResult(String sql, List<Object> params,
149                 Class<T> cls )throws Exception{
150             T resultObject = null;
151             int index = 1;
152             pstmt = connection.prepareStatement(sql);
153             if(params != null && !params.isEmpty()){
154                 for(int i = 0; i<params.size(); i++){
155                     pstmt.setObject(index++, params.get(i));
156                 }
157             }
158             resultSet = pstmt.executeQuery();
159             ResultSetMetaData metaData  = resultSet.getMetaData();
160             int cols_len = metaData.getColumnCount();
161             while(resultSet.next()){
162                 //通过反射机制创建一个实例
163                 resultObject = cls.newInstance();
164                 for(int i = 0; i<cols_len; i++){
165                     String cols_name = metaData.getColumnName(i+1);
166                     Object cols_value = resultSet.getObject(cols_name);
167                     if(cols_value == null){
168                         cols_value = "";
169                     }
170                     Field field = cls.getDeclaredField(cols_name);
171                     field.setAccessible(true); //打开javabean的访问权限
172                     field.set(resultObject, cols_value);
173                 }
174             }
175             return resultObject;
176      
177         }
178      
179         /**通过反射机制查询多条记录
180          * @param sql 
181          * @param params
182          * @param cls
183          * @return
184          * @throws Exception
185          */
186         public <T> List<T> findMoreRefResult(String sql, List<Object> params,
187                 Class<T> cls )throws Exception {
188             List<T> list = new ArrayList<T>();
189             int index = 1;
190             pstmt = connection.prepareStatement(sql);
191             if(params != null && !params.isEmpty()){
192                 for(int i = 0; i<params.size(); i++){
193                     pstmt.setObject(index++, params.get(i));
194                 }
195             }
196             resultSet = pstmt.executeQuery();
197             ResultSetMetaData metaData  = resultSet.getMetaData();
198             int cols_len = metaData.getColumnCount();
199             while(resultSet.next()){
200                 //通过反射机制创建一个实例
201                 T resultObject = cls.newInstance();
202                 for(int i = 0; i<cols_len; i++){
203                     String cols_name = metaData.getColumnName(i+1);
204                     Object cols_value = resultSet.getObject(cols_name);
205                     if(cols_value == null){
206                         cols_value = "";
207                     }
208                     Field field = cls.getDeclaredField(cols_name);
209                     field.setAccessible(true); //打开javabean的访问权限
210                     field.set(resultObject, cols_value);
211                 }
212                 list.add(resultObject);
213             }
214             return list;
215         }
216      
217         /**
218          * 释放数据库连接
219          */
220         public void releaseConn(){
221             if(resultSet != null){
222                 try{
223                     resultSet.close();
224                 }catch(SQLException e){
225                     e.printStackTrace();
226                 }
227             }
228         }
229      
230     }
231 
232 }

一、小结:

1、public Connection getConnection()   获得数据库的连接

2、public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException  更新数据库,包括增加记录、删除记录、改动某个记录三个功能。

3、public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException 查询单条记录,传进去的是一个List<Object>参数填充占位符,返回的是一个Map<String, Object>.一个Map对应一条完整的记录,String对应属性名,Object是属性值。

4、public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException 查询多条记录,放在List里。

 

5、public <T> T findSimpleRefResult(String sql, List<Object> params,
Class<T> cls )throws Exception   利用反射查询单个记录。

 

6、 public <T> List<T> findMoreRefResult(String sql, List<Object> params,
Class<T> cls )throws Exception   利用反射查询多个记录。
二、操作数据库的一般性步骤如下:

 (1)连接数据库,加载驱动: Class.forName(DRIVER); DRIVER = "com.mysql.jdbc.Driver";这本身就是反射!!

   (2) 利用用户名和密码及数据库的名字连接,这一步才是真正的连接:

  connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); 

  其中:String URL = "jdbc:mysql://localhost:3306/mydb";

    (3)编写一个sql语句,其中的参数用?来代替,然后将参数写到List里。

  执行:pstmt = connection.prepareStatement(sql); 然后将参数从list里取出来填充到pstmt里。

     (4)如果是增、删、改执行:result = pstmt.executeUpdate(); 其中的result是执行完影响的数据库里的行数,也即几条记录。

    如果是查询执行:resultSet = pstmt.executeQuery(); 返回的类型是ResultSet类型。

    之后就是把resultSet 弄成Map或List<Map>传递出去,给查询者看。

三、关于查询操作,在得到resultSet后利用getMetaData得到表的结构信息,如:

  (1)getColumnCount()得到有多少个列。

  (2)String cols_name = metaData.getColumnName(i+1); 得到每个列的属性名称,如是id、username还是pswd.然后从Object cols_value = resultSet.getObject(cols_name);取出来,放到Map或List<Map>里。

四.关于查询里利用的反射操作,步骤如下:

     (1) T resultObject = cls.newInstance(); 利用class文件的newInstance()方法创建一个实例。

     (2)在通过getColumnCount()得到有多少个列之后,进入循环,

                 String cols_name = metaData.getColumnName(i+1);
                 Object cols_value = resultSet.getObject(cols_name);

    读取每一列的属性名字和放的值。通过属性的名字cols_name进行反射:Field field = cls.getDeclaredField(cols_name);这样就得到了Field 等于类里的成员变量,field.setAccessible(true); //打开javabean的访问权限 在利用set方法将从数据库中查出来的cols_value通过JavaBean 也即定义的UserInfo这个类的 set方法赋进去。field.set(resultObject, cols_value);

五.一般意义上,要利用Java的反射需要以下步骤

     (1)加载Class对象,这个一般有两种方式:Class cls1 = UserInfo.class  或

········Class cls2 = Class.forName("domain.UserInfo") 后者是利用包名+类名的方法。

   (2)反射出来Class之后干啥事呢?一个类不外乎构造函数、成员变量、成员函数。所以得到Class之后就可以干这三件事。

     ···A、关于构造函数,获得Constructor 有四种方法: 

 ·········· Constructor getConstructor(Class[] params) 

············Constructor[] getConstructors() 

············Constructor getDeclaredConstructor(Class[] params) 

  ··········Constructor[] getDeclaredConstructors()  

      这四个函数,如果不传参数则是获得所有的构造函数,得到的是一个集合。

      如果传特定的参数,则是寻找这个特定的构造函数,不带Declared是获得公共的public,带了Declared是可以获得私有构造函数。

      得到构造函数后就可以利用反射创建实例了:

       Constructor con1[] = cls1.getDeclaredConstructors();
               con1[1].setAccessible(true);
         Object obj1 = con1[1].newInstance(new Object[]{"tom"}); 如果直接调用clcs.newInstance()则是用默认的构造函数创建实例。

    B、关于成员变量,同样有四种方法:

      public Field getDeclaredField(String name)  获取任意指定名字的成员
      public Field[] getDeclaredFields()          获取所有的成员变量
      public Field getField(String name)          获取任意public成员变量
      public Field[] getFields()                  获取所有的public成员变量

      本文封装的JdbcUtils类就是利用这种方式操作类里的私有成员变量,记得要setAccessible打开开关。如下:

      Field field = cls.getDeclaredField(cols_name);
      field.setAccessible(true); //打开javabean的访问权限
      field.set(resultObject, cols_value);

      C、关于成员函数,也有四种方法:

    public Method[] getMethods()    获取所有的共有方法的集合
    public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 ,

    参数1:方法名 参数2:参数类型集合  
    public Method[] getDeclaredMethods()  获取所有的方法
    public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法

    下面是利用文中的UserInfo这个类写的一个完成的反射例子,拿到setUsername(String username)方法,然后反射。再拿到getUsername()方法再反射,然后打印出结果:

Class clcs = UserInfo.class;
    try {
      Object obj = clcs.newInstance();
      Method f = clcs.getDeclaredMethod("setUsername", String.class);
      f.invoke(obj, "yan123");
      Method f2 = clcs.getDeclaredMethod("getUsername", null);
      Object name = f2.invoke(obj, null);
      System.out.println("反射得到的名字 = "  +  name);    } catch (InstantiationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IllegalAccessException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (NoSuchMethodException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (SecurityException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (InvocationTargetException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    在反射方法的时候,Method f = clcs.getDeclaredMethod("setUsername", String.class);

     原函数里的输入参数是什么类型,就写什么类型.class. 如原来的setXXX需要输入参数String,反射的时候就写String.class.

    六. JavaBean是反射的一种,反射对构造函数之类的没任何要求,JavaBean要求这个类必须继承Serializable即可串行化,另外构造函数必须为public.

    另外,就是JavaBean在得到某个field后可以直接调用set和get,而不必再反射得到method后再执行。

        最后,反射是在程序运行的时候而非编译时!!!