使用Spring JDBCTemplate与MariaDB Connector。

huangapple go评论72阅读模式
英文:

Using Spring JDBCTemplate with MariaDB Connector

问题

Java Web 应用程序使用 Spring。

我们目前正在使用 MySQL 并希望迁移到 MariaDB。因此,我们还计划从 MySQL Connector 迁移到 MariaDB Client。

我们的软件在同一台服务器上使用多个数据库,并且某些表可能具有相同的名称,但在两个不同的数据库上。在 MySQL Connector 上,这不是问题。我们只需使用已连接到正确数据库的数据源,JDBCTemple 就知道它必须在当前架构中搜索表。

另一方面,MariaDB Client 不使用架构来区分数据库,而是使用目录。Spring 似乎不知道这一点。因此,在迁移后测试软件时,JDBCTemplate 发现具有相同名称的多个表,因为架构始终为空,并且似乎只使用列表中的最后一个来获取表的元数据。这显然会导致意外错误。

我们通过在 JDBCTemplace 调用中添加 withCatalogName 来纠正了这种行为(请参见下面的代码),但是这样做并不是非常优雅的解决方案。

SimpleJdbcInsert insertStatement = new SimpleJdbcInsert(getJdbcTemplate());
[...] // 业务代码
insertStatement.executeBatch(sqlParameterSource); // 失败
insertStatement.withCatalogName("dbName").executeBatch(sqlParameterSource); // 成功

所以我的问题是,有没有办法告诉 Spring 我们正在使用 MariaDB Client,并且它应该始终使用目录而不是架构来获取元数据?

我们已经使用了 jdbc:mariadb 前缀设置 URL 连接,所以 Spring 知道我们正在使用 MariaDB 而不是 MySQL。

我们不能现实地修改我们的软件,使一切都在同一个数据库中。甚至只是更改服务器上的表名称以确保唯一性都将比我们计划的 MariaDB 迁移成本高得多。

编辑:我们还已经在连接属性中将 org.mariadb.jdbc.Driver 设置为新的驱动程序。

编辑 2:找到了问题,我们在连接属性中使用了 nullDatabaseMeansCurrent,以便 Spring 可以轻松访问表的元数据,但是这个属性不受 MariaDB 连接器支持。还不知道是否有解决方法。

英文:

Java web application using Spring.

We are currently using MySQL and wish to migrate to MariaDB. So we also planned to migrate from MySQL Connector to MariaDB Client.

Our software uses multiple databases on a same server, and some tables can have the same names, but on two different databases. On MySQL Connector, that was not a problem. We simply used a datasource that was already connected to the right database, and JDBCTemple knows that it has to search for the table in the current schema.

MariaDB Client, on the other hand, doesn't use schema to differentiate databases, it uses catalog. Spring does not seems to be aware of that. So when we test our software after the migration, JDBCTemplate finds multiple tables with the same name, since the schema is always null, and seems the just use the last one on the list to get the table's metadatas. Which obviously leads to unexpected errors everywhere.

We manage to correct this behavior by adding withCatalogName the the JDBCTemplace calls (see code below), but doing so at large would not be very elegant solution.

    SimpleJdbcInsert insertStatement = new SimpleJdbcInsert(getJdbcTemplate());
    [...] // business code
    insertStatement.executeBatch(sqlParameterSource); // fails
    insertStatement.withCatalogName("dbName").executeBatch(sqlParameterSource); // succeeds

So my question is, is there a way to tell Spring that we are using the MariaDB Client, and that it should always use the catalog and not the schema to get metadatas ?

We did set up the URL connection with the jdbc:mariadb prefix already, so Spring is aware that we are using MariaDB and not MySQL.

We can't realisticly modify our software so everything is in the same database. Even just changing table names to unique names accross the serveur would cost a lot more than what we planned for the MariaDB migration.

Edit : we also already set org.mariadb.jdbc.Driver as the new driver in the connection properties.

Edit 2: found the problem, we used nullDatabaseMeansCurrent in the connection properties so that Spring can access the table metadata without fuss, but this property is not supported by MariaDB connector. Don't know yet if there is a workaround.

答案1

得分: 2

当使用元数据时,连接器根据参数请求元数据。例如,当不设置目录和表名时,DatabaseMetaData.html#getColumns 将在所有目录中搜索所有对应的表,忽略模式设置。

MySQL 连接器有两个选项,而MariaDB 连接器没有:nullDatabaseMeansCurrent,用于在没有设置数据库时仍然搜索当前数据库,以及 databaseTerm,指示使用设置的目录或模式。

我想你可能使用了这两个选项中的一个,要么模式设置为 nullDatabaseMeansCurrent,要么使用了 databaseTerm 设置,然后连接器使用模式参数。

这第二部分将在 https://jira.mariadb.org/projects/CONJ/issues/CONJ-1088 中实施。现在可能是时候在 Jira 上创建一个问题,以支持 nullDatabaseMeansCurrent

英文:

When using metadata, connector request metadata depending on parameters. For example DatabaseMetaData.html#getColumns when setting not catalog and table name will search all tables corresponding in all catalogs, schema setting will be ignored.

mysql connector has 2 options that mariadb connector don't have : nullDatabaseMeansCurrent in order to search for current database even when no database is set, and databaseTerm that indicate that use setting catalog or schema.

I imagine that you use either one of these option, either schema is set with nullDatabaseMeansCurrent or using setting databaseTerm and connector then use schema parameter.

This second part will be implemented in https://jira.mariadb.org/projects/CONJ/issues/CONJ-1088. It might be the time to create an issue on jira to have nullDatabaseMeansCurrent support as well

答案2

得分: 0

我不是100%确定,但你需要更改spring属性/.yml文件,并告诉spring使用哪个SQL驱动程序和数据库,就像这样(只需将postgre或mysql更改为mariaDB):

spring:
  datasource:
    username: myuser
    password: secret
    url: jdbc://postgresql://localhost:5432/mydatabase
    driver-class-name: org.postgresql.Driver
英文:

I´m not 100% sure here but you need to change the spring properties/.yml file and tell spring wich sql driver and db will use. like this(just change postgre or mysql for mariaDB.):

spring:
 datasource:
 username: myuser
 password: secret
 url: jdbc://postgresql://localhost:5432/mydatabase
 driver-class-name: org.postgresql.Driver

huangapple
  • 本文由 发表于 2023年7月10日 20:16:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653657.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定