package org.jplus.hyb.database; import java.sql.*; import java.util.ArrayList; import java.util.List; import org.jplus.util.LoggerManage; /** * 数据库基本操作工具 * @version 2.0 * @author hyberbin */ public class DatabaseAccess extends SqlFilter { /** 数据库连接对象 */ private Connection conn = null; /** Statement对象,用于执行带参数的SQL语句 */ private PreparedStatement stm = null; /** 数据集 */ private ResultSet rs = null; /** 预处理参数列表 */ public List parmeterList = null; /** 是否自动关闭 */ public boolean autoClose = true; /** 是否自动清除预处理参数 */ public boolean autoClearPrepare = true; /** 数据库是否关闭 */ public boolean isClosed = false; /** 获取用于引用 SQL 标识符的字符串 */ public String quote = ""; public boolean isTransaction = false;//是否带有事务 public boolean isAlive = true;//当前对象是否可用,当前数据库连接是否可用 private boolean isTransactionSucces = false;//事务是否执行成功 public boolean isCommited = false;//事务是否提交过 private String lockedTable; /** * 自带的连接创建数据库操作对象 * @param conn 连接 */ public DatabaseAccess(Connection conn) { this.conn = conn; } /** * 放置一个参数到sql预处理列表 * @param parameter 参数 */ public void setParmeter(Object parameter) { if (isAlive) { if (parmeterList == null) { parmeterList = new ArrayList(); } parmeterList.add(parameter); } else { LoggerManage.logger.getLogger("DatabaseAccess由于事务已经提交参数不能添加!\nparameter:" + parameter + "\n", null); } } /** 是否设定下一次不清除(用于分页的时候查询主表和查询总条数共用) */ public boolean delayClear = false; /** * 清空预处理参数列表 * @return */ public void clearParmeter() { if (!delayClear) { parmeterList = null; } else { delayClear = !delayClear; } } /** * 创建预处理对象 * @param sql 预处理语句 * @throws SQLException */ private void createStatement(String sql) throws SQLException { stm = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); if (DatabaseINI.isSqlout) { sqlOut(sql, false); } int index = 1; if (parmeterList != null) { for (Object parmeter : parmeterList) { stm.setObject(index++, parmeter); } } } /** * 获取连接对象 * @return 连接对象 */ public Connection getConn() { return conn; } /** * 获得Statement * @return */ public PreparedStatement getStatement() { return stm; } /** * 数据库更新操作 * @param sql SQL语句 * @return 是否成功 */ public boolean update(String sql) { boolean b = false; if (isAlive) { try { createStatement(sql); stm.executeUpdate(); b = true; } catch (SQLException ex) { if (isTransaction) {//如果带有事务 this.transactionEnd(false); } LoggerManage.logger.getLogger("DatabaseAccess数据库修改出错\nsql:" + sqlOut(sql, true) + "\n", ex); } finally { close(); } if (autoClearPrepare) { clearParmeter(); } } else { LoggerManage.logger.getLogger("DatabaseAccess由于事务已经提交以下语句未能执行!\nsql:" + sqlOut(sql, true) + "\n", null); } return b; } /** * 数据库查询操作 * @param sql SQL语句 * @return 查询结果 */ public ResultSet query(String sql) { if (isAlive) { try { createStatement(sql); rs = stm.executeQuery(); } catch (SQLException ex) { if (isTransaction) {//如果带有事务 this.transactionEnd(false); } LoggerManage.logger.getLogger("DatabaseAccess数据库查询出错\nsql:" + sqlOut(sql, true) + "\n", ex); } if (autoClearPrepare) { clearParmeter(); } } else { LoggerManage.logger.getLogger("DatabaseAccess由于事务已经提交以下语句未能执行!\nsql:" + sqlOut(sql, true) + "\n", null); } return rs; } /** * 用于插入并返回主键 * @param sql * @return */ public Integer executeInsert(String sql) { update(sql); return getGeneratedKeys(); } public Integer getGeneratedKeys() { Integer primarykey = -1; try { rs = stm.getGeneratedKeys(); if (rs.next()) { primarykey = rs.getInt(1); } } catch (Exception e) { if (isTransaction) {//如果带有事务 this.transactionEnd(false); } LoggerManage.logger.getLogger("DatabaseAccess返回生成的主键出错!", null); } return primarykey; } /** * 判断查询结果是否为空 * @return 是否为空 */ public boolean isResultSetNull() { boolean b = false; try { if (rs.next()) { b = true; } } catch (SQLException ex) { LoggerManage.logger.getLogger("DatabaseAccess数据集合判空出错\t", ex); } return b; } /** * 开启事务 <p>此方法用于开启数据库事务处理机制。 <p>用此方法不会自动关闭数据库连接。 <p>主要用于数据库的修改、删除、添加。 * <p>用于在一定条件下可以还原之前的操作 <p>Ex: <p>Hyberbin hyberbin=new Hyberbin(news); * <strong><p>transactionBegan();</strong> <p>hyberbin.insert(news); * <p>transactionEnd(false);//执行这个语句之上的操作就会无效 */ public void transactionBegan() { try { if (!conn.isClosed() && !isTransaction) { if (DatabaseINI.isSqlout) { LoggerManage.logger.debug("开户事务"); } conn.setAutoCommit(false); autoClose = false; } } catch (SQLException ex) { LoggerManage.logger.getLogger("Hyberbin开启事务出错\t", ex); } isTransaction = true; } /** * 事务完毕 <p>此方法用于完成数据库事务处理机制。 <p>用此方法不会自动关闭数据库连接。 <p>主要用于数据库的修改、删除、添加。 * <p>用于在一定条件下可以还原或提交之前的操作 <p>Ex: <p>Hyberbin hyberbin=new Hyberbin(news); * <p>transactionBegan(); <p>hyberbin.insert(news); * <strong><p>transactionEnd(false);//执行这个语句之上的操作就会无效</strong> * <p>如果要提交操作就执行transactionEnd(true); * * @param success 是否提交 */ public void transactionEnd(boolean success) { if (this.lockedTable != null) {//如果有锁表先解锁 this.unlockTable(); } try { if (!isCommited && !conn.isClosed()&&isTransaction) { isCommited = true; if (DatabaseINI.isSqlout) { LoggerManage.logger.debug(success ? "提交" : "回滚" + "事务"); } if (success) { conn.commit(); isTransactionSucces = true; } else { conn.rollback(); } reallyClose(); } } catch (SQLException ex) { LoggerManage.logger.getLogger("Hyberbin" + (success ? "提交" : "回滚" + "事务出错\t"), ex); } } /** * 自动提交事务 并返回事务是否执行成功 * @return */ public boolean transactionEnd() { if (isAlive && !isCommited) { transactionEnd(true); } return isTransactionSucces; } /** * 返回事务是否成功 * @return */ public boolean isTransactionSucces() { return isTransactionSucces; } /** 是否设定下一次不清除(用于分页的时候查询主表和查询总条数共用) */ public boolean delayClose = false; /** * 关闭数据库连接释放资源 */ public void close() { if (!delayClose && isAlive) { if (!autoClose || isClosed) {//如果非自动关闭就直接返回 return; } if (isTransaction && !isCommited) {//如果有事务就先提交事务 transactionEnd(); } if (!isAlive) { return; } if (rs != null) { try { rs.close(); } catch (Exception ex) { } } if (stm != null) { try { stm.close(); } catch (Exception ex) { } } if (conn != null) { try { conn.close(); } catch (Exception ex) { } } if (DatabaseINI.isSqlout) { LoggerManage.logger.debug("DatabaseAccess关闭数据库连接"); } isAlive = false; isClosed = true; } else { delayClose = !delayClose; } } /** * 真正地关闭数据库连接 */ public void reallyClose() { autoClose = true; close(); } /** * 输出SQL语句 * @param sql */ private String sqlOut(String sql, boolean out) { try { if ((out || DatabaseINI.isSqlout) && parmeterList != null) { for (Object o : parmeterList) { sql = sql.replaceFirst("[?]", o + ""); } } LoggerManage.logger.debug("参考sql语句(各参数的引号已被忽略):" + sql); } catch (Exception e) { LoggerManage.logger.getLogger("在运行正则表达式时发生错误(不严重):" + sql, e); } return sql; } /** * 锁表 * @param tableName 表名 */ public void lockTable(String tableName) { lockedTable = tableName; update("lock table " + lockedTable + " write"); } /** * 解锁 */ public void unlockTable() { if (lockedTable != null) { lockedTable = null; update("unlock table"); } } public String getQuote() { return quote; } public void setQuote(String quote) { this.quote = quote; } }