How to inject a condition in all SQL queries using jOOQ - java

I am using jOOQ to generate my SQL queries and I was wondering if there is a way to inject a condition in all the queries that my application does.
For example, I would like to have something like account = {accountNameHere} in all the SELECT that the application does. Since I already have a a high number of different queries, I would like to do that without manually adding the condition to each statement.
Is there a way to do that easily using jOOQ ? Maybe using the VisitListener ?

Yes, a VisitListener will be the most thorough way to inject a custom predicate into all of your SELECT statements (including subqueries, of course). In fact, what you're looking for is sometimes referred to as "row level security" (natively supported in RDBMS like Oracle or SQL Server).
The following blog post explains how to achieve this via a VisitListener:
http://blog.jooq.org/2015/06/17/implementing-client-side-row-level-security-with-jooq

Related

Hibernate - join tables without NamedNativeQuery

While joining multiple tables on my project using Hibernate jpa /Spring (annotation driven), I had to use the NamedNativeQuery annotation to achieve my objective to extract a distributed resultset spanning multiple tables. This may be a question that merely serves academic merit, but given that I am starting out on Hibernate - is there another way to achieve table joins without having to fall back on queries native to the database dialect?
Yes. I believe this is exactly what you need: https://docs.jboss.org/hibernate/entitymanager/3.5/reference/en/html/querycriteria.html#querycriteria-tuple
Criteria Queries is a way of building a complete query just using its API. If I were you, I'd give it a try.
By the way, according to your question, the reason for using native queries is just for retrieving a specific set of columns. If this is the case, you can also write it using HQL as well. The query doesn't necessarily needs to be native.

Why do we need to create native query?

I am working in a project which uses JPA ORM and framework provides two kinds of method to create queries.
entityManager.createQuery(query1);
entityManager.createNativeQuery(query2);
I understand the kinds of query string is to be passed to use them, but I don't know exactly why do we need to create native query? Probably we don't want to use ORM capabilities there?
You do not need to create a native query unless you want to. JPQL eventually is translated into SQL by the framework but the framework lets you call the native query also. Why would want to do that:
Low level access, which means that you can optimize and handle the mapping by yourself; with SQL you actually access the database table while with JPQL you access the entity objects;
Maybe you do not want to learn JPQL if you already know SQL
You already have the queries written in SQL, and do not have resources/time to port them to JPQL
createQuery uses JPAs own query language, you select from Class names instead of table names. This is not SQL, it is just similar, and is later transformed to real SQL. Mapping to java classes will be done automatically and actual class instances will be returned as result.
createNativeQuery uses real SQL, and will not be able to use JPA features. This method is used in general if you need to do something really odd that is not supported by JPA. A list of Object[] will be returned, and mapping to java objects will have to be done manually. In other words, its just like working with a DB before JPA came to, just slightly more convenient since connection handling is done automatically.
I have used it for optimization purposes. Using Native queries means that the ORM mapping is not in place, and instead of JPQL, you use the DB's native syntax. So, as #RasmusFranke also pointed out, if you need something that is not supported by JPA (like when you want to use DB vendor specific extensions, which is conceptually a bad idea, since JPA is all about being DB agnostic, but happens nevertheless. I know...)
The other effect of this is that by using native queries, only the supplied query is run. No eager fetching of other entities, or other unwanted stuff. This way, if you deal with huge amounts of objects, you can save some heap space.

What benefits MyBatis provides over working with plain JDBC

