视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
详解JDBC数据库链接及相关方法的封装
2020-11-09 20:31:50 责编:小采
文档


详解JDBC数据库链接及相关方法的封装

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

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

实现代码:

public class Consql {
 private static Consql consql=null;//单例设计模式
 private Connection conn=null;//数据库链接
 private final String url;//数据库url
 private final String username;//数据库用户名
 private final String password;//数据库密码
 //驱动类的加载
 static{//以静态代码块的形式加载驱动类,静态代码块只在类加载的时候执行一次
 try {
 Class.forName("com.mysql.jdbc.Driver");
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 }
 //构造函数
 private Consql(String url,String username,String password) throws SQLException{
 this.url = url;
 this.username = username;
 this.password = password;
 open();//创建连接
 }
 private Connection open() throws SQLException
 {
 try {//驱动器获取数据库链接
 conn=DriverManager.getConnection(url, username, password);
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 //e.printStackTrace();
 throw e;
 } 
 return conn; 
 }
 /**
 * 带条件查找
 * @param sql 带占位符?的sql语句
 * @param t 返回相关类型对象的类(T.class)
 * @param params 替换占位符的数据,为动态数组
 * @return ArrayList<T>
 * @throws SQLException 
 */
 public <T> ArrayList<T> select(String sql,Class<T> t,Object...params) throws SQLException
 {//获取T类所有public方法
 Method[] declaredMethods = t.getDeclaredMethods();
 //创建一个盛放该类型对象集合
 ArrayList<T> arrayList=new ArrayList<>();
 try (PreparedStatement pStatement=conn.prepareStatement(sql);)
 { 
 for(int i=0;i<params.length;i++)
 {
 pStatement.setObject(i+1, params[i]);
 } 
 try(ResultSet rSet=pStatement.executeQuery();) 
 {
 ResultSetMetaData rData=rSet.getMetaData();
 //获取查询到结果表的列数
 int columnCount = rData.getColumnCount(); 
 while (rSet.next()) {
 T a=t.newInstance();//创建泛型类实例
 for(int i=0;i<columnCount;i++)
 {//获得方数组里的set方法,这里造成了局限性,只能数据库表列名与对象名一致,且只能是set方法
 String aString="set"+rData.getColumnName(i+1);
 for (Method method : declaredMethods) {
 if(method.getParameterCount()==1&&method.getReturnType().toString().equals("void")&&method.getName().equalsIgnoreCase(aString))
 {//这里存在问题,前两个判断条件基本没用,主要是最初不想用上面拼串的方式来判断是不是调用该参数的方法
 method.setAccessible(true);
 //利用反射调用该方法
 method.invoke(a, rSet.getObject(i+1));
 break;
 }
 }
 }
 arrayList.add(a);
 }
 } catch (InstantiationException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (IllegalAccessException 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();
 } 
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 return arrayList; 
 }
 /**
 * 数据插入
 * @param sql 带占位符?的sql语句
 * @param params 替换占位符的数据,动态数组
 * @throws SQLException
 */
 public void insert(String sql,Object...params) throws SQLException
 {
 try(PreparedStatement pStatement=conn.prepareStatement(sql);) {
 
 for(int i=0;i<params.length;i++)
 {
 pStatement.setObject(i+1, params[i]);
 }
 pStatement.executeUpdate();
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 }
 /**
 * 数据更新
 * @param sql 带占位符?的sql语句
 * @param params 替换占位符的数据,动态数组
 * @throws SQLException
 */
 public void update(String sql,Object...params) throws SQLException
 {
 try(PreparedStatement pStatement=conn.prepareStatement(sql);) {
 
 for(int i=0;i<params.length;i++)
 {
 pStatement.setObject(i+1, params[i]);
 }
 pStatement.executeUpdate();
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 }
 /**
 * 带条件删除
 * @param sql 带占位符?的sql语句
 * @param params 替换占位符的数据,动态数组
 * @throws SQLException
 */
 public void delete(String sql,Object...params) throws SQLException
 {
 try(PreparedStatement pStatement=conn.prepareStatement(sql);) {
 
 for(int i=0;i<params.length;i++)
 {
 pStatement.setObject(i+1, params[i]);
 }
 pStatement.executeUpdate();
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 }
 /**
 * 删除全部,不带有
 * @param sql
 * @throws SQLException
 */
 public void deleteall(String sql) throws SQLException
 {
 try(PreparedStatement pStatement=conn.prepareStatement(sql);) { 
 pStatement.executeUpdate();
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 }
 /**
 * 无条件查找
 * @param sql 
 * @param t 泛型类T.class
 * @return ArrayList<T>
 * @throws SQLException 
 */
 public <T> ArrayList<T> select(String sql,Class<T> t) throws SQLException
 {
 Method[] declaredMethods = t.getDeclaredMethods();
 ArrayList<T> arrayList=new ArrayList<>();
 try (PreparedStatement pStatement=conn.prepareStatement(sql);)
 { 
 try(ResultSet rSet=pStatement.executeQuery();) 
 {
 ResultSetMetaData rData=rSet.getMetaData();
 int columnCount = rData.getColumnCount(); 
 while (rSet.next()) {
 T a=t.newInstance();
 for(int i=0;i<columnCount;i++)
 {
 String aString="set"+rData.getColumnName(i+1);
 for (Method method : declaredMethods) {
 if(method.getName().equalsIgnoreCase(aString))
 {
 method.setAccessible(true);
 method.invoke(a, rSet.getObject(i+1));
 break;
 }
 }
 }
 arrayList.add(a);
 }
 } catch (InstantiationException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (IllegalAccessException 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();
 } 
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 return arrayList; 
 }
 /**
 * 返回表中数据行数
 * @param tableName 数据库表名
 * @return 行数
 * @throws SQLException
 */
 public int count(String tableName) throws SQLException
 {
 String sql="select count(*) from "+tableName;
 try(PreparedStatement pStatement=conn.prepareStatement(sql);
 ResultSet rsSet=pStatement.executeQuery(); )
 { 
 if(rsSet.next())
 {
 return rsSet.getInt(1);
 } 
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 return 0;
 }
 /**
 * 判断数据是否存在
 * @param sql 带占位符?的sql语句
 * @param params 替换占位符的数据,动态数组
 * @return boolean
 * @throws SQLException
 */
 public boolean isExist(String sql,Object...params) throws SQLException
 { 
 try(PreparedStatement pStatement=conn.prepareStatement(sql);)
 {
 for(int i=0;i<params.length;i++)
 {
 pStatement.setObject(i+1, params[i]);
 }
 try(ResultSet rsSet=pStatement.executeQuery();) {
 if(rsSet.next())
 {
 return true;
 }
 } finally {
 
 }
 } catch (SQLException e) {
 // TODO Auto-generated catch block
 throw e;
 }
 return false; 
 }
 /**
 * 创建实例
 * @param url 数据库url
 * @param username 用户名
 * @param password 密码
 * @return consql对象
 * @throws SQLException
 */
 public static Consql getnewInstance(String url,String username,String password) throws SQLException
 {
 if(consql==null)
 consql=new Consql(url, username, password);
 return consql; 
 }
 //垃圾回收,貌似并不能达到析构函数的效果
 protected void finalize() throws Throwable
 {
 if(conn!=null)
 {
 conn.close(); 
 }
 super.finalize();
 }
}

下载本文
显示全文
专题