There are a lot of technologies to access data using Java.
I was reading about some of them, including:
JPQL
HQL
Criteria API
Querydsl
jOOQ
JaQu
JDBC
ActiveJDBC
Now I am really confused because of the overhead. What are the main differences and similarities between these technologies? Which are most commonly used? Short comparison is more than welcome.
The fundamental foundation for database access in Java is JDBC. It is an interface (no implementation) that permits database vendors to expose their databases in a standard way, so Java programmers don't have to radically alter their code to support different relational databases.
That said, it accepts SQL, and SQL is standard, with so many variants that the standards do not permit cross database portability.
The rest of the platforms tend to build upon JDBC in an attempt to ease the cost of integrating with other databases. The numbers of ways one can interact with a database is varied, basically you get improvement on issuing SQL commands or the additional library takes over the writing of a compatible SQL command for you.
The two major categories are "database like" and "object storage" where object storage focuses on you storing a Java Object, and the libraries take care of most of the details of SQL generation.
Technology / query language / type / notes
Java Persistance API / JPQL / object store / not an implementation, but an interface allowing multiple implementations, query language is not table specific, but object specific
Hibernate / HQL / object store / a popular Java solution, but tied to Hibernate only.
Java Persistance API / Criteria API / object store / Criteria API is the code (programming) equivalent to the JPQL strings.
Java Persistance API & JDO / QueryDSL API / object store / Java API to build queries similar to Criteria API, but different
JDBC / jOOQ / direct JDBC / Java API that replaces SQL strings construction with method calls that are table centric
H2 database / JaQu / object store / Linked directly to one database, non-portable. Follows Microsoft LINQ syntax.
JDBC / ActiveJDBC / object store / Looks like a branded version of almost-JPA for webapps.
The two fundamental APIs in this space are JDBC and JDO, where the subset of JDO you wish to use if you are only going to support relational databases is JPA. Neither JDBC nor JDO provide a database connection directly, they are pure-play APIs. That said, a lot of database vendors push their APIs which don't leverage these technologies, I would advise not using any technology that isn't based on JDBC and JPA.
Again to leverage multiple implementations, I would also advise that you not use a query language that isn't based on JPQL (if you build queries in Strings) or the CriteriaAPI (if you build queries in code), both which are conceptual components of JPA. If you are using JDBC directly, use PreparedStatements for all issued SQL, and keep in mind that while you may be able to leverage your existing SQL codebase with a pure JDBC solution, you will likely get a better quality implementation (and possibly faster delivery) using JPA, because there are lots of corner cases in mapping Relational Databases to Java that very few existing database codebases handle.
Do not write JDBC code.
You will never do a better job of it than MyBatis and/or Hibernate.
Instead, learn and use either MyBatis or Hibernate.
MyBatis is simpler (and most likely sufficient for anything you will need) and Hibernate has a million features (none of which you probably need).
Using JDBC API and registering your DB class and making the connection.
Using Datasource, where you define DB details on your server like WebSphere or Weblogic
server And you lookup the defined datasource.
Using some ORM framework like Hibernate.
Related
The question is that I don't understand how orms get access to the database. With JDBC we create connection, write statements and get result. But orm?
I mean - what does Mybatis or Hibernate or other orms use to get access to the database and run queries?
Implementation of JPA? JDBC? What is under the their hoods? They use database drivers?
I'm very curious
JDBC is a low level mechanism for interacting with the database, but it's the base of any Java database interaction. The JDBC doesn't offer any transaction management integration, since it only allows you to implement local transactions (based on the current database connection commit/rollback). It's also verbose and on large enterpise applications, with thousand of queries, it's simply pain to add a new column to a base table as you'd have to update zillions of existing queries.
Beside the object to relational mapping ability, ORM tools come with many other useful features:
optimistic locking on complex entity trees
polymorphic queries
local and XA transaction management integration
schema generation
database independent basic querying and DML
But you don't have to use only the ORM tool. In fact this is an anti-pattern on large applications.
You usually mix Hibernate with native querying, or JOOQ to benefit from database specific features (window functions, common table expressions, etc)
The best approach is to use a data layer stack approach, where you pick and mix the best of Hibernate/JDBC/JOOQ.
JPA implementations like Hibernate and EclipseLink use JDBC for connection and SQL execution, which in turn uses a DB driver.
It is one of the purposes of the JPA specification - to abstract away the DB connection ans SQL generation and execution from your application code.
I'm new in persistence and I'm reading the book "Pro JPA 2". I read that the problems of Java and JDBC pack is that
SQL is not portable
Tight coupling between Java code and SQL
The irony of JDBC is that, although the programming interfaces are
portable, the SQL language is not. Despite the many attempts to
standardize it, it is still rare to write SQL of any complexity that
will run unchanged on two major database platforms. Even where the SQL
dialects are similar, each database performs differently depending on
the structure of the query, necessitating vendor-specific tuning in
most cases.
My questions are:
IS the problem linked with SQL portability is still so critical?
As I understand, Hibernate, TopLink and other frameworks also have to create SQL queries from their metadata (annotations). How they arrange the problem linked with SQL portability?
Java & JDBC tight-coupling means that developer have to write SQL queries. Do I understand it correctly?
Thank in advance for your responses )
Yes the problem is with tight coupling between SQL and code and is very critical to project because if we need to migrate from one database to other without ORM, we need to change all the queries in the application.
Hibernate, TopLink and Other ORM Solutions converts your java code into SQL Queries and fires them to the database, but they are more standard and well tested so instead of directly working on Queries we can rely on ORM tools which will convert our code into queries and abstracts us from the complexity. So it is a good idea to use ORM tools instead of directly writing queries.
Yes, Java & JDBC tight-coupling means that developer have to write SQL queries directly which are not portable, and at time if the database layer changes you need to change all the queries. Instead if you use ORM solutions you can migrate to any database supported by ORM directly, by just changing some XML or configuration files.
SQL portability will be an issue if you ever need to switch to different database.
It is easy to think that you will never switch but that can be costly. I've been on projects that assumed the database would always be vendor x but later vendor y database was needed also. Lots of painful, tedious, rework was required to make application work with both databases.
I recommend that you always use standard SQL and/or use an ORM tool that writes only standard SQL.
My ORM, sormula, always creates standard SQL. If you've developed an application with sormula, all that is required to switch databases is to change the jdbc jar.
JDBC provides an API, which may be used to connect to different RDBMS or similar datastores. But the datastores differ in implementation (e.g. SQL dialects).
Is it possible to use JDBC in such a way, that my queries and statements work on most common RDBMS (e.g.: Oracle, PostgreSQL, SQL Server, MySQL)?
That question is interesting for me at two aspects:
* Common SQL (INSERT, UPDATE, SELECT etc.)
* Accessing Meta data (getting information about tables and columns)
I am currently experimenting with an self written persistence framework and want to plug a JDBC datastore under it. So if I write a JDBC datastore adapter, it would be nice, if it would work on most common RDBMS.
Thanks in advance
JDBC is an abstraction layer for RDBMS.
Unfortunately, as you already recognized in your question, the abstraction is leaky.
If you stick to the small subset of SQL and Metadata that is common to all RDBMS, you'll be fine. However in reality, you're very likely to quickly outgrow these limits.
No this is not possible because they serve two completely different purposes.
JDBC is an abstraction of the DBMS communication protocol, whereas SQL is a query language.
The queries written in SQL are sent to the server using that communcation protocol and the results of the queries are then returned through that protocol (in a DBMS independent way).
There seems to be a blurry line between the communication protocol and the queries as the JDBC API also specifies calls to retrieve meta data from the server (or from the result). But actually the driver is free to use any means of transportation that deems suitable. That does not necessarily need to be a SQL query.
JDBC works as an abstraction of an RDBMS approximately to the same degree SQL does: basic queries are compatible enough, but you constantly bump into requirements that can only be implemented using vendor-specific features:
autoincrementing columns
paging
internationalization
etc.
We are using Eclipselink for ORM, but we have a need for some more lightweight database interactions that are more equivalent to JDBC. My question is whether Eclipselink supports such an idiom and whether there are any advantages of it to straight JDBC. I can see one advantage being consistency and being able to use the existing connection handling. Others?
Specifically, what I'm looking for is something equivalent to Hibernate's Native SQL Query.
If you are using both JPQL and SQL queries in your application then JPA 2 native queries are probably the right approach. Here are some examples :
http://www.oracle.com/technology/pub/articles/vasiliev-jpql.html
If your app only uses SQL queries and updates, then ORM is just an overhead. You can get declarative transactions also differently, for example via Spring's JDBC support.
EclipseLink implements JPA - you can run SQL queries via an EntityManager. If you start running SQL queries not related to the model of your application you'll have no advantages over JDBC - on the contrary you'll be using a much heavier infrastructure. If you tie the SQL to the model however you'll have the advantage of making additional optimizations to queries utilizing the full db potential. I'm not sure if that's what you want to do however...
Does anyone have any experience with creating database agnostic apps in Java, particularly with Hibernate, and simultaneously targeting Oracle and Postgres databases?
In particular I am looking at Oracle Spatial and PostGIS.
We want to create a Java based SOA which can be used with both Oracle Spatial and PostGIS back ends.
I've used Hibernate with both these databases but never with the intention of targeting both.
I can create scenarios where the same code can generate different results depending on which database is used.
It maybe that hibernate can handle this but it would be nice to hear if there are any known problems.
Ken
along with hibernate i can recommend Hibernate Spatial , an extension which supports Mysql, Oracle and Postgre, with their respective GIS extensions.
some pitfalls i encountered:
be aware, the configuration of the dialects was not trivial to do correctly. make sure the dialects are not reconfigured for every statement, as it happened to me.
depending on the features from hibernatespatial you use you might get locked in on a specific version number of hibernate
you can use the criteria api ONLY, hql is not directly supported.
my code using hibernatespatial looks like this:
if (query.getMaxDistance() != null && query.getCenter() != null) {
basicCriteria.add(SpatialRestrictions.within("coordinate", GeoidCircleFactory.circle(query.getCenter(), query.getMaxDistance())));
}
you will suffer from some of the quite dire constraints postgis and others are under.
i would recommend to relax some of your application needs to better fit the possibilities of your DB. for example, queries in "angle space" are much easier to do than in "euclidean space".
the code contained in GeoidCircleFactory looks quite scary... :)
In addition to using Hibernates dialects you will want a database creation management tool like Liquibase which will allow the creation code to be abstracted away from the specific syntax of the different databases.
Hibernate handles targetting different databases using its Dialect abstraction. You don't need to make any changes to your application itself only the hibernate configuration for each database.
You can either specify in your configuration the dialect to use with your database or allow Hibernate to use the JDBC driver settings to determine the appropriate dialect.
Following the comment received, have you looked at Hibernate Spacial? It is an extension to Hibernate to support geographic data by providing the necessary Hibernate types and dialects.