I need to write pretty straight forward DB code and I'm considering MyBatis over plain JDBC (I believe full ORM is an overkill).
Considering that in both MyBatis and plain JDBC you find yourself:
Hand writing SQL statements.
Manually wiring DB rows to JAVA DTO objects (either via code or config).
The MyBatis benefits over JDBC I know of are:
Out-of-the-box table/query caching.
Dynamic SQL.
SQL is stored outside of the code.
Templating SQL for easier DB vendor Independence.
What other MyBatis-Over-JDBC benefits are there to consider?
I dont know you'll count this one as advantage or not but there's MyBatisGenerator, And It generates all basic needed Queries plus some Advanced Queries too and DTO objects automatically based on a single XML file.
Plus it has Eclipse Plugin For the same.
Most of the times you do not need to map explicity columns to pojos so bullet number 2 is a difference rather than a similarity.
The main difference IMHO is the API that is much simpler in MyBatis than in JDBC. If used with Spring or Guice you will not need to call MyBatis API in your code at all.
Mappers and injection helps the testing a lot because mappers are plain interfaces so easy to mock.
About : 'Manually wiring DB rows to JAVA DTO objects (either via code or config).'
This is not totally true, if you use conventions you can get an automatic mapping from DB tables to Java classes, example you have a CUSTOMER table that has fields like ID, COMPANY_NAME, PHONE_NUMBER, and a Java class Customer with properties id, companyName and phoneNumber, MyBatis is smart enough to figurate the DB to camel case convention and no mapping is required from you. Great!
MyBatis require less code and is cleaner than plain JDBC coding
MyBatis supports named parameters, JDBC supports only placeholders? (ugg!)
With a single line you can change from Reuse Prepared Statement Mode to Bath Mode, in plain JDBC it will take you a rewrite of your code.

Java library to write sql statements?

Does exists a java library that can create sql statements?
I'm not in search of something fancy, just something at "string manipulation" level: I just use jdbc (with Preparestatements and Resultsets) but I don't really like to pass huge strings containing SQL code...
What I need is a "simple" Select class (or something similar); in my mind all I really want is to be able to do
SQLStatement stat = Select("*").from("table").where("condition and condition").orderby("something");
ResultSet rs = Connection.getResultSet(stat.toString());
/* equals to "select * from table where condition and condition order by something" */
Maybe I'm blind, but I cannot find something like that...
Obviously, I want some methods/class able to write inserts and updates and the other stuff...
I excluded ORMs for two reasons:
the db schema it's "old" and I cannot change it, and I'm not sure how can I adapt the ORM to follow our db
AFAIK the ORMs needs to change the model (maybe adding a base class, maybe you need to implements an interface) and the model in my project is big, old and grumpy
Onestly, I don't really like ORMs: Objects and Set theory just aren't made to be mapped (IMHO)
ORM (Object Relational Mapping) library is the clue.
Hibernate is the most mature one.
And the Hibernate-s Criteria API is object - oriented way to create such queries as You wished. Criteria API doc.
Hibernate is most likely what you're looking for. It contains many advanced features, but SQL statements are more straightforward.
Take a look at their site: http://www.hibernate.org/
I'd also recommend skimming through this guide:
https://www.owasp.org/index.php/Preventing_SQL_Injection_in_Java
Try SQLBuilder project. Honestly, I have not used this. Looking at their docs, i think it might suit your requirement.
You can also try to find similar APIs in Sourceforge,Google code etc..
I am not sure if you use Java for a native application or for the web.
If you use Java for web you could consider using the Play framework.
Easy and has Hibernate included with a really simple implementation (easier when implementing Hibernate yourself).

Using Spring's JDBC support to get output parameters

I'm using Spring's JDBC support to run SQL queries and updates on an Oracle database. I'd like to insert a row and then get the key that it was assigned (using an Oracle sequence). In normal JDBC code, I would include a RETURNING INTO clause and then register an output parameter (well described here)
However, I would like to just use Spring to handle all my JDBC work for me. For non-insert SQL statements, I'm currently using a MapSqlParameterSource object and registering all my input parameters. Can I also register an output parameter like this and have it returned to me? I looked over the Chapter 11 portion of the Spring docs, and I saw there was support for an output parameter if I'm using stored procedures, but I would like to avoid doing that if possible. Thanks.
I don't think the Spring JDBC support API provides explicit support for OUT parameters, so you may need to step back a bit and use the more general query API provided by JdbcTemplate:
Object execute(PreparedStatementCreator psc, PreparedStatementCallback action)
This lets you perform arbitrary JDBC operations within the scope of a Spring-managed connection and PrepatedStatement. The downside is that the handling and tidyup of things like ResultSets becomes your problem.
Check out this code - it may do what you want, not sure if Oracle supports this syntax though.
getReturnedGeneratedKeys() Spring JDBC Excample

Categories