Java MySQL query named parameters? - java

Is there a way to have named parameters in Java MySQL query?
Like this:
SELECT * FROM table WHERE col1 = :val1 AND col2 = :val2
instead of this:
SELECT * FROM table WHERE col1 = ? AND col2 = ?
UPDATE: Im' using java.sql.*, however would be interested in alternatives capable of this.

Maybe Hibernate is good choice for you. It provided the query style as your description, and it's so powerful and convenient to do persistence work that you'll feel cool.
e.g
Query query = sesion.createQuery("from Student s where s.age = :age");
query.setProperties(student);
see the doc:http://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html#setParameter(java.lang.String, java.lang.Object)

The excellent JDBI library lets you do this and much more.

Yes, there are alternatives. By example, with javax.persistence.* you can achieve that quite easily.
http://docs.oracle.com/javaee/6/tutorial/doc/bnbrg.html
An entity manager will allow you to create dynamic (parametrized) queries with the methods EntityManager.createQuery, and EntityManager.createNamedQuery.

Related

How to use FIND_IN_SET in jpa

How can I use find_in_set in jpa?
I need to achieve like this
SQL - select * from teacher where find_in_set("5", deptIds) and id = 101
where deptIds have comma separated ids (I know it's bad idea but legacy.)
To do so I had been tried using Criteria but not found any Restrictions that can fulfill find_in_set.
Note - need possible solution with Criteria and Restrictions
criteriaBuilder.function("find_in_set", Boolean.class,
criteriaBuilder.literal(s),
root.get("field"))
Here is an example:
Here is java code snippet.
list.add(cb.greaterThan(cb.function("FIND_IN_SET", Integer.class,
cb.literal(val.toString()), root.get(attributeName)), 0));
select t from Teacher t where find_in_set("5", t.deptIds) = 0 and t.id = 101

Hibernate "Like" expressions on two sides Criteria

I'd like to use criteria and create something like this but with hibernate criterias:
WHERE concat(X, Y) like '%Some Value%'
I don't want to do it using query concatenation, but using Restrictions because I am making a dynamic library that gets the left and right side of the like operator? Am I clear? Please if not ask me to give more clarification.
Thank you!
Hope it may works.
Criteria crit = session.createCriteria(Table.class);
crit.add(Restrictions.ilike("param1 || param2", "%" + dniWithLetter + "%"));
If the above code not working, please go through the following link.
Can we concatenate two properties in Hibernate HQL query?
I think that the best solution for your problem is the following
...
Object[] params = {objX, objY, someValue};
Type[] typeOfParams = {Hibernate.STRING, Hibernate.STRING, Hibernate.STRING};
Criteria crit = session.createCriteria(Table.class);
crit.add(Restrictions.sqlRestriction("concat(?, ?) like '%?%'", params, typeOfParams));
...
When you use Restrictions.sqlRestriction, you can build a complex query with multiple parameters, you just have to set the parameters and type of each parameter, this is done with params array and typeOfparams array.
I hope this information helps you.
Good luck.

How to use multiple values in WHERE using JPA CriteriaBuilder

I have an example MyTable with 3 columns - id, common_id, creation_date, where common_id groups entries.
Now I would like to select using CriteriaBuilder all newest entries from each group (that is for each common_id get me latest creation_date).
In SQL the query would look like this:
select * from MyTable where (common_id, creation_date) in (select common_id, max(creation_date) from MyTable group by common_id)
Now I have tried to create the where predicate by writing something like (cb is CriteriaBuilder, root is a Root):
cb.array(root.get('common_id'), cb.max(root.get('creation_date')))
.in(
query.subquery(MyTable.class)
.select(cb.array(root.get('common_id'), cb.max(root.get('creation_date'))))
.groupBy(root.get('common_id')))
But unfortunately cb.array is not an Expression (it's a CompoundSelect), so I cannot use .in() on it.
Thanks for pointers!
could you create it using JPQL? As far that I know, that is not possible.
I looked at the Spect (4.6.16 Subqueries) and it talk about "simples select expression":
simple_select_clause ::= SELECT [DISTINCT] simple_select_expression
I believe that only one return is possible, if you look at the examples there you will not find anything like it.
You will need to use NativeQuery for it.

Spring JdbcTemplate's queryForList() with many args is not readable; SQLQuery don't give me list with column names

Note: This may be a simple question but I can't find a short way to make it clear. So, sorry for this long question.
In a project I am responsible, I use Spring 2.5, Hibernate 3.3.2 as middleware and Oracle database. As database is related to many other projects, some queries as really very complicated and I can't get a solution with Hibernate's solutions (HQL, Criteria, etc...). So I feel more comfortable with JdbcTemplate's queryForX() methods, as an example;
String sql = "select * from myTable";
jdbc.queryForList(sql);
Sure there are mostly "where" conditions and params indeed:
jdbc.querForList(sql, new Object[]{obj1,obj2,obj3 /* and many more arguments... */})
In this case, I must write question marks "?" for my parameters, so my SQL query string turns out some messy and hard to read; something like this:
select t1.col1, t2.col2, t1.col, --...some cols ,
sum(nvl(some_col1,?)-nvl(other_col2,?)) over (partition by col1,col2,col3,col4) sum_of_cols
from weird_table t1, another_table t2
where t1.col20=? and sum_of_cols>? and t1.col3=t2.col3 --and many ?'s...
and not exists (
select ? from boring_table t3 where -- many ?'s
)
--group by and order by order by etc
So now, which question mark is for which parameter? It is obvious but hard to read. But there are some other solutions for binded params like:
select * from a_table t where t.col1= :col1 and t.col2= :col2 -- and many more ":param"s
For this type query, we can write if it were Hibernate:
Query q = hibernateTemplate.createQuery();
q.setString("col1","a value");
q.setInteger("col2", 3);
I think it is more readable and easy to understand which value is what. I know I can do this with SQLQuery;
SQLQuery sq = hibernateTemplate.createSQLQuery();
/* same as above setInteger() etc. */
But this sq.list() gives me a list without a column name. so I have a basic array which is difficult to use:
[[1,2,"a"],[1,2,"b"], ...]
But with queryForList() I get better one:
[{COL1=1,COL2=2,COL3="a"},{COL1=1,COL2=2,COL3="b"},...]
So if I use queryForList(), I must write a very messy params Object;
or I use SQLQuery and then I have to get my list without a map as column names.
Is there a simple solution with mapped list using more readable param setting (like query.setX()) ?
Well you can use NamedParameterJdbcTemplate to do just that
Heres a sample
String query = "INSERT INTO FORUMS (FORUM_ID, FORUM_NAME, FORUM_DESC)
VALUES (:forumId,:forumName,:forumDesc)";
Map namedParameters = new HashMap();
namedParameters.put("forumId", Integer.valueOf(forum.getForumId()));
namedParameters.put("forumName", forum.getForumName());
namedParameters.put("forumDesc", forum.getForumDesc());
namedParameterJdbcTemplate.update(query, namedParameters);
You check the complete example with the source code in the below link
Spring NamedParameterJdbcTemplate Tutorial

Complicated expressions with Hibernate Criteria (like "isnull(retryCount,0)<3" )

I have some query like
SELECT * FROM JobTable
WHERE isnull(retryCount,0)<3
AND updatedOn < dateadd(MI,-5,getdate())
How to convert it to Criteria api calls? Point to use Criteria is to allow refactoring if fields names will be changed.
For simple things this is looks like
criteria.add(Restrictions.lt(JobTable.RETRYCOUNT_FULL, 3));
But what about my case?
criteria.add(Restrictions.lt(JobTable.UPDATEON_FULL, <???>);
criteria.add(Restrictions.lt( <someexpression(JobTable.RETRYCOUNT_FULL)> , 3));
I'm not sure of the correct name but hibernate has some standard functions which are mapped to the dialects functions. They can be used like this
Projections.sqlFunction("dateadd", Projections.property("property"), Hibernate.dateTime);
Hibernate Criteria API has Restrictions.sqlRestriction functions. In these functions you write your SQL the way you like and Hibernate embeds it in to your SQL.
criteria.add(Restrictions.sqlRestriction("isnull({alias}" + JobTable.RETRYCOUNT_FULL + ", 0) < ?", 3, new IntegerType());

Categories