createSqlQuery Hibernate, Java - java

I need to write hibernate query (createSQLquery) in Java land
I have query but I bit lost how to create criteria for my query.
basically I have to transfer regular where clause to hibernate .add(Restriction)
for instance lets take:
where (name LIKE '%test%' or lastname LIKE '%test%') and (site_id = 2) and (date>=121212 and date <= 343343)
Query query = sess.createSQLQuery(sql).addScalar("ID", Hibernate.long);
query.add(Restrictions.or (
Restrictions.like("name", "%test%")
Restrictions.like("lastname", "Fritz%")
))
.add(Restrictions.eq("site_id", new Integer(2)))
.add(Restrictions.add(Restrictions.gr("date_start", 122122)
.add(Restrictions.le("date_end", 345433)));
I did not have chance to run it since do not have access to my environment now, just would love to figure out this.
Thanks

You have to do like this
Criteria criteria = session.createCriteria(YourPojo.class);
criteria.add(Restrictions.eq("id", id));
criteria .add(Restrictions.or (
Restrictions.like("name", "%test%"),
Restrictions.like("lastname", "Fritz%")));
criteria.add(Restrictions.eq("site_id", new Integer(2)))
criteria.add(Restrictions.add(Restrictions.gr("date_start", 122122)
.add(Restrictions.le("date_end", 345433)));
return (criteria.list());

okay, problem solved this way:
Query from XML - I put in where clause
<Applications>
<Application name="AlertData">
<Query name="alerts">
<SQL>
SELECT
mr.measurement_date as measurementDate,
........ // more data
FROM measurement m
LEFT JOIN tags ON mr.tag_id = tags.tag_id
.......... // more joins
WHERE
mr.site_id = :siteid
$searchConstraints$ // just a string
$dateStartFragment$ // just a string
</SQL>
</Query>
</Application>
</Applications>
Next Java code:
if (search != null && !search.isEmpty()) {
searchFragment = " AND (UPPER(field1) LIKE :search" +
" OR UPPER(field2) LIKE :search)";
}
sql = this.prepareQuery(sql, ImmutableMap.of(
"searchConstraints", searchFragment,
"dateStartFragment", dateStartFragment
));
Query query = this.sessionFactory.getCurrentSession()
.createSQLQuery(sql)
//more query here
if (search != null && !search.isEmpty()) {
query.setString("search", "%" + search.toUpperCase() + "%");
}
public String prepareQuery(String queryString, Map<String, String> templateVars) {
ST stringTemplater = new ST(queryString, '$', '$');
for (String key : templateVars.keySet()) {
stringTemplater.add(key, templateVars.get(key));
}
String renderedQuery = stringTemplater.render();
return renderedQuery;
}

Related

Dynamically build SQL where clause based on presence of attributes in DTO

I have a screen where users can search a table based on 1 or more of its columns. I am passing the columns the users would like to filter by as a DTO to the backend.
There I am building a SQL to query by checking for the presence of these fields in the DTO...
Object transactionSearch (TransactionSearchDTO dto ){
StringBuilder transactionQuery = new StringBuilder()
transactionQuery.append("SELECT id, delivery_date, order_date, customer_name FROM transaction where 1=1 ")
if (dto.order_id) {
transactionQuery.append("and order_id = ${dto.order_id}")
}
if (delivery_date) {
transactionQuery.append("and order_id = ${delivery_date}")
}
if (customer_name) {
transactionQuery.append("and order_id = ${customer_name}")
}
}
What I am ending up with is a ton of if statements for each column.
Is there a way to achieve this without having an if block per filter?
I found some ideas here but I need a solution in Groovy or Java.
i suggest to use GString instead of StringBuilder to pass parameters correctly to groovy.sql.Sql
class DTO{
int id
String name
Date created
}
def a = new DTO(id:123, created:new Date())
GString f(DTO a){
GString q = GString.EMPTY + 'select ' + a.getProperties().collect{k,v-> k}.join(',')+' from T'
a.getProperties().each{k,v->
if(k!='class' && v!=null){
q = q + ( q.getValueCount()==0 ? ' WHERE ' : ' AND ' )
q = q + k + " = ${v}"
}
}
return q
}
def s = f(a)
println s
println s.getValues()
println s.getStrings()

JAVA EclipseLink optional query parameters

I have query which filters items by certain conditions:
#NamedQueries({
#NamedQuery(
name = ITEM.FIND_ALL_PARAMS_BY_COMPANY_COUNTRY_GROUP,
query = "SELECT i FROM Item i where "
+ "((i.idCompany=:companyId AND i.idEMGroup=:groupId) "
+ "OR (i.idCompany=:companyId AND i.idEMCountry =:countryId AND i.idEMGroup is null) "
+ "OR (i.idCompany is null AND i.idEMCountry = :countryId AND i.idEMGroup is null)) "
+ "order by i.idEMCountry desc, i.idCompany desc, i.idEMGroup desc")
})
In some cases parameters idEMGroup o companyId can be null which generates sql looking like this IdEmCompany = 200630758) AND (IdEMGroup = NULL) and it is incorrect sql syntax is it possible to dynamically if value is null for it as 'Column IS NULL' instead of 'Column = NULL' without adding a lot of if's, or it's just better to rewrite this query using Criteria API and just check if value is present and add predicates on certain conditions ?
Correct answer would be to use CriteriaQuery.
Though it is also possible to construct the query dynamically but manipulating #NamedQuery is not possible or might require stuff that makes it not worth to do.
Instead you could construct the query first as a String and create TypedQuery by manipulating the query string
String strQuery = "SELECT i FROM Item i"; // .. + the rest of stuff
if(null==companyId) {
// add something like "companyId IS :companyId"
// ":companyId" coulöd also be NULL"
// but to enable using tq.setParameter("companyId", companyId)
// without checking if there is param "companyId" so there always will
} else {
// add something like "companyId=:companyId"
}
TypedQuery<Item> tq = entityManager.createQuery(strQuery, Item.class);
tq.setParameter("companyId", companyId);
There will be some IFs but so will be in CriteriaQuery construction also.

