• 0
daziplqa

أستخدام DataSource في البيئات غير المداره

سؤال

كتبت مثال عن كيفية إستخدام ال java.sql.DataSource في تطبيقات جافا الغير مدارة بحاوي (Container non-managed app) و أرد أن أعرضه هنا للإستفاده.

1- اولا قم بعمل ملف XML و سميه mapping.xml :

<?xml version="1.0" encoding="UTF-8"?>  
<datasource jndi="jdbc/testds" >
<initail-context-factory>com.sun.jndi.rmi.registry.RegistryContextFactory</initail-context-factory>
<provider-url>rmi://localhost:4099</provider-url>
<datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</datasource-class>
<username>root</username>
<password>system</password>
<connection-url>jdbc:mysql://localhost:3306/test</connection-url>
</datasource>

2- هذه الفئة DataSourceWrapper تستخدم في حصول علي معلومات الإتصال من ملف ال XML :

package org.daz.ds;  
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DataSourceWrapper {
private static Document datasourceDoc;
private static DatasourceXmlMapping dsXmlMapping = null;
public static String getJndi() {
return dsXmlMapping.getJndi();
}
public static String getInitialContextFactory() {
return dsXmlMapping.getInitialContextFactory();
}
public static String getProviderUrl() {
return dsXmlMapping.getProviderUrl();
}
public static String getDataSourceClass() {
return dsXmlMapping.getDatasourceClass();
}
public static String getUsername() {
return dsXmlMapping.getUsername();
}
public static String getPassword() {
return dsXmlMapping.getPassword();
}
public static String getConnectionUrl() {
return dsXmlMapping.getConnectionUrl();
}
static {
try {
init();
initDatasourceXmlMapping();
}catch (Exception ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
private static void init() throws Exception{
InputStream is = DataSourceWrapper.class.getClassLoader().getResourceAsStream("org/daz/ds/datasource.xml");
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
datasourceDoc = docBuilder.parse(is);
is.close();
}
private static void initDatasourceXmlMapping() {
final String datasource = "datasource";
final String jndi="jndi";
final String initailContextFactory = "initail-context-factory";
final String providerUrl = "provider-url";
final String datasourceClass = "datasource-class";
final String username = "username";
final String password = "password";
final String connectionUrl = "connection-url";
dsXmlMapping = new DatasourceXmlMapping();
Node datasourceNode = datasourceDoc.getDocumentElement();
Node jndiAttr = datasourceNode.getAttributes().getNamedItem(jndi);
if (jndiAttr == null)
throw new RuntimeException(jndi + " Attribute of " + datasource + " Element is null!");
dsXmlMapping.setJndi(jndiAttr.getNodeValue());
NodeList list = datasourceNode.getChildNodes();
for (int i=0; i <list.getLength(); i++) {
Node currentNode = list.item(i);
if (initailContextFactory.equals(currentNode.getNodeName()))
dsXmlMapping.setInitialContextFactory(currentNode.getTextContent());
if (providerUrl.equals(currentNode.getNodeName()))
dsXmlMapping.setProviderUrl(currentNode.getTextContent());
if (datasourceClass.equals(currentNode.getNodeName()))
dsXmlMapping.setDatasourceClass(currentNode.getTextContent());
if (username.equals(currentNode.getNodeName()))
dsXmlMapping.setUsername(currentNode.getTextContent());
if (password.equals(currentNode.getNodeName()))
dsXmlMapping.setPassword(currentNode.getTextContent());
if (connectionUrl.equals(currentNode.getNodeName()))
dsXmlMapping.setConnectionUrl(currentNode.getTextContent());
}
}
public static class DatasourceXmlMapping{
private String jndi;
private String initialContextFactory;
private String providerUrl;
private String datasourceClass;
private String username;
private String password;
private String connectionUrl;
public String getInitialContextFactory() {
return initialContextFactory;
}
public void setInitialContextFactory(String initialContextFactory) {
this.initialContextFactory = initialContextFactory;
}
public String getProviderUrl() {
return providerUrl;
}
public void setProviderUrl(String providerUrl) {
this.providerUrl = providerUrl;
}
public String getDatasourceClass() {
return datasourceClass;
}
public void setDatasourceClass(String datasourceClass) {
this.datasourceClass = datasourceClass;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConnectionUrl() {
return connectionUrl;
}
public void setConnectionUrl(String connectionUrl) {
this.connectionUrl = connectionUrl;
}
public String getJndi() {
return jndi;
}
public void setJndi(String jndi) {
this.jndi = jndi;
}
}
}

3- هذه الفئه هي التي ستحتاج إي تغييرها لدعم أكثر من DBMS :

 package org.daz.ds;  
public class DataSourceVendor {
public static MethodNames getMethodNames(String vendor) {
MethodNames mn = null;
if (vendor.toLowerCase().contains("mysql")) {
mn = new MethodNames();
mn.setUser = "setUser";
mn.setPassword = "setPassword";
mn.setURL = "setUrl";
return mn;
}
throw new RuntimeException("Non-supported DBMS");
}
public static class MethodNames{
public String setUser;
public String setPassword;
public String setURL;
}
}

4- و أخيرا DataSourceManager :

package org.daz.ds;  

import java.lang.reflect.Method;
import java.rmi.registry.LocateRegistry;
import java.util.Hashtable;
import java.util.logging.Logger;

import javax.naming.InitialContext;
import javax.sql.DataSource;

import org.daz.ds.DataSourceVendor.MethodNames;

public class DataSourceManager {

private Logger logger = Logger.getLogger(DataSourceManager.class.getSimpleName());

public void startRegistry() throws Exception{
final String providerUrl = DataSourceWrapper.getProviderUrl();
final char separator = ':';
int rmiPort = Integer.parseInt(providerUrl.substring(providerUrl.lastIndexOf(separator) + 1));
System.out.println(rmiPort);
LocateRegistry.createRegistry(rmiPort);
}

public void storeDatasource() throws Exception{
Hashtable<string,> env = new Hashtable<string,>();
env.put(InitialContext.INITIAL_CONTEXT_FACTORY, DataSourceWrapper.getInitialContextFactory());
env.put(InitialContext.PROVIDER_URL, DataSourceWrapper.getProviderUrl());
InitialContext ctx = new InitialContext(env);

DataSource ds = (DataSource) Class.forName(DataSourceWrapper.getDataSourceClass()).newInstance();
logger.info("Using Datasource class : " + DataSourceWrapper.getDataSourceClass());

MethodNames mNames = DataSourceVendor.getMethodNames(DataSourceWrapper.getDataSourceClass());

Method m1 = ds.getClass().getMethod(mNames.setUser, String.class);
m1.invoke(ds, DataSourceWrapper.getUsername());
Method m2 = ds.getClass().getMethod(mNames.setPassword, String.class);
m2.invoke(ds, DataSourceWrapper.getPassword());
Method m3 = ds.getClass().getMethod(mNames.setURL, String.class);
m3.invoke(ds, DataSourceWrapper.getConnectionUrl());
logger.info("Using Connection Url : " + DataSourceWrapper.getConnectionUrl());
ctx.rebind(DataSourceWrapper.getJndi(), ds);
}

public DataSource getDatasource()throws Exception{
Hashtable<string,> env = new Hashtable<string,>();
env.put(InitialContext.INITIAL_CONTEXT_FACTORY, DataSourceWrapper.getInitialContextFactory());
env.put(InitialContext.PROVIDER_URL, DataSourceWrapper.getProviderUrl());
InitialContext ctx = new InitialContext(env);
return (DataSource) ctx.lookup(DataSourceWrapper.getJndi());
}
}

5- و هنا مثال علي الإستخدام :

package org.daz.ds;  
import java.sql.Statement;
import javax.sql.DataSource;
public class DatasourceTest {
public static void main(String[] args) throws Exception{
DataSourceManager dsm = new DataSourceManager();
dsm.startRegistry();
dsm.storeDatasource();
DataSource ds = dsm.getDatasource();
Statement stmt = ds.getConnection().createStatement();
stmt.executeQuery("select * from test");
}
}

يمكنك أيضا قراءة الموضوع هنا : http://m-hewedy.blogspot.com/2010/02/using-datasource-in-non-managed.html

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

8 إجابة على هذا السؤال .

  • 0

ما المقصود Container non-managed app؟

هل يمكن نبذة مختصرة عنها؟

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أنا أسف يا أخ علاء لو لم أستطع التعبير عن المعني المراد بسهوله.

التطبيقات تنقسم لنوعين , تطبيقات تعمل على ال JVM فقط, و تطبيقات تعمل داخل حاوي (Container)

1- تطبيقات تعمل داخل حاوي:

هذا الحاوي قد يكون حاوي EJB , و هو ما يطلق عليه أحيانا JEE Application Server مثال JBoss AS, Websphere AS, WebLogic AS .

و قد يكون هذا الحاوي حاوي خفيف (lightweight) , و أشهرهم على الإطلاق Spring

2- تطبيقات لا تعمل داخل حاوي : و هي تطبيق بسيط يبدأ بال Main Method و عادة تكون إدارة بعض الموراد فيها صعبه بالمقارنه بالنوع الأول (مثل ال DataSource)

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

لماذا تتأسف يا أخ هويدي

ليس هناك ما أخطأت فيه

كل ما هناك أن اسأل

بأمانة اتعلم منك الكثير أخي

طيب سؤال ثاني وأنا أعلم أني كثير الأسئلة

لكني أطمح أن تتحملني :)

ما فائدة الحجة DataSource?

تحياتي

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جزاك الله خيرا أخي و غفر لك,

بالنسبه لفائدة ال DataSource, تقصد بإستخدامه بدلا من ال DriverManager ؟

فإن كان كذلك فأولا ال DataSource تستطيع أن تسجله في JNDI و تستدعيه بعد ذلك أيما شئت.

كما أن ال DataSource يتكامل مع موضوع الConnection Pooling (ليست لي معرفه كبيره بهذا الموضوع).

لاحظ أن ال DataSource موجود ب javax.sql على عكس معظم الفئات الأخري الموجوده ب java.sql .

إقرأ هذه الوصله

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جزاك الله خير أخ " هويدي " ، لكن لا أخفيك أني لم أفهم بالظبط عنوان المثال :

non-managed (standalone) java applications

لكن يبدو أنك تفرض في مثالك أن القارئ له خلفية عن الموضوع ، بالتالي أطمع بمقالة أخرى عن هذا الموضوع :-) .

أمر آخر ( خارج عن الموضوع قليلاً ) ، هناك قطعة من الكود غريبة ، ليست داخل أي method ؟ كيف تعمل ومتى تنفّذ ؟ من متى و الجافا تدعم هذا الأسلوب ؟

public static String getConnectionUrl() {

return dsXmlMapping.getConnectionUrl();

}

static {

try {

init();

initDatasourceXmlMapping();

}catch (Exception ex) {

throw new RuntimeException(ex.getMessage(), ex);

}

}

private static void init() throws Exception{

InputStream is = DataSourceWrapper.class.getClassLoader().getResourceAsStream("org/daz/ds/datasource.xml");

DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();

datasourceDoc = docBuilder.parse(is);

is.close();

}

شكراً لك .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

تقصد ال Static Initialize Block , و هذا تنفذ بمجرد أن يتم تحميل الفئة بواسطة ال ClassLoader , فلا نحتاج أن نخلق كائن لتنفيذ هذا البلوك.

لاحظ:

لو أنك مثلا قمت بالتالي :

Class.forName ("DataSourceWrapper");

فإن هذا البلوك ستم تنفيذه.

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

مثال رائع بارك الله بك !

لدي ملاحظة صغيرة: أظن أنه لا يوجد أي فائدة من وجود الفئة DatasourceXmlMapping !

حيث يتم استخدامه داخلياً فقط (أليس كذلك ؟) ولا داعي لتعريفه على أنه public على أية حال ...

ومن الأفضل لو كان هكذا:


package org.daz.ds;

import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DataSourceWrapper {

private static String jndi;
private static String initialContextFactory;
private static String providerUrl;
private static String datasourceClass;
private static String username;
private static String password;
private static String connectionUrl;
private static Document datasourceDoc;

public static String getJndi() {
return jndi;
}

public static String getInitialContextFactory() {
return initialContextFactory;
}

public static String getProviderUrl() {
return providerUrl;
}

public static String getDataSourceClass() {
return datasourceClass;
}

public static String getUsername() {
return username;
}

public static String getPassword() {
return password;
}

public static String getConnectionUrl() {
return connectionUrl;
}

static {
try {
init();
initDatasourceXmlMapping();
} catch (Exception ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}

private static void init() throws Exception {
InputStream is = DataSourceWrapper.class.getClassLoader().getResourceAsStream("org/daz/ds/datasource.xml");
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
datasourceDoc = docBuilder.parse(is);
is.close();
}

private static void initDatasourceXmlMapping() {
final String _datasource = "datasource";
final String _jndi = "jndi";
final String _initailContextFactory = "initail-context-factory";
final String _providerUrl = "provider-url";
final String _datasourceClass = "datasource-class";
final String _username = "username";
final String _password = "password";
final String _connectionUrl = "connection-url";

Node datasourceNode = datasourceDoc.getDocumentElement();
Node jndiAttr = datasourceNode.getAttributes().getNamedItem(jndi);
if (jndiAttr == null) {
throw new RuntimeException(_jndi + " Attribute of " + _datasource + " Element is null!");
}
jndi = jndiAttr.getNodeValue();
NodeList list = datasourceNode.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node currentNode = list.item(i);
if (_initailContextFactory.equals(currentNode.getNodeName())) {
initialContextFactory = currentNode.getTextContent();
}
if (_providerUrl.equals(currentNode.getNodeName())) {
providerUrl = currentNode.getTextContent();
}
if (_datasourceClass.equals(currentNode.getNodeName())) {
datasourceClass = currentNode.getTextContent();
}
if (_username.equals(currentNode.getNodeName())) {
username = currentNode.getTextContent();
}
if (_password.equals(currentNode.getNodeName())) {
password = currentNode.getTextContent();
}
if (_connectionUrl.equals(currentNode.getNodeName())) {
connectionUrl = currentNode.getTextContent();
}
}
}
}

تم تعديل بواسطه Speed_Of_Light
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جميل أخي بارك الله فيك.

طالما أننا لن نستخدم هذا الكائن, فلا داعي من وجوده.

ربما وضعته لأني كنت أستخدمه في كود ما.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .