DBAccessor
JDBC経由でDBを操作するクラス
1 |
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
/**
* DBにアクセスするためのクラス
*/
public class DBAccessor implements Cloneable {
/** エラーをどこにも出力しない */
final public static int TO_NO = 0;
/** エラーをコンソールに出力する */
final public static int TO_CONSOLE = 1;
/** エラーをLogを使って出力する */
final public static int TO_LOG = 2;
/** エラーをDialogに出力する */
final public static int TO_DIALOG = 3;
/** データを読み込むモード */
public static enum MODE {
ALL, //全データを読み込む
ONE //1レコードだけ読み込む
}
/** エラー時にログの出力先 */
protected int errorLog = TO_CONSOLE;
/** データベースコネクション */
protected Connection con = null;
/** 接続文字列(URL) */
protected String connectionString = null;
/** ドライバ名 */
protected String driverName = null;
/** パスワード */
protected String pass = null;
private static DBAccessor self = null;
/** ユーザ名 */
protected String user = null;
/**
* コンストラクタ。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*/
public DBAccessor(String driverName, String connectionString, String user, String pass) {
this(driverName, connectionString, user, pass, TO_CONSOLE);
}
/**
* コンストラクタ。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*/
public DBAccessor(String driverName, String connectionString, String user, String pass, int errorLog) {
this.errorLog = errorLog;
this.driverName = driverName;
this.connectionString = connectionString;
this.user = user;
this.pass = pass;
try {
Class.forName(driverName);
} catch (Exception e) {
this.outputException(e);
}
}
@Override
public Object clone(){
return new DBAccessor(
this.driverName,
this.connectionString,
this.user,
this.pass,
this.errorLog);
}
/** 接続を閉じる */
public void close() {
if (!isClosed()) {
try {
con.close();
} catch (Exception e) {
this.outputException(e);
}
con = null;
}
}
/**
* データベースに接続し、SQL 文をデータベースに送るための Statement オブジェクトを生成します。
*
*@return 新しいデフォルト Statement オブジェクト
*@exception SQLException データベースアクセスエラーが発生した場合、このメソッドがクローズされた接続に対して呼び出された場合、または指定されたパラメータが型および並行処理を示す ResultSet 定数でない場合
*/
public Statement createStatement() throws SQLException{
if (connect()){
return con.createStatement();
}
return null;
}
/**
* データベースに接続し、パラメータ付き SQL 文をデータベースに送るための PreparedStatement オブジェクトを生成します。
*
*@param sql 1 つ以上の '?' IN パラメータプレースホルダーを含めることができる SQL 文
*@return プリコンパイルされた SQL 文を含む新しいデフォルトの PreparedStatement オブジェクト
*@exception SQLException データベースアクセスエラーが発生した場合、またはこのメソッドがクローズされた接続について呼び出された場合
*/
public PreparedStatement prepareStatement(String sql) throws SQLException {
if (connect()){
return con.prepareStatement(sql);
}
return null;
}
/**
* データベースのストアドプロシージャーを呼び出すための CallableStatement オブジェクトを生成します
*
*@param sql - 1 つ以上の '?' パラメータプレースホルダーを含めることができる SQL 文。 通常この文は、JBDC 呼び出しのエスケープ構文を使用して指定される
*@return プリコンパイルされた SQL 文を含む新しいデフォルトの CallableStatement オブジェクト
*@exception SQLException データベースアクセスエラーが発生した場合、またはこのメソッドがクローズされた接続について呼び出された場合
*/
public CallableStatement prepareCall(String sql) throws SQLException {
if (connect()){
return con.prepareCall(sql);
}
return null;
}
/**
* 指定された Statmentクラス インスタンスを解放します。
*
*@param st Statmentクラス インスタンス
*/
public void close(Statement st){
if (st != null){
try {
st.close();
} catch (Exception e){
this.outputException(e);
}
}
}
/**
* 指定された ResultSetクラス インスタンスを解放します。
*
*@param rs ResultSetクラス インスタンス
*/
public void close(ResultSet rs){
if (rs != null){
try {
rs.close();
} catch (Exception e){
this.outputException(e);
}
}
}
/**
* 指定された Statmentクラス インスタンス と ResultSetクラス インスタンス を解放します。
*
*@param st Statmentクラス インスタンス
*@param rs ResultSetクラス インスタンス
*/
public void close(Statement st, ResultSet rs){
close(rs);
close(st);
}
/**
* コミット処理をする
*
*@return コミット処理に成功した場合はTrue、それ以外はFalse。
*/
public boolean commit() {
if (isClosed()) {
return false;
}
try {
con.commit();
return true;
} catch (Exception e) {
this.outputException(e);
return false;
}
}
/**
* データベース接続
*
*@return 接続に成功した場合はTrue、それ以外はFalse。
*/
public boolean connect() throws SQLException{
boolean result = false;
if (isClosed()) {
con = DriverManager.getConnection(connectionString,
user, pass);
con.setAutoCommit(false);
result = true;
} else {
// Log.getLogger().severe("既に接続されています");
result = true;
}
return result;
}
/**
* 指定されたパラメータからDBAccessorインスタンスを返す。
* getInstance() を使用することにより、生成された
* インスタンスを取り出すことが出来る。<br><br>
* もし、以前に生成されたインスタンスがあれば接続を閉じる。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@return 生成したDBAccessorのインスタンス
*/
public static DBAccessor createInstance(String driverName, String connectionString, String user, String pass) {
return createInstance(driverName, connectionString, user, pass, TO_CONSOLE);
}
/**
* 指定されたパラメータからDBAccessorインスタンスを返す。
* getInstance() を使用することにより、生成された
* インスタンスを取り出すことが出来る。<br><br>
* もし、以前に生成されたインスタンスがあれば接続を閉じる。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*@return 生成したDBAccessorのインスタンス
*/
public static DBAccessor createInstance(String driverName, String connectionString, String user, String pass, int errorLog) {
if (self != null && !self.isClosed()){
self.close();
}
self = new DBAccessor(driverName, connectionString, user, pass, errorLog);
return getInstance();
}
/**
* createInstance()メソッドによって生成されたインスタンスを
* 取得する。
*
*@return createInstanceによって生成されたDBAccessorインスタンス
*/
public static DBAccessor getInstance() {
return self;
}
/**
* createInstance()メソッドによって生成されたインスタンスから
* 新しいDBAccessorを返す
*
*@return createInstanceによって生成されたDBAccessorインスタンスから
* 生成された新しいDBAccessor
*/
public static DBAccessor newInstance() {
return (DBAccessor)getInstance().clone();
}
/**
* 接続状態を返す。
*
*@return 閉じている場合はTrue。
*/
public boolean isClosed() {
try {
return (con == null || con.isClosed());
} catch (Exception e) {
this.outputException(e);
return true;
}
}
/**
* ロールバック処理をする
*
*@return Description of the Return Value
*/
public boolean rollback() {
if (isClosed()) {
return false;
}
try {
con.rollback();
return true;
} catch (Exception e) {
this.outputException(e);
return false;
}
}
/**
* 指定された Exceptionクラス インスタンスよりエラーを出力します。
*
*@param e Exceptionクラス インスタンス
*/
private void outputException(Exception e){
switch (errorLog) {
case TO_LOG:
//Log.logStackTrace(e);
break;
case TO_CONSOLE:
System.out.println(e);
break;
case TO_NO:
break;
case TO_DIALOG:
javax.swing.JOptionPane.showMessageDialog(null, e);
break;
}
}
/**
* 指定されたエラーの出力先をセットします。
*
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*/
public void setErrorLog(int errorLog){
this.errorLog = errorLog;
}
/**
* データベースのコネクションを返します。
*
*@return データベースコネクション
*/
public Connection getConnection() throws SQLException{
if (connect()){
return con;
}
return null;
}
/**
* パラメータの型に合わせて PreparedStatement にパラメータをセットする。
*
*@param st PreparedStatementインスタンス
*@param param パラメータのArrayList
*@exception Exception 処理中に発生した例外
*/
public void setParameters(PreparedStatement st, ArrayList<Object> param) throws Exception {
setParameters(st, param.toArray());
}
/**
* パラメータの型に合わせて PreparedStatement にパラメータをセットする。
*
*@param st PreparedStatementインスタンス
*@param param パラメータのObject配列
*@exception Exception 処理中に発生した例外
*/
public void setParameters(PreparedStatement st, Object[] param) throws Exception {
for (int i = 0; i < param.length; i++) {
if (param[i] instanceof Long){
st.setLong(i + 1, (Long)param[i]);
} else if (param[i] instanceof Double){
st.setDouble(i + 1, (Double)param[i]);
} else if (param[i] instanceof Integer){
st.setInt(i + 1, (Integer)param[i]);
} else if (param[i] instanceof java.sql.Date){
st.setDate(i + 1, (java.sql.Date)param[i]);
} else {
st.setString(i + 1, (String)param[i]);
}
}
}
/**
* 指定されたSQLを実行し、実行結果を ArrayList で返す。
*
* @param sql 実行する SQL文
* @param mode 戻り値のモード。ALL の場合は全件、ONE の場合は最初の1件を返す。
*/
public ArrayList<HashMap> executeQuery(String sql, MODE mode) throws Exception {
if (!connect()){
return null;
}
PreparedStatement st = con.prepareStatement(sql);
ArrayList<Object> args = new ArrayList<Object>();
return executeQuery(st,args, mode);
}
/**
* 指定された PreparedStatement を実行し、実行結果を ArrayList で返す。
*
* @param st 実行する PreparedStatement
* @param args PreparedStatement の引数。必要ない場合は null。
* @param mode 戻り値のモード。ALL の場合は全件、ONE の場合は最初の1件を返す。
*/
public ArrayList<HashMap> executeQuery(PreparedStatement st, ArrayList<Object> args, MODE mode) throws Exception {
ResultSet rs = null;
ArrayList<HashMap> rows = null;
try {
if (args == null){
args = new ArrayList<Object>();
}
ResultSetMetaData rsmd = null;
setParameters(st,args);
rs = st.executeQuery();
rsmd = rs.getMetaData();
int colCnt = rsmd.getColumnCount();
String colLabel = "";
rows = new ArrayList<HashMap>();
while(rs.next()){
HashMap<Object,Object> row = new HashMap<Object,Object>();
for (int i = 0; i < colCnt; i++){
colLabel = rsmd.getColumnLabel(i+1);
row.put(colLabel,rs.getObject(colLabel));
}
rows.add(row);
if (mode == MODE.ONE){
break;
}
}
return rows;
} finally {
close(st,rs);
}
}
} |
DBPoolManager
DBAccessorをプールするクラス。
1 |
import java.util.*;
public class DBPoolManager {
/** 接続文字列(URL) */
private String connectionString = null;
/** ドライバ名 */
private String driverName = null;
/** パスワード */
private String pass = null;
/** ユーザ名 */
private String user = null;
/** エラー時にログの出力先 */
protected int errorLog = DBAccessor.TO_CONSOLE;
/** ロックオブジェクト */
private byte[] lock = new byte[0];
/** プール */
private HashStack<DBAccessor> pool;
/** 管理しているすべてのオブジェクト */
private HashSet<DBAccessor> allList;
/** 自動クローズ処理用タイマー */
private Timer closeTimer;
/** 最後に使用されてから自動クローズするまでの時間 */
private long closeTime;
/** 最後に使用されてから自動クローズするまでの時間 のデフォルト値 */
final static private long DEFAULT_DELAY = 1000 * 60 * 60;
/** 自分自身のオブジェクト */
private static DBPoolManager self = null;
/**
* コンストラクタ。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*/
public DBPoolManager(String driverName, String connectionString, String user, String pass, int poolSize) {
this(driverName, connectionString, user, pass, DBAccessor.TO_CONSOLE,poolSize);
}
/**
* コンストラクタ。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*@param poolSize プールのサイズ
*/
public DBPoolManager(String driverName, String connectionString, String user, String pass, int errorLog, int poolSize) {
this(driverName, connectionString, user, pass, DBAccessor.TO_CONSOLE,poolSize, DEFAULT_DELAY);
}
/**
* コンストラクタ。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*@param poolSize プールのサイズ
*@param closeTime 使用していないコネクションを閉じるまでの時間(ミリ秒)
*/
public DBPoolManager(String driverName, String connectionString, String user, String pass, int errorLog, int poolSize, long closeTime) {
this.driverName = driverName;
this.connectionString = connectionString;
this.user = user;
this.pass = pass;
this.errorLog = errorLog;
this.closeTime = closeTime;
if (poolSize < 1){
poolSize = 10;
}
pool = new HashStack<DBAccessor>();
for(int i = 0; i < poolSize; i++){
pool.push(null);
}
allList = new HashSet<DBAccessor>();
startTimer(closeTime / 10);
}
/**
* プールされているコネクションを自動的に
* クローズするためのタイマーを開始する
*
*@param delay コネクションを自動的に閉じるまでの時間
*/
public void startTimer(long delay){
if (this.closeTimer != null){
stopTimer();
}
this.closeTimer = new Timer();
TimerTask task = new TimerTask(){
@Override
public void run(){
closeNotUsed();
}
};
this.closeTimer.schedule(task, delay, delay);
}
/**
* プールされているコネクションを自動的に
* クローズするためのタイマーを止める
*/
public void stopTimer(){
if (this.closeTimer != null){
this.closeTimer.cancel();
this.closeTimer = null;
}
}
/**
* 管理しているコネクションをすべて閉じて、
* メモリを開放する
*/
public void dispose(){
closeAll();
stopTimer();
}
/**
* 指定されたパラメータからDBAccessorインスタンスを返す。
* getInstance() を使用することにより、生成された
* インスタンスを取り出すことが出来る。<br><br>
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param poolSize プールのサイズ
*/
public static DBPoolManager createInstance(String driverName, String connectionString, String user, String pass, int poolSize) {
return createInstance(driverName, connectionString, user, pass, DBAccessor.TO_CONSOLE, poolSize);
}
/**
* 指定されたパラメータからDBAccessorインスタンスを返す。
* getInstance() を使用することにより、生成された
* インスタンスを取り出すことが出来る。<br><br>
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*@param poolSize プールのサイズ
*/
public static DBPoolManager createInstance(String driverName, String connectionString, String user, String pass, int errorLog, int poolSize) {
return createInstance(driverName, connectionString, user, pass, DBAccessor.TO_CONSOLE, poolSize, DEFAULT_DELAY);
}
/**
* 指定されたパラメータからDBAccessorインスタンスを返す。
* getInstance() を使用することにより、生成された
* インスタンスを取り出すことが出来る。<br><br>
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*@param poolSize プールのサイズ
*@param closeTime 使用していないコネクションを閉じるまでの時間(ミリ秒)
*/
public static DBPoolManager createInstance(String driverName, String connectionString, String user, String pass, int errorLog, int poolSize, long closeTime) {
if (self != null){
self.dispose();
}
self = new DBPoolManager(
driverName,
connectionString,
user,
pass,
errorLog,
poolSize,
closeTime);
return getInstance();
}
/**
* createInstance()メソッドによって生成されたインスタンスを
* 取得する。
*
*@return createInstanceによって生成された DBPoolManager インスタンス
*/
public static DBPoolManager getInstance() {
return self;
}
/**
* DBAccessor を返す。
*
*@return DBAccessor
*/
public DBAccessor getDBAccessor(){
synchronized(lock){
// System.out.println("get " + Thread.currentThread());
while(pool.empty()){
try {
// System.out.println("lock " + Thread.currentThread());
lock.wait();
} catch (Exception e){
}
}
// System.out.println("get2 " + Thread.currentThread());
DBAccessor db = pool.pop();
if (db == null){
db = new DBAccessorForPool(
this,
driverName,
connectionString,
user,
pass,
errorLog
);
allList.add(db);
}
return db;
}
}
/**
* DBAccessor をプールへ戻す
*
*@param db プールへ戻す DBAccessor
*/
private void pushDBAccessor(DBAccessor db){
synchronized(lock){
// System.out.println("push " + Thread.currentThread());
if (allList.contains(db) && !pool.contains(db)){
pool.push(db);
// System.out.println("notify " + Thread.currentThread());
lock.notify();
}
}
}
/**
* 管理しているコネクションをすべて閉じる
*
*/
private void closeAll(){
for(DBAccessor db : allList){
if (db instanceof DBAccessorForPool){
((DBAccessorForPool)db).closeConnection();
} else {
db.close();
}
}
}
/**
* 使用されていないコネクションを閉じる
*
*/
private void closeNotUsed(){
synchronized(lock){
Iterator<DBAccessor> iterator = pool.iterator();
long nowTime = System.currentTimeMillis();
while(iterator.hasNext()){
DBAccessor dba = iterator.next();
if (dba != null && !dba.isClosed() && dba instanceof DBAccessorForPool){
DBAccessorForPool dbafp = (DBAccessorForPool)dba;
long lastUseTime = dbafp.getLastUseTime();
if ( nowTime - lastUseTime > closeTime ){
dbafp.closeConnection();
}
}
}
}
}
static class HashStack<T> {
private HashSet<T> set;
private Stack<T> stack;
public HashStack(){
set = new HashSet<T>();
stack = new Stack<T>();
}
public void push(T t){
set.add(t);
stack.push(t);
}
public T pop(){
T t = stack.pop();
set.remove(t);
return t;
}
public int size(){
return set.size();
}
public Iterator<T> iterator() {
return set.iterator();
}
public boolean contains(T t){
return set.contains(t);
}
public boolean empty(){
return stack.empty();
}
}
static class DBAccessorForPool extends DBAccessor {
private DBPoolManager manager;
private long lastUseTime;
/**
* コンストラクタ。
*
*@param driverName DBドライバ名
*@param connectionString DB接続文字列(URL)
*@param user ユーザー名
*@param pass パスワード
*@param errorLog エラーの出力先。TO_NO、TO_CONSOLE、TO_LOG、TO_DIALOGのいずれか
*/
public DBAccessorForPool(DBPoolManager manager, String driverName, String connectionString, String user, String pass, int errorLog) {
super(driverName, connectionString, user, pass, DBAccessor.TO_CONSOLE);
this.manager = manager;
this.lastUseTime = System.currentTimeMillis();
}
private void closeConnection(){
super.close();
}
@Override
public void close(){
rollback();
this.lastUseTime = System.currentTimeMillis();
manager.pushDBAccessor(this);
}
public long getLastUseTime(){
return lastUseTime;
}
}
} |
[通知用URL]
Tweet
最終更新時間:2013年11月04日 18時01分27秒