整合多数据源Neo连接池时遇见的问题以及方案与收获

Posted javartisan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整合多数据源Neo连接池时遇见的问题以及方案与收获相关的知识,希望对你有一定的参考价值。

整合多数据源时候,配置neo数据库连接池时候使用的Druid连接池,遇见的问题以及问题的解决方案与收获简单记录一下。

 

方案1:

配置信息:

<bean name="neoDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driver" value="org.neo4j.jdbc.bolt.BoltDrive"/>
        <property name="url" value="$neo.url"/>
        <property name="username" value="$neo.username"/>
        <property name="password" value="$neo.password"/>
    </bean>

错误信息:

Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.sql.Driver] for property 'driver': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:302)
	at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576)
	... 89 more

很明显,无法将String转为Driver类型,看一下DataSource才知道原来driver配置的是Driver类型的实例,而不是Driver class名字,解决方案有两种。先介绍第一种:

解决办法:

将Driver以bean的方式注册到spring容器中,之后配置ref引用该Driver实例即可。代码如下:

    // 将Driver注册到Spring容器
    <bean id="boltDriver" class="org.neo4j.jdbc.bolt.BoltDriver"></bean>

    //ref引用该实例即可。
    <bean name="neoDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driver" ref="boltDriver"/>
        <property name="url" value="$neo.url"/>
        <property name="username" value="$neo.username"/>
        <property name="password" value="$neo.password"/>
    </bean>

 

方案2:

方案1中的DataSource是配置Driver类型成员;因此可以找到配置DriverName的变量配置即可,发现存在driverClass,可以配置driverClass设置Neo的Driver驱动名字即可。但是配置之后变红:

通过对比url发现,属性名字是setXXX方法中的XXX,该set方法名字为setDriverClassName(此处稍微翻阅源码就可以得知,Bean属性注入是使用set方法,而不是反射Field注入)。因此配置信息如下:

    <bean name="neoDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="org.neo4j.jdbc.bolt.BoltDrive"/>
        <property name="url" value="$neo.url"/>
        <property name="username" value="$neo.username"/>
        <property name="password" value="$neo.password"/>
    </bean>

 

方案3:

使用Mybatis自带的DataSource:org.apache.ibatis.datasource.pooled.PooledDataSource,该类中的driver是一个String类型设置驱动名字的成员:参见org.apache.ibatis.datasource.pooled.PooledDataSource#setDriver方法。

    <bean name="neoDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="org.neo4j.jdbc.bolt.BoltDriver"/>
        <property name="url" value="$neo.url"/>
        <property name="username" value="$neo.username"/>
        <property name="password" value="$neo.password"/>
    </bean>

 

总结:

收获1:

对于常见的数据库连接池,不同的实现有着细微的差别,例如对于阿里Druid数据库连接池,对于常用的数据库,我们可以不用设置driver或者driverClassName属性,数据库连接池会根据url自动识别Driver,识别Driver方法com.alibaba.druid.util.JdbcUtils#getDriverClassName ;源码如下:


    public static String getDriverClassName(String rawUrl) throws SQLException 
        if (rawUrl.startsWith("jdbc:derby:")) 
            return "org.apache.derby.jdbc.EmbeddedDriver";
         else if (rawUrl.startsWith("jdbc:mysql:")) 
            return MYSQL_DRIVER;
         else if (rawUrl.startsWith("jdbc:log4jdbc:")) 
            return LOG4JDBC_DRIVER;
         else if (rawUrl.startsWith("jdbc:mariadb:")) 
            return MARIADB_DRIVER;
         else if (rawUrl.startsWith("jdbc:oracle:") //
                   || rawUrl.startsWith("JDBC:oracle:")) 
            return ORACLE_DRIVER;
         else if (rawUrl.startsWith("jdbc:alibaba:oracle:")) 
            return ALI_ORACLE_DRIVER;
         else if (rawUrl.startsWith("jdbc:microsoft:")) 
            return "com.microsoft.jdbc.sqlserver.SQLServerDriver";
         else if (rawUrl.startsWith("jdbc:sqlserver:")) 
            return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
         else if (rawUrl.startsWith("jdbc:sybase:Tds:")) 
            return "com.sybase.jdbc2.jdbc.SybDriver";
         else if (rawUrl.startsWith("jdbc:jtds:")) 
            return "net.sourceforge.jtds.jdbc.Driver";
         else if (rawUrl.startsWith("jdbc:fake:") || rawUrl.startsWith("jdbc:mock:")) 
            return "com.alibaba.druid.mock.MockDriver";
         else if (rawUrl.startsWith("jdbc:postgresql:")) 
            return POSTGRESQL_DRIVER;
         else if (rawUrl.startsWith("jdbc:odps:")) 
            return ODPS_DRIVER;
         else if (rawUrl.startsWith("jdbc:hsqldb:")) 
            return "org.hsqldb.jdbcDriver";
         else if (rawUrl.startsWith("jdbc:db2:")) 
            return DB2_DRIVER;
         else if (rawUrl.startsWith("jdbc:sqlite:")) 
            return "org.sqlite.JDBC";
         else if (rawUrl.startsWith("jdbc:ingres:")) 
            return "com.ingres.jdbc.IngresDriver";
         else if (rawUrl.startsWith("jdbc:h2:")) 
            return H2_DRIVER;
         else if (rawUrl.startsWith("jdbc:mckoi:")) 
            return "com.mckoi.JDBCDriver";
         else if (rawUrl.startsWith("jdbc:cloudscape:")) 
            return "COM.cloudscape.core.JDBCDriver";
         else if (rawUrl.startsWith("jdbc:informix-sqli:")) 
            return "com.informix.jdbc.IfxDriver";
         else if (rawUrl.startsWith("jdbc:timesten:")) 
            return "com.timesten.jdbc.TimesTenDriver";
         else if (rawUrl.startsWith("jdbc:as400:")) 
            return "com.ibm.as400.access.AS400JDBCDriver";
         else if (rawUrl.startsWith("jdbc:sapdb:")) 
            return "com.sap.dbtech.jdbc.DriverSapDB";
         else if (rawUrl.startsWith("jdbc:JSQLConnect:")) 
            return "com.jnetdirect.jsql.JSQLDriver";
         else if (rawUrl.startsWith("jdbc:JTurbo:")) 
            return "com.newatlanta.jturbo.driver.Driver";
         else if (rawUrl.startsWith("jdbc:firebirdsql:")) 
            return "org.firebirdsql.jdbc.FBDriver";
         else if (rawUrl.startsWith("jdbc:interbase:")) 
            return "interbase.interclient.Driver";
         else if (rawUrl.startsWith("jdbc:pointbase:")) 
            return "com.pointbase.jdbc.jdbcUniversalDriver";
         else if (rawUrl.startsWith("jdbc:edbc:")) 
            return "ca.edbc.jdbc.EdbcDriver";
         else if (rawUrl.startsWith("jdbc:mimer:multi1:")) 
            return "com.mimer.jdbc.Driver";
         else if (rawUrl.startsWith("jdbc:dm:")) 
            return JdbcConstants.DM_DRIVER;
         else if (rawUrl.startsWith("jdbc:kingbase:")) 
            return JdbcConstants.KINGBASE_DRIVER;
         else if (rawUrl.startsWith("jdbc:hive:")) 
            return JdbcConstants.HIVE_DRIVER;
         else if (rawUrl.startsWith("jdbc:hive2:")) 
            return JdbcConstants.HIVE_DRIVER;
         else 
            throw new SQLException("unkow jdbc driver : " + rawUrl);
        
    

阿里巴巴数据库连接池对常见的数据库都可以识别,但是对于neo没有支持,因此就需要配置driver或者driverClassName。

 

收获2:

对于数据库连接池的一些属性配置信息名字不是固定的,这些属性名字不是DataSource规范中的,而是跟各个具体DataSource实现强相关,因此配置时候可以查看DataSource具体实现进行配置。

以上是关于整合多数据源Neo连接池时遇见的问题以及方案与收获的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 遇见 spark(进行整合)

Springboot整合多数据源以及多数据源中的事务处理

Springboot整合多数据源以及多数据源中的事务处理

在 tomcat 服务器上使用连接池时的数据同步问题

Python:使用多处理池时使用队列写入单个文件

spriongboot与数据源的整合以及SQL监控