Using Java 11 and JDBC.
Having PostgreSQL table "employee":
I need to have an ability to select data, but I don't know in advance, what WHERE conditions would be used.
It could be:
SELECT * FROM employee WHERE job_name='PRESIDENT';
SELECT * FROM employee WHERE job_name='PRESIDENT' OR salary>6000;
SELECT * FROM employee WHERE salary<5000 AND manager_id=68319;
Writing all possible SQL in the code, would take a lot of time.
Probably, there is some library, that already has implementation for it.
Try sqlBuilder [http://sqlobject.org/SQLBuilder.html]. it has support to build dynamic where clauses based on condition. something like below
var query = SQL
.SELECT("*")
.FROM("employee")
.WHERE()
._If(job_name=="PRESIDENT", "job_name = {0}", job_name)
.ORDER_BY("job_name");
Related
I use spring boot, and I want to add 1 year to a specific column in mysql database
String queryRecherche = "UPDATE myTable t SET t.dateDebut = DATE_ADD(t.dateDebut, INTERVAL 1 YEAR) WHERE.id = 3 ";
Query query = em.createQuery(queryRecherche);;
query.executeUpdate();
But I get the folowing error :
org.hibernate.query.sqm.ParsingException: line 1:66 no viable alternative at input 'DATE_ADD(t.dateDebut,INTERVAL1'
Have you please any suggestions to do this.
You're using Hibernate 6 (I can tell by the error message), so the correct HQL syntax to use is:
UPDATE MyEntity t SET t.dateDebut = t.dateDebut + 1 year WHERE t.id = 3
You had three errors in your query:
You referred to the name of a table instead of the name of an entity class in the UPDATE clause.
You used the unportable MySQL DATE_ADD function instead of the portable HQL date/time arithmetic described here.
The syntax of your WHERE clause was garbled.
Perhaps you meant for this to be a native SQL query, in which case you called the wrong method of Session. But there's no need to use native SQL for the above query. As you can see, HQL is perfectly capable of expressing that query.
You can use SQL directly, via createNativeQuery, or register a new function as shown in this example to call it from HQL
My laravel eloquent is the following:
Module::select(['a', 'b'])
->whereRaw("OR a ='one' OR a = 'five' OR a ='ten'")
->distinct()
->orderBy('a', 'ASC')
->get();
How can I convert it into hibernate?
You can use the toSql() method to get the SQL query.
For example
DB::table('users')->toSql();
returns the query
select * from users
Then you have to translate the SQL to HQL, using some manual.
Spring Data allows you to create queries using the method name.
Example:
List<Module> findDistinctModuleByAOrderByAAsc(String a);
I would like to launch simple code:
SelectQuery query = dsl.select(field ("id"), field("title")).from("dict.models").getQuery();
if (modelId > 0) query.addConditions(field("model_id", SQLDataType.INTEGER).equal(modelId));
But infortunately in getSQL() I can only see:
select id, title from dict.models where model_id = ?
Where is a mistake?
Thanks.
Query.getSQL() generates the SQL statement as it would be generated if you let jOOQ execute a PreparedStatement - with bind variables. The bind variables can be extracted in the right order via Query.getBindValues()
If you want to inline all bind values into the generated SQL, you have various options through the jOOQ API (all equivalent):
Using Query.getSQL(ParamType) with ParamType.INLINE
Using dsl.renderInlined(QueryPart)
Using StatementType.STATIC_STATEMENT in your Settings
I recently encountered the following problem with buiding queries in jooq (version 3.1.0):
I want to build delete statement with order and limit constraints. So, my aim is to build something like this:
DELETE FROM table ORDER BY field DESC LIMIT 1 (this is MySql syntax)
But i haven't found nesessary methods in result delete query object:
DSLContext context = createContext();
DeleteWhereStep delete = context.delete(createTable(table));
DeleteConditionStep whereStep = delete.where(condition);
whereStep.orderBy(...)//and no such method here
There are all nesessary methods in select statements and none for delete.
Is it possible to set order and limit for delete request in jooq?
As of jOOQ 3.2, these sorts of extensions are currently not implemented yet. Chances are, that #203 could be implemented in jOOQ 3.3, though.
In the mean time, you have two options:
Resort to plain SQL
i.e. write something like:
context.execute("DELETE FROM {0} ORDER BY {1} DESC LIMIT 1",
createTable(table),
field);
Manually transform your SQL statement into something equivalent
I suspect that the ORDER BY .. LIMIT extension to the MySQL DELETE statement is just sugar for:
DELETE FROM table t
WHERE t.id IN (
SELECT id FROM table
ORDER BY field LIMIT 1
)
Or with jOOQ:
context.delete(TABLE)
.where(TABLE.ID.in(
select(TABLE.ID)
.from(TABLE)
.orderBy(TABLE.FIELD)
.limit(1)
))
We have a data table where it has a function based index (database is Oracle). But in our Java EE ejb application, system accesses the data using jpa queries.
But in order to force the oracle to use the function based index instead of doing a full table scan, I need a way to tell the jpa container to generate the sql with the function defined in the index in the WHERE clause of the sql query.
As far as I know, we have to use native queries for creating customizations in the generated queries like that. But in order to use native queries we have to do many code changes.
Could anyone please suggest any other work around for solving this issue?
Index: (We needed to enforce unique constraint for Dev_Id + Dev_Type, but sometimes Dev_Id can be null while Dev_Type can be duplicated.)
(NVL2(Dev_Id, Dev_Id, NULL), NVL2(Dev_Id, Dev_Type, NULL))
Query we need: (In order to use the index)
Select * from some_table where NVL2(Dev_Id, Dev_Id, NULL) = 'some_val';
Container generated query:
Select * from some_table where Dev_Id = 'some_val';
Maybe creating a view and having JPA go through that is an option?
CREATE VIEW SOME_VIEW AS SELECT SOME_TABLE.*,
NVL2(Dev_Id, Dev_Id, NULL) AS NVL_DEV_ID FROM SOME_TABLE;
SELECT * FROM SOME_VIEW WHERE NVL_DEV_ID = ?
Or a virtual column on the table that evaluates to the function?
JPA 2.1 includes a FUNCTION operator that allows to invoke DB-specific functions:
from SomeEntity where function('NVL2', devId, devId, null) = 'some_val';
If you don't have JPA 2.1 available but are using Eclipselink >= 2.4, you can also use FUNCTION, as it is available as a Eclipselink extension.
If you have Eclipselink 2.3.x, you do not have FUNCTION, but you can use the equivalent FUNC that is available as a Eclipselink extension.