您的位置:首页 > 其它

JDBC的简单封装

2017-08-10 17:23 232 查看
  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" });*/

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: