how to connect multiple databases on a single server with JDBC? - java

I'm trying to access data in multiple databases on a single running instance. the table structures of these databases are all the same; As far as I know, create a new connnection using jdbc is very expensive. But the connection string of jdbc require format like this
jdbc:mysql://hostname/ databaseName, which needs to specify a specific database.
So I'm wondering is there any way to query data in multiple databases using one connection?

The MySQL documentation is badly written on this topic.
The SELECT Syntax page refers to the JOIN Syntax page for how a table name can be written, even if you don't use JOIN clauses. The JOIN Syntax page simply says tbl_name, without further defining what that is. There is even a comment at the bottom calling this out:
This page needs to make it explicit that a table reference can be of the form schema_name.tbl_name, and that joins between databases are therefore posible.
The Schema Object Names page says nothing about qualifying names, but does have a sub-page called Identifier Qualifiers, which says that a table column can be referred to using the syntax db_name.tbl_name.col_name. The page says nothing about the ability to refer to tables using db_name.tbl_name.
But, if you can refer to a column using db_name.tbl_name.col_name, it would only make sense if you can also refer to a table using db_name.tbl_name, which means that you can access all your databases using a single Connection, if you're ok with having to qualify the table names in the SQL statements.
As mentioned by #MarkRotteveel in a comment, you can also switch database using the Connection.setCatalog(String catalog) method.
This is documented in the MySQL Connector/J 5.1 Developer Guide:
Initial Database for Connection
If the database is not specified, the connection is made with no default database. In this case, either call the setCatalog() method on the Connection instance, or fully specify table names using the database name (that is, SELECT dbname.tablename.colname FROM dbname.tablename...) in your SQL. Opening a connection without specifying the database to use is generally only useful when building tools that work with multiple databases, such as GUI database managers.
Note: Always use the Connection.setCatalog() method to specify the desired database in JDBC applications, rather than the USE database statement.

Related

Why is Show Tables a better option over DatabaseMetaData.getTables() when looking for a specific table in a database?

I currently have a method in my Java program, using JDBC that checks if a specific table exists in a MySQL database. I had a logic error where the DatabaseMetaData.getTables() method was returning a same-named table from a different database, and I've now solved that by specifying the catalog in the statement as seen below (table represents the table name I'm looking for).
ResultSet tables = connectionToDatabase().getMetaData().getTables("snakeandladder", null, table, null);
However, after doing some research, I saw a lot of people recommending to use Show Tables instead, but not actually explaining why to use Show tables over the above.
Can someone explain to me the limitations of using the statement above and why Show Tables would be a better option?
Thank you!
DatabaseMetaData.getTables() is more portable, most of the databases (not only MySQL) should be able to provide information through defined API.
On the other hand using MySQL specific query "show tables;" may cause more harm than good:
you introduce a query string which can be exploited by an attacker, also the code now contains a statically compiled query string.
if ever the database provider will change, so the code will have to be updated (again portability)

Appropriate way to pass a dataset to Java from Oracle PL/SQL

I need to pass datasets from Oracle to Java through JDBC.
How is it better to organize it so that everything works well and it would be convenient both for Java developers and PL/SQL developers to maintain the code in case of changing, for example, table column types?
I see such variants:
Pass the sys_refcursor via stored procedure, and in Java expect that there will be certain fields with a certain type of data.
Pass a strong ref cursor and in Java do the same, that in item 1, but in the PL/SQL package there is a type description.
Pass SQL "table of" type, described at the schema level. If I understand correctly, in Java apparently it can somehow be applied to the object. The problem is that in these types it is impossible to do fields with the column type - Column_Name%TYPE.
Conduct in the PL/SQL package "table of object / record" type, and using JPublisher to work with it - JPublisher apparently converts it into a SQL type. It is not entirely clear for me how this is implemented, and what needs to be done for the same case when the data type of the column changes.
Using the pipelined function instead of the cursor (does this even make sense for such a task?).
What to choose? Or maybe something else, not from these points?
P.S. Sorry for bad English.
I'm not sure that i've understood your queston right, but i think you confused.
The variants, which you discribed is way to execute Java package on server side (for example, when you have database with application servers and want execute java package on it with data of database).
But if you thinking about JDBC then i guess that you want to make some java-app which could work with database. So that you don't have to user some sys_refcursor of subtupes like table of object / record. The JDBC provides capabilities to work with datasets using simple SQL. You should just connect to database as user (via JDBC) and execute sql query. After that you can get any data from result set.
Examples:
Connection example via JDBC
Execute select after connection
So the answer for your question depends on yours goals.

