zoukankan      html  css  js  c++  java
  • JDBC连接数据库反射实现O/R映射

    [html] view plain copy
     
    1. 测试preparedStatement     
    [html] view plain copy
     
    1. public void testPreparedStatement(){  
    2.     Connection connection=null;  
    3.     PreparedStatement preparedStatement=null;  
    4.     try{  
    5.         connection =JDBCTools.getConnection();  
    6.         String sql="insert into customers(name,email,birth) "+  
    7.         "values(?,?,?)";  
    8.         preparedStatement=connection.prepareStatement(sql);  
    9.         preparedStatement.setString(1, "ATGUIGU");  
    10.         preparedStatement.setString(2, "simleint@163.com");  
    11.         preparedStatement.setDate(3, new Date(new java.util.Date().getTime()));  
    12.         preparedStatement.executeUpdate();  
    13.     }catch(Exception e){  
    14.         e.printStackTrace();  
    15.     }finally{  
    16.         JDBCTools.release(null, preparedStatement, connection);  
    17.     }  
    18.    }  
    [html] view plain copy
     
    1. 测试结果集元数据: 利用SQL进行查询,得到结果集。  
    [html] view plain copy
     
    1. 利用反射创建实体对象,获取结果集的列的别名。  
    [html] view plain copy
     
    1. 在获取结果集的每一列的值,结合3得到一个Map,键的别名,值:列的值。</span>  
    [html] view plain copy
     
    1. 再利用反射为2的对应的属性赋值:属性为Map的键,值为Map的值。</span>  
     
    [html] view plain copy
     
    1. public void testResultSetMetaData(){  
    2. Customer customer=null;  
    3. Connection conn=null;  
    4. PreparedStatement preparedStatement=null;  
    5. ResultSet rs=null;  
    6. try{  
    7.     String sql="select ID id,NAME name,EMAIL email,BIRTH birth from customers";  
    8.     conn=JDBCTools.getConnection();  
    9.     preparedStatement=conn.prepareStatement(sql);  
    10. 1得到rs  
    11.     rs=preparedStatement.executeQuery();  
    12.       
    13.     Map<String,Object>values=  
    14.             new HashMap<String,Object>();  
    15.     //2得到结果集ResultSetMetaData对象。  
    16.     ResultSetMetaData rsmd=rs.getMetaData();  
    17.     while(rs.next()){  
    18.     for(int i=0;i<rsmd.getColumnCount();i++){  
    19.         String columnLabel=rsmd.getColumnLabel(i+1);  
    20.         Object columnValue=rs.getObject(columnLabel);  
    21.           
    22.         values.put(columnLabel,columnValue);  
    23.     }  
    24. }  
    25.     System.out.println(values);  
    26.     Class clazz=Customer.class;  
    27.     Object object=clazz.newInstance();  
    28.     for(Map.Entry<String, Object>entry:values.entrySet()){  
    29.         String fieldName=entry.getKey();  
    30.         Object fieldValue=entry.getValue();  
    31.         System.out.println(fieldName+" :"+fieldValue);  
    32.         ReflectionUtils.setFieldValue(object,fieldName,fieldValue);  
    33.     }  
    34. }catch(Exception e){  
    35.     e.printStackTrace();  
    36. }finally{  
    37.     JDBCTools.release(rs,preparedStatement,conn);  
    38. }  
    39.   
    40. }  

    抽取出泛型方法:

    [html] view plain copy
     
    1.    public void testGet(){  
    2.     String sql="select ID id,NAME name,EMAIL email,BIRTH birth "+"From customers";  
    3.     Customer customer=get(Customer.class,sql);  
    4.     System.out.println(customer);  
    5.       
    6.    }  
    7.    public <T> T get(Class<T> clazz,String sql,Object...args){  
    8.         T entity=null;  
    9.     Connection conn=null;  
    10.     PreparedStatement preparedStatement=null;  
    11.     ResultSet rs=null;  
    12.     try{  
    13.         conn=JDBCTools.getConnection();  
    14.         preparedStatement=conn.prepareStatement(sql);  
    15.         for(int i=0;i<args.length;i++)  
    16.         {  
    17.             preparedStatement.setObject(i+1, args[i]);  
    18.         }  
    19.             //1得到rs  
    20.         rs=preparedStatement.executeQuery();  
    21.         //2得到结果集ResultSetMetaData对象。  
    22.         ResultSetMetaData rsmd=rs.getMetaData();  
    23.         //3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值  
    24.         Map<String,Object>values=  
    25.                 new HashMap<String,Object>();  
    26.            //处理结果集。  
    27.         while(rs.next()){  
    28.         for(int i=0;i<rsmd.getColumnCount();i++){  
    29.             String columnLabel=rsmd.getColumnLabel(i+1);  
    30.             Object columnValue=rs.getObject(columnLabel);  
    31.               
    32.             values.put(columnLabel,columnValue);  
    33.         }  
    34.     }  
    35.     //5若Map不为空利用反射创建clazz对应的对象。  
    36.         if(values.size()>0){  
    37.         entity=clazz.newInstance();  
    38.         for(Map.Entry<String, Object>entry:values.entrySet()){  
    39.             String fieldName=entry.getKey();  
    40.             Object fieldValue=entry.getValue();  
    41.             ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);  
    42.         }  
    43.     }  
    44.     }catch(Exception e){  
    45.         e.printStackTrace();  
    46.     }finally{  
    47.         JDBCTools.release(rs,preparedStatement,conn);  
    48.     }  
    49. return entity;  
    50.  }  

    其中JDBCTools.java为:

    [html] view plain copy
     
    1. /*  
    2.  * 操作JDBC的工具类,其中封装了一些工具方法  
    3.  * 通过读取配置文件从数据库服务器获取一个连接*/  
    4. public class JDBCTools {  
    5.     public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException{  
    6.         //1.准备连接数据库的4个字符串。  
    7.           //1)z创建jdbc.properties对象。  
    8.         Properties properties=new Properties();  
    9.           //2)加载对应的输入流。  
    10.         InputStream in=JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");  
    11.         //3)加载2)对应的输入流   
    12.           properties.load(in);  
    13.         //4)具体决定user,password等4个字符串。  
    14.           String user=properties.getProperty("user");  
    15.           String password=properties.getProperty("password");  
    16.           String driver=properties.getProperty("driverClass");  
    17.           String jdbcUrl=properties.getProperty("jdbcUrl");  
    18.         //2.加载数据库驱动(对应的Driver实现类中有注册驱动的静态代码块)  
    19.           Class.forName(driver);  
    20.         //3.通过DriverManager的getConnection()方法获取数据库连接。  
    21.           return DriverManager.getConnection(jdbcUrl,user,password);  
    22.     }  
    23.     /*  
    24.      *关闭Statement,Connection */  
    25.     public static void  release(ResultSet rs,Statement statement,Connection conn){  
    26.         if(rs!=null){  
    27.             try {  
    28.                 rs.close();  
    29.             } catch (SQLException e) {  
    30.                 // TODO Auto-generated catch block  
    31.                 e.printStackTrace();  
    32.             }  
    33.         }  
    34.         if(statement!=null){  
    35.               try{  
    36.                   statement.close();  
    37.               }catch(Exception e2){  
    38.               e2.printStackTrace();  
    39.             }  
    40.           }  
    41.           if(conn!=null){  
    42.               try{  
    43.                   conn.close();  
    44.               }catch(Exception e2){  
    45.               e2.printStackTrace();  
    46.           }  
    47.         }  
    48.     }  
    49.   
    50.     public static void update(String sql) throws SQLException{        
    51.         Connection conn=null;  
    52.         Statement statement=null;  
    53.         try{  
    54.         conn=JDBCTools.getConnection();  
    55.         statement=conn.createStatement();  
    56.         statement.executeUpdate(sql);  
    57.         }catch(Exception e){  
    58.             e.printStackTrace();  
    59.         }finally{  
    60.         JDBCTools.release(null,statement, conn);  
    61.     }  
    62.    }  
    63.     public static void update(String sql,Object...args) throws IOException, ClassNotFoundException{  
    64.         Connection conn=null;  
    65.           PreparedStatement pstmt=null;  
    66.           try{  
    67.               conn=JDBCTools.getConnection();  
    68.                pstmt=conn.prepareStatement(sql);  
    69.               for(int i=0;i<args.length;i++){  
    70.                   pstmt.setObject(i+1,args[i]);  
    71.               }  
    72.               pstmt.executeUpdate();  
    73.           }catch(SQLException e){  
    74.               System.out.println("使用预编译语句更新数据操作发生异常");  
    75.           }  
    76.     }  
    77.     /*  
    78.      * 1ResultSetMetaData是描述ResultSet的元数据的对象,即从中可以获取到结果集中有多少列,列名是多少。。。  
    79.      * 2得到ResultSetNataData对象:调用ResultSet的getMetaData()方法  
    80.      * ResultSetMetaData有哪些方法。  
    81.      * int getColumnCount():SQL语句中包含哪些列。  
    82.      * String getColumnLable(int column)获取指定的列的别名,其中索引从1开始。*/  
    83.    
    84.   
    85.       
    86.        public <T> T get(Class<T> clazz,String sql,Object...args){  
    87.             /*  
    88.              * 1先利用SQL进行查询得到结果集  
    89.              * 2利用反射创建实体类的对象  
    90.              * 3获取结果集的列的别名:idcard。。。  
    91.              * 4获取结果集的每一列的值,结合3得到一个Map。键:列的别名,值:列的值  
    92.              * 5再利用反射为2的对应的属性赋值。*/  
    93.              T entity=null;  
    94.             Connection conn=null;  
    95.             PreparedStatement preparedStatement=null;  
    96.             ResultSet rs=null;  
    97.             try{  
    98.                 conn=JDBCTools.getConnection();  
    99.                 preparedStatement=conn.prepareStatement(sql);  
    100.                 for(int i=0;i<args.length;i++)  
    101.                 {  
    102.                     preparedStatement.setObject(i+1, args[i]);  
    103.                 }  
    104.                  //1得到rs  
    105.                 rs=preparedStatement.executeQuery();  
    106.                 //2得到结果集ResultSetMetaData对象。  
    107.                 ResultSetMetaData rsmd=rs.getMetaData();  
    108.                 //3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值  
    109.                 Map<String,Object>values=  
    110.                         new HashMap<String,Object>();  
    111.                 //处理结果集。  
    112.                 while(rs.next()){  
    113.                 for(int i=0;i<rsmd.getColumnCount();i++){  
    114.                     String columnLabel=rsmd.getColumnLabel(i+1);  
    115.                     Object columnValue=rs.getObject(columnLabel);  
    116.                       
    117.                     values.put(columnLabel,columnValue);  
    118.                 }  
    119.             }  
    120.             //5若Map不为空利用反射创建clazz对应的对象。  
    121.                 if(values.size()>0){  
    122.                 entity=clazz.newInstance();  
    123.                 for(Map.Entry<String, Object>entry:values.entrySet()){  
    124.                     String fieldName=entry.getKey();  
    125.                     Object fieldValue=entry.getValue();  
    126.                     ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);  
    127.                 }  
    128.             }  
    129.             }catch(Exception e){  
    130.                 e.printStackTrace();  
    131.             }finally{  
    132.                 JDBCTools.release(rs,preparedStatement,conn);  
    133.             }  
    134.         return entity;  
    135.       }   
    136.       
    137.       
    138.     public Customer getCustomer(String sql,Object...args){  
    139.         Customer customer=null;  
    140.         Connection conn=null;  
    141.         PreparedStatement preparedStatement=null;  
    142.         ResultSet rs=null;  
    143.         try{  
    144.             conn=JDBCTools.getConnection();  
    145.             preparedStatement=conn.prepareStatement(sql);  
    146.             for(int i=0;i<args.length;i++)  
    147.             {  
    148.                 preparedStatement.setObject(i+1, args[i]);  
    149.             }  
    150.             rs=preparedStatement.executeQuery();  
    151.               
    152.             if(rs.next()){  
    153.                 customer=new Customer();  
    154.                 customer.setId(rs.getInt(1));  
    155.                 customer.setName(rs.getString(2));  
    156.                 customer.setEmail(rs.getString(3));  
    157.                 customer.setBirth(rs.getDate(4));  
    158.             }  
    159.               
    160.         }catch(Exception e){  
    161.             e.printStackTrace();  
    162.         }finally{  
    163.             JDBCTools.release(rs,preparedStatement,conn);  
    164.         }  
    165.         return customer;  
    166.     }   
    167.       
    168.       
    169. }  

    ReflectionUtils.java为:

    [html] view plain copy
     
    1. package com.atguigu.jdbc;  
    2.   
    3. import java.lang.reflect.Field;  
    4. import java.lang.reflect.InvocationTargetException;  
    5. import java.lang.reflect.Method;  
    6. import java.lang.reflect.Modifier;  
    7. import java.lang.reflect.ParameterizedType;  
    8. import java.lang.reflect.Type;  
    9.   
    10. /**  
    11.  * 反射的 Utils 函数集合  
    12.  * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数  
    13.  * @author Administrator  
    14.  *  
    15.  */  
    16. public class ReflectionUtils {  
    17.   
    18.       
    19.     /**  
    20.      * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型  
    21.      * 如: public EmployeeDao extends BaseDao<Employee, String>  
    22.      * @param clazz  
    23.      * @param index  
    24.      * @return  
    25.      */  
    26.     @SuppressWarnings("unchecked")  
    27.     public static Class getSuperClassGenricType(Class clazz, int index){  
    28.         Type genType = clazz.getGenericSuperclass();  
    29.           
    30.         if(!(genType instanceof ParameterizedType)){  
    31.             return Object.class;  
    32.         }  
    33.           
    34.         Type [] params = ((ParameterizedType)genType).getActualTypeArguments();  
    35.           
    36.         if(index >= params.length || index 0){  
    37.             return Object.class;  
    38.         }  
    39.           
    40.         if(!(params[index] instanceof Class)){  
    41.             return Object.class;  
    42.         }  
    43.           
    44.         return (Class) params[index];  
    45.     }  
    46.       
    47.     /**  
    48.      * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型  
    49.      * 如: public EmployeeDao extends BaseDao<Employee, String>  
    50.      * @param <T>  
    51.      * @param clazz  
    52.      * @return  
    53.      */  
    54.     @SuppressWarnings("unchecked")  
    55.     public static<T> Class<T> getSuperGenericType(Class clazz){  
    56.         return getSuperClassGenricType(clazz, 0);  
    57.     }  
    58.       
    59.     /**  
    60.      * 循环向上转型, 获取对象的 DeclaredMethod  
    61.      * @param object  
    62.      * @param methodName  
    63.      * @param parameterTypes  
    64.      * @return  
    65.      */  
    66.     public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){  
    67.           
    68.         for(Class<?superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){  
    69.             try {  
    70.                 //superClass.getMethod(methodName, parameterTypes);  
    71.                 return superClass.getDeclaredMethod(methodName, parameterTypes);  
    72.             } catch (NoSuchMethodException e) {  
    73.                 //Method 不在当前类定义, 继续向上转型  
    74.             }  
    75.             //..  
    76.         }  
    77.           
    78.         return null;  
    79.     }  
    80.       
    81.     /**  
    82.      * 使 filed 变为可访问  
    83.      * @param field  
    84.      */  
    85.     public static void makeAccessible(Field field){  
    86.         if(!Modifier.isPublic(field.getModifiers())){  
    87.             field.setAccessible(true);  
    88.         }  
    89.     }  
    90.       
    91.     /**  
    92.      * 循环向上转型, 获取对象的 DeclaredField  
    93.      * @param object  
    94.      * @param filedName  
    95.      * @return  
    96.      */  
    97.     public static Field getDeclaredField(Object object, String filedName){  
    98.           
    99.         for(Class<?superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){  
    100.             try {  
    101.                 return superClass.getDeclaredField(filedName);  
    102.             } catch (NoSuchFieldException e) {  
    103.                 //Field 不在当前类定义, 继续向上转型  
    104.             }  
    105.         }  
    106.         return null;  
    107.     }  
    108.       
    109.     /**  
    110.      * 直接调用对象方法, 而忽略修饰符(private, protected)  
    111.      * @param object  
    112.      * @param methodName  
    113.      * @param parameterTypes  
    114.      * @param parameters  
    115.      * @return  
    116.      * @throws InvocationTargetException   
    117.      * @throws IllegalArgumentException   
    118.      */  
    119.     public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,  
    120.             Object [] parameters) throws InvocationTargetException{  
    121.           
    122.         Method method = getDeclaredMethod(object, methodName, parameterTypes);  
    123.           
    124.         if(method == null){  
    125.             throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");  
    126.         }  
    127.           
    128.         method.setAccessible(true);  
    129.           
    130.         try {  
    131.             return method.invoke(object, parameters);  
    132.         } catch(IllegalAccessException e) {  
    133.             System.out.println("不可能抛出的异常");  
    134.         }   
    135.           
    136.         return null;  
    137.     }  
    138.       
    139.     /**  
    140.      * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter  
    141.      * @param object  
    142.      * @param fieldName  
    143.      * @param value  
    144.      */  
    145.     public static void setFieldValue(Object object, String fieldName, Object value){  
    146.         Field field = getDeclaredField(object, fieldName);  
    147.           
    148.         if (field == null)  
    149.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");  
    150.           
    151.         makeAccessible(field);  
    152.           
    153.         try {  
    154.             field.set(object, value);  
    155.         } catch (IllegalAccessException e) {  
    156.             System.out.println("不可能抛出的异常");  
    157.         }  
    158.     }  
    159.       
    160.     /**  
    161.      * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter  
    162.      * @param object  
    163.      * @param fieldName  
    164.      * @return  
    165.      */  
    166.     public static Object getFieldValue(Object object, String fieldName){  
    167.         Field field = getDeclaredField(object, fieldName);  
    168.           
    169.         if (field == null)  
    170.             throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");  
    171.           
    172.         makeAccessible(field);  
    173.           
    174.         Object result = null;  
    175.           
    176.         try {  
    177.             result = field.get(object);  
    178.         } catch (IllegalAccessException e) {  
    179.             System.out.println("不可能抛出的异常");  
    180.         }  
    181.           
    182.         return result;  
    183.     }  
    184. }  

    Customer类为:

    [html] view plain copy
     
    1. package com.atguigu.jdbc;  
    2.   
    3. import java.sql.Date;  
    4.   
    5. public class Customer {  
    6.      private int id;  
    7.      private String name;  
    8.      private String email;  
    9.      private Date birth;  
    10.        
    11.      public int getId() {  
    12.         return id;  
    13.     }  
    14.     public void setId(int id) {  
    15.         this.id = id;  
    16.     }  
    17.     public String getName() {  
    18.         return name;  
    19.     }  
    20.     public void setName(String name) {  
    21.         this.name = name;  
    22.     }  
    23.     public String getEmail() {  
    24.         return email;  
    25.     }  
    26.     public void setEmail(String email) {  
    27.         this.email = email;  
    28.     }  
    29.     public Date getBirth() {  
    30.         return birth;  
    31.     }  
    32.     public void setBirth(Date birth) {  
    33.         this.birth = birth;  
    34.     }  
    35.     public Customer(){}  
    36.   
    37.      public Customer(int id, String name, String email, Date birth) {  
    38.         super();  
    39.         this.id = id;  
    40.         this.name = name;  
    41.         this.email = email;  
    42.         this.birth = birth;  
    43.     }  
    44.   
    45.   
    46.     public String toString() {  
    47.         return "Customer [id=" + id + ", name=" + name + ", email=" + email  
    48.                 + ", birth=" + birth + "]";  
    49.     }  
    50.       
    51. }  
  • 相关阅读:
    在Linux中查找jdk路径
    AABO:自适应Anchor设置优化,性能榨取的最后一步 | ECCV 2020 Spotlight
    CSG:清华大学提出通过分化类特定卷积核来训练可解释的卷积网络 | ECCV 2020 Oral
    PIoU Loss:倾斜目标检测专用损失函数,公开超难倾斜目标数据集Retail50K | ECCV 2020 Spotlight
    简单的特征值梯度剪枝,CPU和ARM上带来4-5倍的训练加速 | ECCV 2020
    Jigsaw pre-training:摆脱ImageNet,拼图式主干网络预训练方法 | ECCV 2020
    在Windows下用VScode构造shell脚本的IDE
    Jmeter JDBC Request 使用详解
    Jmeter逻辑控制器Switch Controller的用法
    Jmeter逻辑控制器之If Controller的使用解析
  • 原文地址:https://www.cnblogs.com/firstdream/p/8673086.html
Copyright © 2011-2022 走看看