zoukankan      html  css  js  c++  java
  • JDBC的简单封装

      JDBC的简单封装

      使用JDBC来处理数据库的接口主要有三个,即Connection,PreparedStatement和ResultSet这三个,而对于这三个接口,还可以获取不同类型的元数据,通过这些元数据类获得一些数据库的信息。
    元数据(MetaData),即定义数据的数据。打个比方,就好像我们要想搜索一首歌(歌本身是数据),而我们可以通过歌名,作者,专辑等信息来搜索,那么这些歌名,作者,专辑等等就是这首歌的元数据。因此数据库的元数据就是一些注明数据库信息的数据。

      ① 由Connection对象的getMetaData()方法获取的是DatabaseMetaData对象。

      ② 由PreparedStatement对象的getParameterMetaData ()方法获取的是ParameterMetaData对象。

      ③由ResultSet对象的getMetaData()方法获取的是ResultSetMetaData对象。

      今天仅仅使用第二点,所以就解释一下第二点
        ParameterMetaData是由PreparedStatement对象通过getParameterMetaData方法获取而来,主要是针对PreparedStatement对象和其预编译的SQL命令语句提供一些信息,比如像”insert into account(id,name,money) values(?,?,?)”这样的预编译SQL语句,ParameterMetaData能提供占位符参数的个数,获取指定位置占位符的SQL类型等等,功能也比较多,这里不列举完,详细请看有关ParameterMetaData的API文档。
    Eg: getParameterCount:获取预编译SQL语句中占位符参数的个数

    下面就是贴代码了:封装了几个类(类中对功能做了详细的说明

    第一个类:CommonDao  封装了对JDBC的获取连接和连接关闭, 查询和更新功能

    package jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ParameterMetaData;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.sql.Types;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    
    public class CommonDAO {
    	// 数据库连接url
    	private static final String url = "jdbc:mysql://localhost:3306/test?Unicode=true&characterEncoding=UTF-8";
    	// 数据库连接用户名
    	private static final String username = "root";
    	// 数据库连接密码
    	private static final String password = "root";
    	// 数据库驱动
    	private static final String jdbcDriver = "com.mysql.jdbc.Driver";
    
    	// 调用 ParameterMetaData.getParameterType(i + 1) 是否会抛出异常
    	protected boolean pmdKnownBroken = false;
    
    	public CommonDAO() {
    	}
    
    	public CommonDAO(boolean pmdKnownBroken) {
    		this.pmdKnownBroken = pmdKnownBroken;
    	}
    
    	// 获取连接
    	public Connection getConnetion() {
    		Connection conn = null;
    		try {
    			Class.forName(jdbcDriver);
    			conn = DriverManager.getConnection(url, username, password);
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		}
    		return conn;
    	}
    
    	/**
    	 * @Title: executeQuery
    	 * @Description: 执行Sql 查询语句,把结果集合放在一个 List<Map<String,Object>> 里面
    	 * @param sql
    	 * @param parmas
    	 * @return
    	 * @return List<Map<String,Object>>
    	 */
    
    	@SuppressWarnings("unchecked")
    	public List<Map<String, Object>> executeQuery(String sql, Object[] params) {
    		return (List<Map<String, Object>>) this.excuteQuery(sql, params, new ListMapHander());
    	}
    
    	/**
    	 * @Title: excuteQuery
    	 * @Description: 查询给定的SQL语句,并且自定义的处理结果集。 调用者需要自己手动实现
    	 *               接口<code>ResultSetHander.doHander(ResultSet rs)</code>
    	 *               方法以得结果集里面的数据
    	 * @param sql
    	 * @param params
    	 * @param rsh
    	 * @return
    	 * @return Object
    	 */
    
    	public Object excuteQuery(String sql, Object[] params, ResultSetHander rsh) {
    		PreparedStatement stmt = null;
    		ResultSet rs = null;
    		Connection con = this.getConnetion();
    		List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
    		try {
    			stmt = con.prepareStatement(sql);
    
    			System.out.println("SQL:" + sql + "; Parameters:" + Arrays.deepToString(params));
    
    			// 填充Statement的参数
    			fillStatement(stmt, params);
    			// 执行查询
    			rs = stmt.executeQuery();
    
    			Object obj = rsh.doHander(rs);
    			return obj;
    
    		} catch (SQLException e) {
    			e.printStackTrace();
    		} finally {
    			// 关闭数据库连接
    			close(con, stmt, rs);
    		}
    		return resultList;
    	}
    
    	public int executeUpdate(String sql, Object[] params) {
    		PreparedStatement stmt = null;
    		Connection con = this.getConnetion();
    
    		int rs = 0;
    		try {
    			con.setAutoCommit(false);
    			// 创建PreparedStatement对象
    			stmt = con.prepareStatement(sql);
    			// 填充Statement的参数
    			fillStatement(stmt, params);
    			System.out.println("SQL:" + sql + "; Parameters:" + Arrays.deepToString(params));
    			// 执行查询
    			rs = stmt.executeUpdate();
    			// 提交事务
    			con.commit();
    			// 把事务设置为原来的
    			con.setAutoCommit(true);
    		} catch (SQLException e) {
    			// 在捕获到异常的时候事务回滚
    			try {
    				con.rollback();
    				if (!con.getAutoCommit()) {
    					con.setAutoCommit(true);
    				}
    			} catch (SQLException e1) {
    				e1.printStackTrace();
    			}
    			e.printStackTrace();
    		} finally {
    			// 关闭数据库连接
    			close(con, stmt, null);
    		}
    		return rs;
    	}
    
    	/**
    	 * @Title: fillStatement
    	 * @Description: 填充SQL参数
    	 * @param stmt
    	 * @param params
    	 * @throws SQLException
    	 * @return void
    	 */
    	private void fillStatement(PreparedStatement stmt, Object[] params) throws SQLException {
    
    		// 检测参数的个数是否合法,但是有的数据库驱动不支持 stmt.getParameterMetaData()这个方法。
    		// 因此我们有一个一个pmdKnownBroken 变量来标识当前数据驱动是否支持该方法的调用。
    		ParameterMetaData pmd = null;
    		if (!pmdKnownBroken) {
    			pmd = stmt.getParameterMetaData();
    			int stmtCount = pmd.getParameterCount();
    			int paramsCount = params == null ? 0 : params.length;
    
    			if (stmtCount != paramsCount) {
    				System.out.println("stmtCount:" + stmtCount + ",paramsCount:" + paramsCount);
    				throw new SQLException(
    						"Wrong number of parameters: expected " + stmtCount + ", was given " + paramsCount);
    			}
    		}
    
    		// 如果 params 为 null 直接返回
    		if (params == null) {
    			return;
    		}
    
    		for (int i = 0; i < params.length; i++) {
    			if (params[i] != null) {
    				stmt.setObject(i + 1, params[i]);
    			} else {
    				int sqlType = Types.VARCHAR;
    				if (!pmdKnownBroken) {
    					try {
    						sqlType = pmd.getParameterType(i + 1);
    					} catch (SQLException e) {
    						pmdKnownBroken = true;
    					}
    				}
    				stmt.setNull(i + 1, sqlType);
    			}
    		}
    	}
    
    	/**
    	 * @Title: close
    	 * @Description: 关闭数据库连接
    	 * @param con
    	 * @param stmt
    	 * @param rs
    	 * @return void
    	 */
    	private void close(Connection con, Statement stmt, ResultSet rs) {
    
    		if (rs != null) {
    			try {
    				rs.close();
    			} catch (Exception e) {
    			} finally {
    				if (stmt != null) {
    					try {
    						stmt.close();
    					} catch (SQLException e) {
    						e.printStackTrace();
    					} finally {
    						if (con != null) {
    							try {
    								con.close();
    							} catch (SQLException e) {
    								e.printStackTrace();
    							}
    						}
    					}
    				}
    			}
    		}
    
    	}
    }
    

      下面是自封装集合处理类:


    package jdbc;
    
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class ListMapHander implements ResultSetHander {
    
        @Override
        public List<Map<String, Object>> doHander(ResultSet rs) throws SQLException {
            List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
            ResultSetMetaData rsmd = rs.getMetaData();
            int cols = rsmd.getColumnCount();
    
            HashMap<String, Object> m = null;
    
            // System.out.println("list 结果:");
            // 遍历结果集
            while (rs.next()) {
                m = new HashMap<String, Object>();
                // 将结果集中的数据保存到HashMap中
                for (int i = 1; i <= cols; i++) {
                    System.out.println("Label:" + rsmd.getColumnLabel(i));
                    System.out.println(rsmd.getColumnName(i) + "," + rs.getObject(i));
                    m.put(rsmd.getColumnLabel(i), rs.getObject(i));
                }
                resultList.add(m);
            }
            return resultList;
        }
    
    }

     数据处理接口类:

    package jdbc;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public interface ResultSetHander {
        //自定义处理结果集
        public Object doHander(ResultSet rs) throws SQLException;
    }

    实现上面的接口类:


    package jdbc;
    
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class ListMapHander implements ResultSetHander {
    
        @Override
        public List<Map<String, Object>> doHander(ResultSet rs) throws SQLException {
            List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
            ResultSetMetaData rsmd = rs.getMetaData();
            int cols = rsmd.getColumnCount();
    
            HashMap<String, Object> m = null;
    
            // System.out.println("list 结果:");
            // 遍历结果集
            while (rs.next()) {
                m = new HashMap<String, Object>();
                // 将结果集中的数据保存到HashMap中
                for (int i = 1; i <= cols; i++) {
                    System.out.println("Label:" + rsmd.getColumnLabel(i));
                    System.out.println(rsmd.getColumnName(i) + "," + rs.getObject(i));
                    m.put(rsmd.getColumnLabel(i), rs.getObject(i));
                }
                resultList.add(m);
            }
            return resultList;
        }
    
    }

     下面是测试类:数据以Objcet对象数组的形式传入, 利用占位符。


    package jdbc;
    
    public class Test {
        public static void main(String[] args) {
            CommonDAO commonDAO = new CommonDAO();
            String sql = "select * from student";
            commonDAO.executeQuery(sql, null);
            /*commonDAO.executeUpdate("insert into student values (?,?,?,?,?)",
                    new Object[] { "210", "彭宇", "男", "1995-02-02", "955330" });*/
            
        }
    }
  • 相关阅读:
    String源码分析
    solr IK分词器
    solr安装
    hadoop HA集群搭建(亲测)
    dubbo-admin安装
    关于idea中使用lamb表达式报错:ambda expressions are not supported at this language level
    web项目数据存入mysql数据库中文乱码问题
    dom4j解析xml
    js监听键盘提交表单
    Location replace() 方法
  • 原文地址:https://www.cnblogs.com/wangnuo/p/7340380.html
Copyright © 2011-2022 走看看