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
     */

    @SuppressWarnings("unchecked")
    private List<Map<String, 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 {
            // 预编译sql
            stmt = con.prepareStatement(sql);
            System.out.println("SQL:" + sql + "; Parameters:" + Arrays.deepToString(params));

            // 填充Statement的参数
            fillStatement(stmt, params);
            // 执行查询
            rs = stmt.executeQuery();

            List<Map<String, Object>> list = (List<Map<String, Object>>) rsh.doHander(rs);
            return list;

        } 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) {
                e.printStackTrace();
            } finally {
                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    } finally {
                        if (con != null) {
                            try {
                                con.close();
                            } catch (SQLException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        } else {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    if (con != null) {
                        try {
                            con.close();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } else {
                if (con != null) {
                    try {
                        con.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }
}

第一个接口:添加了一个数据处理接口



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" });*/

    }
}
时间: 2024-08-01 00:34:28

JDBC的简单封装的相关文章

JDBC简单封装

/** * JDBC简单封装 * 需要借助FastJsonUtil可以参考上一篇 * @author huangxincheng * */ public class BaseDao { private static String URL; private static String USERNAME; private static String PASSWORD; private static String DRIVER; private  Connection connection; priv

通过JDBC进行简单的增删改查

通过JDBC进行简单的增删改查(以MySQL为例) 目录 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操作 (1)定义记录的类(可选) (2)连接的获取 (3)insert (4)update (5)select (6)delete 四.测试 五.代码分析 六.思考问题 前言:什么是JDBC 维基百科的简介: Java 数据库连接,(Java Database Connectivity,简称JDBC)

通过JDBC进行简单的增删改查(以MySQL为例) 目录

通过JDBC进行简单的增删改查(以MySQL为例) 目录 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操作 (1)定义记录的类(可选) (2)连接的获取 (3)insert (4)update (5)select (6)delete 四.测试 五.代码分析 六.思考问题 前言:什么是JDBC 维基百科的简介: Java 数据库连接,(Java Database Connectivity,简称JDBC)

Java通过JDBC进行简单的增删改查(以MySQL为例)

Java通过JDBC进行简单的增删改查(以MySQL为例) 目录: 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操作   (1)定义记录的类(可选) (2)连接的获取 (3)insert (4)update (5)select (6)delete 四.测试 五.代码分析 六.思考问题 前言:什么是JDBC 维基百科的简介: Java 数据库连接,(Java Database Connectivity,

对系统网络请求进行简单封装

AGConnectionNet对系统网络请求进行简单封装,可便利的进行网络请求,并将数据解析与网络请求封装在同一方法下,使用更加便利(JSON 解析采用自身解析方法, XML 解析采用第三方 ReadXML 进行解析). 方法具体参数说明 初始化方法:/*** 类方法,实例化当前数据请求对象 (单例)** @return 当前请求对象*/+ (instancetype)shareRequestData; 仅进行请求数据方法/*** 请求数据 (session 请求)** @param URLSt

iOS sqlite 增删改查 简单封装(基于 FMDB)

/** *  对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查 * *  基于 FMDB * *  操作基于 model ,数据库表字段与 model 属性一一对应,对 model 整体进行操作 * *  根据 model 对象自动建表,字段类型只支持 NSString , NSIteger , float * *  用到 runtime 运行时获取 model 属性 * */ 1 // 2 // AGDatabaseManager.h 3 // 4 // Created by

简单封装sqlite3 实现实体对象与关系型数据库的相关操作【IOS】

源码如下,只有一个类文件 // //  DBHelper.h // //  Created by Jason_Msbaby on 15/10/15. //  Copyright ? 2015年 张杰. All rights reserved. // /**  *  简单封装了对于sqlite的使用 没有加入对事务及其他复杂的特性     基于传入sql语句的方式进行执行     使用单例模式     根据model对象自动创建表 只支持 NSInter NSString float 数据类型的支

httpclient4.3简单封装

对httpclient4.3版本的一个简单封装,下面是代码 /**  * httputil工具类  *   * @author rex  */ public class HttpUtil {     private static CloseableHttpClient client;     private static BasicCookieStore cookieStore;     private static HttpGet get;     private static HttpPos

MySQL的C++简单封装

/* *介绍:MySQL的简单封装,支持流操作输入输出MySQL语句,然而并没有什么软用,大二学生自娱自乐,有不足求指点 *作者:MrEO *日期:2016.3.26 */ 头文件 my_sql.h 1 #ifndef MY_SQL_H 2 #define MY_SQL_H 3 4 #include <mysql.h> 5 #include <iostream> 6 #include <string> 7 #include <iomanip> 8 9 cla