原本以為做完雷達系統後,大概沒機會再有用J2SE建構一個陽春AP Server。想不到這個產品也會用到,正好把以前Thread Monitor抄過來用,但還是會評估可能移殖到AP Server的可能性以及通透性,DB Connection Pool不管用什麼產品,最好統一用JNDI方式。而目前這系統是由Java Main來發散Mulit-Thread,不會依附AP Server,昇陽的fscontext看來是for Java Main的JNDI套件的選擇。
先到http://java.sun.com/products/jndi/downloads/index.html下載相關套件,會有fscontext.jar與providerutil.jar兩個。
接下來我使用ojdbc14.jar提供的OracleDataSource作為Connection Pool產品。雖然有DBCP、Proxool,但我還是不放心使用。根據O'Reilly提供的[Oracle JDBC與Java程式設計]一書下載的飯粒如下:
TestDSBind.java --> 將OracleDataSource連結到fscontext提供的JNDI
import java.sql.SQLException;
import java.util.Properties;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import oracle.jdbc.pool.OracleDataSource;
public class TestDSBind {
public static void main (String args [])
throws SQLException, NamingException {
// For this to work you will need to create the
// directories /JNDI/JDBC on your file system first
Context ctx = null;
try {
Properties prop = new Properties();
prop.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
prop.setProperty(Context.PROVIDER_URL, "file:/JNDI/JDBC"); // file:/JNDI/JDBC是預設為C槽JNDI目錄下的JDBC目錄,bind資料會存放在這裡
ctx = new InitialContext(prop);
}
catch (NamingException ne) {
ne.printStackTrace();
}
throws SQLException, NamingException {
// For this to work you will need to create the
// directories /JNDI/JDBC on your file system first
Context ctx = null;
try {
Properties prop = new Properties();
prop.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
prop.setProperty(Context.PROVIDER_URL, "file:/JNDI/JDBC"); // file:/JNDI/JDBC是預設為C槽JNDI目錄下的JDBC目錄,bind資料會存放在這裡
ctx = new InitialContext(prop);
}
catch (NamingException ne) {
ne.printStackTrace();
}
OracleDataSource ds = new OracleDataSource(); // 以下DataSource的設定請望文生義
ds.setDriverType("thin");
ds.setServerName("localhost");
ds.setPortNumber(1521);
ds.setDatabaseName("XE");
ds.setUser("system");
ds.setPassword("tiger");
ds.setDriverType("thin");
ds.setServerName("localhost");
ds.setPortNumber(1521);
ds.setDatabaseName("XE");
ds.setUser("system");
ds.setPassword("tiger");
ctx.bind("jemmy", ds);
}
}
}
}
若好奇再執行第二次會異常,上面jemmy這個JNDI名已經存在.bindings這檔案,用別的名可以過。若要再重新bind,刪掉.bindings檔。
TestDSLookUp.java --> 測試JNDI
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class TestDSLookUp {
public static void main (String[] args)
throws SQLException, NamingException {
throws SQLException, NamingException {
Context ctx = null;
try {
Properties prop = new Properties();
prop.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
prop.setProperty(Context.PROVIDER_URL, "file:/JNDI/JDBC");
ctx = new InitialContext(prop);
}
catch (NamingException ne) {
System.err.println(ne.getMessage());
}
try {
Properties prop = new Properties();
prop.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
prop.setProperty(Context.PROVIDER_URL, "file:/JNDI/JDBC");
ctx = new InitialContext(prop);
}
catch (NamingException ne) {
System.err.println(ne.getMessage());
}
DataSource ds = (DataSource)ctx.lookup("jemmy");
Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(
"select 'Jemmy Tsai' from dual");
if (rset.next())
System.out.println(rset.getString(1));
rset.close();
stmt.close();
conn.close();
}
}
Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery(
"select 'Jemmy Tsai' from dual");
if (rset.next())
System.out.println(rset.getString(1));
rset.close();
stmt.close();
conn.close();
}
}
因此JNDI在Java Main建構好,若要換掉不同的Connection Pool,只需修改Bind的程式及刪掉.bindings,而caller的程式不動,只需認識DataSource就好。
全站熱搜