zoukankan      html  css  js  c++  java
  • JDBC数据库链接及相关方法的封装

      使用的是MySQL数据库,首先导入驱动类,然后根据数据库URL和用户名密码获得数据的链接。由于使用的是MySQL数据库,它的URL一般为,jdbc:mysql://主机地址:端口号/库名。

      下面是封装的具体类,用到了泛型反射不过还存在些问题,就是对使用的泛型对象有些限制,只能用于泛型类对象属性名与数据库表中列名相同的对象,而且初始化对象的方法必须为set+属性名的方法。

      1 public class Consql {
      2     private static Consql consql=null;//单例设计模式
      3     private Connection conn=null;//数据库链接
      4     private final  String url;//数据库url
      5     private final  String username;//数据库用户名
      6     private final  String password;//数据库密码
      7     //驱动类的加载
      8     static{//以静态代码块的形式加载驱动类,静态代码块只在类加载的时候执行一次
      9         try {
     10             Class.forName("com.mysql.jdbc.Driver");
     11         } catch (ClassNotFoundException e) {
     12             e.printStackTrace();
     13         }
     14     }
     15     //构造函数
     16     private Consql(String url,String username,String password) throws SQLException{
     17         this.url = url;
     18         this.username = username;
     19         this.password = password;
     20         open();//创建连接
     21     }
     22     private Connection open() throws SQLException
     23     {
     24         try {//驱动器获取数据库链接
     25             conn=DriverManager.getConnection(url, username, password);
     26         } catch (SQLException e) {
     27             // TODO Auto-generated catch block
     28             //e.printStackTrace();
     29             throw e;
     30         }        
     31         return conn;        
     32     }
     33     /**
     34      * 带限制条件查找
     35      * @param sql 带占位符?的sql语句
     36      * @param t 返回相关类型对象的类(T.class)
     37      * @param params 替换占位符的数据,为动态数组,不写的话数组长度为0
     38      * @return ArrayList<T>
     39      * @throws SQLException 
     40      */
     41     public <T> ArrayList<T> select(String sql,Class<T> t,Object...params) throws SQLException
     42     {//获取T类所有public方法
     43         Method[] declaredMethods = t.getDeclaredMethods();
     44         //创建一个盛放该类型对象集合
     45         ArrayList<T> arrayList=new ArrayList<>();
     46         try (PreparedStatement pStatement=conn.prepareStatement(sql);)
     47         {            
     48             for(int i=0;i<params.length;i++)
     49             {
     50                 pStatement.setObject(i+1, params[i]);
     51             }            
     52             try(ResultSet rSet=pStatement.executeQuery();) 
     53             {
     54                 ResultSetMetaData rData=rSet.getMetaData();
     55                 //获取查询到结果表的列数
     56                 int columnCount = rData.getColumnCount();                
     57                 while (rSet.next()) {
     58                  T a=t.newInstance();//创建泛型类实例
     59                  for(int i=0;i<columnCount;i++)
     60                     {//获得方数组里的set方法,这里造成了局限性,只能数据库表列名与对象名一致,且只能是set方法
     61                         String aString="set"+rData.getColumnName(i+1);
     62                         for (Method method : declaredMethods) {
     63                             if(method.getParameterCount()==1&&method.getReturnType().toString().equals("void")&&method.getName().equalsIgnoreCase(aString))
     64                             {//这里存在问题,前两个判断条件基本没用,主要是最初不想用上面拼串的方式来判断是不是调用该参数的方法
     65                                 method.setAccessible(true);
     66                                 //利用反射调用该方法
     67                                 method.invoke(a, rSet.getObject(i+1));
     68                                 break;
     69                             }
     70                         }
     71                     }
     72                  arrayList.add(a);
     73                 }
     74             } catch (InstantiationException e) {
     75                 // TODO Auto-generated catch block
     76                 e.printStackTrace();
     77             } catch (IllegalAccessException e) {
     78                 // TODO Auto-generated catch block
     79                 e.printStackTrace();
     80             } catch (IllegalArgumentException e) {
     81                 // TODO Auto-generated catch block
     82                 e.printStackTrace();
     83             } catch (InvocationTargetException e) {
     84                 // TODO Auto-generated catch block
     85                 e.printStackTrace();
     86             } 
     87         } catch (SQLException e) {
     88             // TODO Auto-generated catch block
     89             throw e;
     90         }
     91         return arrayList;        
     92     }
     93     /**
     94      * 数据插入
     95      * @param sql 带占位符?的sql语句
     96      * @param params 替换占位符的数据,动态数组
     97      * @throws SQLException
     98      */
     99     public void insert(String sql,Object...params) throws SQLException
    100     {
    101         try(PreparedStatement pStatement=conn.prepareStatement(sql);) {
    102             
    103             for(int i=0;i<params.length;i++)
    104             {
    105                 pStatement.setObject(i+1, params[i]);
    106             }
    107             pStatement.executeUpdate();
    108         } catch (SQLException e) {
    109             // TODO Auto-generated catch block
    110             throw e;
    111         }
    112     }
    113     /**
    114      * 数据更新
    115      * @param sql 带占位符?的sql语句
    116      * @param params 替换占位符的数据,动态数组
    117      * @throws SQLException
    118      */
    119     public void update(String sql,Object...params) throws SQLException
    120     {
    121         try(PreparedStatement pStatement=conn.prepareStatement(sql);) {
    122             
    123             for(int i=0;i<params.length;i++)
    124             {
    125                 pStatement.setObject(i+1, params[i]);
    126             }
    127             pStatement.executeUpdate();
    128         } catch (SQLException e) {
    129             // TODO Auto-generated catch block
    130             throw e;
    131         }
    132     }
    133     /**
    134      * 带限制条件删除
    135      * @param sql 带占位符?的sql语句
    136      * @param params 替换占位符的数据,动态数组,不写这个参数,数组长度就为0
    137      * @throws SQLException
    138      */
    139     public void delete(String sql,Object...params) throws SQLException
    140     {
    141         try(PreparedStatement pStatement=conn.prepareStatement(sql);) {
    142             
    143             for(int i=0;i<params.length;i++)
    144             {
    145                 pStatement.setObject(i+1, params[i]);
    146             }
    147             pStatement.executeUpdate();
    148         } catch (SQLException e) {
    149             // TODO Auto-generated catch block
    150             throw e;
    151         }
    152     }
    153     /**
    154      * 删除全部,不带有限制,实际上与上一个方法重复了。
    155      * @param sql
    156      * @throws SQLException
    157      */
    158     public void deleteall(String sql) throws SQLException
    159     {
    160         try(PreparedStatement pStatement=conn.prepareStatement(sql);) {                        
    161             pStatement.executeUpdate();
    162         } catch (SQLException e) {
    163             // TODO Auto-generated catch block
    164             throw e;
    165         }
    166     }
    167     /**
    168      * 无限制条件查找,实际上与上一个查询的方法重复了
    169      * @param sql 
    170      * @param t 泛型类T.class
    171      * @return ArrayList<T>
    172      * @throws SQLException 
    173      */
    174     public <T> ArrayList<T> select(String sql,Class<T> t) throws SQLException
    175     {
    176         Method[] declaredMethods = t.getDeclaredMethods();
    177         ArrayList<T> arrayList=new ArrayList<>();
    178         try (PreparedStatement pStatement=conn.prepareStatement(sql);)
    179         {                        
    180             try(ResultSet rSet=pStatement.executeQuery();) 
    181             {
    182                 ResultSetMetaData rData=rSet.getMetaData();
    183                 int columnCount = rData.getColumnCount();                
    184                 while (rSet.next()) {
    185                  T a=t.newInstance();
    186                  for(int i=0;i<columnCount;i++)
    187                     {
    188                         String aString="set"+rData.getColumnName(i+1);
    189                         for (Method method : declaredMethods) {
    190                             if(method.getName().equalsIgnoreCase(aString))
    191                             {
    192                                 method.setAccessible(true);
    193                                 method.invoke(a, rSet.getObject(i+1));
    194                                 break;
    195                             }
    196                         }
    197                     }
    198                  arrayList.add(a);
    199                 }
    200             } catch (InstantiationException e) {
    201                 // TODO Auto-generated catch block
    202                 e.printStackTrace();
    203             } catch (IllegalAccessException e) {
    204                 // TODO Auto-generated catch block
    205                 e.printStackTrace();
    206             } catch (IllegalArgumentException e) {
    207                 // TODO Auto-generated catch block
    208                 e.printStackTrace();
    209             } catch (InvocationTargetException e) {
    210                 // TODO Auto-generated catch block
    211                 e.printStackTrace();
    212             } 
    213         } catch (SQLException e) {
    214             // TODO Auto-generated catch block
    215             throw e;
    216         }
    217         return arrayList;    
    218     }
    219     /**
    220      * 返回表中数据行数
    221      * @param tableName 数据库表名
    222      * @return 行数
    223      * @throws SQLException
    224      */
    225     public int count(String tableName) throws SQLException
    226     {
    227         String sql="select count(*) from "+tableName;
    228         try(PreparedStatement pStatement=conn.prepareStatement(sql);
    229                 ResultSet rsSet=pStatement.executeQuery();    )
    230         {        
    231             if(rsSet.next())
    232             {
    233                 return rsSet.getInt(1);
    234             }            
    235         } catch (SQLException e) {
    236             // TODO Auto-generated catch block
    237             throw e;
    238         }
    239         return 0;
    240     }
    241     /**
    242      * 判断数据是否存在
    243      * @param sql 带占位符?的sql语句
    244      * @param params 替换占位符的数据,动态数组
    245      * @return boolean
    246      * @throws SQLException
    247      */
    248     public boolean isExist(String sql,Object...params) throws SQLException
    249     {        
    250         try(PreparedStatement pStatement=conn.prepareStatement(sql);)
    251         {
    252             for(int i=0;i<params.length;i++)
    253             {
    254                 pStatement.setObject(i+1, params[i]);
    255             }
    256             try(ResultSet rsSet=pStatement.executeQuery();) {
    257                 if(rsSet.next())
    258                 {
    259                     return true;
    260                 }
    261             } finally {
    262                 
    263             }
    264         } catch (SQLException e) {
    265             // TODO Auto-generated catch block
    266             throw e;
    267         }
    268         return false;        
    269     }
    270     /**
    271      * 创建实例
    272      * @param url 数据库url
    273      * @param username 用户名
    274      * @param password 密码
    275      * @return    consql对象
    276      * @throws SQLException
    277      */
    278     public static Consql getnewInstance(String url,String username,String password) throws SQLException
    279     {
    280         if(consql==null)
    281             consql=new Consql(url, username, password);
    282         return consql;        
    283     }
    284     //垃圾回收,貌似并不能达到析构函数的效果
    285     protected void finalize() throws Throwable
    286     {
    287         if(conn!=null)
    288         {
    289             conn.close();        
    290         }
    291         super.finalize();
    292     }
    293 }

     本来想通过返回值类型,参数列表来确定该属性初始化方法的,然而可能是目前学到的还是太少,只学了三周,所以并没有实现,感觉这个方法还是很low,以后还要继续完善。本来看到网上有用beanUtils包,利用map将查询的一列存起来,直接转化成该对象的,但是就是想试试新学到的反射。而且最后的垃圾回收器并不能如同C++的析构函数一样,所以关闭数据库链接的地方也需要改善。

    实际上两个删除的方法和两个查询的方法是重复的,可变的参数列表,当无参数时,数组长度就为0,因此造成了两个方法的包含关系。

    人生如水,不争高山,自然愈下,三年又三年。——struggle!
  • 相关阅读:
    抽签问题及优化
    P1020
    p1852ants
    1,三角形
    TG3
    如何看懂一篇题解
    Unsupported major.minor version 51.0 错误解决方案
    weblogic初学笔记2-在Linux上部署项目
    一块移动硬盘怎样兼容Mac和Windows系统,并且可以在time machine上使用
    org.hibernate.HibernateException: connnection proxy not usable after transaction completion
  • 原文地址:https://www.cnblogs.com/PersistWp/p/7398111.html
Copyright © 2011-2022 走看看