Extracting SubQuery details using SQLQueryParserManager of Eclipse DTP

I am using eclipse SQLQueryParserManager to extract table name and column names from a sql query. I am getting correct details if I use normal query. But when I use subquery within a query, I am not able to get details of subquery.
Here is what I have done :
SQLQueryParserManager parserManager = SQLQueryParserManagerProvider.getInstance()
.getParserManager("oracle", "10g");
SQLQueryParseResult parseResult = parserManager.parseQuery("select distinct xyz
from t_abc where type = 7 and transmiss_id in (select wxy from t_abc where
transmi_name like 'us_'");
QueryStatement resultObject = parseResult.getQueryStatement();
String parsedSQL = resultObject.getSQL();
List tableList = StatementHelper.getTablesForStatement(resultObject);
for (Object obj : tableList) {
TableInDatabase t = (TableInDatabase) obj;
System.out.println(" Tables : " + t.getName());
for (Object column : t.getValueExprColumns()) {
System.out.println(" Columns : " + ((ValueExpressionColumn)column).getName());
}
}
Can anyone suggest what I have to use , in order to get subquery result?

How to make recursive query in SQLite?

if my data structure is like this
parentA
-------parentAA
--------------parentAAA
---------------------childA
if i can get "childA.name" . how can i know all the parent name till the top level.
so it will be like this > parentA/parentAA/parentAAA/childA
what is the best way to do this ?
i'm working with SQLite and JAVA/android .. thanks in adv.
____________ EDIT
Okay guys, thanks for all of u . so i just make it by repeating "select query". BOTTOM-UP this is the method i create
public String getPath(int id, int type) {
StringBuilder pathBuilder = new StringBuilder();
String sql = null;
int parentId = 0;
if (id == 0) {
pathBuilder.insert(0, "/root/");
return pathBuilder.toString();
}
if (type == LayerManagementActivity.PARENT) {
do {
sql = "SELECT id, name, parent_id from parents_table where id="
+ id;
Cursor c = mDatabase.rawQuery(sql, null);
if (c.moveToFirst()) {
parentId = c.getInt(2);
id = c.getInt(0);
pathBuilder.insert(0, "/" + c.getString(1));
c.close();
}
id = parentId;
} while (parentId != 0);
pathBuilder.insert(0, "/root");
pathBuilder.append("/");
} else if (type == LayerManagementActivity.CHILD) {
sql = "SELECT id, name, folder_id FROM childs_table WHERE id=" + id;
Cursor c = mDatabase.rawQuery(sql, null);
if (c.moveToFirst()) {
pathBuilder.append(c.getString(1));
id = c.getInt(0);
int folderId = c.getInt(2);
String path = getPath(folderId, LayerManagementActivity.PARENT);
pathBuilder.insert(0, path);
}
c.close();
}
Log.d("crumb", pathBuilder.toString());
return pathBuilder.toString();
}
In this SQLite Release 3.8.3 On 2014-02-03 has been added support for CTEs. Here is documentation WITH clause
Example:
WITH RECURSIVE
cnt(x) AS (
SELECT 1
UNION ALL
SELECT x+1 FROM cnt
LIMIT 1000000
)
SELECT x FROM cnt;
I have a table called project with a column named rates.
The rates column is a string that holds a JSON array.
To split this string into rows that I can use in an IN statement to get rows from the related table, I use this for the IN part
WITH
split(s, p) AS (
SELECT substr(printf("%s%s", ss, ","), instr(ss, ",")+1), trim(substr(ss, 0, instr(ss, ","))) from ( select replace(replace(rates,"[",""), "]","") ss from project where rowid = 1)
UNION ALL
SELECT substr(s, instr(s, ",")+1), trim(substr(s, 0, instr(s, ","))) FROM split
where p!=""
)
select p from split where p!=""
You can use nested set model. Nested sets have big advantage that they can be implemented in most SQL engines using simple, non-recursive SQL queries.
SQLite doesn't support recursive CTEs (or CTEs at all for that matter),
there is no WITH in SQLite. Since you don't know how deep it goes, you can't use the standard JOIN trick to fake the recursive CTE. You have to do it the hard way and implement the recursion in your client code:
Grab the initial row and the sub-part IDs.
Grab the rows and sub-part IDs for the sub-parts.
Repeat until nothing comes back.

hql query formation

I want to construt a hql query like
select PLAN_ID from "GPIL_DB"."ROUTE_PLAN" where ASSIGNED_TO
in ('prav','sheet') and END_DATE > todays date
I am doing in this way but getting an error in setting parameters
s=('a','b');
Query q = getSession().createQuery("select planId from RoutePlan where assignedTo in REG ");
if(selUsers != null) {
q.setParameter("REG", s);
}
where i am doing wrong? Please help in executing this hwl based query having in clause
You need to assign the parameter list in the query. Also note the brackets around the parameter because it is an 'in' query.
Query q = getSession()
.createQuery("select planId from RoutePlan where assignedTo in (:REG) ");
if(selUsers != null) {
q.setParameterList("REG", s);
}
You can read more about how to use parameters in HQL in the hibernate reference, but this is the relevant example pasted from there:
//named parameter list
List names = new ArrayList();
names.add("Izi");
names.add("Fritz");
Query q = sess.createQuery("from DomesticCat cat where cat.name in (:namesList)");
q.setParameterList("namesList", names);
List cats = q.list();

Categories

Resources