• jdbc增删改查,利用反射查询


    整理自http://blog.csdn.net/yanzi1225627/article/details/26950615,谢谢作者!

    本文我的爱点是:

    1.利用反射实现数据库数据查询

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

    例如使用例子:

    1 String sql = "delete from userinfo where username = ?"; 
    2         List<Object> params = new ArrayList<Object>(); 
    3         params.add("小明"); 
    4         boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);
     1    /** 
     2      * 增加、删除、改 
     3      * @param sql 
     4      * @param params 
     5      * @return 
     6      * @throws SQLException 
     7      */  
     8     public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException{  
     9         boolean flag = false;  
    10         int result = -1;  
    11         pstmt = connection.prepareStatement(sql);  
    12         int index = 1;  
    13         if(params != null && !params.isEmpty()){  
    14             for(int i=0; i<params.size(); i++){  
    15                 pstmt.setObject(index++, params.get(i));  
    16             }  
    17         }  
    18         result = pstmt.executeUpdate();  
    19         flag = result > 0 ? true : false;  
    20         return flag;  
    21     } 

    JdbcUtils.java

    完成对数据库的增删改查。其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口:

    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里。

    上面四个函数已经包括了MySQl的所有操作,完全能够满足使用需要。视频里老罗还扩展了两个反射来查询的函数。

    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 import java.lang.reflect.Field;  
      2 import java.sql.Connection;  
      3 import java.sql.DriverManager;  
      4 import java.sql.PreparedStatement;  
      5 import java.sql.ResultSet;  
      6 import java.sql.ResultSetMetaData;  
      7 import java.sql.SQLException;  
      8 import java.util.ArrayList;  
      9 import java.util.HashMap;  
     10 import java.util.List;  
     11 import java.util.Map;  
     12   
     13 import domain.UserInfo;  
     14   
     15   
     16 public class JdbcUtils {  
     17     //数据库用户名  
     18     private static final String USERNAME = "root";  
     19     //数据库密码  
     20     private static final String PASSWORD = "yanzi";  
     21     //驱动信息   
     22     private static final String DRIVER = "com.mysql.jdbc.Driver";  
     23     //数据库地址  
     24     private static final String URL = "jdbc:mysql://localhost:3306/mydb";  
     25     private Connection connection;  
     26     private PreparedStatement pstmt;  
     27     private ResultSet resultSet;  
     28     public JdbcUtils() {  
     29         // TODO Auto-generated constructor stub  
     30         try{  
     31             Class.forName(DRIVER);  
     32             System.out.println("数据库连接成功!");  
     33   
     34         }catch(Exception e){  
     35   
     36         }  
     37     }  
     38       
     39     /** 
     40      * 获得数据库的连接 
     41      * @return 
     42      */  
     43     public Connection getConnection(){  
     44         try {  
     45             connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);  
     46         } catch (SQLException e) {  
     47             // TODO Auto-generated catch block  
     48             e.printStackTrace();  
     49         }  
     50         return connection;  
     51     }  
     52   
     53       
     54     /** 
     55      * 增加、删除、改 
     56      * @param sql 
     57      * @param params 
     58      * @return 
     59      * @throws SQLException 
     60      */  
     61     public boolean updateByPreparedStatement(String sql, List<Object>params)throws SQLException{  
     62         boolean flag = false;  
     63         int result = -1;  
     64         pstmt = connection.prepareStatement(sql);  
     65         int index = 1;  
     66         if(params != null && !params.isEmpty()){  
     67             for(int i=0; i<params.size(); i++){  
     68                 pstmt.setObject(index++, params.get(i));  
     69             }  
     70         }  
     71         result = pstmt.executeUpdate();  
     72         flag = result > 0 ? true : false;  
     73         return flag;  
     74     }  
     75   
     76     /** 
     77      * 查询单条记录 
     78      * @param sql 
     79      * @param params 
     80      * @return 
     81      * @throws SQLException 
     82      */  
     83     public Map<String, Object> findSimpleResult(String sql, List<Object> params) throws SQLException{  
     84         Map<String, Object> map = new HashMap<String, Object>();  
     85         int index  = 1;  
     86         pstmt = connection.prepareStatement(sql);  
     87         if(params != null && !params.isEmpty()){  
     88             for(int i=0; i<params.size(); i++){  
     89                 pstmt.setObject(index++, params.get(i));  
     90             }  
     91         }  
     92         resultSet = pstmt.executeQuery();//返回查询结果  
     93         ResultSetMetaData metaData = resultSet.getMetaData();  
     94         int col_len = metaData.getColumnCount();  
     95         while(resultSet.next()){  
     96             for(int i=0; i<col_len; i++ ){  
     97                 String cols_name = metaData.getColumnName(i+1);  
     98                 Object cols_value = resultSet.getObject(cols_name);  
     99                 if(cols_value == null){  
    100                     cols_value = "";  
    101                 }  
    102                 map.put(cols_name, cols_value);  
    103             }  
    104         }  
    105         return map;  
    106     }  
    107   
    108     /**查询多条记录 
    109      * @param sql 
    110      * @param params 
    111      * @return 
    112      * @throws SQLException 
    113      */  
    114     public List<Map<String, Object>> findModeResult(String sql, List<Object> params) throws SQLException{  
    115         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
    116         int index = 1;  
    117         pstmt = connection.prepareStatement(sql);  
    118         if(params != null && !params.isEmpty()){  
    119             for(int i = 0; i<params.size(); i++){  
    120                 pstmt.setObject(index++, params.get(i));  
    121             }  
    122         }  
    123         resultSet = pstmt.executeQuery();  
    124         ResultSetMetaData metaData = resultSet.getMetaData();  
    125         int cols_len = metaData.getColumnCount();  
    126         while(resultSet.next()){  
    127             Map<String, Object> map = new HashMap<String, Object>();  
    128             for(int i=0; i<cols_len; i++){  
    129                 String cols_name = metaData.getColumnName(i+1);  
    130                 Object cols_value = resultSet.getObject(cols_name);  
    131                 if(cols_value == null){  
    132                     cols_value = "";  
    133                 }  
    134                 map.put(cols_name, cols_value);  
    135             }  
    136             list.add(map);  
    137         }  
    138   
    139         return list;  
    140     }  
    141   
    142     /**通过反射机制查询单条记录 
    143      * @param sql 
    144      * @param params 
    145      * @param cls 
    146      * @return 
    147      * @throws Exception 
    148      */  
    149     public <T> T findSimpleRefResult(String sql, List<Object> params,  
    150             Class<T> cls )throws Exception{  
    151         T resultObject = null;  
    152         int index = 1;  
    153         pstmt = connection.prepareStatement(sql);  
    154         if(params != null && !params.isEmpty()){  
    155             for(int i = 0; i<params.size(); i++){  
    156                 pstmt.setObject(index++, params.get(i));  
    157             }  
    158         }  
    159         resultSet = pstmt.executeQuery();  
    160         ResultSetMetaData metaData  = resultSet.getMetaData();  
    161         int cols_len = metaData.getColumnCount();  
    162         while(resultSet.next()){  
    163             //通过反射机制创建一个实例  
    164             resultObject = cls.newInstance();  
    165             for(int i = 0; i<cols_len; i++){  
    166                 String cols_name = metaData.getColumnName(i+1);  
    167                 Object cols_value = resultSet.getObject(cols_name);  
    168                 if(cols_value == null){  
    169                     cols_value = "";  
    170                 }  
    171                 Field field = cls.getDeclaredField(cols_name);  
    172                 field.setAccessible(true); //打开javabean的访问权限  
    173                 field.set(resultObject, cols_value);  
    174             }  
    175         }  
    176         return resultObject;  
    177   
    178     }  
    179   
    180     /**通过反射机制查询多条记录 
    181      * @param sql  
    182      * @param params 
    183      * @param cls 
    184      * @return 
    185      * @throws Exception 
    186      */  
    187     public <T> List<T> findMoreRefResult(String sql, List<Object> params,  
    188             Class<T> cls )throws Exception {  
    189         List<T> list = new ArrayList<T>();  
    190         int index = 1;  
    191         pstmt = connection.prepareStatement(sql);  
    192         if(params != null && !params.isEmpty()){  
    193             for(int i = 0; i<params.size(); i++){  
    194                 pstmt.setObject(index++, params.get(i));  
    195             }  
    196         }  
    197         resultSet = pstmt.executeQuery();  
    198         ResultSetMetaData metaData  = resultSet.getMetaData();  
    199         int cols_len = metaData.getColumnCount();  
    200         while(resultSet.next()){  
    201             //通过反射机制创建一个实例  
    202             T resultObject = cls.newInstance();  
    203             for(int i = 0; i<cols_len; i++){  
    204                 String cols_name = metaData.getColumnName(i+1);  
    205                 Object cols_value = resultSet.getObject(cols_name);  
    206                 if(cols_value == null){  
    207                     cols_value = "";  
    208                 }  
    209                 Field field = cls.getDeclaredField(cols_name);  
    210                 field.setAccessible(true); //打开javabean的访问权限  
    211                 field.set(resultObject, cols_value);  
    212             }  
    213             list.add(resultObject);  
    214         }  
    215         return list;  
    216     }  
    217   
    218     /** 
    219      * 释放数据库连接 
    220      */  
    221     public void releaseConn(){  
    222         if(resultSet != null){  
    223             try{  
    224                 resultSet.close();  
    225             }catch(SQLException e){  
    226                 e.printStackTrace();  
    227             }  
    228         }  
    229     }  
    230   
    231     /** 
    232      * @param args 
    233      */  
    234     public static void main(String[] args) throws SQLException {  
    235         // TODO Auto-generated method stub  
    236         JdbcUtils jdbcUtils = new JdbcUtils();  
    237         jdbcUtils.getConnection();  
    238   
    239         /*******************增*********************/  
    240         /*      String sql = "insert into userinfo (username, pswd) values (?, ?), (?, ?), (?, ?)"; 
    241         List<Object> params = new ArrayList<Object>(); 
    242         params.add("小明"); 
    243         params.add("123xiaoming"); 
    244         params.add("张三"); 
    245         params.add("zhangsan"); 
    246         params.add("李四"); 
    247         params.add("lisi000"); 
    248         try { 
    249             boolean flag = jdbcUtils.updateByPreparedStatement(sql, params); 
    250             System.out.println(flag); 
    251         } catch (SQLException e) { 
    252             // TODO Auto-generated catch block 
    253             e.printStackTrace(); 
    254         }*/  
    255   
    256   
    257         /*******************删*********************/  
    258         //删除名字为张三的记录  
    259         /*      String sql = "delete from userinfo where username = ?"; 
    260         List<Object> params = new ArrayList<Object>(); 
    261         params.add("小明"); 
    262         boolean flag = jdbcUtils.updateByPreparedStatement(sql, params);*/  
    263   
    264         /*******************改*********************/  
    265         //将名字为李四的密码改了  
    266         /*      String sql = "update userinfo set pswd = ? where username = ? "; 
    267         List<Object> params = new ArrayList<Object>(); 
    268         params.add("lisi88888"); 
    269         params.add("李四"); 
    270         boolean flag = jdbcUtils.updateByPreparedStatement(sql, params); 
    271         System.out.println(flag);*/  
    272   
    273         /*******************查*********************/  
    274         //不利用反射查询多个记录  
    275         /*      String sql2 = "select * from userinfo "; 
    276         List<Map<String, Object>> list = jdbcUtils.findModeResult(sql2, null); 
    277         System.out.println(list);*/  
    278   
    279         //利用反射查询 单条记录  
    280         String sql = "select * from userinfo where username = ? ";  
    281         List<Object> params = new ArrayList<Object>();  
    282         params.add("李四");  
    283         UserInfo userInfo;  
    284         try {  
    285             userInfo = jdbcUtils.findSimpleRefResult(sql, params, UserInfo.class);  
    286             System.out.print(userInfo);  
    287         } catch (Exception e) {  
    288             // TODO Auto-generated catch block  
    289             e.printStackTrace();  
    290         }  
    291   
    292   
    293     }  
    294   
    295 }  

    对应的JavaBean UserInfo.java

     1 import java.io.Serializable;  
     2   
     3 public class UserInfo implements Serializable{  
     4   
     5     /** 
     6      *  
     7      */  
     8     private static final long serialVersionUID = 1L;  
     9   
    10     private int id;  
    11     private String username;  
    12     private String pswd;  
    13       
    14     public UserInfo() {  
    15         // TODO Auto-generated constructor stub  
    16     }  
    17   
    18     public int getId() {  
    19         return id;  
    20     }  
    21   
    22     public void setId(int id) {  
    23         this.id = id;  
    24     }  
    25   
    26     public String getUsername() {  
    27         return username;  
    28     }  
    29   
    30     public void setUsername(String username) {  
    31         this.username = username;  
    32     }  
    33   
    34     public String getPswd() {  
    35         return pswd;  
    36     }  
    37   
    38     public void setPswd(String pswd) {  
    39         this.pswd = pswd;  
    40     }  
    41   
    42     @Override  
    43     public String toString() {  
    44         return "UserInfo [id=" + id + ", username=" + username + ", pswd="  
    45                 + pswd + "]";  
    46     }  
    47   
    48   
    49   
    50   
    51   
    52 }  
    View Code

    1.抛开以上来说,操作数据库的一般性步骤如下:

        (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>传递出去,给查询者看。

    2.关于查询操作,在得到resultSet后利用getMetaData得到表的结构信息,如getColumnCount()得到有多少个列。String cols_name = metaData.getColumnName(i+1); 得到每个列的属性名称,如是id、username还是pswd.然后从Object cols_value = resultSet.getObject(cols_name);取出来,放到Map或List<Map>里。

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

         (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);

    4.一般意义上,要利用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.

    5. JavaBean是反射的一种,反射对构造函数之类的没任何要求,JavaBean要求这个类必须继承Serializable即可串行化,另外构造函数必须为public. 另外,就是JavaBean在得到某个field后可以直接调用set和get,而不必再反射得到method后再执行。

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

    谢谢作者:http://blog.csdn.net/yanzi1225627/article/details/26950615 

  • 相关阅读:
    android 21 隐式意图启动系统预定义activity
    android 20 Intnet类重要的成员变量
    android 19 activity纵横屏切换的数据保存与恢复
    android 18 Bundle类
    android 17 activity生命周期
    Centos6.4建立本地yum源
    eclipse实现批量修改文件的编码方式
    [系统资源]/proc/meminfo和free输出解释
    监控WebLogic 8.x的解决方案(监控应用服务器系列文章)
    linux网络监控脚本
  • 原文地址:https://www.cnblogs.com/ning1121/p/3933439.html
Copyright © 2020-2023  润新知