JDBC in it's documentation states that it has 4 implementations to connect to databases. I don't quite get what the 4 implementations mean, I was wondering is JDBC truly database agnostic. That is, will I need "drivers" for each type of database, like for MYSQL (jConnector)?
I am writing an app to support Oracle, MySQL and MSSQL.
Reference:
http://docs.oracle.com/javase/tutorial/jdbc/basics/gettingstarted.html
Thanks
Unfortunately, you will need drivers for all database types.
If you want to be truly database agnostic you need to use JPA:
http://en.wikipedia.org/wiki/Java_Persistence_API
With one of its implementations. One of the most popular is Hibernate:
http://en.wikipedia.org/wiki/Hibernate_%28Java%29
When using JDBC, you use an API that is database-agnostic. The interfaces of this API (Connection, Statement, etc.) are implemented by the JDBC driver of the database that you target. So if you use Oracle, you'll need an oracle driver.
Yes the JDBC API is database agnostic - you just need to provide an appropriate driver. Of course, the SQL you send won't be, unless you use JPA
JDBC in it's documentation states that it has 4 implementations to connect to databases
No it doesn't. It might state that there are (currently) 4 implementation levels. However the number of implementations depends on (at least) the number of target databases and the number of iterations of the implementation per database, both of which are considerably greater than 4.
I've explained in this answer how difficult it is to be truly vendor agnostic using JDBC alone. There are two layers to this:
JDBC is a very good abstraction of the network protocol used to connect to the database. Though you'll need a few vendor-specific quirks here and there. These quirks are fine if you're binding to a single RDBMS vendor, but if you need to support multiple products, it gets very hairy
SQL is a very good standard for a query language. Though, again, you'll need quite a few vendor-specific quirks here and there. Same as above, it's OK to support 1 RDBMS and its quirks, but very hard to support multiple.
As others have mentioned, JPA/Hibernate help you abstract over some of the differences, mostly by removing access to more "advanced" SQL features (including derived tables, unions, etc. at least as of version 5). For a more SQL centric abstraction over dialects, jOOQ is a popular option.
Disclaimer: I work for the company behind jOOQ.
Related
Currently I am migrating databases from Oracle to MySQL. I mainly use Java to send queries to the database using JDBC. In the process of migrating, I need to change a lot of my queries in the Java code (the queries are hard-coded) as they will not work in MySQL.
I want to be able to recode my queries in such a way that I can easily switch between the databases if problems arise; I am changing all my queries to standard SQL but there are areas where this is not possible. I am thinking of having two versions of the queries, one for Oracle and one for MySQL so I can switch between both (I will have two versions temporarily just to see if MySQL can cope with our needs). However this seems like a terrible idea - does any one have any advice on a better way they would do this?
You have a bunch of options.
Firstly, many people now use Object-Relational Mapping (ORM) tools to connect applications to SQL databases. These come in a variety of different flavours - Hibernate is popular - and allow you switch between databases at very little cost. However, they do have a fairly steep learning curve. Inexperienced developers often struggle with performance problems in ORM applications.
If you stick with "traditional" JDBC, I suggest you take the body of the SQL out of the Java code, and treat it like a resource. As Henry suggests, you could use property files, and use parameter placeholders (ideally named placeholders, using the Spring template). While this does spread the code for a given piece of functionality into two files, it makes it easy to quickly refine the SQL and test new versions.
One possibility is to store the queries in a properties file. You would have one for Oracle and one for MySql.
I must add - ORM is good advice and will work... when you are starting with a fresh application and you can design your application to work on a domain model.
In this case however there is an existing application that invokes a great number of SQL queries. ORM based queries (HQL, JPQL) translate to SQL just fine; SQL does not by definition translate to the ORM layer however, major changes will be needed to make it a more object oriented approach to the data.
The problem will still persist even when you do manage to work in an ORM layer. There is already a major difference between MySQL and Oracle in how primary key generation works for example; MySQL uses auto-numbering where Oracle uses a sequence. Likely you already have an existing datamodel that you need to reverse engineer into the ORM layer code; it isn't going to be cross-database code.
I've only learned Java last quarter of 2010. I can say the knowledge I gained as of now are not enough and there's a lot of improvement. I still do studying while developing but most of my code is snippet from other current working application. I guess my way of studying the language affect the way I know it. Instead of learning the basic first, I jump up to advanced features that affect how I understand it. (I did advanced to fulfill my previous project tasks.)
I often connect to my MySql database using import java.sql.connection etc. I'm using Eclipse IDE then when I create an instance of Connection/PreparedStatement and I haven't imported the packages. Eclipse will show related Packages that's where mysql.jdbc.* I've encountered.
All though I did some research about it still its not too clear for me. The difference of those to packages.
Does it have pros and cons?
Does it have a big significance difference with performance and security?
Does it use in different way?
Is there more things to know?
I know someone here can enlighten me more about this.
To quote from the javadoc for com.mysql.jdbc.Connection:
This interface contains methods that are considered the "vendor extension" to the JDBC API for MySQL's implementation of java.sql.Connection.
So, that class at least builds on top of JDBC to add more features. But it's still JDBC at heart - you're using this class when you use pure JDBC, you just don't see it.
I would say that if you can build your app using only the standard JDBC interfaces, do so. If you absolutely need MySQL-specific API features, then use the MySQL interfaces. I work with Oracle mostly, and in all the years i've been doing it, i've never had to fall back to any Oracle-specific interfaces; there's a huge amount you can do with JDBC.
To address your points:
The pro is more features; the con is less standardisation
I would not expect any difference with performance and security, since the two packages use the same classes under the hood (AIUI)
The usage should not be fundamentally different; the MySQL package should add on to the JDBC package
There is more to know in the MySQL package, because you need to know about JDBC to use it anyway
To put it simply: Java (J2SE/J2EE) provides java.sql.* as the standard way to connect to a database. The issue is that these classes do not know really know how to connect to each specific database in the model, they are oriented to the programmer.
To connecto to each database, you need to put in its Driver. The Oracle driver will know how to connect to the Oracle database, the mysql driver will know how to connect to MySQL. java.sql. will know how to use each Driver, so by just using it you do not need to know the internals of each Driver.
The java.sql Javadoc defines SQL types in the java.sql.Types class. However, I can't find definitive information describing which type is implemented by which major database player (for me, this means: MySQL, MSSQL, H2, PostGre, Oracle)?
The ultimate information I am looking for is the subset of these types implemented by ALL major database players (as defined above). I want to be able to write portable SQL statements using these types only. I don't want to use ORMs.
Is such information already available somewhere? Thanks.
This table from Wikipedia contains a summary of data types implemented by different database vendors.
Good luck. You've go a hard job ahead of you.
I've had difficulty finding existing general solutions to this problem, apart from ORMs and the like. My conclusion is that most people who want database independence use an ORM these days.
However, you might want to take a look at the SwiSQL API. (Its a commercial product, and the set of supported databases looks a bit dated. But hey, it could work for you ...)
I found an article from 2008 discussing how to call Java code from MySQL. There were a lot of caveats and disclaimers because the process involved working with an experimental branch of MySQL.
For a project I have in mind, it would be very useful to be be able to access Java libraries within MySQL, analogous to Oracle's Java Stored Procedures. Does this capability now exist as a standard feature of MySQL? If not, what open source RDBMSs support something similar to Oracle's Java Stored Procedures?
PostgreSQL supports pluggable procedure languages, and a project exists to extend PostgreSQL with PL/Java as the language.
I don't recommend putting too much code in the RDBMS. Tools to develop, test, and debug code in the application layer are better than tools for code in the RDBMS.
Also many developers don't understand that code inside the RDBMS should obey transaction isolation. They try to send emails from triggers and so forth. I think code with side effects should be in the application layer, so you don't create phantom effects (e.g. an email may notify of a database change, even though the change was rolled back).
If you can use HSQLDB then you can call java methods directly from SQL: http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#N1240C
I fully agree with Bill, but I can imagine business rules being stored (not processed) in the database. I'm thinking of drools here. The engine would be in the application, but the rules could be in the database with a management front-end.
Such a beast would be interesting for scenarios where not only the parameters change, but also the formulas can change.
It is difficult to give good advice based on the limited information that you have provided so far. However:
... the example involves a graph-based data type (chemical structures) that can't be matched to a query using built-in MySQL functions. The Java library would convert the query and contents of a text field into an in-memory object that can by matched. Keeping this logic in the DB layer would, for example, keep joins within the database, which seems like where they belong. That's the idea, at least.
I don't think I would use database-side Java in MySQL for this. Instead, I think I would consider the following options:
Use an object-relational mapping such as JDO or JPA (for example using Hibernate) to deal with the mapping between your graph-based data model and what the database provides. You don't necessarily have to use an RDBMS as the backend, but that is probably the best place to start ... unless you've already found that this is a performance issue.
Take another look at your data model and data access patterns. See if you can figure out some transformation that allows your application's main queries to be implemented as (efficient) table joins without resorting to server-side application logic.
If you do need to use server-side application logic (for performance reasons!) stick with the mechanisms supported by your RDBMS. For example, in Oracle you'd use PL/SQL and PostgreSQL you have a number of options. Be prepared to switch to a different RDBMS that better suits your application requirements.
I (personally) would avoid depending on an experimental branch of some database:
Consider what happens if the experimental branch is not merged back into the main branch. You would be stuck with your code base depending on a branch that is not supported, and is likely to stop being maintained and fizzle out.
Using a (currently) unsupported RDBMS branch will be an impediment to other folks who might want to use your software.
Now obviously, if the long term viability of your software is not a primary concern, you could choose to ignore this advice. But it probably matters to someone; e.g. your research supervisor.
I realise that this is quite an old article, but it bears updating. The ability to call java from a database trigger is is part of the "SQL Routines and Types for the Java Programming Language" (SQL/JRT) standard.
Read more about this on Wikipedia at https://en.wikipedia.org/wiki/SQL/JRT.
Amongst the compliant database engines are..
HyperSQL: http://hsqldb.org/
Oracle: https://www.oracle.com/database/
I have a java-application using JDBC for database interaction. I want to do a search based on a series of regular-expressions, however the application should be generic, we do not know if the database-engine will by mysql,oracle,sql server etc, but we are pretty sure it's gonna be either mysql or oracle.
Will regular-expressions limit my application to a specific database or can i use them without worrying about compatibility?
Well, using regular expressions will limit you to DBMS that support them :-). That said, at least Oracle, MySQL, PostgreSQL and MS-SQL support some sort of regexp, so it should not be a problem in principle. You might still run into compatibility problems, of course.
Your best bet probably is to confine the use of regular expressions to some defined parts of the application, such as a few stored procedures or one module in your app that generates the SQL queries.
That is good practice anyway, and will make later changes doable.
While in theory I believe both MySQL and Oracle are meant to support POSIX ERE, MySQL uses REGEXP where Oracle uses REGEXP_LIKE, and regular-expressions.info notes quirks with Oracle's implementation (there are likely similar ones for MySQL).
So, you probably can't use this.
Yes, using non-standard SQL features like regular expression search will limit your application to a specific database.
Like slekse suggested, a good solution is to confine your use of non-standard SQL features to one specific module. Then you'll only need to change that module if you change DBMS.