まずJDBC接続とJNDI接続の2つがあります。
1. JDBCはDriverMangerを使うため、コードの中に直接データベース情報を書き込まないといけないので可搬性が低くなります。現在ではJNDIのDataSourceを使うのが主流になります。
どちらもgetConnection()メソッドでConnection型の接続オブジェクトを取得します。
今回は両方を試してするのでJNDI、JDBCのインターフェイスを用意したいと思います。
ConnectionProvider.java
=======================================================================================================================
package database;
import java.sql.Connection;
import java.sql.SQLException;
public interface ConnectionProvider {
public Connection getConnection() throws SQLException;
}
=======================================================================================================================次にまずはJDBCクラスを作成します。ConnectionProviderインターフェイルを実装します。
JDBCProvider.java
=======================================================================================================================
package database;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCProvider implements ConnectionProvider { //ConnectionProviderを実装
/**
* JDBC Driver Name
*/
private String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; //ここに直接ドライバー名を記述。今回はSQLServer2005のドライバを使用した場合
**
* JDBC Connection url
*/
private String connectionURL = "jdbc:sqlserver://IDIOM-TEST-AP2:1433;DatabaseName=SampleDataBase;User=sa;Password=P@ssw0rd;";
//ここにデータベースにアクセスする為の情報を記述、データベース名、ユーザー名、パスワードを入力
public Connection getConnection() throws SQLException {
try {
Class.forName(driverName).newInstance();
} catch (InstantiationException e) {
throw new SQLException("Get Database Connection Error");
} catch (IllegalAccessException e) {
throw new SQLException("Get Database Connection Error");
} catch (ClassNotFoundException e) {
throw new SQLException("Get Database Connection Error");
}
return DriverManager.getConnection(connectionURL);
//DriverManagerのgetConnectionメソッドで接続オブジェクトを返します。
}
}
=======================================================================================================================次にConnectionオブジェクトを作成するためのクラスを作成します。外部からConnectionオブジェクトを作成する際には、すべてこのクラスを使うことになります。ConnectionManager.java
=======================================================================================================================package database;import java.sql.Statement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import exception.SchemaException;
public class ConnectionManager {
private static ConnectionProvider connectionProvider = new JDBCProvider();
//private static ConnectionProvider connectionProvider = new JNDIProvider();
//(1)ConnectionオブジェクトをJDBCクラスから作成するのであれば、JNDIをコメントアウトしておきます。
protected static boolean supportsTransactions = true;
/**
* Get general dataBase connection
*
* @return
* @throws PersonManagerException
*/
public static Connection getConnection() throws SchemaException {
Connection con;
try {
con = connectionProvider.getConnection();
//connectionProviderは(1)で有効になっているどちらかのgetConnectionメソッドを実行し、Connectionオブジェクトを返す。こういった時のため、最初にConnectionProviderインターフェイスを作成し、両方getConnectionメソッドを実装するようにした(別にインターフェイスにしなくとも、両方に同じ名前のメソッドを作れば良いのだが、この場合はあえてそうしてみた。)
con.setAutoCommit(false);
} catch (SQLException ex) {
throw new SchemaException(
"When getting general dataBase connection, exception is happened : ", ex);
}
if (con == null) {
throw new SchemaException("Get general dataBase connection error");
}
return con;
}
/**
* Get transaction dataBase connection
*
* @return
* @throws PersonManagerException
*/
public static Connection getTransactionConnection() throws SchemaException {
Connection con = getConnection();
if (supportsTransactions) {
try {
con.setAutoCommit(false);
} catch (SQLException ex) {
throw new SchemaException(
"When getting transaction dataBase connection, exception is happened : ", ex);
}
}
return con;
}
/**
* Close dataBase connection
*
* @param rs
*/
public static void closeResult(ResultSet rs) {
if (rs == null)
return;
try {
rs.close();
} catch (SQLException e) {
System.err.println("Close dataBase connection error");
}
}
/**
* Close statement
*
* @param stat
*/
public static void closeStatement(Statement stat) {
if (stat == null)
return;
try {
stat.close();
} catch (SQLException e) {
System.err.println("Close statement error");
}
}
/**
* Close preparedStatement
*/
public static void closePreparedStatement(PreparedStatement preStat) {
if (preStat == null)
return;
try {
preStat.close();
} catch (SQLException e) {
System.err.println("Close preparedStatement error");
}
}
/**
* Close dataBase connection
*
* @param con
*/
public static void closeConnection(Connection con) {
if (con == null)
return;
try {
con.close();
} catch (SQLException e) {
System.err.println("Close dataBase connection error");
}
}
/**
* Close transaction dataBase connection
*
* @param con
* @param abortTransaction
*/
public static void closeTransactionConnection(Connection con,
boolean abortTransaction) {
if (con == null)
return;
if (supportsTransactions) {
try {
if (abortTransaction) {
con.commit();
} else {
con.rollback();
}
con.close();
} catch (SQLException e) {
System.err.println("Close transaction dataBase connection error");
}
}
}
public static ConnectionProvider getConnectionProvider() {
return connectionProvider;
}
}
=======================================================================================================================
ここまでできたらJDBC経由でデータベースにアクセス可能になる。
では簡単にアクセスするためのコードを書いてみる。長いコードだがデータベース関連のところのみ赤く表示し、説明します。
SampleDataBaseConnection.java
=======================================================================================================================
package database.dao;
import java.sql.*;
import java.util.ArrayList;
import database.ConnectionManager;
public ArrayListselectWords(String mstId, String timestamp, String history) throws SchemaException {
Connection con = null; con = ConnectionManager.getConnection();
//データベースに接続するためのConnectionオブジェクトを取得する ArrayListwords = new ArrayList (); ResultSet rs = null; //データベースから戻ってきた結果を入れるためのオブジェクトを作成する PreparedStatement stmt = null; //SQL文を発行するためのオブジェクトを作成する String sql = ""; //SQL文を入れるオブジェクトを作成する try { sql = "SELECT * FROM WORD WHERE ID IN ("; sql += "SELECT MAX(ID) FROM WORD "; if (timestamp == null) { sql += "WHERE MST_ID = ? AND (INSERTED_AT IS NULL) "; } else { sql += "WHERE MST_ID = ? AND (INSERTED_AT <= ? OR INSERTED_AT IS NULL) "; } sql += "GROUP BY MST_ID, LANG_ID )";
stmt = con.prepareStatement(sql);
//SQLを発行するためのPreparedStatementオブジェクトにSQL文がセットされた。
stmt.setInt(1, Integer.parseInt(mstId));
if (timestamp != null) {
stmt.setString(2, timestamp);
}
//SQL文の中のパラメータに値をセットする。SQL文にある?マークの順番を指定し、データ型に応じてsetメソッドを変える(例: Integer型であればsetIntメソッドを使用するなど)
rs = stmt.executeQuery();
//ここで初めてデータベースにクエリが発行される。結果はResultSetオブジェクトに入る。
while (rs.next()) {
words.add(fillWordEntity(rs));
}
//rsにはSQLの一行が入り、最後まで行くとwhileのループを抜ける。rsの左から一列目の値を取得したければ、rs.getInt(1)などと指定できる。一列目がString型ならrs.getString(1)となる。直接フィールド名を指定して取得も可能である(例: rs.getInt("MST_ID"))など
} catch (SQLException e) {
throw new SchemaException("[" + e.toString() + "]");
} finally {
ConnectionManager.closeResult(rs);
//終わったらまずはResultSetオブジェクトを開放します。
ConnectionManager.closeStatement(stmt);
//次にPreparedStatementオブジェクトを開放します。
ConnectionManager.closeConnection(con);
//最後にConnectionオブジェクトを開放します。これを開放しないとTomcatのConnectionの数には限りがあるので、その数に達した時にConnection Poolingというエラーになってしまいます。
}
return words;
=======================================================================================================================
以上がJDBC経由のやり方です。次にJNDI経由でデータベース接続を行うにはJNDI用のクラスを作成します。
JNDIとはある名前を送ると、その名前にあった値を返してくれるものです。
JNDIProvider.java
=======================================================================================================================
package database;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class JNDIProvider implements ConnectionProvider { //ConnectionProviderを実装
private String jndiName = "java:comp/env/jdbc/SchemaDB";
//"java:comp/env/"はJNDIを表す固定の文字列で"jdbc/SchemaDB"が下記にあるweb.xmlに登録した文字列。
public Connection getConnection() throws SQLException {
Context context = null;
DataSource dataSource = null;
//データソース(DataSource)とはプログラムとデータベースへの接続との間のインターフェースで、データベースへの接続を取得するために使用されます。
try {
context = new InitialContext();
//InitialContextオブジェクトはネーミング操作を実行するための開始コンテキスト
dataSource = (DataSource)context.lookup(jndiName);
} catch (NamingException e) {
throw new SQLException("JNDI Naming Exception : " + e.toString());
}
Connection conn = null;
if (dataSource != null) {
conn = dataSource.getConnection();
//DataSourceのgetConnectionメソッドで接続オブジェクトを返します。
}
return conn;
}
}
=======================================================================================================================
JNDI接続を行うにはこのクラスの他、Tomcatのweb.xmlとServer.xmlを編集する必要があります。
まずはweb.xmlに以下の文字列を追加します。これで"jdbc/SchemaDB"というJNDI名を登録します。
web.xml
======================================================================================================================= <resource-ref>
<description>SchemaDB</description>
<res-ref-name>jdbc/SchemaDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
=======================================================================================================================
次にserver.xmlにDataSourceの情報を登録します。以下の文字列をTomcatのserver.xmlに追加します。
server.xml
======================================================================================================================= <GlobalNamingResources>
<!-- Used by Manager webapp -->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
<Resource name="jdbc/SchemaDB" auth="Container" type="javax.sql.DataSource"
driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
url="jdbc:sqlserver://ServerName:1433;DatabaseName=HDatabaseNameonbanSQL"
username="sa" password="WSisgreat1"
maxActive="10" maxIdle="10" maxWait="10000"/>
//この10がConnectionPoolの数。仮にConnectionを開放しないと10回データベースアクセスした時点でエラーになってしまう
</GlobalNamingResources>
=======================================================================================================================
これでJNDIの設定が完了です。server.xmlにデータベースへの接続情報を書くことでいちいちデータベースが変る度にビルドする必要がないです。
最後にJNDI接続を利用したい場合はConnectionManagerクラスの
//private static ConnectionProvider connectionProvider = new JDBCProvider();
private static ConnectionProvider connectionProvider = new JNDIProvider();
とし、JDBCを無効にさせます。同じようにSampleDataBaseConnection.javaを実行すればJNDI経由で実行されます。
過去の投稿
2008年4月25日金曜日
Javaでのデータベース接続(Tomcat版)について
2008年4月16日水曜日
Excelで最大の行数・列数を求める
==============================================================
Function EffectiveRow() As Long
' 行の最大数を求める A列固定
' Excelの最大行数(65536)から上方向(xlUp)に空白でないセルを探す
EffectiveRow = Range("A65536").End(xlUp).Row
End Function
==============================================================
Function EffectiveColumn() As Long
' 列の最大数を求める 1行目固定
' Excelの最大列数(256)から左方向(xlToLeft)に空白でないセルを探す
EffectiveColumn = Cells(1, 256).End(xlToLeft).Column
End Function
==============================================================
登録:
投稿 (Atom)
自己紹介
- 田辺 幹夫
- 最近気胸になりました。でタバコやめました。