Ibatis+JNDI連接數據庫

做web應用的在客戶現場經常碰到這樣的拓撲結構:

這是一種典型的環境搭建模式.
這是我有一種需求,需要在客戶端CLIENT1機器上做一個客戶端小應用程序,這個程序需要訪問數據庫(DB SERVER),
這裏我是用Ibatis實現的數據訪問層,其訪問數據庫的方式有下面兩種:
一.直連數據庫(jdbc)
SqlMapConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig     PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"     "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>    
    
<properties resource="SqlMapConfig.properties" />
    
<settings 
        
cacheModelsEnabled="true"
        enhancementEnabled
="false" 
        lazyLoadingEnabled
="true" 
        maxRequests
="20" 
        maxSessions
="10" 
        maxTransactions
="15" 
        useStatementNamespaces
="false" />
    
<transactionManager type="JDBC">
        
<dataSource type="SIMPLE">
            
<property name="JDBC.Driver" value="${driver}" />
            
<property name="JDBC.ConnectionURL" value="${url}" />
            
<property name="JDBC.Username" value="${username}" />
            
<property name="JDBC.Password" value="${password}" />
        
</dataSource>
    
</transactionManager>
    
<!--
    ==========================================================
         All SQL Map XML files to be loaded by this SQL map. 
         Notice the paths are relative to the classpath.  
    ==========================================================
    
-->
    
<sqlMap resource="sqlmap-oracle/test.xml" />
</sqlMapConfig>

 SqlMapConfig.properties:
            driver=oracle.jdbc.driver.OracleDriver
            url=jdbc:oracle:thin:@192.168.0.197:1521:TEST
            username=TEST
            password=TestJNDI

 通過這樣連接沒有問題,但是有一點,數據庫的信息全部暴露在客戶端了,無形之中增加了一定的安全隱患,客戶一般也是不允許的.
 如果CLIENT1客戶端有專人管理,可能沒問題,這裏我主要介紹一下通過JNDI連接Web Server間接的訪問數據庫的方式.
二.通過JNDI連數據庫
SqlMapConfig.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig     PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"     "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    
<settings 
        
cacheModelsEnabled="true"
        enhancementEnabled
="false" 
        lazyLoadingEnabled
="true" 
        maxRequests
="20" 
        maxSessions
="10" 
        maxTransactions
="15" 
        useStatementNamespaces
="false" />

    
<transactionManager type="JDBC">
        
<dataSource type="JNDI"> 
             
<property name="context.java.naming.factory.initial" value="weblogic.jndi.WLInitialContextFactory"/>
             
<property name="context.java.naming.provider.url" value="t3://192.168.0.197:7001"/>  
             
<property name="DataSource" value="jndi/ibatis/oraJNDI"/>  
        
</dataSource>   
    
</transactionManager>
    
<!--
    ==========================================================
         All SQL Map XML files to be loaded by this SQL map. 
         Notice the paths are relative to the classpath.  
    ==========================================================
    
-->
    
<sqlMap resource="sqlmap-oracle/test.xml" />
</sqlMapConfig>
具體配置如上所示,注意這兩句:
<property name="context.java.naming.factory.initial" value="weblogic.jndi.WLInitialContextFactory"/>
<property name="context.java.naming.provider.url" value="t3://192.168.0.197:7001"/>
如果沒這兩句會找不到JNDI的,報錯如下:
java.lang.RuntimeException: Error occurred.  Cause: com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: java.lang.RuntimeException: Error parsing XPath '/sqlMapConfig/transactionManager/dataSource/end()'.  Cause: com.ibatis.sqlmap.client.SqlMapException: There was an error configuring JndiDataSourceDaoTransactionPool. Cause: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:
84)
    at com.ibatis.sqlmap.client.SqlMapClientBuilder.buildSqlMapClient(SqlMapClientBuilder.java:
62)
    at com.nstc.greport.ibatis.TestSupport.setUp(TestSupport.java:
29)
    at junit.framework.TestCase.runBare(TestCase.java:
125)
    at junit.framework.TestResult$
1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:
124)
    at junit.framework.TestResult.run(TestResult.java:
109)
    at junit.framework.TestCase.run(TestCase.java:
118)
    at junit.framework.TestSuite.runTest(TestSuite.java:
208)
    at junit.framework.TestSuite.run(TestSuite.java:
203)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
478)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:
344)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:
196)
Caused by: com.ibatis.common.xml.NodeletException: Error parsing XML.  Cause: java.lang.RuntimeException: Error parsing XPath 
'/sqlMapConfig/transactionManager/dataSource/end()'.  Cause: com.ibatis.sqlmap.client.SqlMapException: There was an error configuring JndiDataSourceDaoTransactionPool. Cause: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:
52)
    at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:
81)
    ... 
12 more
Caused by: java.lang.RuntimeException: Error parsing XPath 
'/sqlMapConfig/transactionManager/dataSource/end()'.  Cause: com.ibatis.sqlmap.client.SqlMapException: There was an error configuring JndiDataSourceDaoTransactionPool. Cause: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at com.ibatis.common.xml.NodeletParser.processNodelet(NodeletParser.java:
113)
    at com.ibatis.common.xml.NodeletParser.process(NodeletParser.java:
95)
    at com.ibatis.common.xml.NodeletParser.process(NodeletParser.java:
92)
    at com.ibatis.common.xml.NodeletParser.process(NodeletParser.java:
92)
    at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:
62)
    at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:
50)
    ... 
13 more
Caused by: com.ibatis.sqlmap.client.SqlMapException: There was an error configuring JndiDataSourceDaoTransactionPool. Cause: javax.naming.NoInitialContextException: Need to specify 
class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory.initialize(JndiDataSourceFactory.java:
60)
    at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser$
9.process(SqlMapConfigParser.java:318)
    at com.ibatis.common.xml.NodeletParser.processNodelet(NodeletParser.java:
111)
    ... 
18 more
Caused by: javax.naming.NoInitialContextException: Need to specify 
class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:
640)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:
243)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:
280)
    at javax.naming.InitialContext.lookup(InitialContext.java:
347)
    at com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory.initialize(JndiDataSourceFactory.java:
50)
    ... 
20 more
我這裏是用的weblogic提供的JNDI,在網上查了很多資料才找到這兩個屬性.
另外我們在做數據訪問層時經常要用junit測試,這時在197機器上打開weblogic控制檯,然後在開發機器上便可進行測試了.
需要在工程中加入weblogic.jar包,否則會報找不到weblogic類的錯誤.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章