Joining multiple result set

I am trying to develop a Java application which merges data from multiple data source basically RDBMS. The scenario is some thing like this.
I have creates a connection to two data sources, lets say a MSSQL database and other Oracle. Also on each connection a user can create a DataObject( a Java object) which contains a SQL query and a connection. The query is executed on the connection and result are displayed.
Now what I want is that my user can join and filter result obtained from multiple DataObject.
Currently I am looking on the following solution:
JDO/Hibernate - I will create a object from the ResultSet obtained from the query execution and will use the multiple objects with filter and joining condition.
Java RowSet - I will create a RowSet object over result sets and user JoinRowSet and FilteredRowSet to join multiple result set.
Please advice me on my choice. Also please can other solution be looked into.
I would suggest the former. To me its as simple as getting the list of entities, and add those in a single list, based on some filter.
Oracle comes with a generic ODBC gateway that allows you to link the oracle database with another database, so you can join tables from both databases etc. with SQL, as if both tables were on Oracle. See this link for details. By doing that, you don't have to replicate database features in your java program.

Java - Prepared statements and arrays

How can I handle an array in a prepared statement? i.e, I want to do a query and one of the parameters I get is an array of strings which I want to use in the query (Don't select rows that have a field that's in the array)?
Some JDBC drivers may already (before JDBC 4) contain proprietary extensions that support array-type parameters in prepared statements - you would need to consult with API for this. This would mean that you have to use and manipulate array-like type in SQL.
One work around would be using temporary tables. These are meta-steps for such solution:
Begin transaction (this is automatic if you are inside transactional
method - EJB or Spring);
Using JDBC batch insert with prepared statement create and populate a temporary table with arrary elements (temporary table must have transactional scope - this is also proprietary to databases but supported by Oracle at least);
Construct your desired SQL that includes a join to temporary table to use array values (it could be explicit inner or outer JOIN or implicit join, e.g. using EXISTS, etc.);
Commit (or rollback if application exception) transaction (this should destroy temporary table; concurrent transactions should have no conflict for the same name of temporary table).
Example: IN expression gets replaced with JOIN to temporary table.
This probably won't help you now, but I read that JDBC 4 will support array types as defined in the 2003 version of SQL.
That pretty much depends upon RDBMS being used. Often such functionality can be accomplished using vendor's jdbc driver extensions.
2 variants I found are (for Oracle):
http://blogs.itemis.de/kloss/2009/03/05/arrays-preparedstatements-jdbc-and-oracle/
http://www.angelfire.com/home/jasonvogel/java_jdbc_arrays.html
Try to look if that would help you.

Question about SQL catalogs - What exactly are they?

Something that has been puzzling me for a bit now, and an hour or two of googlin' hasn't really revealed any useful answers on the subject, so I figured I'd just write the question.
When I create a database in SQL using 'CREATE DATABASE DBNAME' am I implicitly creating a catalog in that database? Is it proper to refer to that 'DBNAME' as a catalog? Or is it something completely unrelated?
When I use the MySQL JDBC driver to get the list of tables in a database using the getMetaData() function, the "TABLE_CAT" column (which I would assume means 'catalog') is always set to the name of the database I've choosen.
Coincidence? Or am I just completely wrong on all of this?
catalog is the JDBC term for what many people (and some RDBMs) call databases. i.e. a collection of tables/views/etc. within a database system.

Categories