问题:您是否可以在应用服务器容器外使用zxJDBC.connectx
方法?
我在Jython中有自己的服务器应用程序,我正在寻求升级到使用数据库连接池(因为我现在手动构建和销毁单个连接)。我已经找到了一些示例代码并且已经使用它(使用Tomcat的连接池),但是它的工作方式让我感到烦恼。对我而言,看起来游泳池一次又一次地被创造出来。这是我的工作示例:
from __future__ import with_statement
from com.ziclix.python.sql import zxJDBC
params = { }
params['url'] = 'jdbc:mysql://localhost:3306/my_database'
params['driverClassName'] = 'com.mysql.jdbc.Driver'
params['username'] = 'mario'
params['password'] = 'myP@ssw0rd'
params['validationQuery'] = 'SELECT 1'
params['jdbcInterceptors'] = \
'org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;' + \
'org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer'
# This is the line that worries me!
conn = zxJDBC.connectx('org.apache.tomcat.jdbc.pool.DataSource', **params)
with conn.cursor() as cursor:
cursor.execute('SELECT * FROM MyTable')
data = cursor.fetchall()
print data
conn.close()
看看“令我担忧的那条线”。我想使用zxJDBC
连接对象,但是如果每次我获得它,我必须提供DataSource类名和设置参数,那么我认为首先要重新创建连接池每一次。那显然 不是我想要的。
有没有人确切知道发生了什么,或者我怎么可能会通过一些实验来确认发生了什么?如果我想在我的服务器中使用它,我应该复制servlet容器的JNDI基础结构吗?我无法理解DataSource
到底是什么以及它是如何工作的?我不知道如何深究它。谢谢!
编辑:Jython源代码
我看了一下Jython源代码。 connectx
类支持com.ziclix.python.sql.connect.Connectx
方法。相关代码段如下所示:
/**
* Construct a javax.sql.DataSource or javax.sql.ConnectionPooledDataSource
*/
@Override
public PyObject __call__(PyObject[] args, String[] keywords) {
Connection c = null;
PyConnection pc = null;
Object datasource = null;
PyArgParser parser = new PyArgParser(args, keywords);
try {
String klass = (String) parser.arg(0).__tojava__(String.class);
datasource = Class.forName(klass).newInstance();
} catch (Exception e) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, "unable to instantiate datasource");
}
/*
* The code continues on, setting up the connection pool's parameters,
* handling errors, etc., and obtaining a connection (variable: c).
*/
try {
if (c == null || c.isClosed()) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, "unable to establish connection");
}
pc = new PyConnection(c);
} catch (SQLException e) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, e);
}
return pc;
}
从源代码构建Jython并不是那么容易(似乎没有记录良好的依赖项),或者我会放入一些调试语句来比较datasource
对象。但是当我尝试自己复制创作部分时......
datasource = Class.forName(klass).newInstance();
...在我看来,每次调用都会创建唯一的DataSource
实例(因此,可能是唯一的池实例)。
有没有人对Jython有任何经验并且肯定知道?感谢。
答案 0 :(得分:0)
根据我的研究,我提出了以下解决方案。
我没有使用大多数Jython示例代码中显示的更直接的方法,而是使用Java方法实例化DataSource
。 (我从Apache Tomcat站点上的示例代码中获取此信息。)然后,我不使用zxJDBC方法来获取连接对象,而是使用该方法所依赖的内容:即com.ziclix.python.sql.PyConnection
类。
结果是从池中抽取的传统Java连接对象,然后将其包装在PyConnection对象中,以便于Jython连接及其游标对象。
from __future__ import with_statement
from com.ziclix.python.sql import PyConnection
import org.apache.tomcat.jdbc.pool as pool
# https://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html
p = pool.PoolProperties()
p.setUrl('jdbc:mysql://localhost:3306/my_database')
p.setDriverClassName('com.mysql.jdbc.Driver')
p.setUsername('mario')
p.setPassword('myP@ssw0rd')
p.setValidationQuery("SELECT 1")
p.setJdbcInterceptors('org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;' +
'org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer')
datasource = pool.DataSource()
datasource.setPoolProperties(p)
# http://www.jython.org/javadoc/com/ziclix/python/sql/PyConnection.html
conn = PyConnection(datasource.getConnection())
with conn.cursor() as cursor:
cursor.execute('SELECT * FROM MyTable')
data = cursor.fetchall()
print data
conn.close()
我对这种方法更有信心。我有什么理由不这样做吗?