I came up with the solution and wanted to know any other better approach to handle this problem ?
I am not using hibernate instead using JDBC template.
I've Employee table with following attributes
id (Auto generated Primary key)
first_name
last_name
salary
Requirement :
1.Write getByFilter API in EmployeeDAO.
2.If any of the field is null in the filter object ignore that in the query.
Solution :
I came up with following generic solution.
public List<Employee> getByFilter(Employee filter){
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(
getDataSource());
String query = "SELECT ID as id,"+
"first_name as firstName,"+
"last_name as lastName,"+
"dob as dob ,"+
"department_name as departmentName,"+
"salary as salary"+
"FROM employee "+
"WHERE "+
"(:id IS NULL OR id = :id ) AND"+ // Handling second requirement if field is null
"(:first_name IS NULL or first_name = :firstName ) AND"+
"(:last_name IS NULL or first_name = :lastName) AND"+
"(:salary IS NULL OR salary = :salary)";
Map<String, Object> aMap = new HashMap<String, Object>();
aMap.put("id", filter.getId());
aMap.put("firstName", filter.getFirstName());
aMap.put("lastName", filter.getLastName());
aMap.put("salary", filter.getSalary());
return namedParameterJdbcTemplate.query(getQuery, aMap,
new BeanPropertyRowMapper<Employee>(Employee.class));
}
A better option can be to use hibernate criteria so that it will reduce the query
Criteria criteria = session.createCriteria(classname);
criteria.add(Restrictions.eq("first_name", firstName));
criteria.add(Restrictions.eq("last_name", lastName));
//same for all properties
//for checking null it will be like
criteria.add(Restrictions.isNotNull("id "));
//same for others
hibernate criteria provides better options to write the database query and easier and cleaner approach
Related
SELECT NEW Map (PRODUCT_CATEGORY, COUNT(PRODUCT_CATEGORY) AS COUNTER) from Product WHERE USER_ID = (SELECT USER_ID FROM USERS WHERE USERNAME='burak123'
Hi everyone,
As hibernates document says here: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-select
I am trying to map the query result into a hash map like this
#Query(value = "SELECT NEW Map( PRODUCT_CATEGORY , COUNT(PRODUCT_CATEGORY) AS COUNTER ) from Product WHERE USER_ID=(SELECT USER_ID FROM USERS WHERE USERNAME=(:username)) ",nativeQuery = true)
HashMap<Integer,Integer> getCategoryCountsWithUsername(#Param("username")String username);
But it throws an JdbcSyntaxErrorException. I am trying to solve this for like 1 hours already. Can someone help?
You are using a native query, not an HQL query. Check your SQL syntax.
With a native query, your named parameter won't work. You need to remove the nativeQuery = true
I've a database with many thousands of tables that have been (and continue to be) created with a naming strategy - one table per calendar day:
data_2010_01_01
data_2010_01_02
...
data_2020_01_01
All tables contain sensor data from the same system in the same shape. So a single entity (lets call it SensorRecord) will absolutely map to all tables.
I'd imagined something like this would work:
#Query(nativeQuery = true, value = "SELECT * FROM \"?1\"")
Collection<SensorRecord> findSensorDataForDate(String tableName);
But it does not, and reading around the topic seems to suggest I am on the wrong path. Most posts on dynamic naming seem to state explicitly that you need one entity per table, but generating thousands of duplicate entities also seems wrong.
How can I use JPA (JPQL?) to work with this data where the table name follows a naming convention and can be changed as part of the query?
Parameters are only allowed in the where clause.
You can create custom repository method returns collection of SensorRecord dto. No need to map so many entities. You should get List<Object []> as query result and manually create dto objects.
#Autowired
EntityManager entityManager;
public List<SensorRecord> findSensorDataForDate(LocalDate date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy_MM_dd");
String tableName = "data_" + date.format(formatter);
Query query = entityManager.createNativeQuery(
"select t.first_column, t.second_column from " + tableName + " t");
List<Object[]> queryResults = query.getResultList();
List<SensorRecord> sensorRecords = new ArrayList<>();
for (Object[] row : queryResults) {
SensorRecord record = new SensorRecord();
record.setFirstParameter((Integer) row[0]);
record.setSecondParameter((String) row[1]);
sensorRecords.add(record);
}
return sensorRecords;
}
Could it be just syntax error?
This has worked for me:
#Query(value = "select * from job where job.locked = 1 and job.user = ?1", nativeQuery = true)
public List<JobDAO> getJobsForUser(#Param("user") String user);
I am trying to perform an UPDATE on a MySQL database where I update only one single column full of values corresponding to the correct index position. Here is my current code:
JdbcTemplate temp = new JdbcTemplate(sqlDataSource);
List<Map<String, Object>> results = temp.queryForList("SELECT last_name FROM actor");
List<Object[]> params = new ArrayList<Object[]>();
for (Map<String, Object> row : results) {
params.add(new Object[]{row.get("last_name"), row.get("actor_id")});
}
String sql = "UPDATE actor SET first_name= ? WHERE actor_id=?";
temp.batchUpdate(sql, params)
In this example, I am trying to update all first names in my table to the last names. My main question is how can I include a parameter for the "SET first_name = ?" as well as the WHERE condition "WHERE actor_id = ?" as well? Is this possible with JdbcTemplate?
I think a simple Google search can solve your problem(s).
If you just look up JdbcTemplate batchUpdate, it should guide you in the right direction.
With that said, have a look at these:
https://www.tutorialspoint.com/springjdbc/springjdbc_jdbctemplate
why spring jdbcTemplate batchUpdate insert row by row
Say I have this table
CREATE TABLE person(
person_id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
x_cordinates INT,
y_cordinates INT
);
In the past I have used
Person person = EntityManager.find(Person.class, primaryKey);
But the primary key in this instance is auto incremented, is it possible to get a row back using the other colums such as first_name and last_name to get the primary key along with the other values ?
You can create a NamedQuerry like that :
#NamedQuery(name="person.findAll", query="SELECT p FROM Person p WHERE like :first_name")
And can assign a value to "first_name" like that :
query.setParamter("fist_name", "%name%");
You can read this documentation.
Use method createQuery or createNativeQuery of entityManager.
With createQuery you have to use JPQL syntax and with createNativeQuery, you've to use the standard SQL syntax.
For example :
Query query = EntityManager.createQuery("select * from person p where p.first_name = :fname");
17.
query.setParameter("fname", firstName);
Person p = query.getSingleResult();
Query qry = session.createQuery("From RegistrationBean where ? = ?");
qry.setString(0,searchCriteria);
qry.setString(1,searchField);
searchList =(ArrayList<RegistrationBean>) qry.list();
RegistrationBean Entity class has userName, address, age fields..
I want to search a user by search criteria such as userName, address etc. using the above single query...
But the query is returning me zero results even though the user exist..
what's the problem?
Both parameters are set to 0 position, the second is not set. The position parameter should be set sequentially.
qry.setParameter(0,searchCriteria);
qry.setParameter(1,searchField);
But the field name should pass in the following way
String queryString = "from RegistrationBean as model where model." + propertyName + "= ?";
Query queryObject = getSession().createQuery(queryString);
queryObject.setParameter(0, value);
return queryObject.list();
Try in the following way:
Query qry = session.createQuery("select * from RegistrationBean where :searchCrit = :searchValue");
qry.setString(":searchCrit",searchCriteria);
qry.setString(":searchValue",searchField);
searchList =(ArrayList<RegistrationBean>) qry.list();
It is more appropriate to use it like this instead of setting indexes (your problem is that you set both to 0), because if you change something in your query you might need to change your setters afterwards.