在Android中建立与MySQL的池化连接 [英] Establish pooled connection to MySQL in android
问题描述
我需要从我的Android应用访问MySQL数据库.现在所有的工作都通过
I need to access a MySQL db from my android app. Now all the work is done through
DriverManager.getConnection(url);
,依此类推.但是我必须从多个线程访问数据库,因此必须使用连接池.
and so on. But I have to access the db from multiple threads, so I have to use connection pooling.
问题1.是
com.mysql.jdbc.jdbc2.optional.MysqlDataSource ds = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
创建数据源的正确方法?
the right way of creating the data source?
问题2.如果我编写了上一行代码,则我的应用可以正常编译并安装在设备(而不是仿真器)上,但很奇怪
Question 2. If I write the previous line of code, my app compiles and installs on the device (not emulator) fine, but I get a weird
java.lang.NoClassDefFoundError: com.mysql.jdbc.jdbc2.optional.MysqlDataSource`
,我无法使用try/catch处理程序进行捕获:
, that I can't catch with a try/catch handler:
try
{
com.mysql.jdbc.jdbc2.optional.MysqlDataSource a = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
}
catch (Exception e)
{
I don't get here. The app just crashes, as if I had no try/catch block.
}
问题3.我将mysql-connector-java-5.1.20-bin.jar复制到设备并编写了以下代码:
Question 3. I copied mysql-connector-java-5.1.20-bin.jar to the device and wrote the following code:
try
{
final String str = Environment.getExternalStorageState();
final File sd = getActivity().getExternalFilesDir(null);
final File file = new File(sd, "mysql-connector-java-5.1.20-bin.jar");
boolean b = file.exists();
final URLClassLoader cl = URLClassLoader.newInstance(new URL[] {file.toURI().toURL()} );
cl.loadClass("com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); //$NON-NLS-1$
}
catch (Exception e)
{
new AlertDialog.Builder(getActivity())
.setMessage(ObjectConverter.throwable2String(e))
.show();
}
找到文件,但是
cl.loadClass()
失败
java.lang.NullPointerException
at java.net.URLClassLoader.getPermissions(URLClassLoader.java:614)
at java.security.SecureClassLoader.getPD(SecureClassLoader.java:140)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:93)
at java.net.URLClassLoader.access$600(URLClassLoader.java:55)
at java.net.URLClassLoader$URLJarHandler.createClass(URLClassLoader.java:364)
at java.net.URLClassLoader$URLJarHandler.findClass(URLClassLoader.java:303)
at java.net.URLClassLoader.findClass(URLClassLoader.java:748)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at ru.mypkg.myapp.func(myapp.java:367)
at android.view.View.performClick(View.java:3511)
at android.view.View$PerformClick.run(View.java:14110)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
任何帮助都将不胜感激.
Any help greatly appreciated.
推荐答案
这个问题已有6年历史了,马克(Mark)是正确的,在您能想到的几乎每种情况下,Android上的JDBC与尝试使用JDBC一样明智.烤面包机在浴缸里.但是,有时候我们做事情是因为我们可以做而不是因为我们必须做,而不是因为我们必须做,而今天我有正当的理由要这样做(对于在不寻常的环境中运行的特定的非常小众的应用程序),这就是我找到这个问题的方式.
This question is 6 years old and Mark is correct that, in almost every scenario you can think of, JDBC on Android is about as sensible as trying to use a toaster in the bath. However, sometimes we do things because we can and not because we necessarily should, and today I had a justifiable reason to want to do this (for a specific very niche app running in an unusual environment), which is how I found this question.
首先寻址NoClassDefFoundError
,其未被catch
块捕获的原因是因为它是Error
而不是Exception
. Error
和Exception
都从Throwable
继承,因此您可以捕获它:
Addressing the NoClassDefFoundError
first, the reason it isn't caught by the catch
block is because it's an Error
not an Exception
. Both Error
and Exception
inherit from Throwable
, so you could catch that instead:
catch (Throwable t)
{
// This will catch NoClassDefFoundError
}
我相信它不是找不到的MySqlDataSource
,而是它所依赖的类或接口之一-在我的情况下是javax.naming.Referenceable
. Android不提供javax.naming
包,因此尝试为MySQL使用Connector/J JDBC驱动程序的池化功能不会使您走得太远(您可以尝试提供缺少的依赖项,但是那条路很可能导致疯狂).
I believe that it's not MySqlDataSource
that it can't find, but one of the classes or interfaces that it depends on - in my case it was javax.naming.Referenceable
. Android doesn't provide the javax.naming
package so trying to use the pooling features of the Connector/J JDBC driver for MySQL isn't going to get you very far (you could try to provide the missing dependencies but that road likely leads to madness).
相反,第三方连接池实现可能会给您带来更多的运气.有各种Java库可以执行此操作.其中一些将在Android上运行.我已验证确实有效的一种方法是 HikariCP .在此处有专门的配置说明,对于MySQL,特别是
Instead you'll probably have more luck with a third-party connection pool implementation. There are various Java libraries for doing this. Some of them will work on Android. One that I have verified does work is HikariCP. There are instructions for configuring it here and, specifically for MySQL, here.
这篇关于在Android中建立与MySQL的池化连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!